Merge commit '5b10ef729f610fcbc9c485e7b643ce53268144cb'

* commit '5b10ef729f610fcbc9c485e7b643ce53268144cb':
  h264: parse frame packing arrangement SEI messages and save relevant stereo3d information

Conflicts:
	libavcodec/h264.c
	libavcodec/h264_sei.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2013-12-09 21:53:23 +01:00
commit be6e81463c
3 changed files with 85 additions and 24 deletions

View File

@ -30,6 +30,7 @@
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/stereo3d.h"
#include "internal.h"
#include "cabac.h"
#include "cabac_functions.h"
@ -2108,8 +2109,49 @@ static void decode_postinit(H264Context *h, int setup_finished)
}
}
if (h->sei_frame_packing_present &&
h->frame_packing_arrangement_type >= 0 &&
h->frame_packing_arrangement_type <= 6 &&
h->content_interpretation_type > 0 &&
h->content_interpretation_type < 3) {
AVStereo3D *stereo = av_stereo3d_create_side_data(&cur->f);
if (!stereo)
return;
switch (h->frame_packing_arrangement_type) {
case 0:
stereo->type = AV_STEREO3D_CHECKERBOARD;
break;
case 1:
stereo->type = AV_STEREO3D_LINES;
break;
case 2:
stereo->type = AV_STEREO3D_COLUMNS;
break;
case 3:
if (h->quincunx_subsampling)
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;
case 6:
stereo->type = AV_STEREO3D_2D;
break;
}
if (h->content_interpretation_type == 2)
stereo->flags = AV_STEREO3D_FLAG_INVERT;
}
cur->mmco_reset = h->mmco_reset;
h->mmco_reset = 0;
// FIXME do something with unavailable reference frames
/* Sort B-frames into display order */

View File

@ -616,6 +616,14 @@ typedef struct H264Context {
*/
int prev_interlaced_frame;
/**
* frame_packing_arrangment SEI message
*/
int sei_frame_packing_present;
int frame_packing_arrangement_type;
int content_interpretation_type;
int quincunx_subsampling;
/**
* Bit set of clock types for fields/frames in picture timing SEI message.
* For each found ct_type, appropriate bit is set (e.g., bit 1 for

View File

@ -42,6 +42,7 @@ void ff_h264_reset_sei(H264Context *h)
h->sei_dpb_output_delay = 0;
h->sei_cpb_removal_delay = -1;
h->sei_buffering_period_present = 0;
h->sei_frame_packing_present = 0;
}
static int decode_picture_timing(H264Context *h)
@ -223,31 +224,40 @@ 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);
static int decode_frame_packing_arrangement(H264Context *h)
{
int cancel;
int quincunx = 0;
int content = -1;
int type = -1;
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 */
cancel = get_bits(&h->gb, 1);
if (cancel == 0) {
type = get_bits(&h->gb, 7); // frame_packing_arrangement_type
quincunx = get_bits1(&h->gb); // quincunx_sampling_flag
content = get_bits(&h->gb, 6); // content_interpretation_type
// the following skips: spatial_flipping_flag, frame0_flipped_flag,
// field_views_flag, current_frame_is_frame0_flag,
// frame0_self_contained_flag, frame1_self_contained_flag
skip_bits(&h->gb, 6);
if (quincunx == 0 && type != 5)
skip_bits(&h->gb, 16); // frame[01]_grid_position_[xy]
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 */
skip_bits1(&h->gb); // frame_packing_arrangement_extension_flag
h->sei_frame_packing_present = (cancel == 0);
h->frame_packing_arrangement_type = type;
h->content_interpretation_type = content;
h->quincunx_subsampling = quincunx;
h->sei_fpa.frame_packing_arrangement_cancel_flag = cancel ;
h->sei_fpa.frame_packing_arrangement_type = type ;
h->sei_fpa.quincunx_sampling_flag = quincunx;
h->sei_fpa.content_interpretation_type = content ;
if (h->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d %d\n",
@ -257,7 +267,7 @@ static int decode_frame_packing(H264Context *h, int size) {
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;
}
@ -317,8 +327,9 @@ int ff_h264_decode_sei(H264Context *h)
return ret;
break;
case SEI_TYPE_FRAME_PACKING:
if (decode_frame_packing(h, size) < 0)
return -1;
ret = decode_frame_packing_arrangement(h);
if (ret < 0)
return ret;
break;
default:
av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);