Fix decoding of MPEG-2 TS files.

This commit is contained in:
Gwenole Beauchesne 2011-07-22 15:39:51 +02:00
parent 2f91c9e8c1
commit f2906b7ad0
2 changed files with 84 additions and 27 deletions

View file

@ -93,6 +93,66 @@ enum {
PROP_USE_FFMPEG, PROP_USE_FFMPEG,
}; };
static gboolean
gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps);
static void
gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data)
{
GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data);
GstCaps *caps;
g_assert(decode->decoder == GST_VAAPI_DECODER(obj));
caps = gst_vaapi_decoder_get_caps(decode->decoder);
gst_vaapidecode_update_src_caps(decode, caps);
}
static inline gboolean
gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps)
{
if (decode->sinkpad_caps)
gst_caps_unref(decode->sinkpad_caps);
decode->sinkpad_caps = gst_caps_ref(caps);
return TRUE;
}
static gboolean
gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, GstCaps *caps)
{
GstCaps *other_caps;
GstStructure *structure;
const GValue *v_width, *v_height, *v_framerate, *v_par;
gboolean success;
if (!decode->srcpad_caps) {
decode->srcpad_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME);
if (!decode->srcpad_caps)
return FALSE;
}
structure = gst_caps_get_structure(caps, 0);
v_width = gst_structure_get_value(structure, "width");
v_height = gst_structure_get_value(structure, "height");
v_framerate = gst_structure_get_value(structure, "framerate");
v_par = gst_structure_get_value(structure, "pixel-aspect-ratio");
structure = gst_caps_get_structure(decode->srcpad_caps, 0);
if (v_width && v_height) {
gst_structure_set_value(structure, "width", v_width);
gst_structure_set_value(structure, "height", v_height);
}
if (v_framerate)
gst_structure_set_value(structure, "framerate", v_framerate);
if (v_par)
gst_structure_set_value(structure, "pixel-aspect-ratio", v_par);
other_caps = gst_caps_copy(decode->srcpad_caps);
success = gst_pad_set_caps(decode->srcpad, other_caps);
gst_caps_unref(other_caps);
return success;
}
static void static void
gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object) gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object)
{ {
@ -231,6 +291,13 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
if (!decode->decoder) if (!decode->decoder)
return FALSE; return FALSE;
g_signal_connect(
G_OBJECT(decode->decoder),
"notify::caps",
G_CALLBACK(gst_vaapi_decoder_notify_caps),
decode
);
decode->decoder_caps = gst_caps_ref(caps); decode->decoder_caps = gst_caps_ref(caps);
return TRUE; return TRUE;
} }
@ -300,6 +367,16 @@ gst_vaapidecode_finalize(GObject *object)
gst_vaapidecode_destroy(decode); gst_vaapidecode_destroy(decode);
if (decode->sinkpad_caps) {
gst_caps_unref(decode->sinkpad_caps);
decode->sinkpad_caps = NULL;
}
if (decode->srcpad_caps) {
gst_caps_unref(decode->srcpad_caps);
decode->srcpad_caps = NULL;
}
if (decode->display) { if (decode->display) {
g_object_unref(decode->display); g_object_unref(decode->display);
decode->display = NULL; decode->display = NULL;
@ -490,38 +567,14 @@ static gboolean
gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps)
{ {
GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad)); GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad));
GstCaps *other_caps = NULL;
GstStructure *structure;
const GValue *v_width, *v_height, *v_framerate, *v_par;
gboolean success;
g_return_val_if_fail(pad == decode->sinkpad, FALSE); g_return_val_if_fail(pad == decode->sinkpad, FALSE);
other_caps = gst_caps_from_string(gst_vaapidecode_src_caps_str); if (!gst_vaapidecode_update_sink_caps(decode, caps))
if (!other_caps)
return FALSE; return FALSE;
if (!gst_vaapidecode_update_src_caps(decode, caps))
/* Negotiation succeeded, so now configure ourselves */
structure = gst_caps_get_structure(caps, 0);
v_width = gst_structure_get_value(structure, "width");
v_height = gst_structure_get_value(structure, "height");
v_framerate = gst_structure_get_value(structure, "framerate");
v_par = gst_structure_get_value(structure, "pixel-aspect-ratio");
structure = gst_caps_get_structure(other_caps, 0);
gst_structure_set_value(structure, "width", v_width);
gst_structure_set_value(structure, "height", v_height);
if (v_framerate)
gst_structure_set_value(structure, "framerate", v_framerate);
if (v_par)
gst_structure_set_value(structure, "pixel-aspect-ratio", v_par);
success = gst_pad_set_caps(decode->srcpad, other_caps);
gst_caps_unref(other_caps);
if (!success)
return FALSE; return FALSE;
return gst_vaapidecode_reset(decode, decode->sinkpad_caps);
return gst_vaapidecode_reset(decode, caps);
} }
static GstFlowReturn static GstFlowReturn
@ -584,6 +637,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
gst_element_class_get_pad_template(element_class, "sink"), gst_element_class_get_pad_template(element_class, "sink"),
"sink" "sink"
); );
decode->sinkpad_caps = NULL;
gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps); gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps);
gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps); gst_pad_set_setcaps_function(decode->sinkpad, gst_vaapidecode_set_caps);
@ -596,6 +650,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
gst_element_class_get_pad_template(element_class, "src"), gst_element_class_get_pad_template(element_class, "src"),
"src" "src"
); );
decode->srcpad_caps = NULL;
gst_pad_use_fixed_caps(decode->srcpad); gst_pad_use_fixed_caps(decode->srcpad);
gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event); gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event);

View file

@ -60,7 +60,9 @@ struct _GstVaapiDecode {
GstElement parent_instance; GstElement parent_instance;
GstPad *sinkpad; GstPad *sinkpad;
GstCaps *sinkpad_caps;
GstPad *srcpad; GstPad *srcpad;
GstCaps *srcpad_caps;
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiDecoder *decoder; GstVaapiDecoder *decoder;
GMutex *decoder_mutex; GMutex *decoder_mutex;