x264enc: conditionally expose enhanced upstream capabilities

API: GstX264Enc:sliced-threads
API: GstX264Enc:sync-lookahead
API: GstX264Enc:intra-refresh
API: GstX264Enc:mb-tree
API: GstX264Enc:rc-lookahead

See #607798.
This commit is contained in:
Mark Nauwelaerts 2010-06-18 14:35:00 +02:00
parent a49c2102c7
commit 27025d0ebd
2 changed files with 104 additions and 0 deletions

View file

@ -67,6 +67,18 @@
#define X264_ENC_NALS 1 #define X264_ENC_NALS 1
#endif #endif
#if X264_BUILD >= 69
#define X264_MB_RC
#endif
#if X264_BUILD >= 80
#define X264_ENH_THREADING
#endif
#if X264_BUILD >= 82
#define X264_INTRA_REFRESH
#endif
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -77,12 +89,15 @@ enum
{ {
ARG_0, ARG_0,
ARG_THREADS, ARG_THREADS,
ARG_SLICED_THREADS,
ARG_SYNC_LOOKAHEAD,
ARG_PASS, ARG_PASS,
ARG_QUANTIZER, ARG_QUANTIZER,
ARG_STATS_FILE, ARG_STATS_FILE,
ARG_MULTIPASS_CACHE_FILE, ARG_MULTIPASS_CACHE_FILE,
ARG_BYTE_STREAM, ARG_BYTE_STREAM,
ARG_BITRATE, ARG_BITRATE,
ARG_INTRA_REFRESH,
ARG_VBV_BUF_CAPACITY, ARG_VBV_BUF_CAPACITY,
ARG_ME, ARG_ME,
ARG_SUBME, ARG_SUBME,
@ -103,6 +118,8 @@ enum
ARG_QP_STEP, ARG_QP_STEP,
ARG_IP_FACTOR, ARG_IP_FACTOR,
ARG_PB_FACTOR, ARG_PB_FACTOR,
ARG_RC_MB_TREE,
ARG_RC_LOOKAHEAD,
ARG_NR, ARG_NR,
ARG_INTERLACED ARG_INTERLACED
}; };
@ -136,6 +153,11 @@ enum
#define ARG_PB_FACTOR_DEFAULT 1.3 #define ARG_PB_FACTOR_DEFAULT 1.3
#define ARG_NR_DEFAULT 0 #define ARG_NR_DEFAULT 0
#define ARG_INTERLACED_DEFAULT FALSE #define ARG_INTERLACED_DEFAULT FALSE
#define ARG_SLICED_THREADS_DEFAULT FALSE
#define ARG_SYNC_LOOKAHEAD_DEFAULT -1
#define ARG_RC_MB_TREE_DEFAULT TRUE
#define ARG_RC_LOOKAHEAD_DEFAULT 40
#define ARG_INTRA_REFRESH_DEFAULT FALSE
enum enum
{ {
@ -299,6 +321,16 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
g_param_spec_uint ("threads", "Threads", g_param_spec_uint ("threads", "Threads",
"Number of threads used by the codec (0 for automatic)", "Number of threads used by the codec (0 for automatic)",
0, 4, ARG_THREADS_DEFAULT, G_PARAM_READWRITE)); 0, 4, ARG_THREADS_DEFAULT, G_PARAM_READWRITE));
#ifdef X264_ENH_THREADING
g_object_class_install_property (gobject_class, ARG_SLICED_THREADS,
g_param_spec_boolean ("sliced-threads", "Sliced Threads",
"Low latency but lower efficiency threading",
ARG_SLICED_THREADS_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_SYNC_LOOKAHEAD,
g_param_spec_int ("sync-lookahead", "Sync Lookahead",
"Number of buffer frames for threaded lookahead (-1 for automatic)",
-1, 250, ARG_SYNC_LOOKAHEAD_DEFAULT, G_PARAM_READWRITE));
#endif
g_object_class_install_property (gobject_class, ARG_PASS, g_object_class_install_property (gobject_class, ARG_PASS,
g_param_spec_enum ("pass", "Encoding pass/type", g_param_spec_enum ("pass", "Encoding pass/type",
"Encoding pass/type", GST_X264_ENC_PASS_TYPE, "Encoding pass/type", GST_X264_ENC_PASS_TYPE,
@ -322,6 +354,12 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
g_object_class_install_property (gobject_class, ARG_BITRATE, g_object_class_install_property (gobject_class, ARG_BITRATE,
g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1, g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
100 * 1024, ARG_BITRATE_DEFAULT, G_PARAM_READWRITE)); 100 * 1024, ARG_BITRATE_DEFAULT, G_PARAM_READWRITE));
#ifdef X264_INTRA_REFRESH
g_object_class_install_property (gobject_class, ARG_INTRA_REFRESH,
g_param_spec_boolean ("intra-refresh", "Intra Refresh",
"Use Periodic Intra Refresh instead of IDR frames",
ARG_INTRA_REFRESH_DEFAULT, G_PARAM_READWRITE));
#endif
g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY, g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity", g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
"Size of the VBV buffer in milliseconds", "Size of the VBV buffer in milliseconds",
@ -398,6 +436,16 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
g_param_spec_float ("pb-factor", "PB-Factor", g_param_spec_float ("pb-factor", "PB-Factor",
"Quantizer factor between P- and B-frames", "Quantizer factor between P- and B-frames",
0, 2, ARG_PB_FACTOR_DEFAULT, G_PARAM_READWRITE)); 0, 2, ARG_PB_FACTOR_DEFAULT, G_PARAM_READWRITE));
#ifdef X264_MB_RC
g_object_class_install_property (gobject_class, ARG_RC_MB_TREE,
g_param_spec_boolean ("mb-tree", "Macroblock Tree",
"Macroblock-Tree ratecontrol",
ARG_RC_MB_TREE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_RC_LOOKAHEAD,
g_param_spec_int ("rc-lookahead", "Rate Control Lookahead",
"Number of frames for frametype lookahead",
0, 250, ARG_RC_LOOKAHEAD_DEFAULT, G_PARAM_READWRITE));
#endif
g_object_class_install_property (gobject_class, ARG_NR, g_object_class_install_property (gobject_class, ARG_NR,
g_param_spec_uint ("noise-reduction", "Noise Reducation", g_param_spec_uint ("noise-reduction", "Noise Reducation",
"Noise reduction strength", "Noise reduction strength",
@ -465,11 +513,14 @@ gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
/* properties */ /* properties */
encoder->threads = ARG_THREADS_DEFAULT; encoder->threads = ARG_THREADS_DEFAULT;
encoder->sliced_threads = ARG_SLICED_THREADS_DEFAULT;
encoder->sync_lookahead = ARG_SYNC_LOOKAHEAD_DEFAULT;
encoder->pass = ARG_PASS_DEFAULT; encoder->pass = ARG_PASS_DEFAULT;
encoder->quantizer = ARG_QUANTIZER_DEFAULT; encoder->quantizer = ARG_QUANTIZER_DEFAULT;
encoder->mp_cache_file = g_strdup (ARG_MULTIPASS_CACHE_FILE_DEFAULT); encoder->mp_cache_file = g_strdup (ARG_MULTIPASS_CACHE_FILE_DEFAULT);
encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT; encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT;
encoder->bitrate = ARG_BITRATE_DEFAULT; encoder->bitrate = ARG_BITRATE_DEFAULT;
encoder->intra_refresh = ARG_INTRA_REFRESH_DEFAULT;
encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT; encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT;
encoder->me = ARG_ME_DEFAULT; encoder->me = ARG_ME_DEFAULT;
encoder->subme = ARG_SUBME_DEFAULT; encoder->subme = ARG_SUBME_DEFAULT;
@ -490,6 +541,8 @@ gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
encoder->qp_step = ARG_QP_STEP_DEFAULT; encoder->qp_step = ARG_QP_STEP_DEFAULT;
encoder->ip_factor = ARG_IP_FACTOR_DEFAULT; encoder->ip_factor = ARG_IP_FACTOR_DEFAULT;
encoder->pb_factor = ARG_PB_FACTOR_DEFAULT; encoder->pb_factor = ARG_PB_FACTOR_DEFAULT;
encoder->mb_tree = ARG_RC_MB_TREE_DEFAULT;
encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
encoder->noise_reduction = ARG_NR_DEFAULT; encoder->noise_reduction = ARG_NR_DEFAULT;
encoder->interlaced = ARG_INTERLACED_DEFAULT; encoder->interlaced = ARG_INTERLACED_DEFAULT;
@ -559,6 +612,10 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
/* set up encoder parameters */ /* set up encoder parameters */
encoder->x264param.i_threads = encoder->threads; encoder->x264param.i_threads = encoder->threads;
#ifdef X264_ENH_THREADING
encoder->x264param.b_sliced_threads = encoder->sliced_threads;
encoder->x264param.i_sync_lookahead = encoder->sync_lookahead;
#endif
encoder->x264param.i_fps_num = encoder->fps_num; encoder->x264param.i_fps_num = encoder->fps_num;
encoder->x264param.i_fps_den = encoder->fps_den; encoder->x264param.i_fps_den = encoder->fps_den;
encoder->x264param.i_width = encoder->width; encoder->x264param.i_width = encoder->width;
@ -618,9 +675,17 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
encoder->x264param.i_deblocking_filter_beta = 0; encoder->x264param.i_deblocking_filter_beta = 0;
encoder->x264param.rc.f_ip_factor = encoder->ip_factor; encoder->x264param.rc.f_ip_factor = encoder->ip_factor;
encoder->x264param.rc.f_pb_factor = encoder->pb_factor; encoder->x264param.rc.f_pb_factor = encoder->pb_factor;
#ifdef X264_MB_RC
encoder->x264param.rc.b_mb_tree = encoder->mb_tree;
encoder->x264param.rc.i_lookahead = encoder->rc_lookahead;
GST_DEBUG_OBJECT (encoder, "here %d", encoder->rc_lookahead);
#endif
#ifdef X264_ENC_NALS #ifdef X264_ENC_NALS
encoder->x264param.b_annexb = encoder->byte_stream; encoder->x264param.b_annexb = encoder->byte_stream;
#endif #endif
#ifdef X264_INTRA_REFRESH
encoder->x264param.b_intra_refresh = encoder->intra_refresh;
#endif
switch (encoder->pass) { switch (encoder->pass) {
case GST_X264_ENC_PASS_QUANT: case GST_X264_ENC_PASS_QUANT:
@ -1137,7 +1202,11 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
GST_BUFFER_TIMESTAMP (out_buf) = pic_out.i_pts; GST_BUFFER_TIMESTAMP (out_buf) = pic_out.i_pts;
GST_BUFFER_DURATION (out_buf) = duration; GST_BUFFER_DURATION (out_buf) = duration;
#ifdef X264_INTRA_REFRESH
if (pic_out.b_keyframe) {
#else
if (pic_out.i_type == X264_TYPE_IDR) { if (pic_out.i_type == X264_TYPE_IDR) {
#endif
GST_BUFFER_FLAG_UNSET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT); GST_BUFFER_FLAG_UNSET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
} else { } else {
GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT); GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
@ -1217,6 +1286,12 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
case ARG_THREADS: case ARG_THREADS:
encoder->threads = g_value_get_uint (value); encoder->threads = g_value_get_uint (value);
break; break;
case ARG_SLICED_THREADS:
encoder->sliced_threads = g_value_get_boolean (value);
break;
case ARG_SYNC_LOOKAHEAD:
encoder->sync_lookahead = g_value_get_int (value);
break;
case ARG_PASS: case ARG_PASS:
encoder->pass = g_value_get_enum (value); encoder->pass = g_value_get_enum (value);
break; break;
@ -1235,6 +1310,9 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
case ARG_BITRATE: case ARG_BITRATE:
encoder->bitrate = g_value_get_uint (value); encoder->bitrate = g_value_get_uint (value);
break; break;
case ARG_INTRA_REFRESH:
encoder->intra_refresh = g_value_get_boolean (value);
break;
case ARG_VBV_BUF_CAPACITY: case ARG_VBV_BUF_CAPACITY:
encoder->vbv_buf_capacity = g_value_get_uint (value); encoder->vbv_buf_capacity = g_value_get_uint (value);
break; break;
@ -1295,6 +1373,12 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
case ARG_PB_FACTOR: case ARG_PB_FACTOR:
encoder->pb_factor = g_value_get_float (value); encoder->pb_factor = g_value_get_float (value);
break; break;
case ARG_RC_MB_TREE:
encoder->mb_tree = g_value_get_boolean (value);
break;
case ARG_RC_LOOKAHEAD:
encoder->rc_lookahead = g_value_get_int (value);
break;
case ARG_NR: case ARG_NR:
encoder->noise_reduction = g_value_get_uint (value); encoder->noise_reduction = g_value_get_uint (value);
break; break;
@ -1329,6 +1413,12 @@ gst_x264_enc_get_property (GObject * object, guint prop_id,
case ARG_THREADS: case ARG_THREADS:
g_value_set_uint (value, encoder->threads); g_value_set_uint (value, encoder->threads);
break; break;
case ARG_SLICED_THREADS:
g_value_set_boolean (value, encoder->sliced_threads);
break;
case ARG_SYNC_LOOKAHEAD:
g_value_set_int (value, encoder->sync_lookahead);
break;
case ARG_PASS: case ARG_PASS:
g_value_set_enum (value, encoder->pass); g_value_set_enum (value, encoder->pass);
break; break;
@ -1345,6 +1435,9 @@ gst_x264_enc_get_property (GObject * object, guint prop_id,
case ARG_BITRATE: case ARG_BITRATE:
g_value_set_uint (value, encoder->bitrate); g_value_set_uint (value, encoder->bitrate);
break; break;
case ARG_INTRA_REFRESH:
g_value_set_boolean (value, encoder->intra_refresh);
break;
case ARG_VBV_BUF_CAPACITY: case ARG_VBV_BUF_CAPACITY:
g_value_set_uint (value, encoder->vbv_buf_capacity); g_value_set_uint (value, encoder->vbv_buf_capacity);
break; break;
@ -1405,6 +1498,12 @@ gst_x264_enc_get_property (GObject * object, guint prop_id,
case ARG_PB_FACTOR: case ARG_PB_FACTOR:
g_value_set_float (value, encoder->pb_factor); g_value_set_float (value, encoder->pb_factor);
break; break;
case ARG_RC_MB_TREE:
g_value_set_boolean (value, encoder->mb_tree);
break;
case ARG_RC_LOOKAHEAD:
g_value_set_int (value, encoder->rc_lookahead);
break;
case ARG_NR: case ARG_NR:
g_value_set_uint (value, encoder->noise_reduction); g_value_set_uint (value, encoder->noise_reduction);
break; break;

View file

@ -55,11 +55,14 @@ struct _GstX264Enc
/* properties */ /* properties */
guint threads; guint threads;
gboolean sliced_threads;
gint sync_lookahead;
gint pass; gint pass;
guint quantizer; guint quantizer;
gchar *mp_cache_file; gchar *mp_cache_file;
gboolean byte_stream; gboolean byte_stream;
guint bitrate; guint bitrate;
gboolean intra_refresh;
gint me; gint me;
guint subme; guint subme;
guint analyse; guint analyse;
@ -80,6 +83,8 @@ struct _GstX264Enc
guint qp_min; guint qp_min;
guint qp_max; guint qp_max;
guint qp_step; guint qp_step;
gboolean mb_tree;
gint rc_lookahead;
guint noise_reduction; guint noise_reduction;
gboolean interlaced; gboolean interlaced;