gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10005: Implement AAC audio decoding


From: Bastiaan Jacques
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10005: Implement AAC audio decoding for FLVs analogous to H264.
Date: Mon, 20 Oct 2008 01:23:53 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10005
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Mon 2008-10-20 01:23:53 +0200
message:
  Implement AAC audio decoding for FLVs analogous to H264.
modified:
  libmedia/FLVParser.cpp
  libmedia/FLVParser.h
  libmedia/MediaParser.h
  libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
  libmedia/gst/AudioDecoderGst.cpp
=== modified file 'libmedia/FLVParser.cpp'
--- a/libmedia/FLVParser.cpp    2008-10-19 19:05:30 +0000
+++ b/libmedia/FLVParser.cpp    2008-10-19 23:23:53 +0000
@@ -328,17 +328,19 @@
                        }
                }
 
+               boost::uint8_t codec = (tag[11] & 0xf0) >> 4;
+
+               bool header = false;
+
+               if (codec == AUDIO_CODEC_AAC) {
+                       boost::uint8_t packettype = _stream->read_byte();
+                       header = (packettype == 0);
+               }
+
                std::auto_ptr<EncodedAudioFrame> frame = 
readAudioFrame(bodyLength-1, timestamp);
-               if ( ! frame.get() ) { log_error("could not read audio 
frame?"); }
-               else
-               {
-                       // Release the stream lock 
-                       // *before* pushing the frame as that 
-                       // might block us waiting for buffers flush
-                       // the _qMutex...
-                       // We've done using the stream for this tag parsing 
anyway
-                       streamLock.unlock();
-                       pushEncodedAudioFrame(frame);
+               if ( ! frame.get() ) {
+                       log_error("could not read audio frame?");
+                       return true;
                }
 
                // If this is the first audioframe no info about the
@@ -355,9 +357,28 @@
                        if (samplesize == 0) samplesize = 1;
                        else samplesize = 2;
 
-                       _audioInfo.reset( new AudioInfo((tag[11] & 0xf0) >> 4, 
samplerate, samplesize, (tag[11] & 0x01) >> 0, 0, FLASH) );
+                       _audioInfo.reset( new AudioInfo(codec, samplerate, 
samplesize, (tag[11] & 0x01) >> 0, 0, FLASH) );
+                       if (header) {
+                               boost::uint8_t* newbuf = new 
boost::uint8_t[frame->dataSize];
+                               memcpy(newbuf, frame->data.get(), 
frame->dataSize);
+
+                               _audioInfo->extra.reset( 
+                                       new ExtraAudioInfoFlv(newbuf, 
frame->dataSize)
+                               );
+
+                               // The FAAD decoder will reject us if we pass 
the header buffer.
+                               // It will receive the header via the extra 
audio info anyway.
+                               return true;
+                       }
                }
 
+               // Release the stream lock 
+               // *before* pushing the frame as that 
+               // might block us waiting for buffers flush
+               // the _qMutex...
+               // We've done using the stream for this tag parsing anyway
+               streamLock.unlock();
+               pushEncodedAudioFrame(frame);
        }
        else if (tag[0] == FLV_VIDEO_TAG)
        {
@@ -423,9 +444,9 @@
                                _videoInfo->extra.reset( 
                                        new ExtraVideoInfoFlv(newbuf, 
frame->dataSize())
                                );
+                               // Don't bother emitting the header buffer.
+                               return true;
                        }
-
-                       // Create the videoinfo
                }
 
                // Release the stream lock 

=== modified file 'libmedia/FLVParser.h'
--- a/libmedia/FLVParser.h      2008-10-19 19:05:30 +0000
+++ b/libmedia/FLVParser.h      2008-10-19 23:23:53 +0000
@@ -57,6 +57,19 @@
         size_t size;
 };
 
