gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash server/swf/tag_loaders.cpp backend/sound_...


From: Martin Guy
Subject: [Gnash-commit] gnash server/swf/tag_loaders.cpp backend/sound_...
Date: Fri, 18 May 2007 10:25:44 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Martin Guy <martinwguy> 07/05/18 10:25:44

Modified files:
        server/swf     : tag_loaders.cpp 
        backend        : sound_handler_sdl.cpp sound_handler_gst.cpp 
        .              : ChangeLog 

Log message:
                * server/swf/tag_loaders.cpp: Rewrite of sample-reading code to 
decode
                  all linear formats in one place. 
                * backend/sound_handler_{sdl,gst}.cpp: Remove now unnecessary 
attempts
                  at decoding other linear audio formats.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.101&r2=1.102
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.56&r2=1.57
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_gst.cpp?cvsroot=gnash&r1=1.41&r2=1.42
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3263&r2=1.3264

Patches:
Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -b -r1.101 -r1.102
--- server/swf/tag_loaders.cpp  15 May 2007 14:02:21 -0000      1.101
+++ server/swf/tag_loaders.cpp  18 May 2007 10:25:43 -0000      1.102
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: tag_loaders.cpp,v 1.101 2007/05/15 14:02:21 strk Exp $ */
+/* $Id: tag_loaders.cpp,v 1.102 2007/05/18 10:25:43 martinwguy Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -71,12 +71,14 @@
 namespace gnash {
 
 // Forward declaration for functions at end of file
+//
+// Both modify "data" parameter, allocating memory for it.
 
-static void u8_expand(void* out_data_void, stream* in,
+static void u8_expand(unsigned char* &data, stream* in,
        int sample_count,  // in stereo, this is number of *pairs* of samples
        bool stereo);
 
-static void adpcm_expand(void* out_data_void, stream* in,
+static void adpcm_expand(unsigned char* &data, stream* in,
        int sample_count,  // in stereo, this is number of *pairs* of samples
        bool stereo);
 
@@ -1165,6 +1167,11 @@
 // Sound
 //
 
+// Forward declaration
+static void sound_expand(stream *in, sound_handler::format_type &format,
+       bool sample_16bit, bool stereo,
+       unsigned char* &data, unsigned &data_bytes);
+
 // Common data
 static int     s_sample_rate_table[] = { 5512, 11025, 22050, 44100 };
 
@@ -1199,9 +1206,6 @@
 
        if (handler)
        {
-           unsigned data_bytes = 0;
-           unsigned char*      data = NULL;
-
            if (! (sample_rate >= 0 && sample_rate <= 3))
            {
                IF_VERBOSE_MALFORMED_SWF(
@@ -1210,103 +1214,15 @@
                return;
            }
 
-           switch (format) {
-
-           case sound_handler::FORMAT_ADPCM:
-               // Uncompress the ADPCM before handing data to host.
-               data_bytes = sample_count * (stereo ? 4 : 2);
-               data = new unsigned char[data_bytes];
-               adpcm_expand(data, in, sample_count, stereo);
-               format = sound_handler::FORMAT_NATIVE16;
-               break;
-
-           case sound_handler::FORMAT_RAW:
-               // 8- or 16-bit mono or stereo host-endian audio
-               data_bytes = in->get_tag_end_position() - in->get_position();
-               data = new unsigned char[data_bytes];
-               // Convert to 16-bit host-endian
-               if (sample_16bit) {
-                   // FORMAT_RAW 16-bit is exactly what we want!
-                   in->read((char *)data, data_bytes);
-               } else {
-                   // Convert 8-bit signed to 16-bit range
-                   // Allocate as many shorts as there are samples
-                   int16_t *newdata = new int16_t[data_bytes];
-                   u8_expand(newdata, in, sample_count, stereo);
-
-                   // Keep new data and dispose of old
-                   unsigned char *tmp = data;
-                   data = (unsigned char *) newdata;
-                   delete [] tmp;
-               }
-               format = sound_handler::FORMAT_NATIVE16;
-               break;
+           unsigned char *data; // Expanded audio data ready for playing
+           unsigned data_bytes; // First it is the amount of data from file,
+                       // then the amount allocated at *data (it may grow)
 
-           case sound_handler::FORMAT_UNCOMPRESSED:
-               // 8- or 16-bit mono or stereo little-endian audio
                data_bytes = in->get_tag_end_position() - in->get_position();
 
-               // Convert to 16-bit host-endian.
-               if (!sample_16bit)
-               {
-                   // Convert 8-bit signed to 16-bit range
-                   // Allocate as many shorts as there are 8-bit samples
-                   int16_t *newdata = new int16_t[data_bytes];
-                   u8_expand(newdata, in, sample_count, stereo);
-                   data = (unsigned char *) newdata;
-               } else {
-                   // Read 16-bit data into buffer
-                   data = new unsigned char[data_bytes];
-                   in->read((char *)data, data_bytes);
-
-                   // Convert 16-bit little-endian data to host-endian.
-
-                   // Runtime detection of host endianness costs almost
-                   // nothing and is less of a continual maintenance headache
-                   // than compile-time detection.
-                   union u {
-                       uint16_t s;
-                       struct {
-                           uint8_t c0;
-                           uint8_t c1;
-                       } c;
-                   } u = { 0x0001 };
-
-                   switch (u.c.c0) {
-                   case 0x01:  // Little-endian host: sample is already native.
-                       break;
-                   case 0x00:  // Big-endian host
-                       // Swap sample bytes to get big-endian format.
-                       assert(data_bytes & 1 == 0);
-                       for (unsigned i = 0; i < data_bytes; i+=2)
-                       {
-                           swap(&data[i], &data[i+1]);
-                       }
-                       break;
-                   default:    // Impossible
-                       log_error(_("Host endianness not detected in 
define_sound_loader"));
-                       // Just carry on anyway...
-                   }
-               }
-               format = sound_handler::FORMAT_NATIVE16;
-               break;
-
-           case sound_handler::FORMAT_MP3:
-               // Decompressed elsewhere
-               data_bytes = in->get_tag_end_position() - in->get_position();
-               data = new unsigned char[data_bytes];
-               in->read((char *)data, data_bytes);
-               break;
-
-           case sound_handler::FORMAT_NELLYMOSER:
-               // One day...
-               break;
-
-           // This is impossible as an input but stops fussy compilers
-           // complaining about unhandled enum values.
-           case sound_handler::FORMAT_NATIVE16:
-               break;
-           }
+           // sound_expand allocates storage for data[].
+           // and modifies 3 parameters: format, data and data_bytes.
+           sound_expand(in, format, sample_16bit, stereo, data, data_bytes);
 
            int handler_id = handler->create_sound(
                data,
@@ -1368,6 +1284,13 @@
     }
 }
 
+// There is only one soundstream active per movie, so we cache the extra data
+// we need to be able to decode subsequent soundstreamblocks here.
+//
+static sound_handler::format_type stream_input_format;
+static bool stream_input_is16bit;
+static bool stream_input_stereo;
+
 // Load a SoundStreamHead(2) tag.
 void
 sound_stream_head_loader(stream* in, tag_type tag, movie_definition* m)
@@ -1406,6 +1329,8 @@
                  int(format), sample_rate, int(sample_16bit), int(stereo), 
sample_count);
     );
 
+   // Wot about reading the sample_count samples?
+
     // Ask sound_handler it to init this sound.
     int        data_bytes = 0;
 
@@ -1418,8 +1343,26 @@
        return;
     }
 
-    // Since the ADPCM is converted to NATIVE16, the format is set to that...
-    if (format == sound_handler::FORMAT_ADPCM) format = 
sound_handler::FORMAT_NATIVE16;
+    // Remember settings for decoding of subsequent blocks.
+    // "stereo" is also in the sound object, 16bit no, format get stomped.
+    stream_input_format = format;
+    stream_input_is16bit = sample_16bit;
+    stream_input_stereo = stereo;
+
+    // Tell create_sound what format it will be receiving, in case it cares
+    // at this stage.
+    switch (format) {
+    case sound_handler::FORMAT_ADPCM:
+    case sound_handler::FORMAT_RAW:
+    case sound_handler::FORMAT_UNCOMPRESSED:
+       format = sound_handler::FORMAT_NATIVE16;
+       break;
+    // Shut fussy compilers up...
+    case sound_handler::FORMAT_MP3:
+    case sound_handler::FORMAT_NELLYMOSER:
+    case sound_handler::FORMAT_NATIVE16:
+       break;
+    }
 
     int        handler_id = handler->create_sound(
        NULL,
@@ -1449,69 +1392,135 @@
 
     int handle_id = m->get_loading_sound_stream_id();
 
-    // store the data with the appropiate sound.
-    int        data_bytes = 0;
+    unsigned char *data;       // Storage is allocated by sound_expand()
+    unsigned data_bytes = in->get_tag_end_position() - in->get_position();
 
-    // @@ This is pretty awful -- lots of copying, slow reading.
-    data_bytes = in->get_tag_end_position() - in->get_position();
+    // The format in the input file is in stream_input_*
+    sound_handler::format_type format = stream_input_format;
 
-    if (data_bytes <= 0) return;
-    unsigned char *data = new unsigned char[data_bytes];
+    sound_expand(in, format,
+                stream_input_is16bit, stream_input_stereo,
+                data, data_bytes);
+    // "format" now reflects what we hand(ed) to the sound drivers.
+
+    unsigned sample_count = data_bytes;
+    if (stream_input_stereo)  sample_count /= 2;
+    if (stream_input_is16bit) sample_count /= 2;
 
+    // Fill the data on the apropiate sound, and receives the starting point
+    // for later "start playing from this frame" events.
+    long start = handler->fill_stream_data(data, data_bytes, sample_count, 
handle_id);
 
-    int format = 0;
-    bool stereo = true;
-    int sample_count = -1;
+    delete [] data;
 
-    handler->get_info(handle_id, &format, &stereo);
+    start_stream_sound_tag*    ssst = new start_stream_sound_tag();
+    ssst->read(m, handle_id, start);
+}
 
-    if (format == sound_handler::FORMAT_ADPCM)
+// sound_expand: Expand audio data to 16-bit host endian.
+//
+// This modifies three of its parameters:
+// On entry, "format" is the format of the original data. If this routine
+// expands that to 16-bit native-endian, it will also modify "format" to
+// FORMAT_NATIVE16. Otherwise it leaves it alone (MP3 and NELLYMOSER).
+//
+// Storage for "data" is allocated here, and the the "data" pointer is 
modified.
+//
+// On entry, data_bytes is the amount of sound data to be read from "in";
+// on exit it reflects the number of bytes that "data" now points to.
+static void
+sound_expand(stream *in, sound_handler::format_type &format,
+       bool sample_16bit, bool stereo,
+       unsigned char* &data, unsigned &data_bytes)
+{
+    switch (format) {
+
+    case sound_handler::FORMAT_ADPCM:
     {
        // Uncompress the ADPCM before handing data to host.
-       sample_count =  data_bytes / (stereo ? 4 : 2);
-       data_bytes = sample_count * (stereo ? 4 : 2);
-       data = new unsigned char[data_bytes];
+       unsigned sample_count = data_bytes / (stereo ? 4 : 2);
        adpcm_expand(data, in, sample_count, stereo);
        format = sound_handler::FORMAT_NATIVE16;
-    } else if (format == sound_handler::FORMAT_NATIVE16)
-    {
-       // Raw data
-       sample_count =  data_bytes / (stereo ? 4 : 2);
+       break;
+      }
+    case sound_handler::FORMAT_RAW:
+       // 8- or 16-bit mono or stereo host-endian audio
+       // Convert to 16-bit host-endian
+       if (sample_16bit) {
+           // FORMAT_RAW 16-bit is exactly what we want!
+           data = new unsigned char[data_bytes];
        in->read((char *)data, data_bytes);
     } else {
-       in->read((char *)data, data_bytes);
+           // Convert 8-bit signed to 16-bit range
+           // Allocate as many shorts as there are samples
+           unsigned sample_count = data_bytes / (stereo ? 2 : 1);
+           u8_expand(data, in, sample_count, stereo);
+       }
+       format = sound_handler::FORMAT_NATIVE16;
+       break;
 
-       // Swap bytes on behalf of the host, to make it easier for the handler.
-       // @@ I'm assuming this is a good idea?  Most sound handlers will 
prefer native endianness?
-       // I dunno why this is commented-out, but if you want to re-enable it,
-       // recode it with the same runtime endian order detection as above.
-       // Or, better, unify the two routines as there is a lot of duplicated
-       // code here.
-       /*if (format == sound_handler::FORMAT_UNCOMPRESSED && sample_16bit)
+    case sound_handler::FORMAT_UNCOMPRESSED:
+       // 8- or 16-bit mono or stereo little-endian audio
+       // Convert to 16-bit host-endian.
+       if (!sample_16bit)
        {
-#ifndef (?(*!(_TU_LITTLE_ENDIAN_ has gone. Use <boost/detail/endian.hpp>
+           // Convert 8-bit signed to 16-bit range
+           // Allocate as many shorts as there are 8-bit samples
+           unsigned sample_count = data_bytes / (stereo ? 2 : 1);
+           u8_expand(data, in, sample_count, stereo);
+       } else {
+           // Read 16-bit data into buffer
+           data = new unsigned char[data_bytes];
+           in->read((char *)data, data_bytes);
+
+           // Convert 16-bit little-endian data to host-endian.
+
+           // Runtime detection of host endianness costs almost
+           // nothing and is less of a continual maintenance headache
+           // than compile-time detection.
+           union u {
+               uint16_t s;
+               struct {
+                   uint8_t c0;
+                   uint8_t c1;
+               } c;
+           } u = { 0x0001 };
+
+           switch (u.c.c0) {
+           case 0x01:  // Little-endian host: sample is already native.
+               break;
+           case 0x00:  // Big-endian host
            // Swap sample bytes to get big-endian format.
-           for (int i = 0; i < data_bytes - 1; i += 2)
+               assert(data_bytes & 1 == 0);
+               for (unsigned i = 0; i < data_bytes; i+=2)
            {
                swap(&data[i], &data[i+1]);
            }
-#endif // not _TU_LITTLE_ENDIAN_
-
-           format = sound_handler::FORMAT_NATIVE16;
-       }*/
+               break;
+           default:    // Impossible
+               log_error(_("Host endianness not detected in 
define_sound_loader"));
+               // Just carry on anyway...
     }
+       }
+       format = sound_handler::FORMAT_NATIVE16;
+       break;
 
