• FFmpeg源码分析:av_parser_parse2


    解析报文

    /**
     * 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;
    }

    这里就是调对应的解析器解析数据,返回使用的数据大小。

  • 相关阅读:
    LINUX的SSH下FTP到远程服务器Entering Passive Mode失败解决
    LINUX的SSH下FTP到远程服务器Entering Passive Mode失败解决
    LINUX的SSH下FTP到远程服务器Entering Passive Mode失败解决
    git rm简介
    git rm简介
    git rm简介
    linux rz -e
    新版住院电子病历首页 (2012年修订说明)
    DateEdit和TimeEdit用法
    ORA-22868: 具有 LOB 的表包含有位于不同表空间的段
  • 原文地址:https://www.cnblogs.com/vczf/p/14814077.html
Copyright © 2020-2023  润新知