[FFmpeg-devel] [PATCH 1/2] avformat/flvdec: implement support for parsing ModEx data

Leo Izen leo.izen at gmail.com
Wed Jan 15 09:48:37 EET 2025


On 1/14/25 7:36 PM, Timo Rothenpieler wrote:
> ---
>   libavformat/flv.h    |  5 ++++
>   libavformat/flvdec.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 68 insertions(+)
> 
> diff --git a/libavformat/flv.h b/libavformat/flv.h
> index 74d3b8de8b..d8f7980f2e 100644
> --- a/libavformat/flv.h
> +++ b/libavformat/flv.h
> @@ -130,6 +130,7 @@ enum {
>       PacketTypeMetadata              = 4,
>       PacketTypeMPEG2TSSequenceStart  = 5,
>       PacketTypeMultitrack            = 6,
> +    PacketTypeModEx                 = 7,
>   };
>   
>   enum {
> @@ -139,6 +140,10 @@ enum {
>       AudioPacketTypeMultitrack         = 5,
>   };
>   
> +enum {
> +    PacketModExTypeTimestampOffsetNano = 0,
> +};
> +
>   enum {
>       AudioChannelOrderUnspecified = 0,
>       AudioChannelOrderNative      = 1,
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index 2f46475d08..b4ea984f58 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -1279,6 +1279,57 @@ static int flv_update_video_color_info(AVFormatContext *s, AVStream *st)
>       return 0;
>   }
>   
> +static int flv_parse_mod_ex_data(AVFormatContext *s, int *pkt_type, int *size, int64_t *dts)
> +{
> +    int ex_type, ret;
> +    uint8_t *ex_data;
> +
> +    uint16_t ex_size = (uint8_t)avio_r8(s->pb) + 1;
> +    *size -= 1;
> +
> +    if (ex_size == 256) {
> +        ex_size = (uint16_t)avio_rb16(s->pb);
> +        *size -= 2;
> +    }
> +
> +    ex_data = av_malloc(ex_size);
> +    if (!ex_data)
> +        return AVERROR(ENOMEM);
> +
> +    ret = avio_read(s->pb, ex_data, ex_size);
> +    if (ret < 0) {
> +        av_free(ex_data);
> +        return ret;
> +    }
> +    *size -= ex_size;


Is it possible here for ex_size >= size in this case? If so, should we 
return AVERROR_INVALIDDATA?


> +
> +    ex_type = (uint8_t)avio_r8(s->pb);
> +    *size -= 1;
> +
> +    *pkt_type = ex_type & 0x0f;
> +    ex_type &= 0xf0;
> +
> +    if (ex_type == PacketModExTypeTimestampOffsetNano) {
> +        uint32_t nano_offset;
> +
> +        if (ex_size != 3) {
> +            av_log(s, AV_LOG_WARNING, "Invalid ModEx size for Type TimestampOffsetNano!\n");
> +            nano_offset = 0;
> +        } else {
> +            nano_offset = (ex_data[0] << 16) | (ex_data[1] << 8) | ex_data[2];
> +        }
> +
> +        // this is not likely to ever add anything, but right now timestamps are with ms precision
> +        *dts += nano_offset / 1000000;
> +    } else {
> +        av_log(s, AV_LOG_INFO, "Unknown ModEx type: %d", ex_type);
> +    }
> +
> +    av_free(ex_data);
> +
> +    return 0;
> +}
> +
>   static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
>   {
>       FLVContext *flv = s->priv_data;
> @@ -1347,6 +1398,12 @@ retry:
>               enhanced_flv = 1;
>               pkt_type = flags & ~FLV_AUDIO_CODECID_MASK;
>   
> +            while (pkt_type == PacketTypeModEx) {
> +                ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts);
> +                if (ret < 0)
> +                    goto leave;
> +            }
> +
>               if (pkt_type == AudioPacketTypeMultitrack) {
>                   uint8_t types = avio_r8(s->pb);
>                   multitrack_type = types & 0xF0;
> @@ -1376,6 +1433,12 @@ retry:
>           pkt_type = enhanced_flv ? codec_id : 0;
>           size--;
>   
> +        while (pkt_type == PacketTypeModEx) {
> +            ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts);
> +            if (ret < 0)
> +                goto leave;
> +        }
> +
>           if (pkt_type == PacketTypeMultitrack) {
>               uint8_t types = avio_r8(s->pb);
>               multitrack_type = types & 0xF0;



More information about the ffmpeg-devel mailing list