[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