[FFmpeg-devel] [PATCH] h264: expose stereo_mode from h264 frame packing info
Michael Niedermayer
michaelni at gmx.at
Thu Jun 27 12:34:55 CEST 2013
On Wed, Jun 26, 2013 at 10:20:56PM +0200, Joakim Plate wrote:
> On Mon, Jun 24, 2013 at 12:02 AM, Joakim Plate <elupus at ecce.se> wrote:
>
> >
> > On Sun, Jun 23, 2013 at 10:35 PM, Joakim Plate <elupus at ecce.se> wrote:
> >
> >> So a simplified patch with it just set as internal data. Is there no way
> >> to construct the string on the fly for options? we could expose the
> >> internal values i suppose. But those are harder to use. This one matches
> >> matroska settings.
> >>
> >
> > I see one problem with this. It can't differentiate between a stream that
> > have frame_packing info and it is cancelled, and one where it's just not
> > supplied. Probably should match matroska in the cancelled state and set it
> > to "mono".
> >
> >
> Updated patch that supplies the data as matadata to the frame on output
> instead of only part of the context.
> h264.c | 6 ++++
> h264.h | 35 +++++++++++++++++++++++
> h264_parser.c | 3 +-
> h264_sei.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 127 insertions(+), 2 deletions(-)
> 4eee469426594ce561e6fd96f27ad649d6ae84da 0001-h264-add-frame-packing-as-stereo_mode-frame-metadata.patch
> From 42d5aea5b2c644d0a70908f744614673ef50e84b Mon Sep 17 00:00:00 2001
> From: Joakim Plate <elupus at ecce.se>
> Date: Wed, 26 Jun 2013 22:20:28 +0200
> Subject: [PATCH 1/1] h264: add frame packing as stereo_mode frame metadata
>
> This matches the matroska defintion of stereo_mode, with
> no metadata written if no info exist in sei
> ---
> libavcodec/h264.c | 6 ++++
> libavcodec/h264.h | 35 +++++++++++++++++++-
> libavcodec/h264_parser.c | 3 +-
> libavcodec/h264_sei.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 127 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index bb105ee..b124712 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -1512,6 +1512,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
> h->prev_poc_msb = 1 << 16;
> h->prev_frame_num = -1;
> h->x264_build = -1;
> + h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
> ff_h264_reset_sei(h);
> if (avctx->codec_id == AV_CODEC_ID_H264) {
> if (avctx->ticks_per_frame == 1) {
> @@ -4861,6 +4862,8 @@ static int output_frame(H264Context *h, AVFrame *dst, Picture *srcp)
> if (ret < 0)
> return ret;
>
> + av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0);
> +
> if (!srcp->crop)
> return 0;
>
> @@ -5033,6 +5036,9 @@ static const AVProfile profiles[] = {
> static const AVOption h264_options[] = {
> {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
> {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0},
> + {"frame_packing_arrangement_cancel_flag", "frame_packing_arrangement_cancel_flag", offsetof(H264Context, sei_fpa.frame_packing_arrangement_cancel_flag), FF_OPT_TYPE_INT, {.i64 = -1}, -1, 1, 0},
> + {"frame_packing_arrangement_type", "frame_packing_arrangement_type", offsetof(H264Context, sei_fpa.frame_packing_arrangement_type), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 6, 0},
> + {"content_interpretation_type", "content_interpretation_type", offsetof(H264Context, sei_fpa.content_interpretation_type), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 2, 0},
> {NULL}
> };
how do these interact with frame threads ?
(as they are not strictly global options and could change per frame)
also exporting the cancel flag seems quite low level, isnt exporting
the current state enough ?
>
> diff --git a/libavcodec/h264.h b/libavcodec/h264.h
> index ed07ad6..8b64ec6 100644
> --- a/libavcodec/h264.h
> +++ b/libavcodec/h264.h
> @@ -127,7 +127,8 @@ typedef enum {
> SEI_TYPE_PIC_TIMING = 1, ///< picture timing
> SEI_TYPE_USER_DATA_ITU_T_T35 = 4, ///< user data registered by ITU-T Recommendation T.35
> SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data
> - SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync)
> + SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync)
> + SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement
> } SEI_Type;
>
> /**
> @@ -146,6 +147,19 @@ typedef enum {
> } SEI_PicStructType;
>
> /**
> + * frame_packing_arrangement types
> + */
> +typedef enum {
> + SEI_FPA_TYPE_CHECKERBOARD = 0,
> + SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1,
> + SEI_FPA_TYPE_INTERLEAVE_ROW = 2,
> + SEI_FPA_TYPE_SIDE_BY_SIDE = 3,
> + SEI_FPA_TYPE_TOP_BOTTOM = 4,
> + SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5,
> + SEI_FPA_TYPE_2D = 6,
> +} SEI_FpaType;
> +
> +/**
> * Sequence parameter set
> */
> typedef struct SPS {
> @@ -233,6 +247,17 @@ typedef struct PPS {
> } PPS;
>
> /**
> + * Frame Packing Arrangement Type
> + */
> +typedef struct FPA {
> + int frame_packing_arrangement_id;
> + int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received
> + SEI_FpaType frame_packing_arrangement_type;
> + int content_interpretation_type;
> + int quincunx_sampling_flag;
> +} FPA;
> +
> +/**
> * Memory management control operation opcode.
> */
> typedef enum MMCOOpcode {
> @@ -628,6 +653,8 @@ typedef struct H264Context {
> */
> int valid_recovery_point;
>
> + FPA sei_fpa;
> +
> int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
> int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
>
> @@ -775,6 +802,12 @@ void ff_h264_filter_mb(H264Context *h, int mb_x, int mb_y,
> */
> void ff_h264_reset_sei(H264Context *h);
>
> +/**
> + * Get stereo_mode string from the h264 frame_packing_arrangement
> + * @param h H.264 context.
> + */
> +const char* ff_h264_sei_stereo_mode(H264Context *h);
> +
> /*
> * o-o o-o
> * / / /
> diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
> index 3b7d011..a5d47ed 100644
> --- a/libavcodec/h264_parser.c
> +++ b/libavcodec/h264_parser.c
> @@ -172,6 +172,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
> h->sei_dpb_output_delay = 0;
> h->sei_cpb_removal_delay = -1;
> h->sei_buffering_period_present = 0;
> + h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
>
> if (!buf_size)
> return 0;
> @@ -254,7 +255,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
> }
> h->sps = *h->sps_buffers[h->pps.sps_id];
> h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
> -
> +
> avctx->profile = ff_h264_get_profile(&h->sps);
> avctx->level = h->sps.level_idc;
>
> diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
> index 5f68a13..49f1c00 100644
> --- a/libavcodec/h264_sei.c
> +++ b/libavcodec/h264_sei.c
> @@ -204,6 +204,43 @@ static int decode_buffering_period(H264Context *h){
> return 0;
> }
>
> +static int decode_frame_packing(H264Context *h, int size){
> + int bits = get_bits_left(&h->gb);
> +
> + h->sei_fpa.frame_packing_arrangement_id = get_ue_golomb(&h->gb);
> + h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits(&h->gb, 1);
> + if (!h->sei_fpa.frame_packing_arrangement_cancel_flag) {
> + h->sei_fpa.frame_packing_arrangement_type = get_bits(&h->gb, 7);
> + h->sei_fpa.quincunx_sampling_flag = get_bits(&h->gb, 1);
> + h->sei_fpa.content_interpretation_type = get_bits(&h->gb, 6);
> + skip_bits(&h->gb, 1); /* spatial_flipping_flag */
> + skip_bits(&h->gb, 1); /* frame0_flipped_flag */
> + skip_bits(&h->gb, 1); /* field_views_flag */
> + skip_bits(&h->gb, 1); /* current_frame_is_frame0_flag */
> + skip_bits(&h->gb, 1); /* frame0_self_contained_flag */
> + skip_bits(&h->gb, 1); /* frame1_self_contained_flag */
> + if (!h->sei_fpa.quincunx_sampling_flag && h->sei_fpa.frame_packing_arrangement_type != 5) {
> + skip_bits(&h->gb, 4); /* frame0_grid_position_x */
> + skip_bits(&h->gb, 4); /* frame0_grid_position_y */
> + skip_bits(&h->gb, 4); /* frame1_grid_position_x */
> + skip_bits(&h->gb, 4); /* frame1_grid_position_y */
> + }
> + skip_bits(&h->gb, 8); /* frame_packing_arrangement_reserved_byte */
> + get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */;
> + }
> + skip_bits(&h->gb, 1); /* frame_packing_arrangement_extension_flag */
> +
> + if (h->avctx->debug & FF_DEBUG_PICT_INFO)
> + av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d\n",
> + h->sei_fpa.frame_packing_arrangement_id,
> + h->sei_fpa.frame_packing_arrangement_cancel_flag,
> + h->sei_fpa.frame_packing_arrangement_type,
> + h->sei_fpa.quincunx_sampling_flag,
> + h->sei_fpa.content_interpretation_type);
> + skip_bits(&h->gb, 8*size - (bits - get_bits_left(&h->gb)));
skip_bits_long()
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
it is not once nor twice but times without number that the same ideas make
their appearance in the world. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130627/bf8dd538/attachment.asc>
More information about the ffmpeg-devel
mailing list