+class ExtraAudioInfoFlv : public AudioInfo::ExtraInfo
+{
+public:
+        ExtraAudioInfoFlv(boost::uint8_t* extradata, size_t datasize)
+                :
+                data(extradata),
+                size(datasize)
+        {
+        }
+        boost::scoped_array<boost::uint8_t> data;
+        size_t size;
+};
+
 /// The FLVParser class parses FLV streams
 class DSOEXPORT FLVParser : public MediaParser
 {

=== modified file 'libmedia/MediaParser.h'
--- a/libmedia/MediaParser.h    2008-10-19 19:05:30 +0000
+++ b/libmedia/MediaParser.h    2008-10-19 23:23:53 +0000
@@ -99,7 +99,7 @@
 /// Audio codec ids as defined in flash
 enum audioCodecType
 {
-       /// Raw format.  Useful for 8-bit sounds???
+       /// "Raw" format: linear PCM.
        AUDIO_CODEC_RAW = 0,    
 
        /// ADPCM format, flash's ADPCM is a bit different for normal ADPCM
@@ -115,7 +115,9 @@
        AUDIO_CODEC_NELLYMOSER_8HZ_MONO = 5,
 
        /// Proprietary simple format
-       AUDIO_CODEC_NELLYMOSER = 6
+       AUDIO_CODEC_NELLYMOSER = 6,
+
+       AUDIO_CODEC_AAC = 10
 };
 
 std::ostream& operator<< (std::ostream& os, const audioCodecType& t);

=== modified file 'libmedia/ffmpeg/AudioDecoderFfmpeg.cpp'
--- a/libmedia/ffmpeg/AudioDecoderFfmpeg.cpp    2008-10-10 14:49:00 +0000
+++ b/libmedia/ffmpeg/AudioDecoderFfmpeg.cpp    2008-10-19 23:23:53 +0000
@@ -20,6 +20,7 @@
 
 #include "AudioDecoderFfmpeg.h"
 #include "MediaParserFfmpeg.h" // for ExtraAudioInfoFfmpeg
+#include "FLVParser.h"
 
 #include <cmath> // for std::ceil
 #include <algorithm> // for std::copy, std::max
@@ -150,6 +151,9 @@
                        case AUDIO_CODEC_MP3:
                                codec_id = CODEC_ID_MP3;
                                break;
+                       case AUDIO_CODEC_AAC:
+                               codec_id = CODEC_ID_AAC;
+                               break;
 #if 0
             // Enable this to use ffmpeg for nellymoser
             // decoding (fails in decodeFrame, but probably not Ffmpeg's
@@ -191,10 +195,15 @@
 
        if ( info.extra.get() )
        {
-               assert(dynamic_cast<ExtraAudioInfoFfmpeg*>(info.extra.get()));
-               const ExtraAudioInfoFfmpeg& ei = 
static_cast<ExtraAudioInfoFfmpeg&>(*info.extra);
-               _audioCodecCtx->extradata = ei.data;
-               _audioCodecCtx->extradata_size = ei.dataSize;
+               if (dynamic_cast<ExtraAudioInfoFfmpeg*>(info.extra.get())) {
+                       const ExtraAudioInfoFfmpeg& ei = 
static_cast<ExtraAudioInfoFfmpeg&>(*info.extra);
+                       _audioCodecCtx->extradata = ei.data;
+                       _audioCodecCtx->extradata_size = ei.dataSize;
+               } else if (dynamic_cast<ExtraAudioInfoFlv*>(info.extra.get())) {
+                       ExtraAudioInfoFlv* extra = 
static_cast<ExtraAudioInfoFlv*>(info.extra.get());
+                       _audioCodecCtx->extradata = extra->data.get();
+                       _audioCodecCtx->extradata_size = extra->size;
+               }
        }
 
        int ret = avcodec_open(_audioCodecCtx, _audioCodec);

=== modified file 'libmedia/gst/AudioDecoderGst.cpp'
--- a/libmedia/gst/AudioDecoderGst.cpp  2008-10-07 19:51:29 +0000
+++ b/libmedia/gst/AudioDecoderGst.cpp  2008-10-19 23:23:53 +0000
@@ -26,6 +26,7 @@
 #include "MediaParser.h"
 #include "MediaParserGst.h"
 #include "GstUtil.h"
+#include "FLVParser.h"
 
 namespace gnash {
 namespace media {
@@ -75,6 +76,29 @@
         return;
     }
 
+    if (info.type == FLASH && info.codec == AUDIO_CODEC_AAC)
+    {
+        srccaps = gst_caps_new_simple ("audio/mpeg",
+            "mpegversion", G_TYPE_INT, 4,
+            "rate", G_TYPE_INT, 44100,
+            "channels", G_TYPE_INT, 2, 
+            NULL);
+
+        ExtraAudioInfoFlv* extra = 
dynamic_cast<ExtraAudioInfoFlv*>(info.extra.get());
+        if (extra) {
+            GstBuffer* buf = gst_buffer_new_and_alloc(extra->size);
+            memcpy(GST_BUFFER_DATA(buf), extra->data.get(), extra->size);
+            gst_caps_set_simple (srccaps, "codec_data", GST_TYPE_BUFFER, buf, 
NULL);
+
+        } else {
+            log_error(_("Creating AAC decoder without extra data. This will 
probably fail!"));
+        }
+
+        setup(srccaps);
+        return;
+    }
+
+
     if (info.type == FLASH) {
         throw MediaException("AudioDecoderGst: cannot handle this codec!");
     }


reply via email to

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