ext/dv/: Ueber spiffify some more, added debug category.

Original commit message from CVS:
* ext/dv/gstdvdec.c: (gst_dvdec_base_init), (gst_dvdec_init),
(gst_dvdec_change_state):
* ext/dv/gstdvdec.h:
* ext/dv/gstdvdemux.c: (gst_dvdemux_base_init), (gst_dvdemux_init),
(gst_dvdemux_src_convert), (gst_dvdemux_sink_convert),
(gst_dvdemux_src_query), (gst_dvdemux_sink_query),
(gst_dvdemux_handle_sink_event), (gst_dvdemux_demux_frame),
(gst_dvdemux_flush), (gst_dvdemux_chain),
(gst_dvdemux_change_state):
* ext/dv/gstdvdemux.h:
Ueber spiffify some more, added debug category.
Use _scale.
Use segments, respect playback rate from newsegment.
Fix refcount issue.
This commit is contained in:
Wim Taymans 2006-02-22 20:22:25 +00:00
parent 7eed67bb6b
commit ec24b0dfab
5 changed files with 136 additions and 81 deletions

View file

@ -1,3 +1,20 @@
2006-02-22 Wim Taymans <wim@fluendo.com>
* ext/dv/gstdvdec.c: (gst_dvdec_base_init), (gst_dvdec_init),
(gst_dvdec_change_state):
* ext/dv/gstdvdec.h:
* ext/dv/gstdvdemux.c: (gst_dvdemux_base_init), (gst_dvdemux_init),
(gst_dvdemux_src_convert), (gst_dvdemux_sink_convert),
(gst_dvdemux_src_query), (gst_dvdemux_sink_query),
(gst_dvdemux_handle_sink_event), (gst_dvdemux_demux_frame),
(gst_dvdemux_flush), (gst_dvdemux_chain),
(gst_dvdemux_change_state):
* ext/dv/gstdvdemux.h:
Ueber spiffify some more, added debug category.
Use _scale.
Use segments, respect playback rate from newsegment.
Fix refcount issue.
2006-02-20 Jan Schmidt <thaytan@mad.scientist.com> 2006-02-20 Jan Schmidt <thaytan@mad.scientist.com>
* ext/ladspa/gstsignalprocessor.c: (gst_signal_processor_event), * ext/ladspa/gstsignalprocessor.c: (gst_signal_processor_event),

View file

@ -37,6 +37,9 @@ GST_ELEMENT_DETAILS ("DV (smpte314) decoder plugin",
#define DV_DEFAULT_QUALITY DV_QUALITY_BEST #define DV_DEFAULT_QUALITY DV_QUALITY_BEST
#define DV_DEFAULT_DECODE_NTH 1 #define DV_DEFAULT_DECODE_NTH 1
GST_DEBUG_CATEGORY (dvdec_debug);
#define GST_CAT_DEFAULT dvdec_debug
enum enum
{ {
PROP_0, PROP_0,
@ -133,6 +136,8 @@ gst_dvdec_base_init (gpointer g_class)
gst_static_pad_template_get (&src_temp)); gst_static_pad_template_get (&src_temp));
gst_element_class_set_details (element_class, &dvdec_details); gst_element_class_set_details (element_class, &dvdec_details);
GST_DEBUG_CATEGORY_INIT (dvdec_debug, "dvdec", 0, "DV decoding element");
} }
static void static void
@ -190,7 +195,6 @@ gst_dvdec_init (GstDVDec * dvdec, GstDVDecClass * g_class)
dvdec->height = 0; dvdec->height = 0;
dvdec->wide = FALSE; dvdec->wide = FALSE;
dvdec->drop_factor = 1; dvdec->drop_factor = 1;
dvdec->headers_seen = FALSE;
dvdec->clamp_luma = FALSE; dvdec->clamp_luma = FALSE;
dvdec->clamp_chroma = FALSE; dvdec->clamp_chroma = FALSE;
@ -353,7 +357,6 @@ gst_dvdec_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
dv_decoder_free (dvdec->decoder); dv_decoder_free (dvdec->decoder);
dvdec->decoder = NULL; dvdec->decoder = NULL;
dvdec->headers_seen = FALSE;
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
break; break;

View file

@ -69,7 +69,6 @@ struct _GstDVDec {
gint video_offset; gint video_offset;
gint drop_factor; gint drop_factor;
gboolean headers_seen;
}; };
struct _GstDVDecClass { struct _GstDVDecClass {

View file

@ -84,6 +84,9 @@
#define NTSC_WIDE_PAR_X 40 #define NTSC_WIDE_PAR_X 40
#define NTSC_WIDE_PAR_Y 33 #define NTSC_WIDE_PAR_Y 33
GST_DEBUG_CATEGORY (dvdemux_debug);
#define GST_CAT_DEFAULT dvdemux_debug
static GstElementDetails dvdemux_details = static GstElementDetails dvdemux_details =
GST_ELEMENT_DETAILS ("DV system stream demuxer", GST_ELEMENT_DETAILS ("DV system stream demuxer",
"Codec/Demuxer", "Codec/Demuxer",
@ -150,6 +153,8 @@ gst_dvdemux_base_init (gpointer g_class)
gst_static_pad_template_get (&audio_src_temp)); gst_static_pad_template_get (&audio_src_temp));
gst_element_class_set_details (element_class, &dvdemux_details); gst_element_class_set_details (element_class, &dvdemux_details);
GST_DEBUG_CATEGORY_INIT (dvdemux_debug, "dvdemux", 0, "DV demuxer element");
} }
static void static void
@ -183,20 +188,6 @@ gst_dvdemux_init (GstDVDemux * dvdemux, GstDVDemuxClass * g_class)
dvdemux->adapter = gst_adapter_new (); dvdemux->adapter = gst_adapter_new ();
dvdemux->timestamp = 0LL;
dvdemux->start_timestamp = -1LL;
dvdemux->stop_timestamp = -1LL;
dvdemux->need_discont = FALSE;
dvdemux->new_media = FALSE;
dvdemux->framerate_numerator = 0;
dvdemux->framerate_denominator = 0;
dvdemux->total_frames = 0;
dvdemux->height = 0;
dvdemux->frequency = 0;
dvdemux->channels = 0;
dvdemux->wide = FALSE;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
dvdemux->audio_buffers[i] = dvdemux->audio_buffers[i] =
(gint16 *) g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16)); (gint16 *) g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16));
@ -267,12 +258,12 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
*dest_format = GST_FORMAT_TIME; *dest_format = GST_FORMAT_TIME;
if (pad == dvdemux->videosrcpad) if (pad == dvdemux->videosrcpad)
*dest_value = src_value * GST_SECOND * *dest_value = gst_util_uint64_scale (src_value,
dvdemux->framerate_denominator / GST_SECOND * dvdemux->framerate_denominator,
(dvdemux->frame_len * dvdemux->framerate_numerator); dvdemux->frame_len * dvdemux->framerate_numerator);
else if (pad == dvdemux->audiosrcpad) else if (pad == dvdemux->audiosrcpad)
*dest_value = src_value * GST_SECOND / *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
(2 * dvdemux->frequency * dvdemux->channels); 2 * dvdemux->frequency * dvdemux->channels);
break; break;
default: default:
res = FALSE; res = FALSE;
@ -282,24 +273,25 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
switch (*dest_format) { switch (*dest_format) {
case GST_FORMAT_BYTES: case GST_FORMAT_BYTES:
if (pad == dvdemux->videosrcpad) if (pad == dvdemux->videosrcpad)
*dest_value = src_value * dvdemux->frame_len * *dest_value = gst_util_uint64_scale (src_value,
dvdemux->framerate_numerator / dvdemux->frame_len * dvdemux->framerate_numerator,
(dvdemux->framerate_denominator * GST_SECOND); dvdemux->framerate_denominator * GST_SECOND);
else if (pad == dvdemux->audiosrcpad) else if (pad == dvdemux->audiosrcpad)
*dest_value = 2 * src_value * dvdemux->frequency * *dest_value = gst_util_uint64_scale_int (src_value,
dvdemux->channels / GST_SECOND; 2 * dvdemux->frequency * dvdemux->channels, GST_SECOND);
break; break;
case GST_FORMAT_DEFAULT: case GST_FORMAT_DEFAULT:
if (pad == dvdemux->videosrcpad) { if (pad == dvdemux->videosrcpad) {
if (src_value) if (src_value)
*dest_value = src_value * dvdemux->framerate_numerator / *dest_value = gst_util_uint64_scale (src_value,
(dvdemux->framerate_denominator * GST_SECOND); dvdemux->framerate_numerator,
dvdemux->framerate_denominator * GST_SECOND);
else else
*dest_value = 0; *dest_value = 0;
} else if (pad == dvdemux->audiosrcpad) { } else if (pad == dvdemux->audiosrcpad) {
*dest_value = 2 * src_value * dvdemux->frequency * *dest_value = gst_util_uint64_scale (src_value,
dvdemux->channels / (GST_SECOND * 2 * dvdemux->frequency * dvdemux->channels,
gst_audio_frame_byte_size (pad)); GST_SECOND * gst_audio_frame_byte_size (pad));
} }
break; break;
default: default:
@ -310,13 +302,14 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
switch (*dest_format) { switch (*dest_format) {
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
if (pad == dvdemux->videosrcpad) { if (pad == dvdemux->videosrcpad) {
*dest_value = src_value * GST_SECOND * *dest_value = gst_util_uint64_scale (src_value,
dvdemux->framerate_denominator / dvdemux->framerate_numerator; GST_SECOND * dvdemux->framerate_denominator,
dvdemux->framerate_numerator);
} else if (pad == dvdemux->audiosrcpad) { } else if (pad == dvdemux->audiosrcpad) {
if (src_value) if (src_value)
*dest_value = *dest_value = gst_util_uint64_scale (src_value,
src_value * GST_SECOND * gst_audio_frame_byte_size (pad) GST_SECOND * gst_audio_frame_byte_size (pad),
/ (2 * dvdemux->frequency * dvdemux->channels); 2 * dvdemux->frequency * dvdemux->channels);
else else
*dest_value = 0; *dest_value = 0;
} }
@ -343,8 +336,10 @@ done:
*dest_format, *dest_value, res); *dest_format, *dest_value, res);
return res; return res;
/* ERRORS */
error: error:
{ {
GST_INFO ("source conversion failed");
gst_object_unref (dvdemux); gst_object_unref (dvdemux);
return FALSE; return FALSE;
} }
@ -384,8 +379,9 @@ gst_dvdemux_sink_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
/* get frame number */ /* get frame number */
frame = src_value / dvdemux->frame_len; frame = src_value / dvdemux->frame_len;
*dest_value = (frame * GST_SECOND * dvdemux->framerate_denominator) / *dest_value = gst_util_uint64_scale (frame,
dvdemux->framerate_numerator; GST_SECOND * dvdemux->framerate_denominator,
dvdemux->framerate_numerator);
break; break;
} }
default: default:
@ -399,8 +395,10 @@ gst_dvdemux_sink_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
guint64 frame; guint64 frame;
/* calculate the frame */ /* calculate the frame */
frame = src_value * dvdemux->framerate_numerator / frame =
(dvdemux->framerate_denominator * GST_SECOND); gst_util_uint64_scale (src_value, dvdemux->framerate_numerator,
dvdemux->framerate_denominator * GST_SECOND);
/* calculate the offset */ /* calculate the offset */
*dest_value = frame * dvdemux->frame_len; *dest_value = frame * dvdemux->frame_len;
break; break;
@ -421,6 +419,7 @@ done:
error: error:
{ {
GST_INFO ("sink conversion failed");
gst_object_unref (dvdemux); gst_object_unref (dvdemux);
return FALSE; return FALSE;
} }
@ -526,7 +525,7 @@ gst_dvdemux_src_query (GstPad * pad, GstQuery * query)
error: error:
{ {
gst_object_unref (dvdemux); gst_object_unref (dvdemux);
GST_DEBUG ("error handling event"); GST_DEBUG ("error source query");
return FALSE; return FALSE;
} }
} }
@ -575,7 +574,7 @@ gst_dvdemux_sink_query (GstPad * pad, GstQuery * query)
error: error:
{ {
gst_object_unref (dvdemux); gst_object_unref (dvdemux);
GST_DEBUG ("error handling event"); GST_DEBUG ("error handling sink query");
return FALSE; return FALSE;
} }
} }
@ -611,22 +610,47 @@ gst_dvdemux_handle_sink_event (GstPad * pad, GstEvent * event)
gst_adapter_clear (dvdemux->adapter); gst_adapter_clear (dvdemux->adapter);
GST_DEBUG ("cleared adapter"); GST_DEBUG ("cleared adapter");
res = gst_dvdemux_send_event (dvdemux, event); res = gst_dvdemux_send_event (dvdemux, event);
gst_segment_init (&dvdemux->byte_segment, GST_FORMAT_BYTES);
gst_segment_init (&dvdemux->time_segment, GST_FORMAT_TIME);
break; break;
case GST_EVENT_NEWSEGMENT: case GST_EVENT_NEWSEGMENT:
{ {
gboolean update;
gdouble rate;
GstFormat format; GstFormat format;
gint64 start, stop, time;
/* parse byte start and stop positions */ /* parse byte start and stop positions */
gst_event_parse_new_segment (event, NULL, NULL, &format, gst_event_parse_new_segment (event, &update, &rate, &format,
&dvdemux->start_byte, &dvdemux->stop_byte, NULL); &start, &stop, &time);
/* and queue a DISCONT before sending the next set of buffers */ switch (format) {
dvdemux->need_discont = TRUE; case GST_FORMAT_BYTES:
gst_event_unref (event); gst_segment_set_newsegment (&dvdemux->byte_segment, update,
rate, format, start, stop, time);
/* and queue a SEGMENT before sending the next set of buffers, we
* cannot convert to time yet as we might not know the size of the
* frames, etc.. */
dvdemux->need_segment = TRUE;
gst_event_unref (event);
break;
case GST_FORMAT_TIME:
gst_segment_set_newsegment (&dvdemux->time_segment, update,
rate, format, start, stop, time);
/* and we can just forward this time event */
res = gst_dvdemux_send_event (dvdemux, event);
break;
default:
gst_event_unref (event);
/* cannot accept this format */
res = FALSE;
break;
}
break; break;
} }
case GST_EVENT_EOS: case GST_EVENT_EOS:
default:
/* flush any pending data */ /* flush any pending data */
gst_dvdemux_flush (dvdemux); gst_dvdemux_flush (dvdemux);
/* forward event */ /* forward event */
@ -634,6 +658,9 @@ gst_dvdemux_handle_sink_event (GstPad * pad, GstEvent * event)
/* and clear the adapter */ /* and clear the adapter */
gst_adapter_clear (dvdemux->adapter); gst_adapter_clear (dvdemux->adapter);
break; break;
default:
res = gst_dvdemux_send_event (dvdemux, event);
break;
} }
gst_object_unref (dvdemux); gst_object_unref (dvdemux);
@ -870,7 +897,7 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, const guint8 * data)
GstClockTime next_ts; GstClockTime next_ts;
GstFlowReturn aret, vret, ret; GstFlowReturn aret, vret, ret;
if (dvdemux->need_discont) { if (dvdemux->need_segment) {
GstEvent *event; GstEvent *event;
GstFormat format; GstFormat format;
gboolean res; gboolean res;
@ -878,37 +905,42 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, const guint8 * data)
/* convert to time and store as start/end_timestamp */ /* convert to time and store as start/end_timestamp */
format = GST_FORMAT_TIME; format = GST_FORMAT_TIME;
if (!(res = gst_pad_query_convert (dvdemux->sinkpad, if (!(res = gst_pad_query_convert (dvdemux->sinkpad,
GST_FORMAT_BYTES, GST_FORMAT_BYTES, dvdemux->byte_segment.start,
dvdemux->start_byte, &format, &dvdemux->start_timestamp))) { &format, &dvdemux->time_segment.start))) {
goto discont_error; goto segment_error;
} }
dvdemux->timestamp = dvdemux->start_timestamp; dvdemux->timestamp = dvdemux->time_segment.start;
/* calculate current frame number */ /* calculate current frame number */
format = GST_FORMAT_DEFAULT; format = GST_FORMAT_DEFAULT;
if (!(res = gst_pad_query_convert (dvdemux->videosrcpad, if (!(res = gst_pad_query_convert (dvdemux->videosrcpad,
GST_FORMAT_TIME, GST_FORMAT_TIME, dvdemux->time_segment.start,
dvdemux->start_timestamp, &format, &dvdemux->total_frames))) { &format, &dvdemux->total_frames))) {
goto discont_error; goto segment_error;
} }
if (dvdemux->stop_byte == -1) { if (dvdemux->byte_segment.stop == -1) {
dvdemux->stop_timestamp = -1; dvdemux->time_segment.stop = -1;
} else { } else {
format = GST_FORMAT_TIME; format = GST_FORMAT_TIME;
if (!(res = gst_pad_query_convert (dvdemux->sinkpad, if (!(res = gst_pad_query_convert (dvdemux->sinkpad,
GST_FORMAT_BYTES, GST_FORMAT_BYTES, dvdemux->byte_segment.stop,
dvdemux->stop_byte, &format, &dvdemux->stop_timestamp))) { &format, &dvdemux->time_segment.stop))) {
goto discont_error; goto segment_error;
} }
} }
GST_DEBUG_OBJECT (dvdemux, "sending segment start: %" GST_TIME_FORMAT
", stop: %" GST_TIME_FORMAT ", time: %" GST_TIME_FORMAT,
dvdemux->time_segment.start, dvdemux->time_segment.stop,
dvdemux->time_segment.start);
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
dvdemux->start_timestamp, dvdemux->stop_timestamp, dvdemux->time_segment.start, dvdemux->time_segment.stop,
dvdemux->start_timestamp); dvdemux->time_segment.start);
gst_dvdemux_send_event (dvdemux, event); gst_dvdemux_send_event (dvdemux, event);
dvdemux->need_discont = FALSE; dvdemux->need_segment = FALSE;
} }
next_ts = gst_util_uint64_scale_int ( next_ts = gst_util_uint64_scale_int (
@ -940,9 +972,9 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, const guint8 * data)
done: done:
return ret; return ret;
discont_error: segment_error:
{ {
GST_DEBUG ("error generating discont event"); GST_DEBUG ("error generating new_segment event");
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
} }
@ -999,7 +1031,6 @@ parse_header_error:
{ {
GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE, GST_ELEMENT_ERROR (dvdemux, STREAM, DECODE,
("Error parsing DV header"), ("Error parsing DV header")); ("Error parsing DV header"), ("Error parsing DV header"));
gst_object_unref (dvdemux);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -1017,6 +1048,9 @@ gst_dvdemux_chain (GstPad * pad, GstBuffer * buffer)
dvdemux = GST_DVDEMUX (gst_pad_get_parent (pad)); dvdemux = GST_DVDEMUX (gst_pad_get_parent (pad));
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
gst_adapter_clear (dvdemux->adapter);
/* temporary hack? Can't do this from the state change */ /* temporary hack? Can't do this from the state change */
if (!dvdemux->videosrcpad) if (!dvdemux->videosrcpad)
gst_dvdemux_add_pads (dvdemux); gst_dvdemux_add_pads (dvdemux);
@ -1059,6 +1093,18 @@ gst_dvdemux_change_state (GstElement * element, GstStateChange transition)
dvdemux->framecount = 0; dvdemux->framecount = 0;
dvdemux->found_header = FALSE; dvdemux->found_header = FALSE;
dvdemux->frame_len = -1; dvdemux->frame_len = -1;
dvdemux->timestamp = 0LL;
dvdemux->need_segment = FALSE;
dvdemux->new_media = FALSE;
dvdemux->framerate_numerator = 0;
dvdemux->framerate_denominator = 0;
dvdemux->total_frames = 0;
dvdemux->height = 0;
dvdemux->frequency = 0;
dvdemux->channels = 0;
dvdemux->wide = FALSE;
gst_segment_init (&dvdemux->byte_segment, GST_FORMAT_BYTES);
gst_segment_init (&dvdemux->time_segment, GST_FORMAT_TIME);
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break; break;

View file

@ -21,15 +21,12 @@
#ifndef __GST_DVDEMUX_H__ #ifndef __GST_DVDEMUX_H__
#define __GST_DVDEMUX_H__ #define __GST_DVDEMUX_H__
#include <gst/gst.h> #include <gst/gst.h>
#include <libdv/dv.h> #include <libdv/dv.h>
#include <gst/base/gstadapter.h> #include <gst/base/gstadapter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_DVDEMUX \ #define GST_TYPE_DVDEMUX \
(gst_dvdemux_get_type()) (gst_dvdemux_get_type())
#define GST_DVDEMUX(obj) \ #define GST_DVDEMUX(obj) \
@ -45,7 +42,6 @@ G_BEGIN_DECLS
typedef struct _GstDVDemux GstDVDemux; typedef struct _GstDVDemux GstDVDemux;
typedef struct _GstDVDemuxClass GstDVDemuxClass; typedef struct _GstDVDemuxClass GstDVDemuxClass;
struct _GstDVDemux { struct _GstDVDemux {
GstElement element; GstElement element;
@ -77,12 +73,9 @@ struct _GstDVDemux {
guint64 audio_offset; guint64 audio_offset;
guint64 video_offset; guint64 video_offset;
gint64 start_byte; GstSegment byte_segment;
gint64 stop_byte; GstSegment time_segment;
gint64 start_timestamp; gboolean need_segment;
gint64 stop_timestamp;
gboolean need_discont;
gboolean new_media; gboolean new_media;
gboolean found_header; gboolean found_header;
@ -94,11 +87,8 @@ struct _GstDVDemuxClass {
GstElementClass parent_class; GstElementClass parent_class;
}; };
GType gst_dvdemux_get_type (void); GType gst_dvdemux_get_type (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_DVDEMUX_H__ */ #endif /* __GST_DVDEMUX_H__ */