diff mbox series

[FFmpeg-devel,3/3] lavc/decode: merge stereo3d information from decoder with packet side data

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

Checks

Context Check Description
andriy/configure_x86 warning Failed to apply patch

Commit Message

Anton Khirnov Sept. 22, 2024, 6 p.m. UTC
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.
---
 libavcodec/decode.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

Comments

James Almer Sept. 23, 2024, 2:17 a.m. UTC | #1
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.
Anton Khirnov Sept. 23, 2024, 4:22 a.m. UTC | #2
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.
James Almer Sept. 23, 2024, 2:27 p.m. UTC | #3
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 mbox series

Patch

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)