[FFmpeg-cvslog] avformat/lc3: Only allow AV_CODEC_ID_LC3 in muxer
ffmpeg | branch: master | Andreas Rheinhardt | Tue Apr 16 19:14:30 2024 +0200| [639013aafcd9c534c487070c468e2f5309975fe1] | committer: Andreas Rheinhardt avformat/lc3: Only allow AV_CODEC_ID_LC3 in muxer Also check for the number of streams and the AVCodecID generically using FF_OFMT_FLAGs. Reviewed-by: Stefano Sabatini Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=639013aafcd9c534c487070c468e2f5309975fe1 --- libavformat/lc3.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/libavformat/lc3.c b/libavformat/lc3.c index 93ce720af3..16c12a98d7 100644 --- a/libavformat/lc3.c +++ b/libavformat/lc3.c @@ -186,16 +186,6 @@ const FFInputFormat ff_lc3_demuxer = { #if CONFIG_LC3_MUXER -static av_cold int lc3_muxer_init(AVFormatContext *s) -{ -if (s->nb_streams != 1) { -av_log(s, AV_LOG_ERROR, "This muxer only supports a single stream.\n"); -return AVERROR(EINVAL); -} - -return 0; -} - static int lc3_write_header(AVFormatContext *s) { AVStream *st = s->streams[0]; @@ -243,8 +233,10 @@ const FFOutputFormat ff_lc3_muxer = { .p.extensions = "lc3", .p.audio_codec = AV_CODEC_ID_LC3, .p.video_codec = AV_CODEC_ID_NONE, +.p.subtitle_codec = AV_CODEC_ID_NONE, .p.flags = AVFMT_NOTIMESTAMPS, -.init = lc3_muxer_init, +.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH | +FF_OFMT_FLAG_ONLY_DEFAULT_CODECS, .write_header = lc3_write_header, .write_packet = lc3_write_packet, }; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] lavc/av1: Record reference ordering information for each frame
ffmpeg | branch: release/7.0 | Mark Thompson | Sat Apr 13 20:05:23 2024 +0100| [0d851a82dd974dcafe2f4f67ea0d72fb2e63c6bb] | committer: Lynne lavc/av1: Record reference ordering information for each frame This is needed by Vulkan. Constructing this can't be delegated to CBS because packets might contain multiple frames (when non-shown frames are present) but we need separate snapshots immediately before each frame for the decoder. (cherry picked from commit 22ced1edc6fc4100072e122d549fe379aff76954) > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0d851a82dd974dcafe2f4f67ea0d72fb2e63c6bb --- libavcodec/av1dec.c | 26 ++ libavcodec/av1dec.h | 8 2 files changed, 34 insertions(+) diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index 32a795e758..2850dc96ff 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -358,6 +358,25 @@ static void coded_lossless_param(AV1DecContext *s) } } +static void order_hint_info(AV1DecContext *s) +{ +const AV1RawFrameHeader *header = s->raw_frame_header; +const AV1RawSequenceHeader *seq = s->raw_seq; +AV1Frame *frame = >cur_frame; + +frame->order_hint = header->order_hint; + +for (int i = 0; i < AV1_REFS_PER_FRAME; i++) { +int ref_name = i + AV1_REF_FRAME_LAST; +int ref_slot = header->ref_frame_idx[i]; +int ref_order_hint = s->ref[ref_slot].order_hint; + +frame->order_hints[ref_name] = ref_order_hint; +frame->ref_frame_sign_bias[ref_name] = +get_relative_dist(seq, ref_order_hint, frame->order_hint); +} +} + static void load_grain_params(AV1DecContext *s) { const AV1RawFrameHeader *header = s->raw_frame_header; @@ -700,6 +719,12 @@ static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *s sizeof(dst->film_grain)); dst->coded_lossless = src->coded_lossless; +dst->order_hint = src->order_hint; +memcpy(dst->ref_frame_sign_bias, src->ref_frame_sign_bias, + sizeof(dst->ref_frame_sign_bias)); +memcpy(dst->order_hints, src->order_hints, + sizeof(dst->order_hints)); + return 0; fail: @@ -1255,6 +1280,7 @@ static int get_current_frame(AVCodecContext *avctx) global_motion_params(s); skip_mode_params(s); coded_lossless_param(s); +order_hint_info(s); load_grain_params(s); return ret; diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h index 336eb61359..79a0be510b 100644 --- a/libavcodec/av1dec.h +++ b/libavcodec/av1dec.h @@ -53,6 +53,14 @@ typedef struct AV1Frame { AV1RawFilmGrainParams film_grain; uint8_t coded_lossless; + +// OrderHint for this frame. +uint8_t order_hint; +// RefFrameSignBias[] used when decoding this frame. +uint8_t ref_frame_sign_bias[AV1_TOTAL_REFS_PER_FRAME]; +// OrderHints[] when this is the current frame, otherwise +// SavedOrderHints[s][] when is the reference frame in slot s. +uint8_t order_hints[AV1_TOTAL_REFS_PER_FRAME]; } AV1Frame; typedef struct TileGroupInfo { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] lavc/vulkan_av1: Use av1dec reference order hint information
ffmpeg | branch: release/7.0 | Mark Thompson | Sat Apr 13 20:06:56 2024 +0100| [48721a415a057adde61b586f2eb9815a625abbf7] | committer: Lynne lavc/vulkan_av1: Use av1dec reference order hint information (cherry picked from commit 3cca8dfbd88dfbf9c20f2e8c8da47881b4596567) > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=48721a415a057adde61b586f2eb9815a625abbf7 --- libavcodec/vulkan_av1.c | 23 ++- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/libavcodec/vulkan_av1.c b/libavcodec/vulkan_av1.c index c9e398eaec..fcc9a4f03b 100644 --- a/libavcodec/vulkan_av1.c +++ b/libavcodec/vulkan_av1.c @@ -76,7 +76,7 @@ static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src, StdVideoDecodeAV1ReferenceInfo *vkav1_std_ref, VkVideoDecodeAV1DpbSlotInfoKHR *vkav1_ref, /* Goes in ^ */ const AV1Frame *pic, int is_current, int has_grain, -int *saved_order_hints) +const uint8_t *saved_order_hints) { FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; AV1VulkanDecodePicture *hp = pic->hwaccel_picture_private; @@ -242,7 +242,6 @@ static int vk_av1_start_frame(AVCodecContext *avctx, const AV1RawFrameHeader *frame_header = s->raw_frame_header; const AV1RawFilmGrainParams *film_grain = >cur_frame.film_grain; -CodedBitstreamAV1Context *cbs_ctx = (CodedBitstreamAV1Context *)(s->cbc->priv_data); const int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; @@ -272,7 +271,7 @@ static int vk_av1_start_frame(AVCodecContext *avctx, ap->ref_frame_sign_bias_mask = 0x0; for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) -ap->ref_frame_sign_bias_mask |= cbs_ctx->ref_frame_sign_bias[i] << i; +ap->ref_frame_sign_bias_mask |= pic->ref_frame_sign_bias[i] << i; for (int i = 0; i < STD_VIDEO_AV1_REFS_PER_FRAME; i++) { const int idx = pic->raw_frame_header->ref_frame_idx[i]; @@ -294,7 +293,7 @@ static int vk_av1_start_frame(AVCodecContext *avctx, err = vk_av1_fill_pict(avctx, >ref_src[ref_count], >ref_slots[ref_count], >refs[ref_count], >std_refs[ref_count], >vkav1_refs[ref_count], - ref_frame, 0, 0, cbs_ctx->ref[idx].saved_order_hints); + ref_frame, 0, 0, ref_frame->order_hints); if (err < 0) return err; @@ -491,8 +490,14 @@ static int vk_av1_start_frame(AVCodecContext *avctx, } } -for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) +for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) { +ap->std_pic_info.OrderHints[i] = pic->order_hints[i]; ap->loop_filter.loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i]; +ap->global_motion.GmType[i] = s->cur_frame.gm_type[i]; +for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) { +ap->global_motion.gm_params[i][j] = s->cur_frame.gm_params[i][j]; +} +} for (int i = 0; i < STD_VIDEO_AV1_MAX_CDEF_FILTER_STRENGTHS; i++) { ap->cdef.cdef_y_pri_strength[i] = frame_header->cdef_y_pri_strength[i]; @@ -501,14 +506,6 @@ static int vk_av1_start_frame(AVCodecContext *avctx, ap->cdef.cdef_uv_sec_strength[i] = frame_header->cdef_uv_sec_strength[i]; } -for (int i = 0; i < STD_VIDEO_AV1_NUM_REF_FRAMES; i++) { -ap->std_pic_info.OrderHints[i] = frame_header->ref_order_hint[i]; -ap->global_motion.GmType[i] = s->cur_frame.gm_type[i]; -for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) { -ap->global_motion.gm_params[i][j] = s->cur_frame.gm_params[i][j]; -} -} - if (apply_grain) { for (int i = 0; i < STD_VIDEO_AV1_MAX_NUM_Y_POINTS; i++) { ap->film_grain.point_y_value[i] = film_grain->point_y_value[i]; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] vulkan_av1: add workaround for NVIDIA drivers tested on broken CTS
ffmpeg | branch: release/7.0 | Lynne | Sun Apr 14 14:11:44 2024 +0200| [8dfafe536657e5c5437cf24f7cb058ef7a9f1875] | committer: Lynne vulkan_av1: add workaround for NVIDIA drivers tested on broken CTS The first release of the CTS for AV1 decoding had incorrect offsets for the OrderHints values. The CTS will be fixed, and eventually, the drivers will be updated to the proper spec-conforming behaviour, but we still need to add a workaround as this will take months. Only NVIDIA use these values at all, so limit the workaround to only NVIDIA. Also, other vendors don't tend to provide accurate CTS information. (cherry picked from commit db09f1a5d811a3ca8adc89c58e29932efd0c255e) > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8dfafe536657e5c5437cf24f7cb058ef7a9f1875 --- libavcodec/vulkan_av1.c| 19 +++ libavcodec/vulkan_decode.c | 9 + libavcodec/vulkan_decode.h | 4 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/libavcodec/vulkan_av1.c b/libavcodec/vulkan_av1.c index fcc9a4f03b..49cd69d051 100644 --- a/libavcodec/vulkan_av1.c +++ b/libavcodec/vulkan_av1.c @@ -97,9 +97,14 @@ static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src, .RefFrameSignBias = hp->ref_frame_sign_bias_mask, }; -if (saved_order_hints) -for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) -vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i]; +if (saved_order_hints) { +if (dec->quirk_av1_offset) +for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) +vkav1_std_ref->SavedOrderHints[i - 1] = saved_order_hints[i]; +else +for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) +vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i]; +} *vkav1_ref = (VkVideoDecodeAV1DpbSlotInfoKHR) { .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR, @@ -490,8 +495,14 @@ static int vk_av1_start_frame(AVCodecContext *avctx, } } +if (dec->quirk_av1_offset) +for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) +ap->std_pic_info.OrderHints[i - 1] = pic->order_hints[i]; +else +for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) +ap->std_pic_info.OrderHints[i] = pic->order_hints[i]; + for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) { -ap->std_pic_info.OrderHints[i] = pic->order_hints[i]; ap->loop_filter.loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i]; ap->global_motion.GmType[i] = s->cur_frame.gm_type[i]; for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) { diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c index 4561f26b62..5f6523920d 100644 --- a/libavcodec/vulkan_decode.c +++ b/libavcodec/vulkan_decode.c @@ -1114,6 +1114,7 @@ int ff_vk_decode_init(AVCodecContext *avctx) FFVulkanFunctions *vk; const VkVideoProfileInfoKHR *profile; const FFVulkanDecodeDescriptor *vk_desc; +const VkPhysicalDeviceDriverProperties *driver_props; VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = { .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR, @@ -1275,6 +1276,14 @@ int ff_vk_decode_init(AVCodecContext *avctx) return AVERROR_EXTERNAL; } +driver_props = >shared_ctx->s.driver_props; +if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY && +driver_props->conformanceVersion.major == 1 && +driver_props->conformanceVersion.minor == 3 && +driver_props->conformanceVersion.subminor == 8 && +driver_props->conformanceVersion.patch < 3) +dec->quirk_av1_offset = 1; + ff_vk_decode_flush(avctx); av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization sucessful\n"); diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h index 7ba8b239cb..076af93499 100644 --- a/libavcodec/vulkan_decode.h +++ b/libavcodec/vulkan_decode.h @@ -72,6 +72,10 @@ typedef struct FFVulkanDecodeContext { int external_fg; /* Oddity #2 - hardware can't apply film grain */ uint32_t frame_id_alloc_mask; /* For AV1 only */ +/* Workaround for NVIDIA drivers tested with CTS version 1.3.8 for AV1. + * The tests were incorrect as the OrderHints were offset by 1. */ +int quirk_av1_offset; + /* Thread-local state below */ struct HEVCHeaderSet *hevc_headers; size_t hevc_headers_size; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/h264dec: Properly mark frames as recovered when draining
ffmpeg | branch: master | arch1t3cht | Thu Mar 28 02:56:37 2024 +0100| [5a856ac6e6a627402c1ff57a92fc478efb601131] | committer: Derek Buitenhuis avcodec/h264dec: Properly mark frames as recovered when draining When decoding starts at a SEI recovery point very shortly before the end of the video stream, there can be frames which are decoded before the recovery point's frame is output and which will only be output once the draining has started. Previously, these frames would never be set as recovered. This commit copies the logic from h264_select_output_frame to send_next_delayed_frame to properly mark such frames as recovered. Fixes ticket #10936. Signed-off-by: arch1t3cht Signed-off-by: Derek Buitenhuis > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5a856ac6e6a627402c1ff57a92fc478efb601131 --- libavcodec/h264dec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 727dc1a662..567f0dfa6b 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1014,6 +1014,9 @@ static int send_next_delayed_frame(H264Context *h, AVFrame *dst_frame, h->delayed_pic[i] = h->delayed_pic[i + 1]; if (out) { +h->frame_recovered |= out->recovered; +out->recovered |= h->frame_recovered & FRAME_RECOVERED_SEI; + out->reference &= ~DELAYED_PIC_REF; ret = finalize_frame(h, dst_frame, out, got_frame); if (ret < 0) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/h264dec: Reindent after the previous commit
ffmpeg | branch: master | arch1t3cht | Thu Mar 28 02:56:39 2024 +0100| [e9e1932c1ca85c8ce29a89f3fbda77c7df38e8f0] | committer: Derek Buitenhuis avcodec/h264dec: Reindent after the previous commit Signed-off-by: arch1t3cht Signed-off-by: Derek Buitenhuis > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e9e1932c1ca85c8ce29a89f3fbda77c7df38e8f0 --- libavcodec/h264dec.c | 46 +++--- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 76447e5206..0b111b5b99 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1000,32 +1000,32 @@ static int send_next_delayed_frame(H264Context *h, AVFrame *dst_frame, h->first_field = 0; while (h->delayed_pic[0]) { -out = h->delayed_pic[0]; -out_idx = 0; -for (i = 1; - h->delayed_pic[i] && - !(h->delayed_pic[i]->f->flags & AV_FRAME_FLAG_KEY) && - !h->delayed_pic[i]->mmco_reset; - i++) -if (h->delayed_pic[i]->poc < out->poc) { -out = h->delayed_pic[i]; -out_idx = i; -} +out = h->delayed_pic[0]; +out_idx = 0; +for (i = 1; + h->delayed_pic[i] && + !(h->delayed_pic[i]->f->flags & AV_FRAME_FLAG_KEY) && + !h->delayed_pic[i]->mmco_reset; + i++) +if (h->delayed_pic[i]->poc < out->poc) { +out = h->delayed_pic[i]; +out_idx = i; +} -for (i = out_idx; h->delayed_pic[i]; i++) -h->delayed_pic[i] = h->delayed_pic[i + 1]; +for (i = out_idx; h->delayed_pic[i]; i++) +h->delayed_pic[i] = h->delayed_pic[i + 1]; -if (out) { -h->frame_recovered |= out->recovered; -out->recovered |= h->frame_recovered & FRAME_RECOVERED_SEI; +if (out) { +h->frame_recovered |= out->recovered; +out->recovered |= h->frame_recovered & FRAME_RECOVERED_SEI; -out->reference &= ~DELAYED_PIC_REF; -ret = finalize_frame(h, dst_frame, out, got_frame); -if (ret < 0) -return ret; -if (*got_frame) -break; -} +out->reference &= ~DELAYED_PIC_REF; +ret = finalize_frame(h, dst_frame, out, got_frame); +if (ret < 0) +return ret; +if (*got_frame) +break; +} } return buf_index; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/h264dec: Handle non-recovered frames when draining
ffmpeg | branch: master | arch1t3cht | Thu Mar 28 02:56:38 2024 +0100| [728ffe6ca6d46f55e2f63de9dec8ea11e096c314] | committer: Derek Buitenhuis avcodec/h264dec: Handle non-recovered frames when draining When starting on a SEI recovery point close enough to the end of the stream that draining starts before the recovery point's frame is output, there can be non-recovered frames in the delayed picture buffer that would currently cause the decoder to fail to output a frame. This commit skips such frames and outputs the first recovered frame, if there exists one. Signed-off-by: arch1t3cht Signed-off-by: Derek Buitenhuis > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=728ffe6ca6d46f55e2f63de9dec8ea11e096c314 --- libavcodec/h264dec.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 567f0dfa6b..76447e5206 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -994,11 +994,13 @@ static int send_next_delayed_frame(H264Context *h, AVFrame *dst_frame, int *got_frame, int buf_index) { int ret, i, out_idx; -H264Picture *out = h->delayed_pic[0]; +H264Picture *out; h->cur_pic_ptr = NULL; h->first_field = 0; +while (h->delayed_pic[0]) { +out = h->delayed_pic[0]; out_idx = 0; for (i = 1; h->delayed_pic[i] && @@ -1021,6 +1023,9 @@ static int send_next_delayed_frame(H264Context *h, AVFrame *dst_frame, ret = finalize_frame(h, dst_frame, out, got_frame); if (ret < 0) return ret; +if (*got_frame) +break; +} } return buf_index; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/iamf_writer: reject duplicated stream ids in a stream group
ffmpeg | branch: master | James Almer | Mon Apr 15 18:06:01 2024 -0300| [6b6a0fc53df592183c69e518967841272ab4e862] | committer: James Almer avformat/iamf_writer: reject duplicated stream ids in a stream group Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6b6a0fc53df592183c69e518967841272ab4e862 --- libavformat/iamf_writer.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/libavformat/iamf_writer.c b/libavformat/iamf_writer.c index 37ec8e732a..6d4e4082eb 100644 --- a/libavformat/iamf_writer.c +++ b/libavformat/iamf_writer.c @@ -275,6 +275,17 @@ int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void } } +for (int i = 0; i < audio_element->nb_substreams; i++) { +for (int j = i + 1; j < audio_element->nb_substreams; j++) +if (audio_element->substreams[i].audio_substream_id == +audio_element->substreams[j].audio_substream_id) { +av_log(log_ctx, AV_LOG_ERROR, "Duplicate id %u in streams %u and %u from stream group %u\n", + audio_element->substreams[i].audio_substream_id, i, j, stg->index); +ret = AVERROR(EINVAL); +goto fail; +} +} + if (iamf_audio_element->demixing_info) { AVIAMFParamDefinition *param = iamf_audio_element->demixing_info; const IAMFParamDefinition *param_definition = ff_iamf_get_param_definition(iamf, param->parameter_id); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".