------------------------------------全系列文章目录------------------------------------
相互关系
URLContext
- 用于描述URLProtocol的上下文。
typedef struct URLContext {
const AVClass *av_class; /**< information for av_log(). Set by url_open(). */
const struct URLProtocol *prot;
void *priv_data;
char *filename; /**< specified URL */
int flags;
int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */
int is_streamed; /**< true if streamed (no seek possible), default = false */
int is_connected;
AVIOInterruptCB interrupt_callback;
int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */
const char *protocol_whitelist;
const char *protocol_blacklist;
int min_packet_size; /**< if non zero, the stream is packetized with this min packet size */
} URLContext;
URLProtocol
- 将所有协议都抽象为统一的接口,每种协议都对应一个URLProtocol,如rtp,rtmp,file等。
typedef struct URLProtocol {
const char *name;
int (*url_open)( URLContext *h, const char *url, int flags);
/**
* This callback is to be used by protocols which open further nested
* protocols. options are then to be passed to ffurl_open_whitelist()
* or ffurl_connect() for those nested protocols.
*/
int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
int (*url_accept)(URLContext *s, URLContext **c);
int (*url_handshake)(URLContext *c);
/**
* Read data from the protocol.
* If data is immediately available (even less than size), EOF is
* reached or an error occurs (including EINTR), return immediately.
* Otherwise:
* In non-blocking mode, return AVERROR(EAGAIN) immediately.
* In blocking mode, wait for data/EOF/error with a short timeout (0.1s),
* and return AVERROR(EAGAIN) on timeout.
* Checking interrupt_callback, looping on EINTR and EAGAIN and until
* enough data has been read is left to the calling function; see
* retry_transfer_wrapper in avio.c.
*/
int (*url_read)( URLContext *h, unsigned char *buf, int size);
int (*url_write)(URLContext *h, const unsigned char *buf, int size);
int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);
int (*url_close)(URLContext *h);
int (*url_read_pause)(URLContext *h, int pause);
int64_t (*url_read_seek)(URLContext *h, int stream_index,
int64_t timestamp, int flags);
int (*url_get_file_handle)(URLContext *h);
int (*url_get_multi_file_handle)(URLContext *h, int **handles,
int *numhandles);
int (*url_get_short_seek)(URLContext *h);
int (*url_shutdown)(URLContext *h, int flags);
const AVClass *priv_data_class;
int priv_data_size;
int flags;
int (*url_check)(URLContext *h, int mask);
int (*url_open_dir)(URLContext *h);
int (*url_read_dir)(URLContext *h, AVIODirEntry **next);
int (*url_close_dir)(URLContext *h);
int (*url_delete)(URLContext *h);
int (*url_move)(URLContext *h_src, URLContext *h_dst);
const char *default_whitelist;
} URLProtocol;
-
如file协议的定义如下
const URLProtocol ff_file_protocol = { .name = "file", .url_open = file_open, .url_read = file_read, .url_write = file_write, .url_seek = file_seek, .url_close = file_close, .url_get_file_handle = file_get_handle, .url_check = file_check, .url_delete = file_delete, .url_move = file_move, .priv_data_size = sizeof(FileContext), .priv_data_class = &file_class, .url_open_dir = file_open_dir, .url_read_dir = file_read_dir, .url_close_dir = file_close_dir, .default_whitelist = "file,crypto,data" };
AVIOCntext
- 该结构体用于管理输入/输出数据流。
/*!!! 略有删减*/
typedef struct AVIOContext {
const AVClass *av_class;
unsigned char *buffer; //数据缓存开始的位置
int buffer_size; //缓冲区大小
unsigned char *buf_ptr; //缓冲区当前位置
unsigned char *buf_end; //缓冲区的结尾
void *opaque; //私有数据,指向了URLContext结构体
int64_t pos; //缓冲区当前位置在文件中的pos
int eof_reached; //如果由于错误或 eof 而无法读取,则为 true
int error;
int write_flag;
int max_packet_size;
int min_packet_size;
unsigned long checksum;
unsigned char *checksum_ptr;
int seekable;
int direct;
const char *protocol_whitelist; //允许的protocol列表
const char *protocol_blacklist; //不允许的protocol列表
int ignore_boundary_point;
int64_t written;
unsigned char *buf_ptr_max;
} AVIOContext;
AVFormatContext
- 该结构体描述了一个媒体文件或媒体流的构成和基本信息。
- 使用avformat_alloc_context函数去申请一个AVFormatContext结构体;使用avformat_open_input函数去打开一个输入文件;使用avformat_find_stream_info去查找其中数据流信息。
/*!!! 略有删减*/
typedef struct AVFormatContext {
const AVClass *av_class;
const struct AVInputFormat *iformat; //输入容器的格式
const struct AVOutputFormat *oformat; //输出容器的格式
void *priv_data; //格式的私有数据
AVIOContext *pb; // 管理输入/输出数据流
/* stream info */
int ctx_flags;
unsigned int nb_streams; //数据流streams的数量
AVStream **streams; //数据流的列表
char *url; //输入或输出的URL
int64_t start_time; //第一帧的开始时间,单位为(秒/AV_TIME_BASE)
int64_t duration; //数据流的持续时间,单位为(秒/AV_TIME_BASE)
int64_t bit_rate; //总的比特率
unsigned int packet_size;
int max_delay;
int flags; //该标志位用于修饰(de)muxer的行为,见AVFMT_FLAG_*
int64_t probesize; //为确定流属性,从输入流中读取的最大字节数
int64_t max_analyze_duration;//为确定流属性,从输入流中读取的最大持续时间,单位为AV_TIME_BASE
const uint8_t *key;
int keylen;
unsigned int nb_programs;
AVProgram **programs;
enum AVCodecID video_codec_id; //强制视频的解码器
enum AVCodecID audio_codec_id; //强制音频的解码器
enum AVCodecID subtitle_codec_id; //强制字幕的解码器
unsigned int max_index_size;
unsigned int max_picture_buffer; //缓冲从实时捕获设备获得帧的最大内存量(以字节为单位)
unsigned int nb_chapters;
AVChapter **chapters;
AVDictionary *metadata; //元数据,key-value形式
int64_t start_time_realtime; //流开始的现实世界时间,以1970-1-1-00:00开始的微秒为基准
int fps_probe_size; //avformat_find_stream_info中用于确认fps的帧数量
int error_recognition;
AVIOInterruptCB interrupt_callback;
int debug;
int64_t max_interleave_delta; //mux时,队列中首尾数据包时间戳的最大差值,超过该值输出一个数据包
int strict_std_compliance;
int event_flags; //事件标志
int max_ts_probe;
int avoid_negative_ts; //复用时避免负的时间戳
int ts_id;
int audio_preload;
int max_chunk_duration;
int max_chunk_size;
int use_wallclock_as_timestamps;
int avio_flags;
enum AVDurationEstimationMethod duration_estimation_method; //持续时间估计的方法
int64_t skip_initial_bytes;
unsigned int correct_ts_overflow;
int seek2any;
int flush_packets;
int probe_score;
int format_probesize; //为了识别输入格式,从输入读取的最大字节数
char *codec_whitelist; //允许的解码器列表,为NULL时表示默认
char *format_whitelist; //允许的demuxers列表,为NULL时表示默认
int io_repositioned;
const AVCodec *video_codec; //强制使用视频解码器
const AVCodec *audio_codec; //强制使用音频解码器
const AVCodec *subtitle_codec; //强制使用字幕解码器
const AVCodec *data_codec; //强制使用数据解码器
int metadata_header_padding;
void *opaque; //用户私人数据
av_format_control_message control_message_cb;
int64_t output_ts_offset;
uint8_t *dump_separator;
enum AVCodecID data_codec_id; //强制数据的解码器
char *protocol_whitelist; //允许的protocol列表
char *protocol_blacklist; //不允许的protocol列表
int max_streams; //最大的数据流数量
int skip_estimate_duration_from_pts;
int max_probe_packets; //解码时可探测的最大packet数量
} AVFormatContext;
示例代码
-
打印AVIOCntext信息
void AVIOContext_info(AVIOContext *ctx) { printf("protocol_whitelist: %s\n", ctx->protocol_whitelist); printf("protocol_blacklist: %s\n", ctx->protocol_blacklist); printf("eof_reached: %d, buffer_size: %d\n\n", ctx->eof_reached, ctx->buffer_size); }
-
打印AVFormatContext信息
void AVFormatContext_info(AVFormatContext *ctx) { AVDictionaryEntry *tag = NULL; printf("url: %s\n", ctx->url); printf("nb_streams: %d, total bit_rate: %ld kbps\n", ctx->nb_streams, ctx->bit_rate/1024); printf("start_time: %ld, duration: %.2ld:%ld:%ld\n", ctx->start_time, ctx->duration/AV_TIME_BASE/3600, ctx->duration/AV_TIME_BASE/60, ctx->duration/AV_TIME_BASE%60); switch (ctx->duration_estimation_method) { case AVFMT_DURATION_FROM_PTS: printf("AVFMT_DURATION_FROM PTS\n"); break; case AVFMT_DURATION_FROM_STREAM: printf("AVFMT_DURATION_FROM STREAM\n"); break; case AVFMT_DURATION_FROM_BITRATE: printf("AVFMT_DURATION_FROM BITRATE\n"); break; default: break; } printf("codec_whitelist: %s\n", ctx->codec_whitelist); printf("format_whitelist: %s\n", ctx->format_whitelist); printf("protocol_whitelist: %s\n", ctx->protocol_whitelist); printf("protocol_blacklist: %s\n", ctx->protocol_blacklist); printf("metadata: \n\t"); while ((tag = av_dict_get(ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) printf("[%s = %s]; ", tag->key, tag->value); printf("\n\n"); }
-
输出测试视频的AVIOCntext和AVFormatContext信息
int main(int argc, char **argv) { AVFormatContext *fmt_ctx = NULL; avformat_network_init(); avformat_open_input(&fmt_ctx, "../../output/test.mp4", NULL, NULL); avformat_find_stream_info(fmt_ctx, NULL); AVFormatContext_info(fmt_ctx); AVIOContext_info(fmt_ctx->pb); return 0; }
-
输出如下:
url: ../../output/test.mp4 nb_streams: 2, total bit_rate: 2165 kbps start_time: 0, duration: 00:11:14 AVFMT_DURATION_FROM STREAM codec_whitelist: (null) format_whitelist: (null) protocol_whitelist: file,crypto,data protocol_blacklist: (null) metadata: [major_brand = isom]; [minor_version = 512]; [compatible_brands = isomiso2avc1mp41]; [encoder = Lavf58.20.100]; protocol_whitelist: file,crypto,data protocol_blacklist: (null) eof_reached: 0, buffer_size: 32768