From 8710a634a5d422d9ee9d1578ff1c07cd39f16ce0 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 27 Jun 2013 23:09:06 +0200 Subject: 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 Signed-off-by: Michael Niedermayer --- libavcodec/h264_sei.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'libavcodec/h264_sei.c') diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 5f68a139a3..932085230b 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -204,6 +204,44 @@ 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 */ + h->sei_fpa.frame_packing_arrangement_repetition_period = 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 %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, + h->sei_fpa.frame_packing_arrangement_repetition_period); + skip_bits_long(&h->gb, 8*size - (bits - get_bits_left(&h->gb))); + return 0; +} + int ff_h264_decode_sei(H264Context *h){ while (get_bits_left(&h->gb) > 16) { int size, type; @@ -246,6 +284,9 @@ int ff_h264_decode_sei(H264Context *h){ if(decode_buffering_period(h) < 0) return -1; break; + case SEI_TYPE_FRAME_PACKING: + if(decode_frame_packing(h, size) < 0) + return -1; default: skip_bits(&h->gb, 8*size); } @@ -256,3 +297,48 @@ int ff_h264_decode_sei(H264Context *h){ return 0; } + +const char* ff_h264_sei_stereo_mode(H264Context *h) +{ + if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 0) { + switch (h->sei_fpa.frame_packing_arrangement_type) { + case SEI_FPA_TYPE_CHECKERBOARD: + if (h->sei_fpa.content_interpretation_type == 2) + return "checkerboard_rl"; + else + return "checkerboard_lr"; + case SEI_FPA_TYPE_INTERLEAVE_COLUMN: + if (h->sei_fpa.content_interpretation_type == 2) + return "col_interleaved_rl"; + else + return "col_interleaved_lr"; + case SEI_FPA_TYPE_INTERLEAVE_ROW: + if (h->sei_fpa.content_interpretation_type == 2) + return "row_interleaved_rl"; + else + return "row_interleaved_lr"; + case SEI_FPA_TYPE_SIDE_BY_SIDE: + if (h->sei_fpa.content_interpretation_type == 2) + return "right_left"; + else + return "left_right"; + case SEI_FPA_TYPE_TOP_BOTTOM: + if (h->sei_fpa.content_interpretation_type == 2) + return "bottom_top"; + else + return "top_bottom"; + case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: + if (h->sei_fpa.content_interpretation_type == 2) + return "block_rl"; + else + return "block_lr"; + case SEI_FPA_TYPE_2D: + default: + return "mono"; + } + } else if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 1) { + return "mono"; + } else { + return NULL; + } +} -- cgit v1.2.3