diff options
Diffstat (limited to 'media/libstagefright/mpeg2ts')
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 17 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.h | 1 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ESQueue.cpp | 63 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ESQueue.h | 2 |
4 files changed, 83 insertions, 0 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 27c7bf4..9faa6bc 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -131,6 +131,8 @@ private: sp<AnotherPacketSource> mSource; bool mPayloadStarted; + uint64_t mPrevPTS; + ElementaryStreamQueue *mQueue; status_t flush(); @@ -458,6 +460,7 @@ ATSParser::Stream::Stream( mPCR_PID(PCR_PID), mExpectedContinuityCounter(-1), mPayloadStarted(false), + mPrevPTS(0), mQueue(NULL) { switch (mStreamType) { case STREAMTYPE_H264: @@ -486,6 +489,11 @@ ATSParser::Stream::Stream( ElementaryStreamQueue::MPEG4_VIDEO); break; + case STREAMTYPE_PCM_AUDIO: + mQueue = new ElementaryStreamQueue( + ElementaryStreamQueue::PCM_AUDIO); + break; + default: break; } @@ -583,6 +591,7 @@ bool ATSParser::Stream::isAudio() const { case STREAMTYPE_MPEG1_AUDIO: case STREAMTYPE_MPEG2_AUDIO: case STREAMTYPE_MPEG2_AUDIO_ADTS: + case STREAMTYPE_PCM_AUDIO: return true; default: @@ -827,6 +836,14 @@ status_t ATSParser::Stream::flush() { void ATSParser::Stream::onPayloadData( unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS, const uint8_t *data, size_t size) { +#if 0 + ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld", + mStreamType, + PTS, + (int64_t)PTS - mPrevPTS); + mPrevPTS = PTS; +#endif + ALOGV("onPayloadData mStreamType=0x%02x", mStreamType); int64_t timeUs = 0ll; // no presentation timestamp available. diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 5ccbab7..46edc45 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -87,6 +87,7 @@ struct ATSParser : public RefBase { STREAMTYPE_MPEG2_AUDIO_ADTS = 0x0f, STREAMTYPE_MPEG4_VIDEO = 0x10, STREAMTYPE_H264 = 0x1b, + STREAMTYPE_PCM_AUDIO = 0x83, }; protected: diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index e58e9bf..82fb637 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -31,6 +31,8 @@ #include "include/avc_utils.h" +#include <netinet/in.h> + namespace android { ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags) @@ -248,6 +250,11 @@ status_t ElementaryStreamQueue::appendData( break; } + case PCM_AUDIO: + { + break; + } + default: TRESPASS(); break; @@ -324,12 +331,68 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() { return dequeueAccessUnitMPEGVideo(); case MPEG4_VIDEO: return dequeueAccessUnitMPEG4Video(); + case PCM_AUDIO: + return dequeueAccessUnitPCMAudio(); default: CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO); return dequeueAccessUnitMPEGAudio(); } } +sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() { + if (mBuffer->size() < 4) { + return NULL; + } + + ABitReader bits(mBuffer->data(), 4); + CHECK_EQ(bits.getBits(8), 0xa0); + unsigned numAUs = bits.getBits(8); + bits.skipBits(8); + unsigned quantization_word_length = bits.getBits(2); + unsigned audio_sampling_frequency = bits.getBits(3); + unsigned num_channels = bits.getBits(3); + + CHECK_EQ(audio_sampling_frequency, 2); // 48kHz + CHECK_EQ(num_channels, 1u); // stereo! + + if (mFormat == NULL) { + mFormat = new MetaData; + mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); + mFormat->setInt32(kKeyChannelCount, 2); + mFormat->setInt32(kKeySampleRate, 48000); + } + + static const size_t kFramesPerAU = 80; + size_t frameSize = 2 /* numChannels */ * sizeof(int16_t); + + size_t payloadSize = numAUs * frameSize * kFramesPerAU; + + if (mBuffer->size() < 4 + payloadSize) { + return NULL; + } + + sp<ABuffer> accessUnit = new ABuffer(payloadSize); + memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize); + + int64_t timeUs = fetchTimestamp(payloadSize + 4); + CHECK_GE(timeUs, 0ll); + accessUnit->meta()->setInt64("timeUs", timeUs); + + int16_t *ptr = (int16_t *)accessUnit->data(); + for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) { + ptr[i] = ntohs(ptr[i]); + } + + memmove( + mBuffer->data(), + mBuffer->data() + 4 + payloadSize, + mBuffer->size() - 4 - payloadSize); + + mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize); + + return accessUnit; +} + sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { int64_t timeUs; diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h index 72aa2e7..66a8087 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.h +++ b/media/libstagefright/mpeg2ts/ESQueue.h @@ -35,6 +35,7 @@ struct ElementaryStreamQueue { MPEG_AUDIO, MPEG_VIDEO, MPEG4_VIDEO, + PCM_AUDIO, }; enum Flags { @@ -69,6 +70,7 @@ private: sp<ABuffer> dequeueAccessUnitMPEGAudio(); sp<ABuffer> dequeueAccessUnitMPEGVideo(); sp<ABuffer> dequeueAccessUnitMPEG4Video(); + sp<ABuffer> dequeueAccessUnitPCMAudio(); // consume a logical (compressed) access unit of size "size", // returns its timestamp in us (or -1 if no time information). |