解析报文
/** * 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 buffer size in bytes without the padding. I.e. the full buffer 输入数据大小 size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. 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);
实现
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) { int index, i; uint8_t dummy_buf[AV_INPUT_BUFFER_PADDING_SIZE]; av_assert1(avctx->codec_id != AV_CODEC_ID_NONE); /* Parsers only work for the specified codec ids. */ av_assert1(avctx->codec_id == s->parser->codec_ids[0] || avctx->codec_id == s->parser->codec_ids[1] || avctx->codec_id == s->parser->codec_ids[2] || avctx->codec_id == s->parser->codec_ids[3] || avctx->codec_id == s->parser->codec_ids[4]); if (!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) { s->next_frame_offset = s->cur_offset = pos; s->flags |= PARSER_FLAG_FETCHED_OFFSET; } if (buf_size == 0) { /* padding is always necessary even if EOF, so we add it here */ memset(dummy_buf, 0, sizeof(dummy_buf)); buf = dummy_buf; } else if (s->cur_offset + buf_size != s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ /* add a new packet descriptor */ i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); s->cur_frame_start_index = i; s->cur_frame_offset[i] = s->cur_offset; s->cur_frame_end[i] = s->cur_offset + buf_size; s->cur_frame_pts[i] = pts; s->cur_frame_dts[i] = dts; s->cur_frame_pos[i] = pos; } if (s->fetch_timestamp) { s->fetch_timestamp = 0; s->last_pts = s->pts; s->last_dts = s->dts; s->last_pos = s->pos; ff_fetch_timestamp(s, 0, 0, 0); } /* WARNING: the returned index can be negative */ index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf, poutbuf_size, buf, buf_size); av_assert0(index > -0x20000000); // The API does not allow returning AVERROR codes #define FILL(name) if(s->name > 0 && avctx->name <= 0) avctx->name = s->name if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { FILL(field_order); } /* update the file pointer */ if (*poutbuf_size) { /* fill the data for the current frame */ s->frame_offset = s->next_frame_offset; /* offset of the next frame */ s->next_frame_offset = s->cur_offset + index; s->fetch_timestamp = 1; } if (index < 0) index = 0; s->cur_offset += index; return index; }
这里就是调对应的解析器解析数据,返回使用的数据大小。