- 论坛徽章:
- 0
|
written by DotaFox 2008-07-25
由于工作的原因,一直很想了解ffmpeg,但是由于自己的懒惰,学习的脚步一直停滞不前。以下的文字可能你在ffmpeg的sdk指南里面都有出现,我也只是用笨人的方法把文字重新整理一遍,这样才有助于记忆。
1.ffmpeg中的数据结构
I AVFormatContext //format I/O context
此结构包含了一个视频流的格式内容。其中存有AVInputFormat(or AVOutputFormat,同一时间只能存在其中的一个),和AVstream,AVPacket这几个重要的数据结构以及一些其他的相关信息,比如title,author,copyright等。还有一些可能在编解码中会用到的信息,诸如:duration,file_size,bit_rate等
Usage
声明:
AVFormatContext *oc
初始化过程:
由于AVFormatContext结构包含许多信息因此初始化过程是分布完成,而且有些变量没有值可用,也可以不初始化,但是由于一般声明都是用指针,因此一个分配内存过程不可少
oc=av_alloc_format_context();
结构中的AVOutputFormat *(或AVInputFormat *)是一定要初始化的,基本上这是编解码要使用什么codec的依据所在:
oc->oformat=fmt;or oc->iformat=fmt;
snprintf(oc->filename,sizeof(oc->filename),"%s",filename);
把文件名写入AVFormatContext中
在完成以上步骤后(完成AVInputFormat(AVOutputFormat)以及AVFormatContext)接下来就是要用oc初始化AVstream。(假设已经有了声明AVStream *video_st)
video_st = add_video_stream(oc,fmt->video_codec);
最后AVFormatContext最后的一个设置工作就是:
if(av_set_paramters(oc,NULL)
//handle error;
}
dump_format(oc,0,filename,1);
主要的作用就是看看先前的初始化过程中设置的参数是否符合规范,否则将报错。
编码过程:
//open video codec and allocate the necessary encode buffers
if(video_st)
open_video(oc,video_st);
//write the stream header,if any
av_write_header(oc);
//encode and decode process
for(;;){
write_video_frame(oc,video_st);
//break condition here
}
//close codec
if(video_st)
close_video(oc,video_st);
//write the trailer, if any
av_write_trailer(oc);
//free the streams
for(i=0;ib_streams,i++){
av_freep(&oc->streams->codec);
av_freep(&oc->streams);
}
//close the output file
if(!(fmt->flags&AVFMT_NOFILE)){
url_fclose(&oc->pb);
}
av_free(oc);
对以上标有红色的标记的函数进行单独分析
1> open_video(oc,video_st)
这个函数主要是对视频编(解)码器的初始化过程。初始化的数据结构为 AVCodec *codec和AVCodecContext *c
c=st->codec;
codec=avcodec_find_encoder(c->codec_id);// 编码时找编码器
codec=avcodec_find_decoder(c->codec_id);//解码时找解码器
AVCodecContext是结构AVStream中的一个数据结构,因此在AVStream初始化后直接赋值给c
//internal open video codec
avcodec_open(c,codec); //打开视频编解码
//allocate video stream buffer
video_outbuf_size=200000;
video_outbuf=av_malloc(video_outbuf_size); //分配输出流缓存大小
//allocate video frame buffer
pirture=alloc_picture(c->pix_fmt,c->width,c->height);//分配每一帧图像缓存大小
2>write_video_frame(AVFormatContext *oc,AVStream *st)
这个函数做了真正的编解码工作,用到的数据结构有 AVCodecContext *c,SwsContext *img_convert_ctx.其中SwsContext是用来变换图像格式的,比如yuv422 to yuv420
3>close_video(AVFormatContext *oc,AVStream *st)
avcode_close(st->codec);
av_free(picture->data[0]);
av_free(picture);
av_free(video_outbuf);
II AVOutputFormat
编解码器将要使用那个codec的指示。其成员数据中,最重要的就是关于视频codec的了:enum CodecID video_codec;
AVOutputFormat *fmt;
fmt=guess_format(NULL,filename,NULL);
III AVStream
成员数据有AVCodecContext,同时作为"stream",还包含了 帧率(r_frame_rate),基本时间计量单位(time_base),首帧位置(start_time),持续时间(duration),帧数(nb_frames)以及一些ip信息
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74296/showart_1092312.html |
|