ffmpeg的编程笔记1 - 基本函数与流程


两年前自己的工作记录,没有整理,有些乱了。分两部分来记录下ffmpeg编程中基本的东西。


AVInputFormat
AVOutputFormat



一、初始化及常用函数、结构:
av_register_all(); //注册所有的compiled muxers, demuxers and protocols.
avformat_network_init(); //开启libavformat的网络功能.

辅助函数:
av_iformat_next() / av_oformat_next() 枚举所有系统注册的input/output formats.
avio_enum_protocols() 枚举系统支持的协议,获取其名称.

AVFormatContext:
   包括媒体文件的读/写的所有信息:
  To create an AVFormatContext, use avformat_alloc_context() (some functions, like avformat_open_input() might do that for you).

AVPacket
  "packet" 包含一个编码过的 frame(或多个属于一个流的帧).   AVPacket.pts, AVPacket.dts and AVPacket.duration 的时间基准是AVStream.time_base。
  AVPacket.buf保存数据
 
  av_read_frame(); //读取一帧
  av_dup_packet(); //复制一帧
  av_free_packet(); //释放一帧

metadata :
     默认是UTF-8编码的Unicode. 但demuxers导出的metadata不见得就是UTF-8
     以key/value对存在,key是唯一的;是扁平的,不能分级,没有subtag。
     范例: Author-ger=Michael, Author-eng=Mike

 
二、打开文件解码 流程: 
avformat_open_input(); //打开文件,初始化AVFormatContext
avformat_find_stream_info(); //试着读取几帧数据,以获取之前读取head中没有的介质信息.
{
  av_read_frame();  //读取一个AVStream的某一帧AVPacket数据(AVPacket.stream_index)
  avcodec_decode_video2()/ avcodec_decode_audio4() / avcodec_decode_subtitle2(); //解码一帧
}
avformat_close_input(); //关闭文件,释放相关资源。

特殊情况:
1、打开raw视频文件时,demux无法从文件读取参数就得通这种方式来传入设置:
AVDictionary *options = NULL;
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "pixel_format", "rgb24", 0);

if (avformat_open_input(&s, url, NULL, &options) < 0)
    abort();
av_dict_free(&options);

2、初始化时遇到不认识的option时,可以如下读取:
AVDictionaryEntry *e;
if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))
{
    fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key);
    abort();
}


三、mux流程

avformat_alloc_context(); //创建muxing context

...... //设置参数
AVFormatContext.oformat
AVFormatContext.pb   //format不是AVFMT_NOFILE时,需初始化AVIOContext:
                     //从一个打开的IO context, 或者从avio_open2()中,或者自定义一个.
AVStream* = avformat_new_stream(AVFormatContext *s, const AVCodec *c);//format不是AVFMT_NOSTREAMS时:
    AVStream.codec
    AVCodecContext.codec_type
     AVCodecContext.codec_id
     AVCodecContext.other parameters (如 width / height, the pixel or sample format,等)
     AVCodecContext.time_base
AVFormatContext.metadata //额外参数,视容器格式而定,如AVStream.metadata,AVFormatContext.chapters,
......

avformat_write_header() 初始化muxer内部参数,并且写文件头
av_write_frame() / av_interleaved_write_frame() 写packet数据
av_write_trailer() 清理缓存的Packet,结束文件.

avformat_free_context(); // 清理muxing context


四、codec流程:

avcodec_register_all();
av_dict_set(&opts, "b", "2.5M", 0);
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec)
    exit(1);

context = avcodec_alloc_context3(codec);

if (avcodec_open2(context, codec, opts) < 0)
    exit(1);

av_init_packet() //初始化AVPacket
av_free_packet()

int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr);
int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr);

int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub);


五、成对释放函数
avcodec_encode_video2()

int avformat_alloc_output_context2(AVFormatContext **ctx, ...);
AVFormatContext *avformat_alloc_context(void);
void avformat_free_context(AVFormatContext *s);


AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);
* User is required to call avcodec_close() and avformat_free_context() to
* clean up the allocation by avformat_new_stream().


SwsContext *sws_getContext()
void sws_freeContext( struct SwsContext *swsContext);

void av_init_packet(AVPacket *pkt);
void av_free_packet(AVPacket *pkt);


int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
int avcodec_close(AVCodecContext *avctx);

AVIOContext *avio_alloc_context()
av_free();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值