Message ID | 20240922180005.6549-3-anton@khirnov.net |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/3] lavc/decode: clear side data in reget_buffer() | expand |
Context | Check | Description |
---|---|---|
andriy/configure_x86 | warning | Failed to apply patch |
On 9/22/2024 3:00 PM, Anton Khirnov wrote: > The HEVC decoder will start setting stereoscopic view position (left or > right) based on 3D Reference Displays Info SEI message in future > commits. This information should be merged with container-derived > stereo3D side data. After this set, a re-encode with the CLI will have information at the container level that may not be correct, like type and view. For mv-hevc it probably makes no difference currently, as type unspec and frame sequence are not supported values in any container, and view left/right is only supported in mov eyes box, which we currently don't write, but it nonetheless needs to be handled in some form, like by propagating global side data through the filterchain as you suggested.
Quoting James Almer (2024-09-23 04:17:46) > On 9/22/2024 3:00 PM, Anton Khirnov wrote: > > The HEVC decoder will start setting stereoscopic view position (left or > > right) based on 3D Reference Displays Info SEI message in future > > commits. This information should be merged with container-derived > > stereo3D side data. > > After this set, a re-encode with the CLI will have information at the > container level that may not be correct, like type and view. The same is true before this set as well, so I don't quite see your point. Yes, this set does not resolve the problem fully, but it still should be a step in the right direction.
On 9/23/2024 1:22 AM, Anton Khirnov wrote: > Quoting James Almer (2024-09-23 04:17:46) >> On 9/22/2024 3:00 PM, Anton Khirnov wrote: >>> The HEVC decoder will start setting stereoscopic view position (left or >>> right) based on 3D Reference Displays Info SEI message in future >>> commits. This information should be merged with container-derived >>> stereo3D side data. >> >> After this set, a re-encode with the CLI will have information at the >> container level that may not be correct, like type and view. > > The same is true before this set as well, so I don't quite see your True, before this set the container level info from the source is passed through to the output, which may also be bogus. > point. Yes, this set does not resolve the problem fully, but it still > should be a step in the right direction. Yes, it is.
diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 9303254ef3..ffae322612 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -37,6 +37,7 @@ #include "libavutil/internal.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/mem.h" +#include "libavutil/stereo3d.h" #include "avcodec.h" #include "avcodec_internal.h" @@ -1417,6 +1418,42 @@ const AVPacketSideData *ff_get_coded_side_data(const AVCodecContext *avctx, return packet_side_data_get(avctx->coded_side_data, avctx->nb_coded_side_data, type); } +static int side_data_stereo3d_merge(AVFrameSideData *sd_frame, + const AVPacketSideData *sd_pkt) +{ + const AVStereo3D *src; + AVStereo3D *dst; + int ret; + + ret = av_buffer_make_writable(&sd_frame->buf); + if (ret < 0) + return ret; + sd_frame->data = sd_frame->buf->data; + + dst = ( AVStereo3D*)sd_frame->data; + src = (const AVStereo3D*)sd_pkt->data; + + if (dst->type == AV_STEREO3D_UNSPEC) + dst->type = src->type; + + if (dst->view == AV_STEREO3D_VIEW_UNSPEC) + dst->view = src->view; + + if (dst->primary_eye == AV_PRIMARY_EYE_NONE) + dst->primary_eye = src->primary_eye; + + if (!dst->baseline) + dst->baseline = src->baseline; + + if (!dst->horizontal_disparity_adjustment.num) + dst->horizontal_disparity_adjustment = src->horizontal_disparity_adjustment; + + if (!dst->horizontal_field_of_view.num) + dst->horizontal_field_of_view = src->horizontal_field_of_view; + + return 0; +} + static int side_data_map(AVFrame *dst, const AVPacketSideData *sd_src, int nb_sd_src, const SideDataMap *map) @@ -1433,8 +1470,15 @@ static int side_data_map(AVFrame *dst, continue; sd_frame = av_frame_get_side_data(dst, type_frame); - if (sd_frame) + if (sd_frame) { + if (type_frame == AV_FRAME_DATA_STEREO3D) { + int ret = side_data_stereo3d_merge(sd_frame, sd_pkt); + if (ret < 0) + return ret; + } + continue; + } sd_frame = av_frame_new_side_data(dst, type_frame, sd_pkt->size); if (!sd_frame)