From ce3fd0ba2bbac184e1405d35c0d5120cfb3147b9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 13 Jun 2002 22:30:15 +0000 Subject: [PATCH] Add audio decoding to the dv decoder. Original commit message from CVS: Add audio decoding to the dv decoder. --- ext/dv/gstdvdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ ext/dv/gstdvdec.h | 13 +++++++++---- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index 580b83b..3ac150b 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -208,6 +208,8 @@ gst_dvdec_class_init (GstDVDecClass *klass) static void gst_dvdec_init(GstDVDec *dvdec) { + gint i; + dvdec->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_temp), "sink"); gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->sinkpad); @@ -222,6 +224,11 @@ gst_dvdec_init(GstDVDec *dvdec) dvdec->decoder = dv_decoder_new (0, 0, 0); dvdec->decoder->quality = DV_QUALITY_BEST; dvdec->pool = NULL; + dvdec->length = 0; + + for (i = 0; i <4; i++) { + dvdec->audio_buffers[i] = (gint16 *)g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16)); + } } static gboolean @@ -272,6 +279,8 @@ gst_dvdec_loop (GstElement *element) gboolean PAL; gint height; guint32 length, got_bytes; + gint16 *a_ptr; + gint i, j; dvdec = GST_DVDEC (element); @@ -288,6 +297,11 @@ gst_dvdec_loop (GstElement *element) height = (PAL ? PAL_HEIGHT : NTSC_HEIGHT); length = (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) { @@ -342,6 +356,39 @@ gst_dvdec_loop (GstElement *element) return; } } + + /* if we did not negotiate yet, do it now */ + if (!GST_PAD_CAPS (dvdec->audiosrcpad)) { + gst_pad_try_set_caps (dvdec->audiosrcpad, + GST_CAPS_NEW ( + "dvdec_audio_caps", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "rate", GST_PROPS_INT (dvdec->decoder->audio->frequency), + "law", GST_PROPS_INT (0), + "depth", GST_PROPS_INT (16), + "width", GST_PROPS_INT (16), + "signed", GST_PROPS_BOOLEAN (TRUE), + "channels", GST_PROPS_INT (dvdec->decoder->audio->num_channels), + "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN) + )); + } + + dv_decode_full_audio (dvdec->decoder, GST_BUFFER_DATA (buf), dvdec->audio_buffers); + + outbuf = gst_buffer_new (); + GST_BUFFER_SIZE (outbuf) = dvdec->decoder->audio->samples_this_frame * sizeof (gint16) * dvdec->decoder->audio->num_channels; + GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf)); + + a_ptr = (gint16 *) GST_BUFFER_DATA (outbuf); + + for (i = 0; i < dvdec->decoder->audio->samples_this_frame; i++) { + for (j = 0; j < dvdec->decoder->audio->num_channels; j++) { + *(a_ptr++) = dvdec->audio_buffers[j][i]; + } + } + gst_pad_push (dvdec->audiosrcpad, outbuf); + /* try to grab a pool */ if (!dvdec->pool) { dvdec->pool = gst_pad_get_bufferpool (dvdec->videosrcpad); @@ -359,6 +406,7 @@ gst_dvdec_loop (GstElement *element) GST_BUFFER_SIZE (outbuf) = (720 * height) * dvdec->bpp; GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf)); } + outframe = GST_BUFFER_DATA (outbuf); diff --git a/ext/dv/gstdvdec.h b/ext/dv/gstdvdec.h index 53aa3ca..dc62b2d 100644 --- a/ext/dv/gstdvdec.h +++ b/ext/dv/gstdvdec.h @@ -41,16 +41,21 @@ typedef struct _GstDVDec GstDVDec; * an Element or even an Object. */ struct _GstDVDec { - GstElement element; + GstElement element; /* We need to keep track of our pads, so we do so here. */ - GstPad *sinkpad,*videosrcpad,*audiosrcpad; + GstPad *sinkpad, + *videosrcpad, + *audiosrcpad; - dv_decoder_t *decoder; + dv_decoder_t *decoder; GstByteStream *bs; GstBufferPool *pool; dv_color_space_t space; - gint bpp; + gint bpp; + gint length; + + gint16 *audio_buffers[4]; }; /* The other half of the object is its class. The class also derives from -- 2.7.4