mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
ext/a52dec/gsta52dec.c: Add more debug
Original commit message from CVS: * ext/a52dec/gsta52dec.c: (gst_a52dec_chain): Add more debug * gst/dvdlpcmdec/gstdvdlpcmdec.c: (gst_dvdlpcm_reset), (gst_dvdlpcmdec_init), (update_timestamps), (gst_dvdlpcmdec_chain_dvd), (gst_dvdlpcmdec_chain_raw), (dvdlpcmdec_sink_event): * gst/dvdlpcmdec/gstdvdlpcmdec.h: If we have a first_access offset but no current timestamp (might happen after a seek), then calculate a start time for the first portion so that it will align with the timestamp given for the first_access portion. If a new-segment arrives with format time, store the start time as a failsafe timestamp in case we never get any further timestamp info (unlikely) Mask out the 'frame number' section of the incoming header so that we don't consider it to be changing on every buffer and reset the caps constantly. Use gst_util_uint64_scale for duration calculation
This commit is contained in:
parent
313be6facc
commit
2f68d625c1
4 changed files with 119 additions and 11 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
2006-05-11 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
||||
* ext/a52dec/gsta52dec.c: (gst_a52dec_chain):
|
||||
Add more debug
|
||||
|
||||
* gst/dvdlpcmdec/gstdvdlpcmdec.c: (gst_dvdlpcm_reset),
|
||||
(gst_dvdlpcmdec_init), (update_timestamps),
|
||||
(gst_dvdlpcmdec_chain_dvd), (gst_dvdlpcmdec_chain_raw),
|
||||
(dvdlpcmdec_sink_event):
|
||||
* gst/dvdlpcmdec/gstdvdlpcmdec.h:
|
||||
If we have a first_access offset but no current timestamp (might
|
||||
happen after a seek), then calculate a start time for the first
|
||||
portion so that it will align with the timestamp given for the
|
||||
first_access portion.
|
||||
|
||||
If a new-segment arrives with format time, store the start
|
||||
time as a failsafe timestamp in case we never get any further
|
||||
timestamp info (unlikely)
|
||||
|
||||
Mask out the 'frame number' section of the incoming header so
|
||||
that we don't consider it to be changing on every buffer and
|
||||
reset the caps constantly.
|
||||
|
||||
Use gst_util_uint64_scale for duration calculation
|
||||
|
||||
2006-05-11 Michael Smith <msmith@fluendo.com>
|
||||
|
||||
* gst/dvdlpcmdec/gstdvdlpcmdec.c: (gst_dvdlpcmdec_chain_dvd):
|
||||
|
|
|
@ -535,7 +535,8 @@ gst_a52dec_chain (GstPad * pad, GstBuffer * buf)
|
|||
len = first_access - 1;
|
||||
|
||||
if (len <= 0 || offset + len > size) {
|
||||
GST_ERROR_OBJECT (pad, "Bad first_access parameter in buffer");
|
||||
GST_ERROR_OBJECT (pad, "Bad first_access parameter (%d) in buffer",
|
||||
first_access);
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ static GstFlowReturn gst_dvdlpcmdec_chain_raw (GstPad * pad,
|
|||
static GstFlowReturn gst_dvdlpcmdec_chain_dvd (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
static gboolean gst_dvdlpcmdec_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static GstStateChangeReturn gst_dvdlpcmdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
@ -150,7 +151,7 @@ gst_dvdlpcm_reset (GstDvdLpcmDec * dvdlpcmdec)
|
|||
dvdlpcmdec->dynamic_range = 0;
|
||||
dvdlpcmdec->emphasis = FALSE;
|
||||
dvdlpcmdec->mute = FALSE;
|
||||
dvdlpcmdec->timestamp = 0;
|
||||
dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
||||
dvdlpcmdec->header = 0;
|
||||
|
||||
|
@ -165,6 +166,7 @@ gst_dvdlpcmdec_init (GstDvdLpcmDec * dvdlpcmdec)
|
|||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_dvdlpcmdec_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (dvdlpcmdec->sinkpad, gst_dvdlpcmdec_setcaps);
|
||||
gst_pad_set_event_function (dvdlpcmdec->sinkpad, dvdlpcmdec_sink_event);
|
||||
gst_element_add_pad (GST_ELEMENT (dvdlpcmdec), dvdlpcmdec->sinkpad);
|
||||
|
||||
dvdlpcmdec->srcpad =
|
||||
|
@ -257,15 +259,21 @@ caps_parse_error:
|
|||
static void
|
||||
update_timestamps (GstDvdLpcmDec * dvdlpcmdec, GstBuffer * buf, int samples)
|
||||
{
|
||||
GST_BUFFER_DURATION (buf) = samples * GST_SECOND / dvdlpcmdec->rate;
|
||||
GST_BUFFER_DURATION (buf) =
|
||||
gst_util_uint64_scale (samples, GST_SECOND, dvdlpcmdec->rate);
|
||||
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||
/* Then leave it as-is, and save this timestamp */
|
||||
dvdlpcmdec->timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||
} else {
|
||||
dvdlpcmdec->timestamp += GST_BUFFER_DURATION (buf);
|
||||
if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp))
|
||||
dvdlpcmdec->timestamp = dvdlpcmdec->segment_start;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (buf) = dvdlpcmdec->timestamp;
|
||||
}
|
||||
|
||||
dvdlpcmdec->timestamp += GST_BUFFER_DURATION (buf);
|
||||
|
||||
GST_LOG_OBJECT (dvdlpcmdec, "Updated timestamp to %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
}
|
||||
|
@ -315,7 +323,7 @@ gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstBuffer * buf)
|
|||
guint first_access;
|
||||
guint32 header;
|
||||
GstBuffer *subbuf;
|
||||
GstFlowReturn ret;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
gint off, len;
|
||||
|
||||
dvdlpcmdec = GST_DVDLPCMDEC (gst_pad_get_parent (pad));
|
||||
|
@ -348,7 +356,8 @@ gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstBuffer * buf)
|
|||
goto done;
|
||||
}
|
||||
|
||||
header = (data[2] << 16) | (data[3] << 8) | data[4];
|
||||
/* Don't keep the 'frame number' low 5 bits of the first byte */
|
||||
header = ((data[2] & 0xC0) << 16) | (data[3] << 8) | data[4];
|
||||
|
||||
/* see if we have a new header */
|
||||
if (header != dvdlpcmdec->header) {
|
||||
|
@ -389,11 +398,14 @@ gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstBuffer * buf)
|
|||
off = 5;
|
||||
|
||||
if (first_access > 4) {
|
||||
guint samples = 0;
|
||||
GstClockTime ts;
|
||||
|
||||
/* length of first buffer */
|
||||
len = first_access - 4;
|
||||
|
||||
GST_LOG_OBJECT (dvdlpcmdec, "Creating first sub-buffer off %d, len %d", off,
|
||||
len);
|
||||
GST_LOG_OBJECT (dvdlpcmdec, "Creating first sub-buffer off %d, len %d",
|
||||
off, len);
|
||||
|
||||
/* see if we need a subbuffer without timestamp */
|
||||
if (off + len > size) {
|
||||
|
@ -406,7 +418,35 @@ gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstBuffer * buf)
|
|||
}
|
||||
|
||||
subbuf = gst_buffer_create_sub (buf, off, len);
|
||||
|
||||
/* If we don't have a stored timestamp from the last packet,
|
||||
* (it's straight after a new-segment, but we have one on the
|
||||
* first access buffer, then calculate the timestamp to align
|
||||
* this buffer to just before the first_access buffer */
|
||||
if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp) &&
|
||||
GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||
switch (dvdlpcmdec->width) {
|
||||
case 16:
|
||||
samples = len / dvdlpcmdec->channels / 2;
|
||||
break;
|
||||
case 20:
|
||||
samples = (len / dvdlpcmdec->channels) * 2 / 5;
|
||||
break;
|
||||
case 24:
|
||||
samples = len / dvdlpcmdec->channels / 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (samples != 0) {
|
||||
ts = gst_util_uint64_scale (samples, GST_SECOND, dvdlpcmdec->rate);
|
||||
if (ts < GST_BUFFER_TIMESTAMP (buf))
|
||||
GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf) - ts;
|
||||
else
|
||||
GST_BUFFER_TIMESTAMP (subbuf) = 0;
|
||||
} else {
|
||||
GST_BUFFER_TIMESTAMP (subbuf) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
ret = gst_dvdlpcmdec_chain_raw (pad, subbuf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto done;
|
||||
|
@ -462,7 +502,9 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
|||
size = GST_BUFFER_SIZE (buf);
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
|
||||
GST_LOG_OBJECT (dvdlpcmdec, "got buffer %p of size %d", buf, size);
|
||||
GST_LOG_OBJECT (dvdlpcmdec,
|
||||
"got buffer %p of size %d with ts %" GST_TIME_FORMAT,
|
||||
buf, size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
|
||||
if (dvdlpcmdec->rate == 0)
|
||||
goto not_negotiated;
|
||||
|
@ -475,7 +517,7 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
|||
/* We can just pass 16-bits straight through intact, once we set
|
||||
* appropriate things on the buffer */
|
||||
samples = size / dvdlpcmdec->channels / 2;
|
||||
buf = gst_buffer_make_writable (buf);
|
||||
buf = gst_buffer_make_metadata_writable (buf);
|
||||
break;
|
||||
}
|
||||
case 20:
|
||||
|
@ -600,6 +642,45 @@ invalid_width:
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (GST_PAD_PARENT (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
{
|
||||
gdouble rate, arate;
|
||||
GstFormat format;
|
||||
gboolean update;
|
||||
gint64 start, end, base;
|
||||
|
||||
gst_event_parse_new_segment_full (event, &update, &rate, &arate,
|
||||
&format, &start, &end, &base);
|
||||
|
||||
GST_DEBUG_OBJECT (dvdlpcmdec,
|
||||
"new segment, format=%d, start = %" G_GINT64_FORMAT
|
||||
", end = %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
||||
format, start, end, base);
|
||||
|
||||
dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
|
||||
if (format == GST_FORMAT_TIME)
|
||||
dvdlpcmdec->segment_start = start;
|
||||
else
|
||||
dvdlpcmdec->segment_start = 0;
|
||||
|
||||
GST_DEBUG_OBJECT (dvdlpcmdec,
|
||||
"Have new segment. Resetting timestamp. segment_start = % "
|
||||
G_GINT64_FORMAT, dvdlpcmdec->segment_start);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return gst_pad_event_default (pad, event);
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_dvdlpcmdec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
|
|
|
@ -55,6 +55,7 @@ struct _GstDvdLpcmDec {
|
|||
gint mute;
|
||||
|
||||
GstClockTime timestamp;
|
||||
GstClockTime segment_start;
|
||||
};
|
||||
|
||||
struct _GstDvdLpcmDecClass {
|
||||
|
|
Loading…
Reference in a new issue