AVFormatContext介绍(avformat.h)

 


typedef struct AVFormatContext结构体介绍

表示解复用(解码)或复用(编码)多媒体流的格式上下文。在使用FFMPEG进行开发的时候,AVFormatContext是一个贯穿时钟的数据结构,很多函数都要用它作为参数。它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体。

typedef struct AVFormatContext {
    const AVClass *av_class;//指向AVOptions和日志记录的AVClass结构的指针,用于AVOptions和日志记录
    struct AVInputFormat *iformat;//指向输入格式的指针。
    struct AVOutputFormat *oformat;//指向输出格式的指针。
    void *priv_data;//格式私有数据,一个AVOptions的结构。
    AVIOContext *pb;//格式的I/O上下文
    unsigned int nb_streams;//文件中流的信息
    AVStream **streams;//文件中的信息
    char filename[1024];//输入或输出文件名 
    int64_t start_time;//有关流的时间信息
    int64_t duration;//有关流的时间信息
    int bit_rate;//总流比特率
    unsigned int packet_size;//数据包大小
    int max_delay;//最大延迟
    int flags;//标志位,指示各种格式相关的属性,如是否生成pts、是否忽略索引等。
#define AVFMT_FLAG_GENPTS       0x0001 ///< Generate missing pts even if it requires parsing future frames.
#define AVFMT_FLAG_IGNIDX       0x0002 ///< Ignore index.
#define AVFMT_FLAG_NONBLOCK     0x0004 ///< Do not block when reading packets from input.
#define AVFMT_FLAG_IGNDTS       0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN     0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE      0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
#define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_MP4A_LATM    0x8000 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_SORT_DTS    0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_PRIV_OPT    0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Dont merge side data but keep it separate
    unsigned int probesize;//数据探测大小
    int max_analyze_duration;//最大分析时长
    const uint8_t *key;//密钥
    int keylen;//密钥长度
    unsigned int nb_programs;//文件中程序的数量
    AVProgram **programs;//指向AVProgram指针数组的指针,表示文件中的所有程序。
    enum CodecID video_codec_id;//视频编码器ID
    enum CodecID audio_codec_id;//音频编码器ID
    enum CodecID subtitle_codec_id;//字幕编解码器ID
    unsigned int max_index_size;//最大索引大小
    unsigned int max_picture_buffer;//最大图像缓冲区大小
    unsigned int nb_chapters;//文件中章节的数量
    AVChapter **chapters;//指向AVChapter指针数组的指针,表示文件中的所有章节
    AVDictionary *metadata;//元数据
    int64_t start_time_realtime;//实际开始时间
    int fps_probe_size;//fps探测大小
    int error_recognition;//错误识别
    AVIOInterruptCB interrupt_callback;//I/O中断回调函数
    int debug;//调试标志
#define FF_FDEBUG_TS        0x0001
    int ts_id;//传输流ID
    int audio_preload;//音频预加载
    int max_chunk_duration;//最大块时长
    int max_chunk_size;//最大块大小
    struct AVPacketList *packet_buffer;//数据包缓冲区
    struct AVPacketList *packet_buffer_end;//数据包缓冲区末尾
    int64_t data_offset; //数据偏移量
    struct AVPacketList *raw_packet_buffer;//原始数据包缓冲区剩余大小
    struct AVPacketList *raw_packet_buffer_end;
    struct AVPacketList *parse_queue;
    struct AVPacketList *parse_queue_end;
#define RAW_PACKET_BUFFER_SIZE 2500000
    int raw_packet_buffer_remaining_size;
} AVFormatContext;

其中最重要的结构是

AVIOContext *pb //输入数据的缓冲
unsigned int nb_streams//视音频的个数
AVStream **streams//视音频流
char filename[1024]://文件名
int_64 duration:时长(单位:微秒us,转换为秒需要除以100000)
int bit_rate:比特率(单位bps,转换为kbps需要除以1000)
AVDictionary *metadata//元素据

视频的时长可以转换HH::MM::SS的形式,示例代码如下:

AVFormatContext *pFormatCtx;
CString timelong;
int tns,thh,tmm,tss;
tns = (pFormatCtx->duration)/1000000;
thh = tns / 3600
tmm = (tns % 3600)/60;
tss = (tns % 60);
timelong.Format("%02d:%02d:%02d",thh,tmm,tss);

视频的原数据(metadata)信息可以通过AVDictionary获取。元数据存储在AVDictionaryEntry结构体中,如下所示

typedef struct AVDictionaryEntry{
      char *key;
      char *value;
}AVDictionaryEntry;

每一条元数据分为key和value两个属性
在ffmpeg中通过av_dict_get()函数获得视频的原数据。
.下列代码显示获取元数据并存入meta字符串变量的过程,注意每一条key和value之间有一个"\t",value之后有一个"\r\n"

//MetaData------------------------------------------------------------
//从AVDictionary获得
//需要用到AVDictionaryEntry对象
//CString author,copyright,description;
CString meta=NULL,key,value;
AVDictionaryEntry *m = NULL;
//不用一个一个找出来
/*	m=av_dict_get(pFormatCtx->metadata,"author",m,0);
author.Format("作者:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"copyright",m,0);
copyright.Format("版权:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"description",m,0);
description.Format("描述:%s",m->value);
*/
//使用循环读出
//(需要读取的数据,字段名称,前一条字段(循环时使用),参数)
while(m=av_dict_get(pFormatCtx->metadata,"",m,AV_DICT_IGNORE_SUFFIX)){
	key.Format(m->key);
	value.Format(m->value);
	meta+=key+"\t:"+value+"\r\n" ;
}

本文作者:不会笑的孩子

本文链接:https://www.cnblogs.com/doubleconquer/p/18061950

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   不会笑的孩子  阅读(807)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.