#ifndef KITSOURCE_H #define KITSOURCE_H /** * @brief Video/Audio source file handling * * @file kitsource.h * @author Tuomas Virtanen * @date 2018-06-27 */ #include #include "kitchensink/kitconfig.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Type of the stream. * * This is used by Kit_SourceStreamInfo and Kit_GetSourceStreamInfo(). */ typedef enum Kit_StreamType { KIT_STREAMTYPE_UNKNOWN, ///< Unknown stream type KIT_STREAMTYPE_VIDEO, ///< Video stream KIT_STREAMTYPE_AUDIO, ///< Audio stream KIT_STREAMTYPE_DATA, ///< Data stream KIT_STREAMTYPE_SUBTITLE, ///< Subtitle streawm KIT_STREAMTYPE_ATTACHMENT ///< Attachment stream (images, etc) } Kit_StreamType; /** * @brief Audio/video source. * * Should be created using Kit_CreateSourceFromUrl() or Kit_CreateSourceFromCustom(), and * closed with Kit_CloseSource(). * * Source must exist for the whole duration of using a player. You must take care of closing the source * yourself after you are done with it! */ typedef struct Kit_Source { void *format_ctx; ///< FFmpeg: Videostream format context void *avio_ctx; ///< FFmpeg: AVIO context } Kit_Source; /** * @brief Information for a source stream. * * Fetch information by using Kit_GetSourceStreamInfo(). */ typedef struct Kit_SourceStreamInfo { int index; ///< Stream index Kit_StreamType type; ///< Stream type } Kit_SourceStreamInfo; /** * @brief Callback function type for reading data stream * * Used by Kit_CreateSourceFromCustom() for reading data from user defined source. * * A custom reader function must accept three arguments: * - userdata, this is the same data as set as last argument for Kit_CreateSourceFromCustom * - buf, a buffer the data must be copied into * - size, how much data you are expected to provide at maximum. * * The function must return the amount of bytes copied to the buffer. * * Note that this callback is passed directly to ffmpeg avio, so please refer to ffmpeg documentation * for any further details. */ typedef int (*Kit_ReadCallback)(void *userdata, uint8_t *buf, int size); /** * @brief Callback function type for seeking data strema * * Used by Kit_CreateSourceFromCustom() for seeking a user defined source. * * A custom seeking function must accept three arguments: * - userdata, this is the same data as set as last argument for Kit_CreateSourceFromCustom * - offset, an seeking offset in bytes * - whence, reference position for the offset. * * The function must return the position (in bytes) we seeked to. * * Note that this callback is passed directly to ffmpeg avio, so please refer to ffmpeg documentation * for any further details. */ typedef int64_t (*Kit_SeekCallback)(void *userdata, int64_t offset, int whence); /** * @brief Create a new source from a given url * * This can be used to load video/audio from a file or network resource. If you wish to * use network resources, make sure the library has been initialized using KIT_INIT_NETWORK flag. * * This function will return an initialized Kit_Source on success. Note that you need to manually * free the source when it's no longer needed by calling Kit_CloseSource(). * * On failure, this function will return NULL, and further error data is available via Kit_GetError(). * * For example: * ``` * if(Kit_CreateSourceFromUrl(filename) == NULL) { * fprintf(stderr, "Error: %s\n", Kit_GetError()); * return 1; * } * ``` * * @param url File path or URL to a video/audio resource * @return Returns an initialized Kit_Source* on success or NULL on failure */ KIT_API Kit_Source* Kit_CreateSourceFromUrl(const char *url); /** * @brief Create a new source from custom data * * This can be used to load data from any resource via the given read and seek functions. * * This function will return an initialized Kit_Source on success. Note that you need to manually * free the source when it's no longer needed by calling Kit_CloseSource(). * * On failure, this function will return NULL, and further error data is available via Kit_GetError(). * * For example: * ``` * if(Kit_CreateSourceFromUrl(filename) == NULL) { * fprintf(stderr, "Error: %s\n", Kit_GetError()); * return 1; * } * ``` * * @param read_cb Read function callback * @param seek_cb Seek function callback * @param userdata Any data (or NULL). Will be passed to read_cb and/or seek_cb functions as-is. * @return Returns an initialized Kit_Source* on success or NULL on failure */ KIT_API Kit_Source* Kit_CreateSourceFromCustom(Kit_ReadCallback read_cb, Kit_SeekCallback seek_cb, void *userdata); /** * @brief Closes a previously initialized source * * Closes a Kit_Source that was previously created by Kit_CreateSourceFromUrl() or Kit_CreateSourceFromCustom() * and frees up all memory and resources used by it. Using the source for anything after this will * lead to undefined behaviour. * * Passing NULL as argument is valid, and will do nothing. * * @param src Previously initialized Kit_Source to close */ KIT_API void Kit_CloseSource(Kit_Source *src); /** * @brief Fetches stream information for a given stream index * * Sets fields for given Kit_SourceStreamInfo with information about the stream. * * For example: * ``` * Kit_SourceStreamInfo stream; * if(Kit_GetSourceStreamInfo(source, &stream, 0) == 1) { * fprintf(stderr, "Error: %s\n", Kit_GetError()); * return 1; * } * fprintf(stderr, "Stream type: %s\n", Kit_GetKitStreamTypeString(stream.type)) * ``` * * @param src Source to query from * @param info A previously allocated Kit_SourceStreamInfo to fill out * @param index Stream index (starting from 0) * @return 0 on success, 1 on error. */ KIT_API int Kit_GetSourceStreamInfo(const Kit_Source *src, Kit_SourceStreamInfo *info, int index); /** * @brief Gets the amount of streams in source * * @param src Source to query from * @return Number of streams in the source */ KIT_API int Kit_GetSourceStreamCount(const Kit_Source *src); /** * @brief Gets the best stream index for a given stream type. * * Find the best stream index for a given stream type, if one exists. If there is no * stream for the wanted type, will return -1. * * @param src Source to query from * @param type Stream type * @return Index number on success (>=0), -1 on error. */ KIT_API int Kit_GetBestSourceStream(const Kit_Source *src, const Kit_StreamType type); #ifdef __cplusplus } #endif #endif // KITSOURCE_H