Loading media/libstagefright/wifi-display/source/Converter.cpp +145 −9 Original line number Original line Diff line number Diff line Loading @@ -38,12 +38,14 @@ namespace android { Converter::Converter( Converter::Converter( const sp<AMessage> ¬ify, const sp<AMessage> ¬ify, const sp<ALooper> &codecLooper, const sp<ALooper> &codecLooper, const sp<AMessage> &format) const sp<AMessage> &format, bool usePCMAudio) : mInitCheck(NO_INIT), : mInitCheck(NO_INIT), mNotify(notify), mNotify(notify), mCodecLooper(codecLooper), mCodecLooper(codecLooper), mInputFormat(format), mInputFormat(format), mIsVideo(false), mIsVideo(false), mIsPCMAudio(usePCMAudio), mDoMoreWorkPending(false) mDoMoreWorkPending(false) #if ENABLE_SILENCE_DETECTION #if ENABLE_SILENCE_DETECTION ,mFirstSilentFrameUs(-1ll) ,mFirstSilentFrameUs(-1ll) Loading @@ -57,6 +59,8 @@ Converter::Converter( mIsVideo = true; mIsVideo = true; } } CHECK(!usePCMAudio || !mIsVideo); mInitCheck = initEncoder(); mInitCheck = initEncoder(); if (mInitCheck != OK) { if (mInitCheck != OK) { Loading Loading @@ -109,7 +113,11 @@ status_t Converter::initEncoder() { AString outputMIME; AString outputMIME; bool isAudio = false; bool isAudio = false; if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { if (mIsPCMAudio) { outputMIME = MEDIA_MIMETYPE_AUDIO_RAW; } else { outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; } isAudio = true; isAudio = true; } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; Loading @@ -117,14 +125,21 @@ status_t Converter::initEncoder() { TRESPASS(); TRESPASS(); } } if (!mIsPCMAudio) { mEncoder = MediaCodec::CreateByType( mEncoder = MediaCodec::CreateByType( mCodecLooper, outputMIME.c_str(), true /* encoder */); mCodecLooper, outputMIME.c_str(), true /* encoder */); if (mEncoder == NULL) { if (mEncoder == NULL) { return ERROR_UNSUPPORTED; return ERROR_UNSUPPORTED; } } } mOutputFormat = mInputFormat->dup(); mOutputFormat = mInputFormat->dup(); if (mIsPCMAudio) { return OK; } mOutputFormat->setString("mime", outputMIME.c_str()); mOutputFormat->setString("mime", outputMIME.c_str()); int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); Loading Loading @@ -197,7 +212,7 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { int32_t what; int32_t what; CHECK(msg->findInt32("what", &what)); CHECK(msg->findInt32("what", &what)); if (mEncoder == NULL) { if (!mIsPCMAudio && mEncoder == NULL) { ALOGV("got msg '%s' after encoder shutdown.", ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str()); msg->debugString().c_str()); Loading Loading @@ -317,8 +332,11 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { case kWhatShutdown: case kWhatShutdown: { { ALOGI("shutting down encoder"); ALOGI("shutting down encoder"); if (mEncoder != NULL) { mEncoder->release(); mEncoder->release(); mEncoder.clear(); mEncoder.clear(); } AString mime; AString mime; CHECK(mInputFormat->findString("mime", &mime)); CHECK(mInputFormat->findString("mime", &mime)); Loading @@ -332,6 +350,11 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { } } void Converter::scheduleDoMoreWork() { void Converter::scheduleDoMoreWork() { if (mIsPCMAudio) { // There's no encoder involved in this case. return; } if (mDoMoreWorkPending) { if (mDoMoreWorkPending) { return; return; } } Loading @@ -350,7 +373,120 @@ void Converter::scheduleDoMoreWork() { #endif #endif } } status_t Converter::feedRawAudioInputBuffers() { // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each // and add a 4 byte header according to the wifi display specs. while (!mInputBufferQueue.empty()) { sp<ABuffer> buffer = *mInputBufferQueue.begin(); mInputBufferQueue.erase(mInputBufferQueue.begin()); int16_t *ptr = (int16_t *)buffer->data(); int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); while (ptr < stop) { *ptr = htons(*ptr); ++ptr; } static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo static const size_t kFramesPerAU = 80; static const size_t kNumAUsPerPESPacket = 6; if (mPartialAudioAU != NULL) { size_t bytesMissingForFullAU = kNumAUsPerPESPacket * kFramesPerAU * kFrameSize - mPartialAudioAU->size() + 4; size_t copy = buffer->size(); if(copy > bytesMissingForFullAU) { copy = bytesMissingForFullAU; } memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), buffer->data(), copy); mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); buffer->setRange(buffer->offset() + copy, buffer->size() - copy); int64_t timeUs; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); timeUs += copyUs; buffer->meta()->setInt64("timeUs", timeUs); if (bytesMissingForFullAU == copy) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setBuffer("accessUnit", mPartialAudioAU); notify->post(); mPartialAudioAU.clear(); } } while (buffer->size() > 0) { sp<ABuffer> partialAudioAU = new ABuffer( 4 + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); uint8_t *ptr = partialAudioAU->data(); ptr[0] = 0xa0; // 10100000b ptr[1] = kNumAUsPerPESPacket; ptr[2] = 0; // reserved, audio _emphasis_flag = 0 static const unsigned kQuantizationWordLength = 0; // 16-bit static const unsigned kAudioSamplingFrequency = 2; // 48Khz static const unsigned kNumberOfAudioChannels = 1; // stereo ptr[3] = (kQuantizationWordLength << 6) | (kAudioSamplingFrequency << 3) | kNumberOfAudioChannels; size_t copy = buffer->size(); if (copy > partialAudioAU->size() - 4) { copy = partialAudioAU->size() - 4; } memcpy(&ptr[4], buffer->data(), copy); partialAudioAU->setRange(0, 4 + copy); buffer->setRange(buffer->offset() + copy, buffer->size() - copy); int64_t timeUs; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); partialAudioAU->meta()->setInt64("timeUs", timeUs); int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); timeUs += copyUs; buffer->meta()->setInt64("timeUs", timeUs); if (copy == partialAudioAU->size() - 4) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setBuffer("accessUnit", partialAudioAU); notify->post(); partialAudioAU.clear(); continue; } mPartialAudioAU = partialAudioAU; } } return OK; } status_t Converter::feedEncoderInputBuffers() { status_t Converter::feedEncoderInputBuffers() { if (mIsPCMAudio) { return feedRawAudioInputBuffers(); } while (!mInputBufferQueue.empty() while (!mInputBufferQueue.empty() && !mAvailEncoderInputIndices.empty()) { && !mAvailEncoderInputIndices.empty()) { sp<ABuffer> buffer = *mInputBufferQueue.begin(); sp<ABuffer> buffer = *mInputBufferQueue.begin(); Loading media/libstagefright/wifi-display/source/Converter.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ #define CONVERTER_H_ #define CONVERTER_H_ #include "WifiDisplaySource.h" #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AHandler.h> namespace android { namespace android { Loading @@ -34,7 +36,8 @@ struct Converter : public AHandler { Converter( Converter( const sp<AMessage> ¬ify, const sp<AMessage> ¬ify, const sp<ALooper> &codecLooper, const sp<ALooper> &codecLooper, const sp<AMessage> &format); const sp<AMessage> &format, bool usePCMAudio); status_t initCheck() const; status_t initCheck() const; Loading Loading @@ -73,6 +76,7 @@ private: sp<ALooper> mCodecLooper; sp<ALooper> mCodecLooper; sp<AMessage> mInputFormat; sp<AMessage> mInputFormat; bool mIsVideo; bool mIsVideo; bool mIsPCMAudio; sp<AMessage> mOutputFormat; sp<AMessage> mOutputFormat; sp<MediaCodec> mEncoder; sp<MediaCodec> mEncoder; Loading @@ -92,6 +96,8 @@ private: bool mInSilentMode; bool mInSilentMode; #endif #endif sp<ABuffer> mPartialAudioAU; status_t initEncoder(); status_t initEncoder(); status_t feedEncoderInputBuffers(); status_t feedEncoderInputBuffers(); Loading @@ -101,6 +107,11 @@ private: void notifyError(status_t err); void notifyError(status_t err); // Packetizes raw PCM audio data available in mInputBufferQueue // into a format suitable for transport stream inclusion and // notifies the observer. status_t feedRawAudioInputBuffers(); static bool IsSilence(const sp<ABuffer> &accessUnit); static bool IsSilence(const sp<ABuffer> &accessUnit); DISALLOW_EVIL_CONSTRUCTORS(Converter); DISALLOW_EVIL_CONSTRUCTORS(Converter); Loading media/libstagefright/wifi-display/source/PlaybackSession.cpp +14 −10 Original line number Original line Diff line number Diff line Loading @@ -312,10 +312,11 @@ WifiDisplaySource::PlaybackSession::PlaybackSession( status_t WifiDisplaySource::PlaybackSession::init( status_t WifiDisplaySource::PlaybackSession::init( const char *clientIP, int32_t clientRtp, int32_t clientRtcp, const char *clientIP, int32_t clientRtp, int32_t clientRtcp, TransportMode transportMode) { TransportMode transportMode, bool usePCMAudio) { mClientIP = clientIP; mClientIP = clientIP; status_t err = setupPacketizer(); status_t err = setupPacketizer(usePCMAudio); if (err != OK) { if (err != OK) { return err; return err; Loading Loading @@ -823,7 +824,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( } } } } status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { status_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) { mPacketizer = new TSPacketizer; mPacketizer = new TSPacketizer; status_t err = addVideoSource(); status_t err = addVideoSource(); Loading @@ -832,12 +833,15 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { return err; return err; } } return addAudioSource(); return addAudioSource(usePCMAudio); } } status_t WifiDisplaySource::PlaybackSession::addSource( status_t WifiDisplaySource::PlaybackSession::addSource( bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, size_t *numInputBuffers) { bool usePCMAudio, size_t *numInputBuffers) { CHECK(!usePCMAudio || !isVideo); CHECK(!isRepeaterSource || isVideo); sp<ALooper> pullLooper = new ALooper; sp<ALooper> pullLooper = new ALooper; pullLooper->setName("pull_looper"); pullLooper->setName("pull_looper"); Loading Loading @@ -875,7 +879,7 @@ status_t WifiDisplaySource::PlaybackSession::addSource( notify->setSize("trackIndex", trackIndex); notify->setSize("trackIndex", trackIndex); sp<Converter> converter = sp<Converter> converter = new Converter(notify, codecLooper, format); new Converter(notify, codecLooper, format, usePCMAudio); if (converter->initCheck() != OK) { if (converter->initCheck() != OK) { return converter->initCheck(); return converter->initCheck(); Loading Loading @@ -928,12 +932,12 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource() { size_t numInputBuffers; size_t numInputBuffers; status_t err = addSource( status_t err = addSource( true /* isVideo */, videoSource, true /* isRepeaterSource */, true /* isVideo */, videoSource, true /* isRepeaterSource */, &numInputBuffers); false /* usePCMAudio */, &numInputBuffers); #else #else size_t numInputBuffers; size_t numInputBuffers; status_t err = addSource( status_t err = addSource( true /* isVideo */, source, false /* isRepeaterSource */, true /* isVideo */, source, false /* isRepeaterSource */, &numInputBuffers); false /* usePCMAudio */, &numInputBuffers); #endif #endif if (err != OK) { if (err != OK) { Loading @@ -948,7 +952,7 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource() { return OK; return OK; } } status_t WifiDisplaySource::PlaybackSession::addAudioSource() { status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) { sp<AudioSource> audioSource = new AudioSource( sp<AudioSource> audioSource = new AudioSource( AUDIO_SOURCE_REMOTE_SUBMIX, AUDIO_SOURCE_REMOTE_SUBMIX, 48000 /* sampleRate */, 48000 /* sampleRate */, Loading @@ -957,7 +961,7 @@ status_t WifiDisplaySource::PlaybackSession::addAudioSource() { if (audioSource->initCheck() == OK) { if (audioSource->initCheck() == OK) { return addSource( return addSource( false /* isVideo */, audioSource, false /* isRepeaterSource */, false /* isVideo */, audioSource, false /* isRepeaterSource */, NULL /* numInputBuffers */); usePCMAudio, NULL /* numInputBuffers */); } } ALOGW("Unable to instantiate audio source"); ALOGW("Unable to instantiate audio source"); Loading media/libstagefright/wifi-display/source/PlaybackSession.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,8 @@ struct WifiDisplaySource::PlaybackSession : public AHandler { }; }; status_t init( status_t init( const char *clientIP, int32_t clientRtp, int32_t clientRtcp, const char *clientIP, int32_t clientRtp, int32_t clientRtcp, TransportMode transportMode); TransportMode transportMode, bool usePCMAudio); void destroyAsync(); void destroyAsync(); Loading Loading @@ -180,16 +181,17 @@ private: void addSDES(const sp<ABuffer> &buffer); void addSDES(const sp<ABuffer> &buffer); static uint64_t GetNowNTP(); static uint64_t GetNowNTP(); status_t setupPacketizer(); status_t setupPacketizer(bool usePCMAudio); status_t addSource( status_t addSource( bool isVideo, bool isVideo, const sp<MediaSource> &source, const sp<MediaSource> &source, bool isRepeaterSource, bool isRepeaterSource, bool usePCMAudio, size_t *numInputBuffers); size_t *numInputBuffers); status_t addVideoSource(); status_t addVideoSource(); status_t addAudioSource(); status_t addAudioSource(bool usePCMAudio); ssize_t appendTSData( ssize_t appendTSData( const void *data, size_t size, bool timeDiscontinuity, bool flush); const void *data, size_t size, bool timeDiscontinuity, bool flush); Loading media/libstagefright/wifi-display/source/TSPacketizer.cpp +10 −1 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct TSPacketizer::Track : public RefBase { bool isVideo() const; bool isVideo() const; bool isH264() const; bool isH264() const; bool isAAC() const; bool lacksADTSHeader() const; bool lacksADTSHeader() const; sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; Loading Loading @@ -139,6 +140,10 @@ bool TSPacketizer::Track::isH264() const { return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); } } bool TSPacketizer::Track::isAAC() const { return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC); } bool TSPacketizer::Track::lacksADTSHeader() const { bool TSPacketizer::Track::lacksADTSHeader() const { return mAudioLacksATDSHeaders; return mAudioLacksATDSHeaders; } } Loading Loading @@ -247,6 +252,10 @@ ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) { streamType = 0x0f; streamType = 0x0f; streamIDStart = 0xc0; streamIDStart = 0xc0; streamIDStop = 0xdf; streamIDStop = 0xdf; } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { streamType = 0x83; streamIDStart = 0xbd; streamIDStop = 0xbd; } else { } else { return ERROR_UNSUPPORTED; return ERROR_UNSUPPORTED; } } Loading Loading @@ -298,7 +307,7 @@ status_t TSPacketizer::packetize( && IsIDR(accessUnit)) { && IsIDR(accessUnit)) { // prepend codec specific data, i.e. SPS and PPS. // prepend codec specific data, i.e. SPS and PPS. accessUnit = track->prependCSD(accessUnit); accessUnit = track->prependCSD(accessUnit); } else if (track->isAudio() && track->lacksADTSHeader()) { } else if (track->isAAC() && track->lacksADTSHeader()) { CHECK(!(flags & IS_ENCRYPTED)); CHECK(!(flags & IS_ENCRYPTED)); accessUnit = track->prependADTSHeader(accessUnit); accessUnit = track->prependADTSHeader(accessUnit); } } Loading Loading
media/libstagefright/wifi-display/source/Converter.cpp +145 −9 Original line number Original line Diff line number Diff line Loading @@ -38,12 +38,14 @@ namespace android { Converter::Converter( Converter::Converter( const sp<AMessage> ¬ify, const sp<AMessage> ¬ify, const sp<ALooper> &codecLooper, const sp<ALooper> &codecLooper, const sp<AMessage> &format) const sp<AMessage> &format, bool usePCMAudio) : mInitCheck(NO_INIT), : mInitCheck(NO_INIT), mNotify(notify), mNotify(notify), mCodecLooper(codecLooper), mCodecLooper(codecLooper), mInputFormat(format), mInputFormat(format), mIsVideo(false), mIsVideo(false), mIsPCMAudio(usePCMAudio), mDoMoreWorkPending(false) mDoMoreWorkPending(false) #if ENABLE_SILENCE_DETECTION #if ENABLE_SILENCE_DETECTION ,mFirstSilentFrameUs(-1ll) ,mFirstSilentFrameUs(-1ll) Loading @@ -57,6 +59,8 @@ Converter::Converter( mIsVideo = true; mIsVideo = true; } } CHECK(!usePCMAudio || !mIsVideo); mInitCheck = initEncoder(); mInitCheck = initEncoder(); if (mInitCheck != OK) { if (mInitCheck != OK) { Loading Loading @@ -109,7 +113,11 @@ status_t Converter::initEncoder() { AString outputMIME; AString outputMIME; bool isAudio = false; bool isAudio = false; if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { if (mIsPCMAudio) { outputMIME = MEDIA_MIMETYPE_AUDIO_RAW; } else { outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; } isAudio = true; isAudio = true; } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; Loading @@ -117,14 +125,21 @@ status_t Converter::initEncoder() { TRESPASS(); TRESPASS(); } } if (!mIsPCMAudio) { mEncoder = MediaCodec::CreateByType( mEncoder = MediaCodec::CreateByType( mCodecLooper, outputMIME.c_str(), true /* encoder */); mCodecLooper, outputMIME.c_str(), true /* encoder */); if (mEncoder == NULL) { if (mEncoder == NULL) { return ERROR_UNSUPPORTED; return ERROR_UNSUPPORTED; } } } mOutputFormat = mInputFormat->dup(); mOutputFormat = mInputFormat->dup(); if (mIsPCMAudio) { return OK; } mOutputFormat->setString("mime", outputMIME.c_str()); mOutputFormat->setString("mime", outputMIME.c_str()); int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); Loading Loading @@ -197,7 +212,7 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { int32_t what; int32_t what; CHECK(msg->findInt32("what", &what)); CHECK(msg->findInt32("what", &what)); if (mEncoder == NULL) { if (!mIsPCMAudio && mEncoder == NULL) { ALOGV("got msg '%s' after encoder shutdown.", ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str()); msg->debugString().c_str()); Loading Loading @@ -317,8 +332,11 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { case kWhatShutdown: case kWhatShutdown: { { ALOGI("shutting down encoder"); ALOGI("shutting down encoder"); if (mEncoder != NULL) { mEncoder->release(); mEncoder->release(); mEncoder.clear(); mEncoder.clear(); } AString mime; AString mime; CHECK(mInputFormat->findString("mime", &mime)); CHECK(mInputFormat->findString("mime", &mime)); Loading @@ -332,6 +350,11 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { } } void Converter::scheduleDoMoreWork() { void Converter::scheduleDoMoreWork() { if (mIsPCMAudio) { // There's no encoder involved in this case. return; } if (mDoMoreWorkPending) { if (mDoMoreWorkPending) { return; return; } } Loading @@ -350,7 +373,120 @@ void Converter::scheduleDoMoreWork() { #endif #endif } } status_t Converter::feedRawAudioInputBuffers() { // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each // and add a 4 byte header according to the wifi display specs. while (!mInputBufferQueue.empty()) { sp<ABuffer> buffer = *mInputBufferQueue.begin(); mInputBufferQueue.erase(mInputBufferQueue.begin()); int16_t *ptr = (int16_t *)buffer->data(); int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); while (ptr < stop) { *ptr = htons(*ptr); ++ptr; } static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo static const size_t kFramesPerAU = 80; static const size_t kNumAUsPerPESPacket = 6; if (mPartialAudioAU != NULL) { size_t bytesMissingForFullAU = kNumAUsPerPESPacket * kFramesPerAU * kFrameSize - mPartialAudioAU->size() + 4; size_t copy = buffer->size(); if(copy > bytesMissingForFullAU) { copy = bytesMissingForFullAU; } memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), buffer->data(), copy); mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); buffer->setRange(buffer->offset() + copy, buffer->size() - copy); int64_t timeUs; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); timeUs += copyUs; buffer->meta()->setInt64("timeUs", timeUs); if (bytesMissingForFullAU == copy) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setBuffer("accessUnit", mPartialAudioAU); notify->post(); mPartialAudioAU.clear(); } } while (buffer->size() > 0) { sp<ABuffer> partialAudioAU = new ABuffer( 4 + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); uint8_t *ptr = partialAudioAU->data(); ptr[0] = 0xa0; // 10100000b ptr[1] = kNumAUsPerPESPacket; ptr[2] = 0; // reserved, audio _emphasis_flag = 0 static const unsigned kQuantizationWordLength = 0; // 16-bit static const unsigned kAudioSamplingFrequency = 2; // 48Khz static const unsigned kNumberOfAudioChannels = 1; // stereo ptr[3] = (kQuantizationWordLength << 6) | (kAudioSamplingFrequency << 3) | kNumberOfAudioChannels; size_t copy = buffer->size(); if (copy > partialAudioAU->size() - 4) { copy = partialAudioAU->size() - 4; } memcpy(&ptr[4], buffer->data(), copy); partialAudioAU->setRange(0, 4 + copy); buffer->setRange(buffer->offset() + copy, buffer->size() - copy); int64_t timeUs; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); partialAudioAU->meta()->setInt64("timeUs", timeUs); int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); timeUs += copyUs; buffer->meta()->setInt64("timeUs", timeUs); if (copy == partialAudioAU->size() - 4) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setBuffer("accessUnit", partialAudioAU); notify->post(); partialAudioAU.clear(); continue; } mPartialAudioAU = partialAudioAU; } } return OK; } status_t Converter::feedEncoderInputBuffers() { status_t Converter::feedEncoderInputBuffers() { if (mIsPCMAudio) { return feedRawAudioInputBuffers(); } while (!mInputBufferQueue.empty() while (!mInputBufferQueue.empty() && !mAvailEncoderInputIndices.empty()) { && !mAvailEncoderInputIndices.empty()) { sp<ABuffer> buffer = *mInputBufferQueue.begin(); sp<ABuffer> buffer = *mInputBufferQueue.begin(); Loading
media/libstagefright/wifi-display/source/Converter.h +12 −1 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ #define CONVERTER_H_ #define CONVERTER_H_ #include "WifiDisplaySource.h" #include <media/stagefright/foundation/AHandler.h> #include <media/stagefright/foundation/AHandler.h> namespace android { namespace android { Loading @@ -34,7 +36,8 @@ struct Converter : public AHandler { Converter( Converter( const sp<AMessage> ¬ify, const sp<AMessage> ¬ify, const sp<ALooper> &codecLooper, const sp<ALooper> &codecLooper, const sp<AMessage> &format); const sp<AMessage> &format, bool usePCMAudio); status_t initCheck() const; status_t initCheck() const; Loading Loading @@ -73,6 +76,7 @@ private: sp<ALooper> mCodecLooper; sp<ALooper> mCodecLooper; sp<AMessage> mInputFormat; sp<AMessage> mInputFormat; bool mIsVideo; bool mIsVideo; bool mIsPCMAudio; sp<AMessage> mOutputFormat; sp<AMessage> mOutputFormat; sp<MediaCodec> mEncoder; sp<MediaCodec> mEncoder; Loading @@ -92,6 +96,8 @@ private: bool mInSilentMode; bool mInSilentMode; #endif #endif sp<ABuffer> mPartialAudioAU; status_t initEncoder(); status_t initEncoder(); status_t feedEncoderInputBuffers(); status_t feedEncoderInputBuffers(); Loading @@ -101,6 +107,11 @@ private: void notifyError(status_t err); void notifyError(status_t err); // Packetizes raw PCM audio data available in mInputBufferQueue // into a format suitable for transport stream inclusion and // notifies the observer. status_t feedRawAudioInputBuffers(); static bool IsSilence(const sp<ABuffer> &accessUnit); static bool IsSilence(const sp<ABuffer> &accessUnit); DISALLOW_EVIL_CONSTRUCTORS(Converter); DISALLOW_EVIL_CONSTRUCTORS(Converter); Loading
media/libstagefright/wifi-display/source/PlaybackSession.cpp +14 −10 Original line number Original line Diff line number Diff line Loading @@ -312,10 +312,11 @@ WifiDisplaySource::PlaybackSession::PlaybackSession( status_t WifiDisplaySource::PlaybackSession::init( status_t WifiDisplaySource::PlaybackSession::init( const char *clientIP, int32_t clientRtp, int32_t clientRtcp, const char *clientIP, int32_t clientRtp, int32_t clientRtcp, TransportMode transportMode) { TransportMode transportMode, bool usePCMAudio) { mClientIP = clientIP; mClientIP = clientIP; status_t err = setupPacketizer(); status_t err = setupPacketizer(usePCMAudio); if (err != OK) { if (err != OK) { return err; return err; Loading Loading @@ -823,7 +824,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( } } } } status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { status_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) { mPacketizer = new TSPacketizer; mPacketizer = new TSPacketizer; status_t err = addVideoSource(); status_t err = addVideoSource(); Loading @@ -832,12 +833,15 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { return err; return err; } } return addAudioSource(); return addAudioSource(usePCMAudio); } } status_t WifiDisplaySource::PlaybackSession::addSource( status_t WifiDisplaySource::PlaybackSession::addSource( bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, size_t *numInputBuffers) { bool usePCMAudio, size_t *numInputBuffers) { CHECK(!usePCMAudio || !isVideo); CHECK(!isRepeaterSource || isVideo); sp<ALooper> pullLooper = new ALooper; sp<ALooper> pullLooper = new ALooper; pullLooper->setName("pull_looper"); pullLooper->setName("pull_looper"); Loading Loading @@ -875,7 +879,7 @@ status_t WifiDisplaySource::PlaybackSession::addSource( notify->setSize("trackIndex", trackIndex); notify->setSize("trackIndex", trackIndex); sp<Converter> converter = sp<Converter> converter = new Converter(notify, codecLooper, format); new Converter(notify, codecLooper, format, usePCMAudio); if (converter->initCheck() != OK) { if (converter->initCheck() != OK) { return converter->initCheck(); return converter->initCheck(); Loading Loading @@ -928,12 +932,12 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource() { size_t numInputBuffers; size_t numInputBuffers; status_t err = addSource( status_t err = addSource( true /* isVideo */, videoSource, true /* isRepeaterSource */, true /* isVideo */, videoSource, true /* isRepeaterSource */, &numInputBuffers); false /* usePCMAudio */, &numInputBuffers); #else #else size_t numInputBuffers; size_t numInputBuffers; status_t err = addSource( status_t err = addSource( true /* isVideo */, source, false /* isRepeaterSource */, true /* isVideo */, source, false /* isRepeaterSource */, &numInputBuffers); false /* usePCMAudio */, &numInputBuffers); #endif #endif if (err != OK) { if (err != OK) { Loading @@ -948,7 +952,7 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource() { return OK; return OK; } } status_t WifiDisplaySource::PlaybackSession::addAudioSource() { status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) { sp<AudioSource> audioSource = new AudioSource( sp<AudioSource> audioSource = new AudioSource( AUDIO_SOURCE_REMOTE_SUBMIX, AUDIO_SOURCE_REMOTE_SUBMIX, 48000 /* sampleRate */, 48000 /* sampleRate */, Loading @@ -957,7 +961,7 @@ status_t WifiDisplaySource::PlaybackSession::addAudioSource() { if (audioSource->initCheck() == OK) { if (audioSource->initCheck() == OK) { return addSource( return addSource( false /* isVideo */, audioSource, false /* isRepeaterSource */, false /* isVideo */, audioSource, false /* isRepeaterSource */, NULL /* numInputBuffers */); usePCMAudio, NULL /* numInputBuffers */); } } ALOGW("Unable to instantiate audio source"); ALOGW("Unable to instantiate audio source"); Loading
media/libstagefright/wifi-display/source/PlaybackSession.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,8 @@ struct WifiDisplaySource::PlaybackSession : public AHandler { }; }; status_t init( status_t init( const char *clientIP, int32_t clientRtp, int32_t clientRtcp, const char *clientIP, int32_t clientRtp, int32_t clientRtcp, TransportMode transportMode); TransportMode transportMode, bool usePCMAudio); void destroyAsync(); void destroyAsync(); Loading Loading @@ -180,16 +181,17 @@ private: void addSDES(const sp<ABuffer> &buffer); void addSDES(const sp<ABuffer> &buffer); static uint64_t GetNowNTP(); static uint64_t GetNowNTP(); status_t setupPacketizer(); status_t setupPacketizer(bool usePCMAudio); status_t addSource( status_t addSource( bool isVideo, bool isVideo, const sp<MediaSource> &source, const sp<MediaSource> &source, bool isRepeaterSource, bool isRepeaterSource, bool usePCMAudio, size_t *numInputBuffers); size_t *numInputBuffers); status_t addVideoSource(); status_t addVideoSource(); status_t addAudioSource(); status_t addAudioSource(bool usePCMAudio); ssize_t appendTSData( ssize_t appendTSData( const void *data, size_t size, bool timeDiscontinuity, bool flush); const void *data, size_t size, bool timeDiscontinuity, bool flush); Loading
media/libstagefright/wifi-display/source/TSPacketizer.cpp +10 −1 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct TSPacketizer::Track : public RefBase { bool isVideo() const; bool isVideo() const; bool isH264() const; bool isH264() const; bool isAAC() const; bool lacksADTSHeader() const; bool lacksADTSHeader() const; sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; Loading Loading @@ -139,6 +140,10 @@ bool TSPacketizer::Track::isH264() const { return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); } } bool TSPacketizer::Track::isAAC() const { return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC); } bool TSPacketizer::Track::lacksADTSHeader() const { bool TSPacketizer::Track::lacksADTSHeader() const { return mAudioLacksATDSHeaders; return mAudioLacksATDSHeaders; } } Loading Loading @@ -247,6 +252,10 @@ ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) { streamType = 0x0f; streamType = 0x0f; streamIDStart = 0xc0; streamIDStart = 0xc0; streamIDStop = 0xdf; streamIDStop = 0xdf; } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { streamType = 0x83; streamIDStart = 0xbd; streamIDStop = 0xbd; } else { } else { return ERROR_UNSUPPORTED; return ERROR_UNSUPPORTED; } } Loading Loading @@ -298,7 +307,7 @@ status_t TSPacketizer::packetize( && IsIDR(accessUnit)) { && IsIDR(accessUnit)) { // prepend codec specific data, i.e. SPS and PPS. // prepend codec specific data, i.e. SPS and PPS. accessUnit = track->prependCSD(accessUnit); accessUnit = track->prependCSD(accessUnit); } else if (track->isAudio() && track->lacksADTSHeader()) { } else if (track->isAAC() && track->lacksADTSHeader()) { CHECK(!(flags & IS_ENCRYPTED)); CHECK(!(flags & IS_ENCRYPTED)); accessUnit = track->prependADTSHeader(accessUnit); accessUnit = track->prependADTSHeader(accessUnit); } } Loading