Menu Home

ffmpeg的内部Video Buffer管理和传送机制

ffmpeg的内部Video Buffer管理和传送机制

本文主要介绍ffmpeg解码器内部管理Video Buffer的原理和过程,ffmpeg的Videobuffer为内部管理,其流程大致为:注册处理函数->帧级释放->帧级申请->清空。

1 注册get_buffer()和release_buffer()

FFAPI_InitCodec()

avcodec_alloc_context()

avcodec_alloc_context2()

avcodec_get_context_default2(AVCodecContext *s,…){

……

s->get_buffer = avcodec_default_get_buffer;

s->release_buffer = avcodec_default_release_buffer;

……

}

2帧级的内存申请和释放调用

0_1302927911vOO3

图1帧级内存申请和释放的函数调用

2.1 FFAPI函数调用libavcodec相应的codec(WMV3对应的Codec是VC1)函数进行解码,过程中调用内部buffer处理函数。其中buffer管理被统一封装到Mpegvideo接口中(包括的codec有H.261, H.263, H.264, mpeg12, rv10,rv34, svq1和VC1)

FFAPI_Decode()

avcodec_decode_video2()

avctx->codec->decode()//初始化过程中注册codec,wmv3的解码函数是

vc1_decode_frame(){

decode_vc1_header;

MPV_frame_start();                                     //2.2.2

vc1_decode_blocks();

MPV_frame_end();                                     //2.2.3

}

2.2 MPV_frame_start()//通过调用get_buffer()申请当前帧的video buffer。

MPV_frame_start()

//首先调用release_buffer()释放非参考帧的video buffer

for(i=0; i<MAX_PICTURE_COUNT; i++)

if(s->picture[i].data[0] && !s->picture[i].reference)

free_frame_buffer(s, &s->picture[i]); //调用s->avctx->get_buffer(),回调avcodec_default_release_buffer()

 

ff_alloc_picture()

alloc_frame_buffer()

s->avctx->get_buffer()      //回调avcodec_default_get_buffer()

2.3MPV_frame_end()                                          //完成视频加边等操作

 

3帧级的内存申请和释放处理方法

3.1内部buffer数据结构

–   typedef struct InternalBuffer{

–       int last_pic_num;

–       uint8_t *base[4];

–       uint8_t *data[4];

–       int linesize[4];

–       int width, height;

–       enum PixelFormat pix_fmt;

–   }InternalBuffer;

–   typedef struct AVCodecContext {

–          ……

–   int internal_buffer_count; //记录当前内部buffer的个数,get_buffer和release_buffer时均需要对其进行维护。

–   void *internal_buffer;//初始化为数组InternalBuffer [INTERNAL_BUFFER_SIZE]

–   ……

–   } AVCodecContext;

Codec通过维护internal_buffer_count和internal_buffer实现高效的内存管理。

3.2参考帧管理相关数据结构

–   typedef  struct Picture{

–       uint8_t *data[4];

–       int linesize[4];

–       uint8_t *base[4];

–       int reference;

–       ……

–   } Picture;

–   typedef  struct MpegEncContext{

–       ……

–       Picture* picture;   //初始化为数组Picture[INTERNAL_BUFFER_SIZE]

–       Picture* last_picture_ptr;      //指向前一帧

–       Picture* next_picture_ptr;;    //双向预测时,指向后一帧

–       Picture* current_picture_ptr;//指向当前帧

–   ……

–   } MpegEncContext; 

3.3申请和释放原理

0_13029279181Joq

图2 内存申请和释放原理

(1)初始化时将internal_buffer全部清零

(2)释放buffer时,将释放的buffer与最后一个有效buffer交换,而不是用av_free()释放内存。

avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){

s->internal_buffer_count–;

last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];

//将last buffer和要释放的buffer交换,使last buffer变成无效buffer,在下次get_buffer时能被申请到。

FFSWAP(InternalBuffer, *buf, *last);

for(i=0; i<4; i++){

pic->data[i]=NULL;

}

}

(3)申请buffer时,检查internal_buffer[internal_buffer_count]的基址是否非空,若非空则直接使用internal_buffer[internal_buffer_count];若空,使用av_malloc()函数进行申请。

这样处理的好处是避免了频繁的调用malloc()和free(),从而提升了效率。

avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){

……

buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];

get_size_info(size[]);

buf->base[0, 1, 2] = av_malloc(size[0, 1, 2]);

buf->data[0, 1, 2] = buf->base[0, 1, 2] + padding_offset[0, 1, 2];

……

}

(4)决定输出帧是在每帧解码后,根据当前帧的类型和参考信息决定输出帧。

if (s->pict_type == FF_B_TYPE || s->low_delay) {

*pict= *(AVFrame*)s->current_picture_ptr;

} else if (s->last_picture_ptr != NULL) {

*pict= *(AVFrame*)s->last_picture_ptr;

}

3.4举例——假设解码IPBPB的非H.264码流。

(1)初始化后的状态如所示,IBC为ctx->internal_buffer_count,CurPtr为s->current_picture_ptr,LastPtr为s->last_picture_ptr,NextPtr为s->next_picture_ptr。

gpAVPicture指针为输出图像的指针。

 0_1302927929p9BZ

图3 初始化状态

(2)解码第一个I帧,过程中不会不调用release_buffer(),get_buffer()得到picture[0] ,此时不输出任何图像。

 0_1302927934rV3c

图4解码第一个I帧后的状态

