[x264-devel] commit: Add frame-packing SEI support for signalling 3D video ( Vittorio Giovara )
git at videolan.org
git at videolan.org
Wed Dec 15 04:19:33 CET 2010
x264 | branch: master | Vittorio Giovara <vitto.giova at yahoo.it> | Fri Dec 10 20:43:00 2010 -0800| [3ee357af82f01b8fd6a3ecf052ef98f632f375a2] | committer: Jason Garrett-Glaser
Add frame-packing SEI support for signalling 3D video
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=3ee357af82f01b8fd6a3ecf052ef98f632f375a2
---
common/common.c | 3 +++
common/common.h | 1 +
encoder/encoder.c | 15 ++++++++++++++-
encoder/set.c | 41 +++++++++++++++++++++++++++++++++++++++++
encoder/set.h | 1 +
x264.c | 8 ++++++++
x264.h | 5 ++++-
7 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/common/common.c b/common/common.c
index 951e326..26b62a3 100644
--- a/common/common.c
+++ b/common/common.c
@@ -165,6 +165,7 @@ void x264_param_default( x264_param_t *param )
param->b_tff = 1;
param->b_pic_struct = 0;
param->b_fake_interlaced = 0;
+ param->i_frame_packing = -1;
}
static int x264_param_apply_preset( x264_param_t *param, const char *preset )
@@ -978,6 +979,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
p->b_pic_struct = atobool(value);
OPT("fake-interlaced")
p->b_fake_interlaced = atobool(value);
+ OPT("frame-packing")
+ p->i_frame_packing = atoi(value);
else
return X264_PARAM_BAD_NAME;
#undef OPT
diff --git a/common/common.h b/common/common.h
index 3c80c0c..119508c 100644
--- a/common/common.h
+++ b/common/common.h
@@ -309,6 +309,7 @@ enum sei_payload_type_e
SEI_USER_DATA_REGISTERED = 4,
SEI_USER_DATA_UNREGISTERED = 5,
SEI_RECOVERY_POINT = 6,
+ SEI_FRAME_PACKING = 45,
};
typedef struct
diff --git a/encoder/encoder.c b/encoder/encoder.c
index ab66661..f5c481c 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -469,6 +469,8 @@ static int x264_validate_parameters( x264_t *h )
}
}
+ h->param.i_frame_packing = x264_clip3( h->param.i_frame_packing, -1, 5 );
+
/* Detect default ffmpeg settings and terminate with an error. */
{
int score = 0;
@@ -1199,6 +1201,7 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
COPY( b_deblocking_filter );
COPY( i_deblocking_filter_alphac0 );
COPY( i_deblocking_filter_beta );
+ COPY( i_frame_packing );
COPY( analyse.inter );
COPY( analyse.intra );
COPY( analyse.i_direct_mv_pred );
@@ -2674,7 +2677,17 @@ int x264_encoder_encode( x264_t *h,
int time_to_recovery = h->param.i_open_gop ? 0 : X264_MIN( h->mb.i_mb_width - 1, h->param.i_keyint_max ) + h->param.i_bframe - 1;
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
x264_sei_recovery_point_write( h, &h->out.bs, time_to_recovery );
- x264_nal_end( h );
+ if( x264_nal_end( h ) )
+ return -1;
+ overhead += h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD - (h->param.b_annexb && h->out.i_nal-1);
+ }
+
+ if ( h->param.i_frame_packing >= 0 )
+ {
+ x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
+ x264_sei_frame_packing_write( h, &h->out.bs );
+ if( x264_nal_end( h ) )
+ return -1;
overhead += h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD - (h->param.b_annexb && h->out.i_nal-1);
}
}
diff --git a/encoder/set.c b/encoder/set.c
index 6cf0c6a..622d16f 100644
--- a/encoder/set.c
+++ b/encoder/set.c
@@ -638,6 +638,47 @@ void x264_sei_pic_timing_write( x264_t *h, bs_t *s )
x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_PIC_TIMING );
}
+void x264_sei_frame_packing_write( x264_t *h, bs_t *s )
+{
+ bs_t q;
+ uint8_t tmp_buf[100];
+ bs_init( &q, tmp_buf, 100 );
+
+ bs_realign( &q );
+
+ bs_write_ue( &q, 0 ); // frame_packing_arrangement_id
+ bs_write1( &q, 0 ); // frame_packing_arrangement_cancel_flag
+ bs_write ( &q, 7, h->param.i_frame_packing ); // frame_packing_arrangement_type
+ bs_write1( &q, 0 ); // quincunx_sampling_flag
+
+ // 0: views are unrelated, 1: left view is on the left, 2: left view is on the right
+ bs_write ( &q, 6, 1 ); // content_interpretation_type
+
+ /* The following flags shall be set to 0 and ignored by the decoder
+ * (Why, then, do they even exist? Who knows.) */
+ bs_write1( &q, 0 ); // spatial_flipping_flag
+ bs_write1( &q, 0 ); // frame0_flipped_flag
+ bs_write1( &q, 0 ); // field_views_flag
+ bs_write1( &q, 0 ); // current_frame_is_frame0_flag
+ bs_write1( &q, 0 ); // frame0_self_contained_flag
+ bs_write1( &q, 0 ); // frame1_self_contained_flag
+ if ( /* quincunx_sampling_flag == 0 && */ h->param.i_frame_packing != 5 )
+ {
+ bs_write( &q, 4, 0 ); // frame0_grid_position_x
+ bs_write( &q, 4, 0 ); // frame0_grid_position_y
+ bs_write( &q, 4, 0 ); // frame1_grid_position_x
+ bs_write( &q, 4, 0 ); // frame1_grid_position_y
+ }
+ bs_write( &q, 8, 0 ); // frame_packing_arrangement_reserved_byte
+ bs_write_ue( &q, 0 ); // frame_packing_arrangement_repetition_period
+ bs_write1( &q, 0 ); // frame_packing_arrangement_extension_flag
+
+ bs_align_10( &q );
+ bs_flush( &q );
+
+ x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_FRAME_PACKING );
+}
+
void x264_filler_write( x264_t *h, bs_t *s, int filler )
{
bs_realign( s );
diff --git a/encoder/set.h b/encoder/set.h
index 6d70e96..83c1bd9 100644
--- a/encoder/set.h
+++ b/encoder/set.h
@@ -36,6 +36,7 @@ int x264_sei_version_write( x264_t *h, bs_t *s );
int x264_validate_levels( x264_t *h, int verbose );
void x264_sei_buffering_period_write( x264_t *h, bs_t *s );
void x264_sei_pic_timing_write( x264_t *h, bs_t *s );
+void x264_sei_frame_packing_write( x264_t *h, bs_t *s );
void x264_sei_write( bs_t *s, uint8_t *payload, int payload_size, int payload_type );
void x264_filler_write( x264_t *h, bs_t *s, int filler );
diff --git a/x264.c b/x264.c
index 6fdd24a..1e465ad 100644
--- a/x264.c
+++ b/x264.c
@@ -551,6 +551,13 @@ static void help( x264_param_t *defaults, int longhelp )
H2( " --fake-interlaced Flag stream as interlaced but encode progressive.\n"
" Makes it possible to encode 25p and 30p Blu-Ray\n"
" streams. Ignored in interlaced mode.\n" );
+ H2( " --frame-packing <integer> For stereoscopic videos define frame arrangement\n"
+ " - 0: checkerboard - pixels are alternatively from L and R\n"
+ " - 1: column alternation - L and R are interlaced by column\n"
+ " - 2: row alternation - L and R are interlaced by row\n"
+ " - 3: side by side - L is on the left, R on the right\n"
+ " - 4: top bottom - L is on top, R on bottom\n"
+ " - 5: frame alternation - one view per frame\n" );
H0( "\n" );
H0( "Ratecontrol:\n" );
H0( "\n" );
@@ -937,6 +944,7 @@ static struct option long_options[] =
{ "nal-hrd", required_argument, NULL, 0 },
{ "pulldown", required_argument, NULL, OPT_PULLDOWN },
{ "fake-interlaced", no_argument, NULL, 0 },
+ { "frame-packing", required_argument, NULL, 0 },
{ "vf", required_argument, NULL, OPT_VIDEO_FILTER },
{ "video-filter", required_argument, NULL, OPT_VIDEO_FILTER },
{ "input-res", required_argument, NULL, OPT_INPUT_RES },
diff --git a/x264.h b/x264.h
index d6c2120..c0fe84d 100644
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,7 @@
#include "x264_config.h"
-#define X264_BUILD 110
+#define X264_BUILD 111
/* x264_t:
* opaque handler for encoder */
@@ -390,6 +390,9 @@ typedef struct x264_param_t
unsigned int i_bottom;
} crop_rect;
+ /* frame packing arrangement flag */
+ int i_frame_packing;
+
/* Muxing parameters */
int b_aud; /* generate access unit delimiters */
int b_repeat_headers; /* put SPS/PPS before each keyframe */
More information about the x264-devel
mailing list