mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
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.
This commit is contained in:
parent
9794bc5087
commit
7ed5a3d96f
3 changed files with 134 additions and 90 deletions
|
@ -1,3 +1,11 @@
|
|||
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,89 +668,43 @@ gst_dvdec_handle_src_event (GstPad *pad, GstEvent *event)
|
|||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvdec_push (GstDVDec *dvdec, GstBuffer *outbuf, GstPad *pad, GstClockTime ts)
|
||||
{
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
||||
|
||||
if (dvdec->need_discont) {
|
||||
GstEvent *discont;
|
||||
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, ts, NULL);
|
||||
gst_pad_push (pad, GST_DATA (discont));
|
||||
}
|
||||
|
||||
gst_pad_push (pad, GST_DATA (outbuf));
|
||||
|
||||
if ((dvdec->end_position != -1) &&
|
||||
(dvdec->next_ts >= dvdec->end_position)) {
|
||||
if (dvdec->loop)
|
||||
gst_pad_push (pad, GST_DATA(gst_event_new (GST_EVENT_SEGMENT_DONE)));
|
||||
else
|
||||
gst_pad_push (pad, GST_DATA(gst_event_new (GST_EVENT_EOS)));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvdec_loop (GstElement *element)
|
||||
{
|
||||
GstDVDec *dvdec;
|
||||
GstBuffer *buf, *outbuf;
|
||||
guint8 *inframe;
|
||||
gint height;
|
||||
guint32 length, got_bytes;
|
||||
GstFormat format;
|
||||
guint64 ts;
|
||||
gfloat fps;
|
||||
|
||||
dvdec = GST_DVDEC (element);
|
||||
|
||||
/* first read enough bytes to parse the header */
|
||||
got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, header_size);
|
||||
if (got_bytes < header_size) {
|
||||
gst_dvdec_handle_sink_event (dvdec);
|
||||
return;
|
||||
}
|
||||
dv_parse_header (dvdec->decoder, inframe);
|
||||
/* after parsing the header we know the size 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->height = height = (dvdec->PAL ? PAL_HEIGHT : NTSC_HEIGHT);
|
||||
length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER);
|
||||
|
||||
if (length != dvdec->length) {
|
||||
dvdec->length = length;
|
||||
gst_bytestream_size_hint (dvdec->bs, length);
|
||||
}
|
||||
|
||||
/* then read the read data */
|
||||
got_bytes = gst_bytestream_read (dvdec->bs, &buf, length);
|
||||
if (got_bytes < length) {
|
||||
gst_dvdec_handle_sink_event (dvdec);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we did not negotiate yet, do it now */
|
||||
if (!GST_PAD_CAPS (dvdec->videosrcpad)) {
|
||||
GstCaps *caps = NULL;
|
||||
GstCaps *negotiated_caps = NULL;
|
||||
static GstCaps*
|
||||
gst_dvdec_video_getcaps (GstPad *pad)
|
||||
{
|
||||
GstDVDec *dvdec;
|
||||
GstCaps *caps;
|
||||
GstPadTemplate *src_pad_template;
|
||||
int i;
|
||||
|
||||
/* try to fix our height */
|
||||
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));
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (caps); i++)
|
||||
|
||||
if (dvdec->found_header)
|
||||
{
|
||||
GstStructure *structure = gst_caps_get_structure (caps, i);
|
||||
gst_structure_set(structure,
|
||||
"height", G_TYPE_INT, height,
|
||||
"framerate", G_TYPE_INT, fps, NULL
|
||||
);
|
||||
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);
|
||||
|
@ -787,11 +752,77 @@ gst_dvdec_loop (GstElement *element)
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvdec_push (GstDVDec *dvdec, GstBuffer *outbuf, GstPad *pad, GstClockTime ts)
|
||||
{
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
||||
|
||||
if (dvdec->need_discont) {
|
||||
GstEvent *discont;
|
||||
|
||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, ts, NULL);
|
||||
gst_pad_push (pad, GST_DATA (discont));
|
||||
}
|
||||
|
||||
gst_pad_push (pad, GST_DATA (outbuf));
|
||||
|
||||
if ((dvdec->end_position != -1) &&
|
||||
(dvdec->next_ts >= dvdec->end_position)) {
|
||||
if (dvdec->loop)
|
||||
gst_pad_push (pad, GST_DATA(gst_event_new (GST_EVENT_SEGMENT_DONE)));
|
||||
else
|
||||
gst_pad_push (pad, GST_DATA(gst_event_new (GST_EVENT_EOS)));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dvdec_loop (GstElement *element)
|
||||
{
|
||||
GstDVDec *dvdec;
|
||||
GstBuffer *buf, *outbuf;
|
||||
guint8 *inframe;
|
||||
gint height;
|
||||
guint32 length, got_bytes;
|
||||
GstFormat format;
|
||||
guint64 ts;
|
||||
gfloat fps;
|
||||
const GstCaps *cur_caps;
|
||||
|
||||
dvdec = GST_DVDEC (element);
|
||||
|
||||
/* first read enough bytes to parse the header */
|
||||
got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, header_size);
|
||||
if (got_bytes < header_size) {
|
||||
gst_dvdec_handle_sink_event (dvdec);
|
||||
return;
|
||||
}
|
||||
dv_parse_header (dvdec->decoder, inframe);
|
||||
|
||||
/* after parsing the header we know the length of the data */
|
||||
dvdec->PAL = dv_system_50_fields (dvdec->decoder);
|
||||
|
||||
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);
|
||||
|
||||
if (length != dvdec->length) {
|
||||
dvdec->length = length;
|
||||
gst_bytestream_size_hint (dvdec->bs, length);
|
||||
}
|
||||
|
||||
/* then read the read data */
|
||||
got_bytes = gst_bytestream_read (dvdec->bs, &buf, length);
|
||||
if (got_bytes < length) {
|
||||
gst_dvdec_handle_sink_event (dvdec);
|
||||
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];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue