1. 程式人生 > >FFmpeg編解碼常用函式ffmpeg av_parser_parse2()函式

FFmpeg編解碼常用函式ffmpeg av_parser_parse2()函式

主要是通過av_parser_parse2拿到AVPaket資料,跟av_read_frame類似。
輸入必須是隻包含視訊編碼資料“裸流”(例如H.264、HEVC碼流檔案),而不能是包含封裝格式的媒體資料(例如AVI、MKV、MP4)。

av_parser_init():初始化AVCodecParserContext。其引數是codec_id,所以同時只能解析一種
AVCodecParser用於解析輸入的資料流並把它們分成一幀一幀的壓縮編碼資料。比較形象的說法就是把長長的一段連續的資料“切割”成一段段的資料。核心函式是av_parser_parse2():
av_parser_parse2():解析資料獲得一個Packet, 從輸入的資料流中分離出一幀一幀的壓縮編碼資料。

   /** 
     * Parse a packet. 
     * 
     * @param s             parser context. 
     * @param avctx         codec context. 
     * @param poutbuf       set to pointer to parsed buffer or NULL if not yet finished. 
     * @param poutbuf_size  set to size of parsed buffer or zero if not yet finished. 
     * @param
buf input buffer. * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). * @param pts input presentation timestamp. * @param dts input decoding timestamp. * @param pos input byte position in stream. * @return
the number of bytes of the input bitstream used. * * Example: * @code * while(in_len){ * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, * in_data, in_len, * pts, dts, pos); * in_data += len; * in_len -= len; * * if(size) * decode_frame(data, size); * } * @endcode */ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos);

第一個引數:

eg:

 AVCodecParserContext *parser = NULL;

 if (avcodec_open(c, codec) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    /* the codec gives us the frame size, in samples */
    parser = av_parser_init(c->codec_id);
    parser->flags |= PARSER_FLAG_ONCE;//在開啟解碼器後初始化parase

另一種用法:

  AVStream *st = s->streams[stream_index];

      len = av_parser_parse2(st->parser, st->codec,
                               &out_pkt.data, &out_pkt.size, data, size,
                               pkt->pts, pkt->dts, pkt->pos);

第二個引數:正常的AVCodecContext

第三個引數:初始化後的avpkt的avpkt.data

第四個引數:初始化後的avpkt的avpkt.size

第五個引數:一次接收的資料包

第六個引數:本次接收資料包的長度

第七個引數:pts,沒有的話,可以在聲明後直接用int pts,單單h264的話直接掛上pts即可

第八個引數:dts,同上

第九個引數:接收資料
其中poutbuf指向解析後輸出的壓縮編碼資料幀,buf指向輸入的壓縮編碼資料。如果函式執行完後輸出資料為空(poutbuf_size為0),則代表解析還沒有完成,還需要再次呼叫av_parser_parse2()解析一部分資料才可以得到解析後的資料幀。當函式執行完後輸出資料不為空的時候,代表解析完成,可以將poutbuf中的這幀資料取出來做後續處理。
avformat_open_input()會呼叫avformat_new_stream()建立AVStream
avformat_new_stream()中又會呼叫avcodec_alloc_context3()建立AVCodecContext
av_read_frame():獲取媒體的一幀壓縮編碼資料。其中呼叫了av_parser_parse2()。
“純淨”的解碼器中,通過avcodec_decode_video2()成功解碼第一幀之後,才能獲取到寬高等資訊
解析出來的資料,可通過下面的方法判斷幀型別:
AVCodecParserContext->pict_type :AV_PICTURE_TYPE_I,AV_PICTURE_TYPE_P