+    case sound_handler::FORMAT_MP3:
+       // Decompressed elsewhere
+       data = new unsigned char[data_bytes];
+       in->read((char *)data, data_bytes);
+       break;
 
-    // Fill the data on the apropiate sound, and receives the starting point
-    // for later "start playing from this frame" events.
-    long start = handler->fill_stream_data(data, data_bytes, sample_count, 
handle_id);
-
-    delete [] data;
-
-    start_stream_sound_tag*    ssst = new start_stream_sound_tag();
-    ssst->read(m, handle_id, start);
+    case sound_handler::FORMAT_NELLYMOSER:
+       // One day...
+       in->skip_bytes(data_bytes);
+       break;
 
-    // @@ who's going to delete the start_stream_sound_tag ??
+    // This is impossible as an input but stops fussy compilers
+    // complaining about unhandled enum values.
+    case sound_handler::FORMAT_NATIVE16:
+       break;
+    }
 }
 
 void
@@ -1632,7 +1641,7 @@
 //
 // Provides:
 //
-// void        adpcm_expand(void* out_data_void, stream* in,
+// void        adpcm_expand(unsigned char* &data, stream* in,
 //     int sample_count, // in stereo, this is number of *pairs* of samples
 //     bool stereo)
 //
@@ -1647,17 +1656,19 @@
 //
 // Unsigned 8-bit expansion (128 is silence)
 //
