diff --git a/src/gstducatih264dec.c b/src/gstducatih264dec.c
index eeb1d4c7010e95a219cd247bd9cb49157552aeb8..47456150e086669e681c08c4a73ec1d4270986ca 100644 (file)
--- a/src/gstducatih264dec.c
+++ b/src/gstducatih264dec.c
#include "gstducatih264dec.h"
+#define GST_BUFFER_FLAG_B_FRAME (GST_BUFFER_FLAG_LAST << 0)
#define PADX 32
#define PADY 24
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-h264, "
-// "alignment = au, " /* only entire frames */
-// "stream-format = byte-stream, " /* only byte-stream */
+ "stream-format = byte-stream, " /* only byte-stream */
+ "align = au, " /* only entire frames */
"width = (int)[ 16, 2048 ], "
"height = (int)[ 16, 2048 ], "
- "framerate = (fraction)[ 0, max ];")
+ "framerate = (fraction)[ 0, max ],"
+ "profile = (string){constrained-baseline, baseline, main, extended};"
+ "video/x-h264, "
+ "stream-format = byte-stream, " /* only byte-stream */
+ "align = au, " /* only entire frames */
+ "width = (int)[ 16, 2048 ], "
+ "height = (int)[ 16, 2048 ], "
+ "framerate = (fraction)[ 0, max ],"
+ "profile = (string) {high, high-10-intra, high-10, high-4:2:2-intra, "
+ "high-4:2:2, high-4:4:4-intra, high-4:4:4, cavlc-4:4:4-intra}, "
+ "level = (string) {1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2};"
+ )
);
/* GstDucatiVidDec vmethod implementations */
if (ret) {
IH264VDEC_Params *params = (IH264VDEC_Params *) self->params;
- self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
+ self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1;
params->maxNumRefFrames = IH264VDEC_NUM_REFFRAMES_AUTO;
params->pConstantMemory = 0;
params->presetLevelIdc = IH264VDEC_LEVEL41;
params->errConcealmentMode = IH264VDEC_APPLY_CONCEALMENT;
+ params->temporalDirModePred = TRUE;
}
return ret;
}
+static gint
+gst_ducati_h264dec_handle_error (GstDucatiVidDec * self, gint ret,
+ gint extended_error, gint status_extended_error)
+{
+ if (extended_error & 0x00000001) {
+ /* No valid slice. This seems to be bad enough that it's better to flush and
+ * skip to the next keyframe.
+ */
+
+ if (extended_error == 0x00000201) {
+ /* the codec doesn't unlock the input buffer in this case... */
+ gst_buffer_unref ((GstBuffer *) self->inArgs->inputID);
+ self->inArgs->inputID = 0;
+ }
+
+ self->needs_flushing = TRUE;
+ }
+
+ ret = parent_class->handle_error (self, ret, extended_error,
+ status_extended_error);
+
+ return ret;
+}
+
+static gboolean
+gst_ducati_h264dec_query (GstDucatiVidDec * vdec, GstPad * pad,
+ GstQuery * query, gboolean * forward)
+{
+ GstDucatiH264Dec * self = GST_DUCATIH264DEC (vdec);
+ gboolean res = TRUE;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_LATENCY:
+ {
+ gboolean live;
+ GstClockTime min, max, latency;
+
+ if (vdec->fps_d == 0) {
+ GST_INFO_OBJECT (self, "not ready to report latency");
+ res = FALSE;
+ break;
+ }
+
+ gst_query_parse_latency (query, &live, &min, &max);
+ if (vdec->fps_n != 0)
+ latency = gst_util_uint64_scale (GST_SECOND,
+ vdec->fps_d, vdec->fps_n);
+ else
+ latency = 0;
+
+ if (min == GST_CLOCK_TIME_NONE)
+ min = latency;
+ else
+ min += latency;
+
+ if (max != GST_CLOCK_TIME_NONE)
+ max += latency;
+
+ GST_INFO_OBJECT (self, "latency %"GST_TIME_FORMAT " ours %"GST_TIME_FORMAT,
+ GST_TIME_ARGS (min), GST_TIME_ARGS (latency));
+ gst_query_set_latency (query, live, min, max);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (res)
+ res = parent_class->query (vdec, pad, query, forward);
+
+ return res;
+}
+
+static gboolean
+gst_ducati_h264dec_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
+ gint64 diff)
+{
+ gboolean is_bframe = GST_BUFFER_FLAG_IS_SET (buf,
+ GST_BUFFER_FLAG_B_FRAME);
+
+ if (diff >= 0 && is_bframe)
+ return TRUE;
+
+ return FALSE;
+}
+
/* GObject vmethod implementations */
static void
GST_DEBUG_FUNCPTR (gst_ducati_h264dec_update_buffer_size);
bclass->allocate_params =
GST_DEBUG_FUNCPTR (gst_ducati_h264dec_allocate_params);
+ bclass->handle_error = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_handle_error);
+ bclass->drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_drop_frame);
+ bclass->query = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_query);
}
static void