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 )
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
SEI_USER_DATA_REGISTERED = 4,
SEI_USER_DATA_UNREGISTERED = 5,
SEI_RECOVERY_POINT = 6,
+ SEI_FRAME_PACKING = 45,
};
typedef struct
}
}
+ 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;
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 );
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);
}
}
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 );
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 );
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" );
{ "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 },
#include "x264_config.h"
-#define X264_BUILD 110
+#define X264_BUILD 111
/* x264_t:
* opaque handler for encoder */
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 */