(3)解码第一个P帧,过程中不调用release_buffer(),get_buffer()得到picture[1] ,输出picture[0]。

 0_13029279382i4T

图5解码第一个P帧后的状态

(4)解码第一个B帧,过程中不调用release_buffer(),get_buffer()得到picture[2] ,输出picture[2]。

 0_1302927943C7D9

图6解码第一个B帧后的状态

(5)解码第二个P帧,调用release_buffer(&picture[2]),再调用get_buffer(),得到picture[2], 输出picture[1]。

 0_1302928016IUon

图7解码第二个P帧的状态

ref: http://blog.csdn.net/xietao_live_cn/article/details/6327451

13 replies

  1. I not to mention my pals were actually taking note of the best items from the blog then at once developed an awful feeling I had not expressed respect to the web site owner for those secrets. The women came certainly warmed to read through them and have now honestly been enjoying them. Thanks for really being very helpful and for using these kinds of impressive guides millions of individuals are really wanting to be informed on. My sincere apologies for not expressing appreciation to you sooner.

  2. I enjoy you because of all your labor on this site. Kate enjoys setting aside time for research and it’s simple to grasp why. A number of us hear all concerning the compelling tactic you offer functional tricks via your web site and therefore increase response from website visitors about this matter then my daughter has been being taught a lot of things. Have fun with the remaining portion of the new year. You are always doing a superb job.

  3. I want to get across my love for your kind-heartedness supporting men and women that really need help with in this theme. Your personal dedication to getting the solution all around had been particularly beneficial and have constantly made associates like me to reach their targets. Your personal helpful tutorial means so much a person like me and extremely more to my colleagues. Thank you; from all of us.

  4. Thanks for all of the work on this website. My mother really loves engaging in investigation and it is simple to grasp why. A number of us know all relating to the compelling means you offer practical tips and tricks by means of your blog and therefore improve contribution from website visitors about this situation so our own daughter is discovering a lot of things. Have fun with the rest of the new year. You’re doing a brilliant job.

  5. I’m also writing to let you be aware of what a amazing encounter our child had reading through your blog. She came to understand so many pieces, with the inclusion of what it’s like to possess a marvelous giving spirit to have the rest completely know precisely a variety of specialized issues. You actually did more than our own expectations. Thanks for delivering those valuable, safe, educational not to mention fun tips on your topic to Jane.

  6. I wish to point out my love for your kindness supporting men and women who really need guidance on this one issue. Your real dedication to getting the solution all over came to be remarkably productive and have really permitted professionals just like me to realize their objectives. Your new informative publication signifies a great deal a person like me and somewhat more to my fellow workers. Warm regards; from each one of us.

  7. I simply had to thank you so much all over again. I do not know what I would’ve made to happen in the absence of those thoughts contributed by you about such concern. It had become a very frightful condition in my position, however , being able to see your expert form you managed it made me to weep with delight. Now i’m happy for the work and thus pray you know what a powerful job you’re accomplishing teaching some other people by way of your blog post. Probably you haven’t come across any of us.

  8. I must voice my love for your kind-heartedness giving support to folks who really want assistance with that question. Your very own commitment to getting the solution throughout was especially significant and have constantly permitted those much like me to reach their targets. This warm and helpful key points implies a great deal a person like me and even more to my colleagues. Thank you; from all of us.

  9. Thanks for your entire labor on this web page. Gloria take interest in setting aside time for internet research and it is obvious why. We all notice all regarding the lively method you produce powerful suggestions through your blog and even cause response from visitors about this concept plus my girl is certainly becoming educated a great deal. Take advantage of the remaining portion of the year. You have been conducting a pretty cool job.

  10. I have to express some appreciation to you for bailing me out of this trouble. Because of researching through the the web and meeting suggestions that were not powerful, I thought my life was gone. Existing without the presence of approaches to the problems you’ve sorted out by way of your good article is a critical case, and those that might have in a wrong way affected my career if I had not discovered your site. Your personal ability and kindness in playing with everything was helpful. I don’t know what I would have done if I hadn’t encountered such a stuff like this. It’s possible to at this time look ahead to my future. Thank you so much for this expert and result oriented guide. I will not hesitate to refer your web blog to anybody who needs and wants guidelines on this area.

  11. I and also my pals have already been reading the great procedures found on the website while then developed a terrible feeling I never expressed respect to the blog owner for them. All the young boys became so very interested to read through all of them and have now undoubtedly been taking advantage of them. Thank you for being so accommodating and for obtaining some awesome information most people are really needing to understand about. My very own sincere regret for not expressing appreciation to sooner.

  12. Thank you so much for giving everyone an exceptionally marvellous chance to read from here. It really is very kind and also stuffed with a good time for me personally and my office fellow workers to search your blog no less than 3 times in 7 days to read the new guides you will have. And lastly, I am also always fulfilled with all the special tips and hints served by you. Selected 4 tips in this article are definitely the simplest we’ve ever had.

  13. I must express some thanks to the writer just for bailing me out of such a circumstance. Because of looking out throughout the the web and getting views which are not powerful, I thought my entire life was over. Existing without the solutions to the difficulties you’ve resolved as a result of the website is a critical case, and those which may have badly affected my career if I hadn’t encountered your web blog. Your own personal natural talent and kindness in dealing with almost everything was invaluable. I don’t know what I would have done if I hadn’t come across such a step like this. I can also at this point look ahead to my future. Thanks so much for this specialized and effective help. I won’t be reluctant to propose your site to anyone who requires assistance on this area.

Leave a Reply

Your email address will not be published.