Commit 7ed5a3d9 authored by Jan Schmidt's avatar Jan Schmidt

Rework caps negotiation in the element so that it works again.

Original commit message from CVS:
Rework caps negotiation in the element so that it works again.
parent 9794bc50
2004-02-06 Jan Schmidt <thaytan@mad.scientist.com>
* ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_video_getcaps),
(gst_dvdec_video_link), (gst_dvdec_loop):
* ext/dv/gstdvdec.h:
rework the caps negotiation so that dvdec works again instead
of just segfaulting.
2004-02-05 Thomas Vander Stichele <thomas at apestaart dot org>
* gst-libs/gst/gconf/gstreamer-gconf-uninstalled.pc.in:
......
......@@ -93,12 +93,12 @@ GST_STATIC_PAD_TEMPLATE
"format = (fourcc) YUY2, "
"width = (int) 720, "
"height = (int) { "
G_STRINGIFY(NTSC_HEIGHT) ", "
G_STRINGIFY(PAL_HEIGHT)
G_STRINGIFY(NTSC_HEIGHT) ", "
G_STRINGIFY(PAL_HEIGHT)
" }, "
"framerate = (double) { "
G_STRINGIFY(PAL_FRAMERATE) ", "
G_STRINGIFY(NTSC_FRAMERATE)
G_STRINGIFY(PAL_FRAMERATE) ", "
G_STRINGIFY(NTSC_FRAMERATE)
" }; "
"video/x-raw-rgb, "
......@@ -186,6 +186,10 @@ static gboolean gst_dvdec_sink_convert (GstPad *pad, GstFormat src_format, gi
static gboolean gst_dvdec_src_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
static GstPadLinkReturn gst_dvdec_video_link (GstPad *pad,
const GstCaps *caps);
static GstCaps* gst_dvdec_video_getcaps (GstPad *pad);
static const GstEventMask*
gst_dvdec_get_event_masks (GstPad *pad);
static gboolean gst_dvdec_handle_src_event (GstPad *pad, GstEvent *event);
......@@ -310,22 +314,25 @@ gst_dvdec_init(GstDVDec *dvdec)
gst_pad_set_formats_function (dvdec->sinkpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_formats));
dvdec->videosrcpad = gst_pad_new_from_template (gst_static_pad_template_get (&video_src_temp), "video");
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->videosrcpad);
gst_pad_set_query_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_src_query));
gst_pad_set_query_type_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_src_query_types));
gst_pad_set_event_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_handle_src_event));
gst_pad_set_event_mask_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_event_masks));
gst_pad_set_convert_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_src_convert));
gst_pad_set_formats_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_formats));
gst_pad_set_link_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_video_link));
gst_pad_set_getcaps_function (dvdec->videosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_video_getcaps));
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->videosrcpad);
dvdec->audiosrcpad = gst_pad_new_from_template (gst_static_pad_template_get (&audio_src_temp), "audio");
gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->audiosrcpad);
gst_pad_set_query_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_src_query));
gst_pad_set_query_type_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_src_query_types));
gst_pad_set_event_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_handle_src_event));
gst_pad_set_event_mask_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_event_masks));
gst_pad_set_convert_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_src_convert));
gst_pad_set_formats_function (dvdec->audiosrcpad, GST_DEBUG_FUNCPTR (gst_dvdec_get_formats));
gst_pad_use_explicit_caps (dvdec->audiosrcpad);
gst_element_add_pad (GST_ELEMENT(dvdec), dvdec->audiosrcpad);
gst_element_set_loop_function (GST_ELEMENT (dvdec), gst_dvdec_loop);
......@@ -335,11 +342,15 @@ gst_dvdec_init(GstDVDec *dvdec)
dvdec->need_discont = FALSE;
dvdec->framerate = 0;
dvdec->height = 0;
dvdec->frequency = 0;
dvdec->channels = 0;
dvdec->clamp_luma = FALSE;
dvdec->clamp_chroma = FALSE;
dvdec->quality = DV_QUALITY_BEST;
dvdec->loop = FALSE;
dvdec->found_header = FALSE;
for (i = 0; i <4; i++) {
dvdec->audio_buffers[i] = (gint16 *)g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16));
}
......@@ -657,6 +668,92 @@ gst_dvdec_handle_src_event (GstPad *pad, GstEvent *event)
return res;
}
static GstCaps*
gst_dvdec_video_getcaps (GstPad *pad)
{
GstDVDec *dvdec;
GstCaps *caps;
GstPadTemplate *src_pad_template;
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
src_pad_template = gst_static_pad_template_get (&video_src_temp);
caps = gst_caps_copy(gst_pad_template_get_caps (src_pad_template));
if (dvdec->found_header)
{
int i;
/* set the height */
for (i = 0; i < gst_caps_get_size (caps); i++)
{
GstStructure *structure = gst_caps_get_structure (caps, i);
gst_structure_set(structure,
"height", G_TYPE_INT, dvdec->height,
"framerate", G_TYPE_DOUBLE, dvdec->, NULL
);
}
}
return caps;
}
static GstPadLinkReturn
gst_dvdec_video_link (GstPad *pad, const GstCaps *caps)
{
/* if we did not find a header yet, return delayed */
if (!dvdec->found_header)
return GST_PAD_LINK_DELAYED;
for (i=0; i < gst_caps_get_size(caps); i++) {
GstStructure *to_try_struct = gst_caps_get_structure (caps, i);
GstCaps *try_caps =
gst_caps_new_full (gst_structure_copy(to_try_struct), NULL);
/* try each format */
if (gst_pad_try_set_caps (dvdec->videosrcpad, try_caps) > 0) {
negotiated_caps = try_caps;
break;
}
gst_caps_free(try_caps);
}
gst_caps_free (caps);
/* Check if we negotiated caps successfully */
if (negotiated_caps != NULL) {
GstStructure *structure = gst_caps_get_structure (negotiated_caps, 0);
guint32 fourcc;
/* it worked, try to find what it was again */
gst_structure_get_fourcc (structure, "format", &fourcc);
if (fourcc == GST_STR_FOURCC ("RGB ")) {
gint bpp;
gst_structure_get_int (structure, "bpp", &bpp);
if (bpp == 24) {
dvdec->space = e_dv_color_rgb;
dvdec->bpp = 3;
}
else {
dvdec->space = e_dv_color_bgr0;
dvdec->bpp = 4;
}
}
else {
dvdec->space = e_dv_color_yuv;
dvdec->bpp = 2;
}
} else {
GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL), (NULL));
return;
}
}
}
static void
gst_dvdec_push (GstDVDec *dvdec, GstBuffer *outbuf, GstPad *pad, GstClockTime ts)
{
......@@ -691,6 +788,7 @@ gst_dvdec_loop (GstElement *element)
GstFormat format;
guint64 ts;
gfloat fps;
const GstCaps *cur_caps;
dvdec = GST_DVDEC (element);
......@@ -701,11 +799,11 @@ gst_dvdec_loop (GstElement *element)
return;
}
dv_parse_header (dvdec->decoder, inframe);
/* after parsing the header we know the size of the data */
/* after parsing the header we know the length of the data */
dvdec->PAL = dv_system_50_fields (dvdec->decoder);
dvdec->framerate = (dvdec->PAL ? 2500 : 2997);
fps = (dvdec->PAL ? PAL_FRAMERATE : NTSC_FRAMERATE);
dvdec->framerate = fps = (dvdec->PAL ? PAL_FRAMERATE : NTSC_FRAMERATE);
dvdec->height = height = (dvdec->PAL ? PAL_HEIGHT : NTSC_HEIGHT);
length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER);
......@@ -721,77 +819,10 @@ gst_dvdec_loop (GstElement *element)
return;
}
/* if we did not negotiate yet, do it now */
if (!GST_PAD_CAPS (dvdec->videosrcpad)) {
GstCaps *caps = NULL;
GstCaps *negotiated_caps = NULL;
GstPadTemplate *src_pad_template;
int i;
/* try to fix our height */
src_pad_template = gst_static_pad_template_get (&video_src_temp);
caps = gst_caps_copy(gst_pad_template_get_caps (src_pad_template));
for (i = 0; i < gst_caps_get_size (caps); i++)
{
GstStructure *structure = gst_caps_get_structure (caps, i);
gst_structure_set(structure,
"height", G_TYPE_INT, height,
"framerate", G_TYPE_INT, fps, NULL
);
}
for (i=0; i < gst_caps_get_size(caps); i++) {
GstStructure *to_try_struct = gst_caps_get_structure (caps, i);
GstCaps *try_caps =
gst_caps_new_full (gst_structure_copy(to_try_struct), NULL);
/* try each format */
if (gst_pad_try_set_caps (dvdec->videosrcpad, try_caps) > 0) {
negotiated_caps = try_caps;
break;
}
gst_caps_free(try_caps);
}
gst_caps_free (caps);
/* Check if we negotiated caps successfully */
if (negotiated_caps != NULL) {
GstStructure *structure = gst_caps_get_structure (negotiated_caps, 0);
guint32 fourcc;
/* it worked, try to find what it was again */
gst_structure_get_fourcc (structure, "format", &fourcc);
if (fourcc == GST_STR_FOURCC ("RGB ")) {
gint bpp;
gst_structure_get_int (structure, "bpp", &bpp);
if (bpp == 24) {
dvdec->space = e_dv_color_rgb;
dvdec->bpp = 3;
}
else {
dvdec->space = e_dv_color_bgr0;
dvdec->bpp = 4;
}
}
else {
dvdec->space = e_dv_color_yuv;
dvdec->bpp = 2;
}
} else {
GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL), (NULL));
return;
}
}
format = GST_FORMAT_TIME;
gst_pad_query (dvdec->videosrcpad, GST_QUERY_POSITION, &format, &ts);
dvdec->next_ts += (GST_SECOND*100) / dvdec->framerate;
dvdec->next_ts += GST_SECOND / dvdec->framerate;
if (GST_PAD_IS_LINKED (dvdec->audiosrcpad)) {
gint16 *a_ptr;
......@@ -801,7 +832,7 @@ gst_dvdec_loop (GstElement *element)
/* if we did not negotiate yet, do it now */
if (!GST_PAD_CAPS (dvdec->audiosrcpad)) {
gst_pad_try_set_caps (dvdec->audiosrcpad,
gst_pad_set_explicit_caps (dvdec->audiosrcpad,
gst_caps_new_simple (
"audio/x-raw-int",
"rate", G_TYPE_INT, dvdec->decoder->audio->frequency,
......
......@@ -46,7 +46,7 @@ struct _GstDVDec {
/* We need to keep track of our pads, so we do so here. */
GstPad *sinkpad,
*videosrcpad,
*audiosrcpad;
*audiosrcpad;
dv_decoder_t *decoder;
gboolean clamp_luma;
......@@ -56,14 +56,19 @@ struct _GstDVDec {
GstByteStream *bs;
dv_color_space_t space;
gint bpp;
gboolean PAL;
gint framerate;
gboolean PAL;
gdouble framerate;
gint height;
gint frequency;
gint channels;
gint length;
guint64 next_ts;
guint64 end_position;
gboolean need_discont;
gboolean loop;
gboolean found_header;
gint16 *audio_buffers[4];
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment