mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 10:25:33 +00:00
ext/ogg/gstoggdemux.c: Mark buffers with DISCONT after seek and after activating new chains.
Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_chain_peer), (gst_ogg_chain_mark_discont), (gst_ogg_chain_new_stream), (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek): Mark buffers with DISCONT after seek and after activating new chains. * ext/theora/gsttheoradec.h: * ext/theora/theoradec.c: (gst_theora_dec_reset), (theora_get_query_types), (theora_dec_sink_event), (theora_dec_push), (theora_handle_data_packet), (theora_dec_chain), (theora_dec_change_state): Fix frame counter. Detect and mark DISCONT buffers. * ext/vorbis/vorbisdec.c: (vorbis_dec_src_query), (vorbis_dec_sink_event), (vorbis_dec_push), (vorbis_dec_chain), (vorbis_dec_change_state): * ext/vorbis/vorbisdec.h: Use GstSegment. Detect and mark DISCONT buffers. Don't crash on 0 sized buffers.
This commit is contained in:
parent
461ffeda1b
commit
9e6ae51849
6 changed files with 133 additions and 35 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
2006-05-03 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_chain_peer),
|
||||||
|
(gst_ogg_chain_mark_discont), (gst_ogg_chain_new_stream),
|
||||||
|
(gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek):
|
||||||
|
Mark buffers with DISCONT after seek and after activating new
|
||||||
|
chains.
|
||||||
|
|
||||||
|
* ext/theora/gsttheoradec.h:
|
||||||
|
* ext/theora/theoradec.c: (gst_theora_dec_reset),
|
||||||
|
(theora_get_query_types), (theora_dec_sink_event),
|
||||||
|
(theora_dec_push), (theora_handle_data_packet), (theora_dec_chain),
|
||||||
|
(theora_dec_change_state):
|
||||||
|
Fix frame counter.
|
||||||
|
Detect and mark DISCONT buffers.
|
||||||
|
|
||||||
|
* ext/vorbis/vorbisdec.c: (vorbis_dec_src_query),
|
||||||
|
(vorbis_dec_sink_event), (vorbis_dec_push), (vorbis_dec_chain),
|
||||||
|
(vorbis_dec_change_state):
|
||||||
|
* ext/vorbis/vorbisdec.h:
|
||||||
|
Use GstSegment.
|
||||||
|
Detect and mark DISCONT buffers.
|
||||||
|
Don't crash on 0 sized buffers.
|
||||||
|
|
||||||
2006-05-03 Wim Taymans <wim@fluendo.com>
|
2006-05-03 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/volume/gstvolume.c: (volume_funcfind), (volume_set_caps),
|
* gst/volume/gstvolume.c: (volume_funcfind), (volume_set_caps),
|
||||||
|
|
|
@ -137,6 +137,8 @@ struct _GstOggPad
|
||||||
|
|
||||||
ogg_stream_state stream;
|
ogg_stream_state stream;
|
||||||
|
|
||||||
|
gboolean discont;
|
||||||
|
|
||||||
gboolean dynamic; /* True if the internal element had dynamic pads */
|
gboolean dynamic; /* True if the internal element had dynamic pads */
|
||||||
guint padaddedid; /* The signal id for element::pad-added */
|
guint padaddedid; /* The signal id for element::pad-added */
|
||||||
};
|
};
|
||||||
|
@ -949,6 +951,12 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
|
||||||
GST_BUFFER_OFFSET (buf) = -1;
|
GST_BUFFER_OFFSET (buf) = -1;
|
||||||
GST_BUFFER_OFFSET_END (buf) = packet->granulepos;
|
GST_BUFFER_OFFSET_END (buf) = packet->granulepos;
|
||||||
|
|
||||||
|
/* Mark discont on the buffer */
|
||||||
|
if (pad->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
pad->discont = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_pad_push (GST_PAD (pad), buf);
|
ret = gst_pad_push (GST_PAD (pad), buf);
|
||||||
/* ignore not linked */
|
/* ignore not linked */
|
||||||
if (ret == GST_FLOW_NOT_LINKED)
|
if (ret == GST_FLOW_NOT_LINKED)
|
||||||
|
@ -1204,6 +1212,18 @@ gst_ogg_chain_free (GstOggChain * chain)
|
||||||
g_free (chain);
|
g_free (chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ogg_chain_mark_discont (GstOggChain * chain)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
|
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
|
|
||||||
|
pad->discont = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstOggPad *
|
static GstOggPad *
|
||||||
gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
||||||
{
|
{
|
||||||
|
@ -1225,6 +1245,7 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
||||||
GST_PAD_DIRECTION (ret) = GST_PAD_SRC;
|
GST_PAD_DIRECTION (ret) = GST_PAD_SRC;
|
||||||
ret->chain = chain;
|
ret->chain = chain;
|
||||||
ret->ogg = chain->ogg;
|
ret->ogg = chain->ogg;
|
||||||
|
ret->discont = TRUE;
|
||||||
gst_object_set_name (GST_OBJECT (ret), name);
|
gst_object_set_name (GST_OBJECT (ret), name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
|
@ -1643,6 +1664,9 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
pad = g_array_index (chain->streams, GstOggPad *, i);
|
pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad);
|
GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad);
|
||||||
|
|
||||||
|
/* mark discont */
|
||||||
|
pad->discont = TRUE;
|
||||||
|
|
||||||
/* activate first */
|
/* activate first */
|
||||||
gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
|
gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
|
||||||
|
|
||||||
|
@ -1667,6 +1691,11 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
for (headers = pad->headers; headers; headers = g_list_next (headers)) {
|
for (headers = pad->headers; headers; headers = g_list_next (headers)) {
|
||||||
GstBuffer *buffer = GST_BUFFER (headers->data);
|
GstBuffer *buffer = GST_BUFFER (headers->data);
|
||||||
|
|
||||||
|
if (pad->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
pad->discont = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* we don't care about the return value here */
|
/* we don't care about the return value here */
|
||||||
gst_pad_push (GST_PAD_CAST (pad), buffer);
|
gst_pad_push (GST_PAD_CAST (pad), buffer);
|
||||||
}
|
}
|
||||||
|
@ -1991,7 +2020,8 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg, GstEvent * event)
|
||||||
/* switch to different chain, send segment on new chain */
|
/* switch to different chain, send segment on new chain */
|
||||||
gst_ogg_demux_activate_chain (ogg, chain, event);
|
gst_ogg_demux_activate_chain (ogg, chain, event);
|
||||||
} else {
|
} else {
|
||||||
/* send segment on current chain */
|
/* mark discont and send segment on current chain */
|
||||||
|
gst_ogg_chain_mark_discont (chain);
|
||||||
gst_ogg_demux_send_event (ogg, event);
|
gst_ogg_demux_send_event (ogg, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct _GstTheoraDec
|
||||||
|
|
||||||
/* segment info */ /* with STREAM_LOCK */
|
/* segment info */ /* with STREAM_LOCK */
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
|
gboolean discont;
|
||||||
|
|
||||||
/* QoS stuff */ /* with LOCK*/
|
/* QoS stuff */ /* with LOCK*/
|
||||||
gdouble proportion;
|
gdouble proportion;
|
||||||
|
|
|
@ -172,6 +172,8 @@ gst_theora_dec_reset (GstTheoraDec * dec)
|
||||||
dec->need_keyframe = TRUE;
|
dec->need_keyframe = TRUE;
|
||||||
dec->last_timestamp = -1;
|
dec->last_timestamp = -1;
|
||||||
dec->granulepos = -1;
|
dec->granulepos = -1;
|
||||||
|
dec->discont = TRUE;
|
||||||
|
dec->frame_nr = -1;
|
||||||
gst_segment_init (&dec->segment, GST_FORMAT_TIME);
|
gst_segment_init (&dec->segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (dec);
|
GST_OBJECT_LOCK (dec);
|
||||||
|
@ -180,7 +182,6 @@ gst_theora_dec_reset (GstTheoraDec * dec)
|
||||||
GST_OBJECT_UNLOCK (dec);
|
GST_OBJECT_UNLOCK (dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: copy from libtheora, theora should somehow make this available for seeking */
|
|
||||||
static int
|
static int
|
||||||
_theora_ilog (unsigned int v)
|
_theora_ilog (unsigned int v)
|
||||||
{
|
{
|
||||||
|
@ -281,6 +282,8 @@ theora_get_query_types (GstPad * pad)
|
||||||
{
|
{
|
||||||
static const GstQueryType theora_src_query_types[] = {
|
static const GstQueryType theora_src_query_types[] = {
|
||||||
GST_QUERY_POSITION,
|
GST_QUERY_POSITION,
|
||||||
|
GST_QUERY_DURATION,
|
||||||
|
GST_QUERY_CONVERT,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -641,7 +644,6 @@ theora_dec_sink_event (GstPad * pad, GstEvent * event)
|
||||||
ret = gst_pad_push_event (dec->srcpad, event);
|
ret = gst_pad_push_event (dec->srcpad, event);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
/* FIXME, makes us waiting for keyframes */
|
|
||||||
gst_theora_dec_reset (dec);
|
gst_theora_dec_reset (dec);
|
||||||
ret = gst_pad_push_event (dec->srcpad, event);
|
ret = gst_pad_push_event (dec->srcpad, event);
|
||||||
break;
|
break;
|
||||||
|
@ -876,6 +878,11 @@ theora_dec_push (GstTheoraDec * dec, GstBuffer * buf)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "patch buffer %lld %lld", size, time);
|
GST_DEBUG_OBJECT (dec, "patch buffer %lld %lld", size, time);
|
||||||
GST_BUFFER_TIMESTAMP (buffer) = time;
|
GST_BUFFER_TIMESTAMP (buffer) = time;
|
||||||
|
|
||||||
|
if (dec->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
dec->discont = FALSE;
|
||||||
|
}
|
||||||
/* ignore the result.. */
|
/* ignore the result.. */
|
||||||
gst_pad_push (dec->srcpad, buffer);
|
gst_pad_push (dec->srcpad, buffer);
|
||||||
size--;
|
size--;
|
||||||
|
@ -883,6 +890,10 @@ theora_dec_push (GstTheoraDec * dec, GstBuffer * buf)
|
||||||
g_list_free (dec->queued);
|
g_list_free (dec->queued);
|
||||||
dec->queued = NULL;
|
dec->queued = NULL;
|
||||||
}
|
}
|
||||||
|
if (dec->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
dec->discont = FALSE;
|
||||||
|
}
|
||||||
result = gst_pad_push (dec->srcpad, buf);
|
result = gst_pad_push (dec->srcpad, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,20 +915,23 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
|
||||||
gint cwidth, cheight;
|
gint cwidth, cheight;
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
|
|
||||||
if (!dec->have_header)
|
if (G_UNLIKELY (!dec->have_header))
|
||||||
goto not_initialized;
|
goto not_initialized;
|
||||||
|
|
||||||
/* the second most significant bit of the first data byte is cleared
|
/* the second most significant bit of the first data byte is cleared
|
||||||
* for keyframes */
|
* for keyframes */
|
||||||
keyframe = (packet->packet[0] & 0x40) == 0;
|
keyframe = (packet->packet[0] & 0x40) == 0;
|
||||||
if (keyframe) {
|
if (keyframe) {
|
||||||
|
GST_DEBUG_OBJECT (dec, "we have a keyframe");
|
||||||
dec->need_keyframe = FALSE;
|
dec->need_keyframe = FALSE;
|
||||||
} else if (dec->need_keyframe) {
|
} else if (dec->need_keyframe) {
|
||||||
goto dropping;
|
goto dropping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dec, "parsing data packet");
|
||||||
|
|
||||||
/* this does the decoding */
|
/* this does the decoding */
|
||||||
if (theora_decode_packetin (&dec->state, packet))
|
if (G_UNLIKELY (theora_decode_packetin (&dec->state, packet)))
|
||||||
goto decode_error;
|
goto decode_error;
|
||||||
|
|
||||||
if (outtime != -1) {
|
if (outtime != -1) {
|
||||||
|
@ -942,10 +956,11 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
|
||||||
|
|
||||||
/* this does postprocessing and set up the decoded frame
|
/* this does postprocessing and set up the decoded frame
|
||||||
* pointers in our yuv variable */
|
* pointers in our yuv variable */
|
||||||
if (theora_decode_YUVout (&dec->state, &yuv) < 0)
|
if (G_UNLIKELY (theora_decode_YUVout (&dec->state, &yuv) < 0))
|
||||||
goto no_yuv;
|
goto no_yuv;
|
||||||
|
|
||||||
if ((yuv.y_width != dec->info.width) || (yuv.y_height != dec->info.height))
|
if (G_UNLIKELY ((yuv.y_width != dec->info.width)
|
||||||
|
|| (yuv.y_height != dec->info.height)))
|
||||||
goto wrong_dimensions;
|
goto wrong_dimensions;
|
||||||
|
|
||||||
width = dec->width;
|
width = dec->width;
|
||||||
|
@ -966,7 +981,7 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
|
||||||
result =
|
result =
|
||||||
gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
|
gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
|
||||||
out_size, GST_PAD_CAPS (dec->srcpad), &out);
|
out_size, GST_PAD_CAPS (dec->srcpad), &out);
|
||||||
if (result != GST_FLOW_OK)
|
if (G_UNLIKELY (result != GST_FLOW_OK))
|
||||||
goto no_buffer;
|
goto no_buffer;
|
||||||
|
|
||||||
/* copy the visible region to the destination. This is actually pretty
|
/* copy the visible region to the destination. This is actually pretty
|
||||||
|
@ -1011,9 +1026,9 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME, frame_nr not correct */
|
|
||||||
GST_BUFFER_OFFSET (out) = dec->frame_nr;
|
GST_BUFFER_OFFSET (out) = dec->frame_nr;
|
||||||
dec->frame_nr++;
|
if (dec->frame_nr != -1)
|
||||||
|
dec->frame_nr++;
|
||||||
GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
|
GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
|
||||||
GST_BUFFER_DURATION (out) =
|
GST_BUFFER_DURATION (out) =
|
||||||
gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
|
gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
|
||||||
|
@ -1034,11 +1049,14 @@ not_initialized:
|
||||||
dropping:
|
dropping:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe");
|
GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe");
|
||||||
|
dec->discont = TRUE;
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
dropping_qos:
|
dropping_qos:
|
||||||
{
|
{
|
||||||
dec->frame_nr++;
|
if (dec->frame_nr != -1)
|
||||||
|
dec->frame_nr++;
|
||||||
|
dec->discont = TRUE;
|
||||||
GST_WARNING_OBJECT (dec, "dropping frame because of QoS");
|
GST_WARNING_OBJECT (dec, "dropping frame because of QoS");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
@ -1079,9 +1097,11 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
/* resync on DISCONT */
|
/* resync on DISCONT */
|
||||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
|
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
|
||||||
|
GST_DEBUG_OBJECT (dec, "received DISCONT buffer");
|
||||||
dec->need_keyframe = TRUE;
|
dec->need_keyframe = TRUE;
|
||||||
dec->last_timestamp = -1;
|
dec->last_timestamp = -1;
|
||||||
dec->granulepos = -1;
|
dec->granulepos = -1;
|
||||||
|
dec->discont = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make ogg_packet out of the buffer */
|
/* make ogg_packet out of the buffer */
|
||||||
|
@ -1107,7 +1127,7 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
if (packet.bytes < 1)
|
if (packet.bytes < 1)
|
||||||
goto wrong_size;
|
goto wrong_size;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "header=%d packetno=%lld, outtime=%" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (dec, "header=%02x packetno=%lld, outtime=%" GST_TIME_FORMAT,
|
||||||
packet.packet[0], packet.packetno, GST_TIME_ARGS (dec->last_timestamp));
|
packet.packet[0], packet.packetno, GST_TIME_ARGS (dec->last_timestamp));
|
||||||
|
|
||||||
/* switch depending on packet type */
|
/* switch depending on packet type */
|
||||||
|
@ -1122,7 +1142,7 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* interpollate granule pos */
|
/* interpolate granule pos */
|
||||||
dec->granulepos = _inc_granulepos (dec, dec->granulepos);
|
dec->granulepos = _inc_granulepos (dec, dec->granulepos);
|
||||||
|
|
||||||
gst_object_unref (dec);
|
gst_object_unref (dec);
|
||||||
|
@ -1135,6 +1155,7 @@ done:
|
||||||
wrong_size:
|
wrong_size:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (dec, "received empty packet");
|
GST_WARNING_OBJECT (dec, "received empty packet");
|
||||||
|
dec->discont = TRUE;
|
||||||
result = GST_FLOW_OK;
|
result = GST_FLOW_OK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1171,6 +1192,7 @@ theora_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
theora_clear (&dec->state);
|
theora_clear (&dec->state);
|
||||||
theora_comment_clear (&dec->comment);
|
theora_comment_clear (&dec->comment);
|
||||||
theora_info_clear (&dec->info);
|
theora_info_clear (&dec->info);
|
||||||
|
gst_theora_dec_reset (dec);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -275,7 +275,7 @@ vorbis_dec_src_query (GstPad * pad, GstQuery * query)
|
||||||
&value)))
|
&value)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
value = (value - dec->segment_start) + dec->segment_time;
|
value = (value - dec->segment.start) + dec->segment.time;
|
||||||
|
|
||||||
gst_query_set_position (query, format, value);
|
gst_query_set_position (query, format, value);
|
||||||
|
|
||||||
|
@ -426,25 +426,18 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
|
||||||
gst_event_parse_new_segment (event, &update, &rate, &format, &start,
|
gst_event_parse_new_segment (event, &update, &rate, &format, &start,
|
||||||
&stop, &time);
|
&stop, &time);
|
||||||
|
|
||||||
|
/* we need time and a positive rate for now */
|
||||||
if (format != GST_FORMAT_TIME)
|
if (format != GST_FORMAT_TIME)
|
||||||
goto newseg_wrong_format;
|
goto newseg_wrong_format;
|
||||||
|
|
||||||
if (rate <= 0.0)
|
if (rate <= 0.0)
|
||||||
goto newseg_wrong_rate;
|
goto newseg_wrong_rate;
|
||||||
|
|
||||||
/* now copy over the values */
|
/* now configure the values */
|
||||||
dec->segment_rate = rate;
|
gst_segment_set_newsegment (&dec->segment, update,
|
||||||
dec->segment_start = start;
|
rate, format, start, stop, time);
|
||||||
dec->segment_stop = stop;
|
|
||||||
dec->segment_time = time;
|
|
||||||
|
|
||||||
dec->granulepos = -1;
|
/* and forward */
|
||||||
dec->cur_timestamp = GST_CLOCK_TIME_NONE;
|
|
||||||
dec->prev_timestamp = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
#ifdef HAVE_VORBIS_SYNTHESIS_RESTART
|
|
||||||
vorbis_synthesis_restart (&dec->vd);
|
|
||||||
#endif
|
|
||||||
ret = gst_pad_push_event (dec->srcpad, event);
|
ret = gst_pad_push_event (dec->srcpad, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -659,6 +652,8 @@ header_read_error:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* These samples can be outside of the float -1.0 -- 1.0 range, this
|
||||||
|
* is allowed, downstream elements are supposed to clip */
|
||||||
static void
|
static void
|
||||||
copy_samples (float *out, float **in, guint samples, gint channels)
|
copy_samples (float *out, float **in, guint samples, gint channels)
|
||||||
{
|
{
|
||||||
|
@ -714,11 +709,19 @@ vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
||||||
GstBuffer *buffer = GST_BUFFER (walk->data);
|
GstBuffer *buffer = GST_BUFFER (walk->data);
|
||||||
|
|
||||||
/* ignore the result */
|
/* ignore the result */
|
||||||
|
if (dec->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
dec->discont = FALSE;
|
||||||
|
}
|
||||||
gst_pad_push (dec->srcpad, buffer);
|
gst_pad_push (dec->srcpad, buffer);
|
||||||
}
|
}
|
||||||
g_list_free (dec->queued);
|
g_list_free (dec->queued);
|
||||||
dec->queued = NULL;
|
dec->queued = NULL;
|
||||||
}
|
}
|
||||||
|
if (dec->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
dec->discont = FALSE;
|
||||||
|
}
|
||||||
result = gst_pad_push (dec->srcpad, buf);
|
result = gst_pad_push (dec->srcpad, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,12 +844,18 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
ogg_packet packet;
|
ogg_packet packet;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
|
||||||
vd = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
|
vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (buffer) == 0) {
|
/* resync on DISCONT */
|
||||||
gst_buffer_unref (buffer);
|
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
|
||||||
GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty buffer received"));
|
GST_DEBUG_OBJECT (vd, "received DISCONT buffer");
|
||||||
return GST_FLOW_ERROR;
|
vd->granulepos = -1;
|
||||||
|
vd->cur_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
|
vd->prev_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
|
#ifdef HAVE_VORBIS_SYNTHESIS_RESTART
|
||||||
|
vorbis_synthesis_restart (&vd->vd);
|
||||||
|
#endif
|
||||||
|
vd->discont = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only ogg has granulepos, demuxers of other container formats
|
/* only ogg has granulepos, demuxers of other container formats
|
||||||
|
@ -876,6 +885,9 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
*/
|
*/
|
||||||
packet.e_o_s = 0;
|
packet.e_o_s = 0;
|
||||||
|
|
||||||
|
if (packet.bytes < 1)
|
||||||
|
goto wrong_size;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT,
|
GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT,
|
||||||
(gint64) packet.granulepos);
|
(gint64) packet.granulepos);
|
||||||
|
|
||||||
|
@ -895,8 +907,18 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
done:
|
done:
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
gst_object_unref (vd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
wrong_size:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (vd, "received empty packet");
|
||||||
|
result = GST_FLOW_OK;
|
||||||
|
vd->discont = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
@ -917,6 +939,7 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
vd->prev_timestamp = GST_CLOCK_TIME_NONE;
|
vd->prev_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
vd->granulepos = -1;
|
vd->granulepos = -1;
|
||||||
vd->packetno = 0;
|
vd->packetno = 0;
|
||||||
|
vd->discont = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -64,10 +64,8 @@ struct _GstVorbisDec {
|
||||||
|
|
||||||
GList *queued;
|
GList *queued;
|
||||||
|
|
||||||
gdouble segment_rate;
|
GstSegment segment;
|
||||||
gint64 segment_start;
|
gboolean discont;
|
||||||
gint64 segment_stop;
|
|
||||||
gint64 segment_time;
|
|
||||||
|
|
||||||
GstClockTime cur_timestamp; /* only used with non-ogg container formats */
|
GstClockTime cur_timestamp; /* only used with non-ogg container formats */
|
||||||
GstClockTime prev_timestamp; /* only used with non-ogg container formats */
|
GstClockTime prev_timestamp; /* only used with non-ogg container formats */
|
||||||
|
|
Loading…
Reference in a new issue