[Top][All Lists]
[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!");
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10005: Implement AAC audio decoding for FLVs analogous to H264.,
Bastiaan Jacques <=