+// u8_expand allocates the memory for its "data" pointer.
+//
 
 static void u8_expand(
-       void* out_data_void,
+       unsigned char * &data,
        stream* in,
        int sample_count,       // in stereo, this is number of *pairs* of 
samples
        bool stereo)
 {
-       int16_t *out_data = (int16_t*) out_data_void;
-
        unsigned total_samples = stereo ? sample_count*2 : sample_count;
        uint8_t *in_data = new uint8_t[total_samples];
+       int16_t *out_data = new int16_t[total_samples];
+
        in->read((char *)in_data, total_samples); // Read 8-bit samples
 
        // Convert 8-bit to 16
@@ -1667,6 +1678,8 @@
                *outp++ = ((int16_t)(*inp++) - 128) * 256;
        }
        
+       data = (unsigned char *)out_data;
+
        delete [] in_data;
 }
 
@@ -1813,12 +1826,12 @@
 // out_data[]. The output buffer must have (sample_count*2)
 // bytes for mono, or (sample_count*4) bytes for stereo.
 static void adpcm_expand(
-       void* out_data_void,
+       unsigned char* &data,
        stream* in,
        int sample_count,       // in stereo, this is number of *pairs* of 
samples
        bool stereo)
 {
-       int16_t*        out_data = (int16_t*) out_data_void;
+       int16_t* out_data = new int16_t[stereo ? sample_count*2 : sample_count];
 
        // Read header.
        int     n_bits = in->read_uint(2) + 2;  // 2 to 5 bits
@@ -1874,6 +1887,8 @@
                        }
                }
        }
