主要是通過
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);
其中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
參考:
