gst/dvdlpcmdec/gstdvdlpcmdec.*: Implement all sample rates.
Original commit message from CVS: * gst/dvdlpcmdec/gstdvdlpcmdec.c: (gst_dvdlpcm_reset), (update_timestamps), (parse_header), (gst_dvdlpcmdec_chain_dvd), (gst_dvdlpcmdec_chain_raw), (dvdlpcmdec_sink_event): * gst/dvdlpcmdec/gstdvdlpcmdec.h: Implement all sample rates. Implement sample permutation a little smarter avoiding a memcpy. Fix timestamps, use segments, fix seeking.
This commit is contained in:
parent
549ec77758
commit
d8659dad60
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
2007-02-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/dvdlpcmdec/gstdvdlpcmdec.c: (gst_dvdlpcm_reset),
|
||||||
|
(update_timestamps), (parse_header), (gst_dvdlpcmdec_chain_dvd),
|
||||||
|
(gst_dvdlpcmdec_chain_raw), (dvdlpcmdec_sink_event):
|
||||||
|
* gst/dvdlpcmdec/gstdvdlpcmdec.h:
|
||||||
|
Implement all sample rates.
|
||||||
|
Implement sample permutation a little smarter avoiding a memcpy.
|
||||||
|
Fix timestamps, use segments, fix seeking.
|
||||||
|
|
||||||
2007-02-28 Wim Taymans <wim@fluendo.com>
|
2007-02-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* docs/plugins/Makefile.am:
|
* docs/plugins/Makefile.am:
|
||||||
|
@ -155,8 +155,7 @@ gst_dvdlpcm_reset (GstDvdLpcmDec * dvdlpcmdec)
|
|||||||
|
|
||||||
dvdlpcmdec->header = 0;
|
dvdlpcmdec->header = 0;
|
||||||
|
|
||||||
GST_LOG_OBJECT (dvdlpcmdec, "Setting NULL caps on src pad");
|
gst_segment_init (&dvdlpcmdec->segment, GST_FORMAT_UNDEFINED);
|
||||||
gst_pad_set_caps (dvdlpcmdec->srcpad, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -276,7 +275,7 @@ update_timestamps (GstDvdLpcmDec * dvdlpcmdec, GstBuffer * buf, int samples)
|
|||||||
take_buf_ts = TRUE;
|
take_buf_ts = TRUE;
|
||||||
}
|
}
|
||||||
} else if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp)) {
|
} else if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp)) {
|
||||||
dvdlpcmdec->timestamp = dvdlpcmdec->segment_start;
|
dvdlpcmdec->timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (take_buf_ts) {
|
if (take_buf_ts) {
|
||||||
@ -318,11 +317,21 @@ parse_header (GstDvdLpcmDec * dec, guint32 header)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only two sample rates supported */
|
/* Only four sample rates supported */
|
||||||
if (header & 0x1000)
|
switch (header & 0x3000) {
|
||||||
dec->rate = 96000;
|
case 0x0000:
|
||||||
else
|
|
||||||
dec->rate = 48000;
|
dec->rate = 48000;
|
||||||
|
break;
|
||||||
|
case 0x1000:
|
||||||
|
dec->rate = 96000;
|
||||||
|
break;
|
||||||
|
case 0x2000:
|
||||||
|
dec->rate = 44100;
|
||||||
|
break;
|
||||||
|
case 0x3000:
|
||||||
|
dec->rate = 32000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* And, of course, the number of channels (up to 8) */
|
/* And, of course, the number of channels (up to 8) */
|
||||||
dec->channels = ((header >> 8) & 0x7) + 1;
|
dec->channels = ((header >> 8) & 0x7) + 1;
|
||||||
@ -426,7 +435,7 @@ gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstBuffer * buf)
|
|||||||
GST_WARNING_OBJECT (pad, "Bad first_access parameter in buffer");
|
GST_WARNING_OBJECT (pad, "Bad first_access parameter in buffer");
|
||||||
GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, DECODE,
|
GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, DECODE,
|
||||||
(NULL),
|
(NULL),
|
||||||
("first_access parameter out of range: bad buffer from " "demuxer"));
|
("first_access parameter out of range: bad buffer from demuxer"));
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -496,8 +505,7 @@ done:
|
|||||||
negotiation_failed:
|
negotiation_failed:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (dvdlpcmdec, "Failed to set caps!");
|
GST_DEBUG_OBJECT (dvdlpcmdec, "Failed to set caps!");
|
||||||
GST_DEBUG_OBJECT (dvdlpcmdec, "Couldn't negotiate caps on src pad");
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
ret = GST_FLOW_ERROR;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,7 +514,7 @@ static GstFlowReturn
|
|||||||
gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstDvdLpcmDec *dvdlpcmdec;
|
GstDvdLpcmDec *dvdlpcmdec;
|
||||||
guchar *data;
|
guint8 *data;
|
||||||
guint size;
|
guint size;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
guint samples = 0;
|
guint samples = 0;
|
||||||
@ -523,6 +531,9 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
|||||||
if (dvdlpcmdec->rate == 0)
|
if (dvdlpcmdec->rate == 0)
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
|
|
||||||
|
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
|
||||||
|
dvdlpcmdec->timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
|
||||||
/* We don't currently do anything at all regarding emphasis, mute or
|
/* We don't currently do anything at all regarding emphasis, mute or
|
||||||
* dynamic_range - I'm not sure what they're for */
|
* dynamic_range - I'm not sure what they're for */
|
||||||
switch (dvdlpcmdec->width) {
|
switch (dvdlpcmdec->width) {
|
||||||
@ -540,8 +551,8 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
|||||||
gint64 samples = size * 8 / 20;
|
gint64 samples = size * 8 / 20;
|
||||||
gint64 count = size / 10;
|
gint64 count = size / 10;
|
||||||
gint64 i;
|
gint64 i;
|
||||||
guchar *src;
|
guint8 *src;
|
||||||
guchar *dest;
|
guint8 *dest;
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
GstCaps *bufcaps = GST_PAD_CAPS (dvdlpcmdec->srcpad);
|
GstCaps *bufcaps = GST_PAD_CAPS (dvdlpcmdec->srcpad);
|
||||||
|
|
||||||
@ -598,19 +609,19 @@ gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
|
|||||||
|
|
||||||
src = GST_BUFFER_DATA (buf);
|
src = GST_BUFFER_DATA (buf);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
guchar temp[9];
|
guint8 tmp;
|
||||||
|
|
||||||
temp[0] = src[8];
|
tmp = src[10];
|
||||||
temp[1] = src[2];
|
src[10] = src[7];
|
||||||
temp[2] = src[3];
|
src[7] = src[5];
|
||||||
temp[3] = src[9];
|
src[5] = src[9];
|
||||||
temp[4] = src[4];
|
src[9] = src[6];
|
||||||
temp[5] = src[5];
|
src[6] = src[4];
|
||||||
temp[6] = src[10];
|
src[4] = src[3];
|
||||||
temp[7] = src[6];
|
src[3] = src[2];
|
||||||
temp[8] = src[7];
|
src[2] = src[8];
|
||||||
|
src[8] = tmp;
|
||||||
|
|
||||||
memcpy (src + 2, temp, 9);
|
|
||||||
src += 12;
|
src += 12;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -659,7 +670,10 @@ invalid_width:
|
|||||||
static gboolean
|
static gboolean
|
||||||
dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event)
|
dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (GST_PAD_PARENT (pad));
|
GstDvdLpcmDec *dvdlpcmdec;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
dvdlpcmdec = GST_DVDLPCMDEC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_NEWSEGMENT:
|
||||||
@ -667,32 +681,37 @@ dvdlpcmdec_sink_event (GstPad * pad, GstEvent * event)
|
|||||||
gdouble rate, arate;
|
gdouble rate, arate;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gboolean update;
|
gboolean update;
|
||||||
gint64 start, end, base;
|
gint64 start, stop, pos;
|
||||||
|
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate, &arate,
|
gst_event_parse_new_segment_full (event, &update, &rate, &arate,
|
||||||
&format, &start, &end, &base);
|
&format, &start, &stop, &pos);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdlpcmdec,
|
GST_DEBUG_OBJECT (dvdlpcmdec,
|
||||||
"new segment, format=%d, start = %" G_GINT64_FORMAT
|
"new segment, format=%d, start = %" G_GINT64_FORMAT
|
||||||
", end = %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
", stop = %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
|
||||||
format, start, end, base);
|
format, start, stop, pos);
|
||||||
|
|
||||||
|
gst_segment_set_newsegment_full (&dvdlpcmdec->segment, update,
|
||||||
|
rate, arate, format, start, stop, pos);
|
||||||
|
|
||||||
|
if (format == GST_FORMAT_TIME) {
|
||||||
dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
|
dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
|
||||||
if (format == GST_FORMAT_TIME)
|
} else {
|
||||||
dvdlpcmdec->segment_start = start;
|
dvdlpcmdec->timestamp = 0;
|
||||||
else
|
}
|
||||||
dvdlpcmdec->segment_start = 0;
|
res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdlpcmdec,
|
|
||||||
"Have new segment. Resetting timestamp. segment_start = % "
|
|
||||||
G_GINT64_FORMAT, dvdlpcmdec->segment_start);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
gst_segment_init (&dvdlpcmdec->segment, GST_FORMAT_UNDEFINED);
|
||||||
|
res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gst_pad_event_default (pad, event);
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
@ -55,7 +55,7 @@ struct _GstDvdLpcmDec {
|
|||||||
gint mute;
|
gint mute;
|
||||||
|
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
GstClockTime segment_start;
|
GstSegment segment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDvdLpcmDecClass {
|
struct _GstDvdLpcmDecClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user