zoukankan      html  css  js  c++  java
  • 【C/C++开发】ffplay中的FrameQueue的自我理解

    最近在研究ffplay,以下是本人今天在研究FrameQueue的时候整理的笔记,如有错误还请有心人指出来~
    //这个队列是一个循环队列,windex是指其中的首元素,rindex是指其中的尾部元素.
    typedef struct FrameQueue {
                     Frame queue[FRAME_QUEUE_SIZE ];
                     int rindex;//表示循环队列的结尾处
                     int windex;//表示循环队列的开始处
                     int size;
                     int max_size;
                     int keep_last;
                     int rindex_shown;//一开始为0,之后一直为1
                     SDL_mutex *mutex;
                     SDL_cond *cond;
                     PacketQueue *pktq;
    } FrameQueue;
    //表示FrameQueue的初始化主要是针对内存的处理,针对视频来说,keep_last为1
    static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
    {
    int i;
    memset(f, 0, sizeof(FrameQueue));
    if (!(f->mutex = SDL_CreateMutex()))
    return AVERROR(ENOMEM);
    if (!(f->cond = SDL_CreateCond()))
    return AVERROR(ENOMEM);
    f->pktq = pktq;
    f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
    f->keep_last = !!keep_last;
    for (i = 0; i < f->max_size; i++)
    if (!(f->queue[i].frame = av_frame_alloc()))
    return AVERROR(ENOMEM);
    return 0;
    }

    //表示从循环队列帧里面取出当前需要显示的一帧视频
    static Frame *frame_queue_peek(FrameQueue * f)
    {
                     return &f ->queue[(f->rindex + f->rindex_shown) % f ->max_size];
    }
    //表示从循环队列帧里面取出当前需要显示的下哦i一帧视频
    static Frame *frame_queue_peek_next( FrameQueue * f )
    {
                     return &f ->queue[( f->rindex + f ->rindex_shown + 1) % f ->max_size];
    }

    //返回要填充的frame_queue中的Frame。
    static Frame *frame_queue_peek_writable( FrameQueue * f )
    {
                     /* wait until we have space to put a new frame */
                    SDL_LockMutex( f ->mutex);
                     while (f ->size >= f->max_size &&
                           ! f ->pktq->abort_request) {
                                    SDL_CondWait( f ->cond, f ->mutex);
                    }
                    SDL_UnlockMutex( f ->mutex);

                     if (f ->pktq->abort_request)
                                     return NULL ;

                     return &f ->queue[ f->windex];
    }
    //放帧到队列中(frame_queue_peek_writable)之后的参数操作,windex++
    static void frame_queue_push( FrameQueue * f )
    {
                     if (++f ->windex == f->max_size)
                                     f ->windex = 0;
                    SDL_LockMutex( f ->mutex);
                     f ->size++;
                    SDL_CondSignal( f ->cond);
                    SDL_UnlockMutex( f ->mutex);
    }
    //从帧队列中取出帧之后的参数操作,当rindex_show为0的时候使其变为1,否则--rindex
    static void frame_queue_next( FrameQueue * f )
    {
                     if (f ->keep_last && ! f->rindex_shown) {
                                     f ->rindex_shown = 1;
                                     return ;
                    }
                    frame_queue_unref_item(& f ->queue[f ->rindex]);
                     if (++f ->rindex == f->max_size)
                                     f ->rindex = 0;
                    SDL_LockMutex( f ->mutex);
                     f ->size--;
                    SDL_CondSignal( f ->cond);
                    SDL_UnlockMutex( f ->mutex);
    }
    其中size-rindex_shown为现在队列中的帧数目
  • 相关阅读:
    二维码生成库phpqrcode使用小结
    微信扫码支付开发小结
    Xcode下开发c静态库for ios CPU架构 静态库合并
    Android.mk的用法和基础
    Android.mk介绍
    查看与修改网关,DNS
    WebRTC编译系统之GYP,gn和ninja
    sed awk文本处理教程
    有哪些自媒体平台?
    camke使用例程
  • 原文地址:https://www.cnblogs.com/huty/p/8517380.html
Copyright © 2011-2022 走看看