aboutsummaryrefslogtreecommitdiff
path: root/ext/x264/gstx264enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/x264/gstx264enc.c')
-rw-r--r--ext/x264/gstx264enc.c401
1 files changed, 355 insertions, 46 deletions
diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c
index 82177e7..dcaf5d0 100644
--- a/ext/x264/gstx264enc.c
+++ b/ext/x264/gstx264enc.c
@@ -15,8 +15,8 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
@@ -389,11 +389,17 @@ gst_x264_enc_build_tunings_string (GstX264Enc * x264enc)
x264enc->tunings->str);
}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define FORMATS "I420, YV12, Y42B, Y444, NV12, I420_10LE, I422_10LE, Y444_10LE"
+#else
+#define FORMATS "I420, YV12, Y42B, Y444, NV12, I420_10BE, I422_10BE, Y444_10BE"
+#endif
+
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw, "
- "format = (string) { I420, YV12 }, "
+ "format = (string) { " FORMATS " }, "
"framerate = (fraction) [0, MAX], "
"width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ]")
);
@@ -405,13 +411,16 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
"framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ], "
"stream-format = (string) { avc, byte-stream }, "
- "alignment = (string) { au }, "
- "profile = (string) { high-10, high, main, baseline, "
- "constrained-baseline, high-10-intra }")
+ "alignment = (string) au, "
+ "profile = (string) { high-4:4:4, high-4:2:2, high-10, high, main,"
+ " baseline, constrained-baseline, high-4:4:4-intra, high-4:2:2-intra,"
+ " high-10-intra }")
);
static void gst_x264_enc_finalize (GObject * object);
-static gboolean gst_x264_enc_reset (GstVideoEncoder * encoder, gboolean hard);
+static gboolean gst_x264_enc_start (GstVideoEncoder * encoder);
+static gboolean gst_x264_enc_stop (GstVideoEncoder * encoder);
+static gboolean gst_x264_enc_flush (GstVideoEncoder * encoder);
static gboolean gst_x264_enc_init_encoder (GstX264Enc * encoder);
static void gst_x264_enc_close_encoder (GstX264Enc * encoder);
@@ -423,7 +432,6 @@ static void gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send);
static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder,
x264_picture_t * pic_in, GstVideoCodecFrame * input_frame, int *i_nal,
gboolean send);
-static gboolean gst_x264_enc_stop (GstVideoEncoder * encoder);
static gboolean gst_x264_enc_set_format (GstVideoEncoder * video_enc,
GstVideoCodecState * state);
static gboolean gst_x264_enc_propose_allocation (GstVideoEncoder * encoder,
@@ -463,6 +471,219 @@ gst_x264_enc_build_partitions (gint analyse)
}
static void
+set_value (GValue * val, gint count, ...)
+{
+ const gchar *fmt = NULL;
+ GValue sval = G_VALUE_INIT;
+ va_list ap;
+ gint i;
+
+ g_value_init (&sval, G_TYPE_STRING);
+
+ if (count > 1)
+ g_value_init (val, GST_TYPE_LIST);
+
+ va_start (ap, count);
+ for (i = 0; i < count; i++) {
+ fmt = va_arg (ap, const gchar *);
+ g_value_set_string (&sval, fmt);
+ if (count > 1) {
+ gst_value_list_append_value (val, &sval);
+ }
+ }
+ va_end (ap);
+
+ if (count == 1)
+ *val = sval;
+ else
+ g_value_unset (&sval);
+}
+
+static void
+gst_x264_enc_add_x264_chroma_format (GstStructure * s,
+ int x264_chroma_format_local)
+{
+ GValue fmt = G_VALUE_INIT;
+
+ if (x264_bit_depth == 8) {
+ GST_INFO ("This x264 build supports 8-bit depth");
+ if (x264_chroma_format_local == 0) {
+ set_value (&fmt, 5, "I420", "YV12", "Y42B", "Y444", "NV12");
+ } else if (x264_chroma_format_local == X264_CSP_I420) {
+ set_value (&fmt, 3, "I420", "YV12", "NV12");
+ } else if (x264_chroma_format_local == X264_CSP_I422) {
+ set_value (&fmt, 1, "Y42B");
+ } else if (x264_chroma_format_local == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format_local);
+ }
+ } else if (x264_bit_depth == 10) {
+ GST_INFO ("This x264 build supports 10-bit depth");
+
+ if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
+ if (x264_chroma_format_local == 0) {
+ set_value (&fmt, 3, "I420_10LE", "I422_10LE", "Y444_10LE");
+ } else if (x264_chroma_format_local == X264_CSP_I420) {
+ set_value (&fmt, 1, "I420_10LE");
+ } else if (x264_chroma_format_local == X264_CSP_I422) {
+ set_value (&fmt, 1, "I422_10LE");
+ } else if (x264_chroma_format_local == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444_10LE");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format_local);
+ }
+ } else {
+ if (x264_chroma_format_local == 0) {
+ set_value (&fmt, 3, "I420_10BE", "I422_10BE", "Y444_10BE");
+ } else if (x264_chroma_format_local == X264_CSP_I420) {
+ set_value (&fmt, 1, "I420_10BE");
+ } else if (x264_chroma_format_local == X264_CSP_I422) {
+ set_value (&fmt, 1, "I422_10BE");
+ } else if (x264_chroma_format_local == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444_10BE");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format_local);
+ }
+ }
+ } else {
+ GST_ERROR ("Unsupported bit depth %d, we only support 8-bit and 10-bit",
+ x264_bit_depth);
+ }
+
+ if (G_VALUE_TYPE (&fmt) != G_TYPE_INVALID)
+ gst_structure_take_value (s, "format", &fmt);
+}
+
+static GstCaps *
+gst_x264_enc_get_supported_input_caps (void)
+{
+ GstCaps *caps;
+
+ caps = gst_caps_new_simple ("video/x-raw",
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+ "width", GST_TYPE_INT_RANGE, 16, G_MAXINT,
+ "height", GST_TYPE_INT_RANGE, 16, G_MAXINT, NULL);
+
+ gst_x264_enc_add_x264_chroma_format (gst_caps_get_structure (caps, 0),
+ x264_chroma_format);
+
+ GST_DEBUG ("returning %" GST_PTR_FORMAT, caps);
+ return caps;
+}
+
+static void
+check_formats (const gchar * str, gboolean * has_420, gboolean * has_422,
+ gboolean * has_444)
+{
+ if (g_str_has_prefix (str, "high-4:4:4"))
+ *has_444 = TRUE;
+ else if (g_str_has_prefix (str, "high-4:2:2"))
+ *has_422 = TRUE;
+ else
+ *has_420 = TRUE;
+}
+
+
+/* allowed input caps depending on whether libx264 was built for 8 or 10 bits */
+static GstCaps *
+gst_x264_enc_sink_getcaps (GstVideoEncoder * enc, GstCaps * filter)
+{
+ GstCaps *supported_incaps;
+ GstCaps *allowed;
+ GstCaps *filter_caps, *fcaps;
+ gint i, j, k;
+
+ supported_incaps = gst_x264_enc_get_supported_input_caps ();
+
+ /* Allow downstream to specify width/height/framerate/PAR constraints
+ * and forward them upstream for video converters to handle
+ */
+ if (!supported_incaps)
+ supported_incaps = gst_pad_get_pad_template_caps (enc->sinkpad);
+ allowed = gst_pad_get_allowed_caps (enc->srcpad);
+
+ if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
+ fcaps = supported_incaps;
+ goto done;
+ }
+
+ GST_LOG_OBJECT (enc, "template caps %" GST_PTR_FORMAT, supported_incaps);
+ GST_LOG_OBJECT (enc, "allowed caps %" GST_PTR_FORMAT, allowed);
+
+ filter_caps = gst_caps_new_empty ();
+
+ for (i = 0; i < gst_caps_get_size (supported_incaps); i++) {
+ GQuark q_name =
+ gst_structure_get_name_id (gst_caps_get_structure (supported_incaps,
+ i));
+
+ for (j = 0; j < gst_caps_get_size (allowed); j++) {
+ const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
+ const GValue *val;
+ GstStructure *s;
+
+ s = gst_structure_new_id_empty (q_name);
+ if ((val = gst_structure_get_value (allowed_s, "width")))
+ gst_structure_set_value (s, "width", val);
+ if ((val = gst_structure_get_value (allowed_s, "height")))
+ gst_structure_set_value (s, "height", val);
+ if ((val = gst_structure_get_value (allowed_s, "framerate")))
+ gst_structure_set_value (s, "framerate", val);
+ if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
+ gst_structure_set_value (s, "pixel-aspect-ratio", val);
+ if ((val = gst_structure_get_value (allowed_s, "profile"))) {
+ gboolean has_420 = FALSE;
+ gboolean has_422 = FALSE;
+ gboolean has_444 = FALSE;
+
+ if (G_VALUE_HOLDS_STRING (val)) {
+ check_formats (g_value_get_string (val), &has_420, &has_422,
+ &has_444);
+ } else if (GST_VALUE_HOLDS_LIST (val)) {
+ for (k = 0; k < gst_value_list_get_size (val); k++) {
+ const GValue *vlist = gst_value_list_get_value (val, k);
+
+ if (G_VALUE_HOLDS_STRING (vlist))
+ check_formats (g_value_get_string (vlist), &has_420, &has_422,
+ &has_444);
+ }
+ }
+
+ if (has_444 && has_422 && has_420)
+ gst_x264_enc_add_x264_chroma_format (s, 0);
+ else if (has_444)
+ gst_x264_enc_add_x264_chroma_format (s, X264_CSP_I444);
+ else if (has_422)
+ gst_x264_enc_add_x264_chroma_format (s, X264_CSP_I422);
+ else if (has_420)
+ gst_x264_enc_add_x264_chroma_format (s, X264_CSP_I420);
+ }
+
+ filter_caps = gst_caps_merge_structure (filter_caps, s);
+ }
+ }
+
+ fcaps = gst_caps_intersect (filter_caps, supported_incaps);
+ gst_caps_unref (filter_caps);
+ gst_caps_unref (supported_incaps);
+
+ if (filter) {
+ GST_LOG_OBJECT (enc, "intersecting with %" GST_PTR_FORMAT, filter);
+ filter_caps = gst_caps_intersect (fcaps, filter);
+ gst_caps_unref (fcaps);
+ fcaps = filter_caps;
+ }
+
+done:
+ gst_caps_replace (&allowed, NULL);
+
+ GST_LOG_OBJECT (enc, "proxy caps %" GST_PTR_FORMAT, fcaps);
+
+ return fcaps;
+}
+
+static void
gst_x264_enc_class_init (GstX264EncClass * klass)
{
GObjectClass *gobject_class;
@@ -480,12 +701,14 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
gobject_class->get_property = gst_x264_enc_get_property;
gobject_class->finalize = gst_x264_enc_finalize;
- gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_x264_enc_stop);
gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_x264_enc_set_format);
gstencoder_class->handle_frame =
GST_DEBUG_FUNCPTR (gst_x264_enc_handle_frame);
- gstencoder_class->reset = GST_DEBUG_FUNCPTR (gst_x264_enc_reset);
+ gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_x264_enc_start);
+ gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_x264_enc_stop);
+ gstencoder_class->flush = GST_DEBUG_FUNCPTR (gst_x264_enc_flush);
gstencoder_class->finish = GST_DEBUG_FUNCPTR (gst_x264_enc_finish);
+ gstencoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_x264_enc_sink_getcaps);
gstencoder_class->propose_allocation =
GST_DEBUG_FUNCPTR (gst_x264_enc_propose_allocation);
@@ -721,11 +944,9 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
"Mark Nauwelaerts <mnauw@users.sf.net>");
gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
-
-
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_factory));
}
static void
@@ -814,8 +1035,6 @@ gst_x264_enc_init (GstX264Enc * encoder)
encoder->x264param.pf_log = gst_x264_enc_log_callback;
encoder->x264param.p_log_private = encoder;
encoder->x264param.i_log_level = X264_LOG_DEBUG;
-
- gst_x264_enc_reset (GST_VIDEO_ENCODER (encoder), FALSE);
}
typedef struct
@@ -880,22 +1099,43 @@ gst_x264_enc_dequeue_all_frames (GstX264Enc * enc)
}
static gboolean
-gst_x264_enc_reset (GstVideoEncoder * encoder, gboolean hard)
+gst_x264_enc_start (GstVideoEncoder * encoder)
{
GstX264Enc *x264enc = GST_X264_ENC (encoder);
- if (hard) {
- gst_x264_enc_flush_frames (x264enc, FALSE);
- gst_x264_enc_close_encoder (x264enc);
- }
+ x264enc->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
+
+ return TRUE;
+}
+
+static gboolean
+gst_x264_enc_stop (GstVideoEncoder * encoder)
+{
+ GstX264Enc *x264enc = GST_X264_ENC (encoder);
+
+ gst_x264_enc_flush_frames (x264enc, FALSE);
+ gst_x264_enc_close_encoder (x264enc);
+ gst_x264_enc_dequeue_all_frames (x264enc);
if (x264enc->input_state)
gst_video_codec_state_unref (x264enc->input_state);
x264enc->input_state = NULL;
- x264enc->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
+ return TRUE;
+}
+
+
+static gboolean
+gst_x264_enc_flush (GstVideoEncoder * encoder)
+{
+ GstX264Enc *x264enc = GST_X264_ENC (encoder);
+
+ gst_x264_enc_flush_frames (x264enc, FALSE);
+ gst_x264_enc_close_encoder (x264enc);
gst_x264_enc_dequeue_all_frames (x264enc);
+ gst_x264_enc_init_encoder (x264enc);
+
return TRUE;
}
@@ -974,6 +1214,56 @@ gst_x264_enc_parse_options (GstX264Enc * encoder, const gchar * str)
return !ret;
}
+static gint
+gst_x264_enc_gst_to_x264_video_format (GstVideoFormat format, gint * nplanes)
+{
+ switch (format) {
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I420;
+ break;
+ case GST_VIDEO_FORMAT_I420_10BE:
+ case GST_VIDEO_FORMAT_I420_10LE:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I420 | X264_CSP_HIGH_DEPTH;
+ break;
+ case GST_VIDEO_FORMAT_Y42B:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I422;
+ break;
+ case GST_VIDEO_FORMAT_I422_10BE:
+ case GST_VIDEO_FORMAT_I422_10LE:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I422 | X264_CSP_HIGH_DEPTH;
+ break;
+ case GST_VIDEO_FORMAT_Y444:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I444;
+ break;
+ case GST_VIDEO_FORMAT_Y444_10BE:
+ case GST_VIDEO_FORMAT_Y444_10LE:
+ if (nplanes)
+ *nplanes = 3;
+ return X264_CSP_I444 | X264_CSP_HIGH_DEPTH;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ if (nplanes)
+ *nplanes = 2;
+ return X264_CSP_NV12;
+ break;
+ default:
+ g_assert_not_reached ();
+ return GST_VIDEO_FORMAT_UNKNOWN;
+ break;
+ }
+}
+
/*
* gst_x264_enc_init_encoder
* @encoder: Encoder which should be initialized.
@@ -985,7 +1275,14 @@ static gboolean
gst_x264_enc_init_encoder (GstX264Enc * encoder)
{
guint pass = 0;
- GstVideoInfo *info = &encoder->input_state->info;
+ GstVideoInfo *info;
+
+ if (!encoder->input_state) {
+ GST_DEBUG_OBJECT (encoder, "Have no input state yet");
+ return FALSE;
+ }
+
+ info = &encoder->input_state->info;
/* make sure that the encoder is closed */
gst_x264_enc_close_encoder (encoder);
@@ -1052,6 +1349,8 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
}
/* set up encoder parameters */
+ encoder->x264param.i_csp =
+ gst_x264_enc_gst_to_x264_video_format (info->finfo->format, NULL);
if (info->fps_d == 0 || info->fps_n == 0) {
/* No FPS so must use VFR
* This raises latency apparently see http://mewiki.project357.com/wiki/X264_Encoding_Suggestions */
@@ -1173,9 +1472,7 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
if (encoder->peer_level->frame_only) {
encoder->x264param.b_interlaced = FALSE;
-#if X264_BUILD >= 95
encoder->x264param.b_fake_interlaced = FALSE;
-#endif
}
}
@@ -1460,6 +1757,7 @@ gst_x264_enc_set_format (GstVideoEncoder * video_enc,
{
GstX264Enc *encoder = GST_X264_ENC (video_enc);
GstVideoInfo *info = &state->info;
+ GstCaps *template_caps;
GstCaps *allowed_caps = NULL;
gboolean level_ok = TRUE;
@@ -1468,7 +1766,8 @@ gst_x264_enc_set_format (GstVideoEncoder * video_enc,
if (encoder->x264enc) {
GstVideoInfo *old = &encoder->input_state->info;
- if (info->width == old->width && info->height == old->height
+ if (info->finfo->format == old->finfo->format
+ && info->width == old->width && info->height == old->height
&& info->fps_n == old->fps_n && info->fps_d == old->fps_d
&& info->par_n == old->par_n && info->par_d == old->par_d) {
gst_video_codec_state_unref (encoder->input_state);
@@ -1483,16 +1782,23 @@ gst_x264_enc_set_format (GstVideoEncoder * video_enc,
}
if (encoder->input_state)
- gst_video_codec_state_unref (state);
+ gst_video_codec_state_unref (encoder->input_state);
encoder->input_state = gst_video_codec_state_ref (state);
encoder->peer_profile = NULL;
encoder->peer_intra_profile = FALSE;
encoder->peer_level = NULL;
+ template_caps = gst_static_pad_template_get_caps (&src_factory);
allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
- if (allowed_caps) {
+ /* Output byte-stream if downstream has ANY caps, it's what people expect,
+ * and it makes more sense too */
+ if (allowed_caps == template_caps) {
+ GST_INFO_OBJECT (encoder,
+ "downstream has ANY caps, outputting byte-stream");
+ encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
+ } else if (allowed_caps) {
GstStructure *s;
const gchar *profile;
const gchar *level;
@@ -1512,15 +1818,19 @@ gst_x264_enc_set_format (GstVideoEncoder * video_enc,
/* FIXME - if libx264 ever adds support for FMO, ASO or redundant slices
* make sure constrained profile has a separate case which disables
* those */
+ if (g_str_has_suffix (profile, "-intra")) {
+ encoder->peer_intra_profile = TRUE;
+ }
if (!strcmp (profile, "constrained-baseline") ||
!strcmp (profile, "baseline")) {
encoder->peer_profile = "baseline";
- } else if (!strcmp (profile, "high-10-intra")) {
- encoder->peer_intra_profile = TRUE;
+ } else if (g_str_has_prefix (profile, "high-10")) {
encoder->peer_profile = "high10";
- } else if (!strcmp (profile, "high-10")) {
- encoder->peer_profile = "high10";
- } else if (!strcmp (profile, "high")) {
+ } else if (g_str_has_prefix (profile, "high-4:2:2")) {
+ encoder->peer_profile = "high422";
+ } else if (g_str_has_prefix (profile, "high-4:4:4")) {
+ encoder->peer_profile = "high444";
+ } else if (g_str_has_prefix (profile, "high")) {
encoder->peer_profile = "high";
} else if (!strcmp (profile, "main")) {
encoder->peer_profile = "main";
@@ -1583,6 +1893,8 @@ gst_x264_enc_set_format (GstVideoEncoder * video_enc,
gst_caps_unref (allowed_caps);
}
+ gst_caps_unref (template_caps);
+
if (!level_ok)
return FALSE;
@@ -1628,6 +1940,7 @@ gst_x264_enc_handle_frame (GstVideoEncoder * video_enc,
x264_picture_t pic_in;
gint i_nal, i;
FrameData *fdata;
+ gint nplanes;
if (G_UNLIKELY (encoder->x264enc == NULL))
goto not_inited;
@@ -1642,9 +1955,10 @@ gst_x264_enc_handle_frame (GstVideoEncoder * video_enc,
if (!fdata)
goto invalid_frame;
- pic_in.img.i_csp = X264_CSP_I420;
- pic_in.img.i_plane = 3;
- for (i = 0; i < 3; i++) {
+ pic_in.img.i_csp =
+ gst_x264_enc_gst_to_x264_video_format (info->finfo->format, &nplanes);
+ pic_in.img.i_plane = nplanes;
+ for (i = 0; i < nplanes; i++) {
pic_in.img.plane[i] = GST_VIDEO_FRAME_PLANE_DATA (&fdata->vframe, i);
pic_in.img.i_stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (&fdata->vframe, i);
}
@@ -1767,12 +2081,13 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
}
}
- frame->dts = pic_out.i_dts + encoder->dts_offset;
- /* should be ok now, surprise if not */
- if (frame->dts < 0) {
+ if (pic_out.i_dts + (gint64) encoder->dts_offset < 0) {
+ /* should be ok now, surprise if not */
GST_WARNING_OBJECT (encoder, "negative dts after offset compensation");
frame->dts = GST_CLOCK_TIME_NONE;
- }
+ } else
+ frame->dts = pic_out.i_dts + encoder->dts_offset;
+
if (pic_out.b_keyframe) {
GST_DEBUG_OBJECT (encoder, "Output keyframe");
@@ -1802,12 +2117,6 @@ gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send)
&& x264_encoder_delayed_frames (encoder->x264enc) > 0);
}
-static gboolean
-gst_x264_enc_stop (GstVideoEncoder * encoder)
-{
- return gst_x264_enc_reset (encoder, TRUE);
-}
-
static void
gst_x264_enc_reconfig (GstX264Enc * encoder)
{