1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

avcodec/h2645_sei: Attach AVStereo3D side data generically

There are only slight differences between H.264 and HEVC
for this side data, so it makes sense to share the code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2022-06-29 12:42:43 +02:00
parent 38d0d12c46
commit 01e775f4b7
3 changed files with 64 additions and 83 deletions

View File

@ -28,6 +28,7 @@
#include "libavutil/display.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "atsc_a53.h"
#include "avcodec.h"
@ -419,10 +420,73 @@ int ff_h2645_sei_ctx_replace(H2645SEI *dst, const H2645SEI *src)
return 0;
}
static int is_frame_packing_type_valid(SEIFpaType type, enum AVCodecID codec_id)
{
if (IS_H264(codec_id))
return type <= SEI_FPA_H264_TYPE_2D &&
type >= SEI_FPA_H264_TYPE_CHECKERBOARD;
else
return type <= SEI_FPA_TYPE_INTERLEAVE_TEMPORAL &&
type >= SEI_FPA_TYPE_SIDE_BY_SIDE;
}
int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
enum AVCodecID codec_id,
AVCodecContext *avctx)
{
H2645SEIFramePacking *fp = &sei->frame_packing;
if (fp->present &&
is_frame_packing_type_valid(fp->arrangement_type, codec_id) &&
fp->content_interpretation_type > 0 &&
fp->content_interpretation_type < 3) {
AVStereo3D *stereo = av_stereo3d_create_side_data(frame);
if (!stereo)
return AVERROR(ENOMEM);
switch (fp->arrangement_type) {
#if CONFIG_H264_SEI
case SEI_FPA_H264_TYPE_CHECKERBOARD:
stereo->type = AV_STEREO3D_CHECKERBOARD;
break;
case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN:
stereo->type = AV_STEREO3D_COLUMNS;
break;
case SEI_FPA_H264_TYPE_INTERLEAVE_ROW:
stereo->type = AV_STEREO3D_LINES;
break;
#endif
case SEI_FPA_TYPE_SIDE_BY_SIDE:
if (fp->quincunx_sampling_flag)
stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
else
stereo->type = AV_STEREO3D_SIDEBYSIDE;
break;
case SEI_FPA_TYPE_TOP_BOTTOM:
stereo->type = AV_STEREO3D_TOPBOTTOM;
break;
case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
stereo->type = AV_STEREO3D_FRAMESEQUENCE;
break;
#if CONFIG_H264_SEI
case SEI_FPA_H264_TYPE_2D:
stereo->type = AV_STEREO3D_2D;
break;
#endif
}
if (fp->content_interpretation_type == 2)
stereo->flags = AV_STEREO3D_FLAG_INVERT;
if (fp->arrangement_type == SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) {
if (fp->current_frame_is_frame0_flag)
stereo->view = AV_STEREO3D_VIEW_LEFT;
else
stereo->view = AV_STEREO3D_VIEW_RIGHT;
}
}
if (sei->display_orientation.present &&
(sei->display_orientation.anticlockwise_rotation ||
sei->display_orientation.hflip ||

View File

@ -31,7 +31,6 @@
#include "libavutil/display.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "internal.h"
#include "cabac.h"
@ -1227,52 +1226,6 @@ static int h264_export_frame_props(H264Context *h)
}
}
if (h->sei.common.frame_packing.present &&
h->sei.common.frame_packing.arrangement_type <= 6 &&
h->sei.common.frame_packing.content_interpretation_type > 0 &&
h->sei.common.frame_packing.content_interpretation_type < 3) {
H2645SEIFramePacking *fp = &h->sei.common.frame_packing;
AVStereo3D *stereo = av_stereo3d_create_side_data(out);
if (stereo) {
switch (fp->arrangement_type) {
case SEI_FPA_H264_TYPE_CHECKERBOARD:
stereo->type = AV_STEREO3D_CHECKERBOARD;
break;
case SEI_FPA_H264_TYPE_INTERLEAVE_COLUMN:
stereo->type = AV_STEREO3D_COLUMNS;
break;
case SEI_FPA_H264_TYPE_INTERLEAVE_ROW:
stereo->type = AV_STEREO3D_LINES;
break;
case SEI_FPA_TYPE_SIDE_BY_SIDE:
if (fp->quincunx_sampling_flag)
stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
else
stereo->type = AV_STEREO3D_SIDEBYSIDE;
break;
case SEI_FPA_TYPE_TOP_BOTTOM:
stereo->type = AV_STEREO3D_TOPBOTTOM;
break;
case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL:
stereo->type = AV_STEREO3D_FRAMESEQUENCE;
break;
case SEI_FPA_H264_TYPE_2D:
stereo->type = AV_STEREO3D_2D;
break;
}
if (fp->content_interpretation_type == 2)
stereo->flags = AV_STEREO3D_FLAG_INVERT;
if (fp->arrangement_type == SEI_FPA_TYPE_INTERLEAVE_TEMPORAL) {
if (fp->current_frame_is_frame0_flag)
stereo->view = AV_STEREO3D_VIEW_LEFT;
else
stereo->view = AV_STEREO3D_VIEW_RIGHT;
}
}
}
if (h->sei.common.afd.present) {
AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD,
sizeof(uint8_t));

View File

@ -35,7 +35,6 @@
#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "libavutil/timecode.h"
#include "bswapdsp.h"
@ -2726,41 +2725,6 @@ static int set_side_data(HEVCContext *s)
AVFrame *out = s->ref->frame;
int ret;
if (s->sei.common.frame_packing.present &&
s->sei.common.frame_packing.arrangement_type >= 3 &&
s->sei.common.frame_packing.arrangement_type <= 5 &&
s->sei.common.frame_packing.content_interpretation_type > 0 &&
s->sei.common.frame_packing.content_interpretation_type < 3) {
AVStereo3D *stereo = av_stereo3d_create_side_data(out);
if (!stereo)
return AVERROR(ENOMEM);
switch (s->sei.common.frame_packing.arrangement_type) {
case 3:
if (s->sei.common.frame_packing.quincunx_sampling_flag)
stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
else
stereo->type = AV_STEREO3D_SIDEBYSIDE;
break;
case 4:
stereo->type = AV_STEREO3D_TOPBOTTOM;
break;
case 5:
stereo->type = AV_STEREO3D_FRAMESEQUENCE;
break;
}
if (s->sei.common.frame_packing.content_interpretation_type == 2)
stereo->flags = AV_STEREO3D_FLAG_INVERT;
if (s->sei.common.frame_packing.arrangement_type == 5) {
if (s->sei.common.frame_packing.current_frame_is_frame0_flag)
stereo->view = AV_STEREO3D_VIEW_LEFT;
else
stereo->view = AV_STEREO3D_VIEW_RIGHT;
}
}
// Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1
// so the side data persists for the entire coded video sequence.
if (s->sei.mastering_display.present > 0 &&