+
+       data = (unsigned char *)out_data;
 }
 
 } // namespace gnash

Index: backend/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -b -r1.56 -r1.57
--- backend/sound_handler_sdl.cpp       15 May 2007 10:47:50 -0000      1.56
+++ backend/sound_handler_sdl.cpp       18 May 2007 10:25:43 -0000      1.57
@@ -18,7 +18,7 @@
 // Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
 // which has been donated to the Public Domain.
 
-// $Id: sound_handler_sdl.cpp,v 1.56 2007/05/15 10:47:50 tgc Exp $
+// $Id: sound_handler_sdl.cpp,v 1.57 2007/05/18 10:25:43 martinwguy Exp $
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -91,19 +91,6 @@
 
        switch (format)
        {
-       case FORMAT_RAW:
-
-               if (data_bytes > 0) {
-                       convert_raw_data(&adjusted_data, &adjusted_size, data, 
sample_count, 1, sample_rate, stereo);
-                       if (!adjusted_data) {
-                               gnash::log_error(_("Some kind of error occurred 
with raw sound data"));
-                               return -1;
-                       }
-                       sounddata->data_size = adjusted_size;
-                       sounddata->data = (Uint8*) adjusted_data;
-               }
-               break;
-
        case FORMAT_NATIVE16:
 
                if (data_bytes > 0) {
@@ -130,15 +117,16 @@
                        return -1;
                }
                memcpy(sounddata->data, data, data_bytes);
-
                break;
+
        //case FORMAT_VORBIS:
 
+       case FORMAT_RAW:
        case FORMAT_ADPCM:
        case FORMAT_UNCOMPRESSED:
                // These should have been converted to FORMAT_NATIVE16
                gnash::log_error(_("Sound data format not properly converted"));
-               assert(0);
+               return -1;
                break;
 
        case FORMAT_NELLYMOSER:

Index: backend/sound_handler_gst.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_gst.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -b -r1.41 -r1.42
--- backend/sound_handler_gst.cpp       15 May 2007 10:47:50 -0000      1.41
+++ backend/sound_handler_gst.cpp       18 May 2007 10:25:43 -0000      1.42
@@ -20,7 +20,7 @@
 // Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
 // which has been donated to the Public Domain.
 
-/* $Id: sound_handler_gst.cpp,v 1.41 2007/05/15 10:47:50 tgc Exp $ */
+/* $Id: sound_handler_gst.cpp,v 1.42 2007/05/18 10:25:43 martinwguy Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -88,33 +88,7 @@
 
        switch (format)
        {
-       // TODO: Do we need to do the raw-data-convert? Can't Gstreamer handle 
it?
-       case FORMAT_RAW:
-/*     caps info:
-    audio/x-raw-int
-                rate: [ 1, 2147483647 ]
-            channels: [ 1, 8 ]
-            endianness: { 1234, 4321 }
-                width: 8
-                depth: [ 1, 8 ]
-                signed: { true, false }*/
-               sounddata->data = new guint8[data_bytes];
-               if (!sounddata->data) { 
-                       gnash::log_error(_("Could not allocate space for data 
in sound handler"));
-                       return -1;
-               }
-               memcpy(sounddata->data, data, data_bytes);
-               break;
-
        case FORMAT_NATIVE16:
-/*     caps info:
-    audio/x-raw-int
-                rate: [ 1, 2147483647 ]
-            channels: [ 1, 8 ]
-            endianness: { 1234, 4321 }
-                width: 16
-                depth: [ 1, 16 ]
-                signed: { true, false }*/
                sounddata->data = new guint8[data_bytes];
                if (!sounddata->data) { 
                        gnash::log_error(_("Could not allocate space for data 
in sound handler"));
@@ -134,6 +108,7 @@
 
                break;
 
+       case FORMAT_RAW:
        case FORMAT_ADPCM:
        case FORMAT_UNCOMPRESSED:
                // These should have been converted to FORMAT_NATIVE16
@@ -600,19 +575,6 @@
        gnash::log_unimpl(__PRETTY_FUNCTION__);
 }
 
-void GST_sound_handler::convert_raw_data(
-       int16_t** /*adjusted_data*/,
-       int* /*adjusted_size*/,
-       void* /*data*/,
-       int /*sample_count*/,
-       int /*sample_size*/,
-       int /*sample_rate*/,
-       bool /*stereo*/)
-{
-       gnash::log_unimpl(__PRETTY_FUNCTION__);
-}
-
-
 gnash::sound_handler*  gnash::create_sound_handler_gst()
 // Factory.
 {

Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3263
retrieving revision 1.3264
diff -u -b -r1.3263 -r1.3264
--- ChangeLog   18 May 2007 10:14:10 -0000      1.3263
+++ ChangeLog   18 May 2007 10:25:43 -0000      1.3264
@@ -21,6 +21,12 @@
        * backend/sound_handler.h: Remove old adpcm_expand() decl
        * macros/x11.m4: Two typoes "if x${a} != xfoo"
        * utilities/parser.cpp: Shut compiler up
+       * backend/sound_handler_gst.cpp, testsuite/sound_handler_test.cpp:
+         Remove never-implemented stub declaration.
+       * server/swf/tag_loaders.cpp: Rewrite of sample-reading code to decode
+         all linear formats in one place.
+       * backend/sound_handler_{sdl,gst}.cpp: Remove now unnecessary attempts
+         at decoding other linear audio formats.
 
 2007-05-17  Rob Savoye  <address@hidden>
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]