diff options
Diffstat (limited to 'media/libmediaplayerservice')
26 files changed, 238 insertions, 900 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index e65f6d8..fadad28 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -31,8 +31,7 @@ LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ libstagefright \ libstagefright_omx \ - libstagefright_foundation \ - libsurfaceflinger_client \ + libstagefright_foundation \ libgui LOCAL_STATIC_LIBRARIES := \ diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 0156634..d51c946 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -51,6 +51,9 @@ #include <media/MediaMetadataRetrieverInterface.h> #include <media/Metadata.h> #include <media/AudioTrack.h> +#include <media/MemoryLeakTrackUtil.h> + +#include <system/audio.h> #include <private/android_filesystem_config.h> @@ -392,139 +395,6 @@ static int myTid() { #endif } -#if defined(__arm__) -extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, - size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); -extern "C" void free_malloc_leak_info(uint8_t* info); - -// Use the String-class below instead of String8 to allocate all memory -// beforehand and not reenter the heap while we are examining it... -struct MyString8 { - static const size_t MAX_SIZE = 256 * 1024; - - MyString8() - : mPtr((char *)malloc(MAX_SIZE)) { - *mPtr = '\0'; - } - - ~MyString8() { - free(mPtr); - } - - void append(const char *s) { - strcat(mPtr, s); - } - - const char *string() const { - return mPtr; - } - - size_t size() const { - return strlen(mPtr); - } - -private: - char *mPtr; - - MyString8(const MyString8 &); - MyString8 &operator=(const MyString8 &); -}; - -void memStatus(int fd, const Vector<String16>& args) -{ - const size_t SIZE = 256; - char buffer[SIZE]; - MyString8 result; - - typedef struct { - size_t size; - size_t dups; - intptr_t * backtrace; - } AllocEntry; - - uint8_t *info = NULL; - size_t overallSize = 0; - size_t infoSize = 0; - size_t totalMemory = 0; - size_t backtraceSize = 0; - - get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); - if (info) { - uint8_t *ptr = info; - size_t count = overallSize / infoSize; - - snprintf(buffer, SIZE, " Allocation count %i\n", count); - result.append(buffer); - snprintf(buffer, SIZE, " Total memory %i\n", totalMemory); - result.append(buffer); - - AllocEntry * entries = new AllocEntry[count]; - - for (size_t i = 0; i < count; i++) { - // Each entry should be size_t, size_t, intptr_t[backtraceSize] - AllocEntry *e = &entries[i]; - - e->size = *reinterpret_cast<size_t *>(ptr); - ptr += sizeof(size_t); - - e->dups = *reinterpret_cast<size_t *>(ptr); - ptr += sizeof(size_t); - - e->backtrace = reinterpret_cast<intptr_t *>(ptr); - ptr += sizeof(intptr_t) * backtraceSize; - } - - // Now we need to sort the entries. They come sorted by size but - // not by stack trace which causes problems using diff. - bool moved; - do { - moved = false; - for (size_t i = 0; i < (count - 1); i++) { - AllocEntry *e1 = &entries[i]; - AllocEntry *e2 = &entries[i+1]; - - bool swap = e1->size < e2->size; - if (e1->size == e2->size) { - for(size_t j = 0; j < backtraceSize; j++) { - if (e1->backtrace[j] == e2->backtrace[j]) { - continue; - } - swap = e1->backtrace[j] < e2->backtrace[j]; - break; - } - } - if (swap) { - AllocEntry t = entries[i]; - entries[i] = entries[i+1]; - entries[i+1] = t; - moved = true; - } - } - } while (moved); - - for (size_t i = 0; i < count; i++) { - AllocEntry *e = &entries[i]; - - snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups); - result.append(buffer); - for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) { - if (ct) { - result.append(", "); - } - snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]); - result.append(buffer); - } - result.append("\n"); - } - - delete[] entries; - free_malloc_leak_info(info); - } - - write(fd, result.string(), result.size()); -} -#endif - status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; @@ -623,7 +493,6 @@ status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) result.append("\n"); } -#if defined(__arm__) bool dumpMem = false; for (size_t i = 0; i < args.size(); i++) { if (args[i] == String16("-m")) { @@ -631,9 +500,8 @@ status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) } } if (dumpMem) { - memStatus(fd, args); + dumpMemoryAddresses(fd); } -#endif } write(fd, result.string(), result.size()); return NO_ERROR; @@ -1156,7 +1024,22 @@ status_t MediaPlayerService::Client::attachAuxEffect(int effectId) return NO_ERROR; } -void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) +status_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) { + LOGV("[%d] setParameter(%d)", mConnId, key); + sp<MediaPlayerBase> p = getPlayer(); + if (p == 0) return UNKNOWN_ERROR; + return p->setParameter(key, request); +} + +status_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) { + LOGV("[%d] getParameter(%d)", mConnId, key); + sp<MediaPlayerBase> p = getPlayer(); + if (p == 0) return UNKNOWN_ERROR; + return p->getParameter(key, reply); +} + +void MediaPlayerService::Client::notify( + void* cookie, int msg, int ext1, int ext2, const Parcel *obj) { Client* client = static_cast<Client*>(cookie); @@ -1173,7 +1056,7 @@ void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext client->addNewMetadataUpdate(metadata_type); } LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); - client->mClient->notify(msg, ext1, ext2); + client->mClient->notify(msg, ext1, ext2, obj); } @@ -1342,7 +1225,7 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId) mSessionId(sessionId) { LOGV("AudioOutput(%d)", sessionId); mTrack = 0; - mStreamType = AudioSystem::MUSIC; + mStreamType = AUDIO_STREAM_MUSIC; mLeftVolume = 1.0; mRightVolume = 1.0; mLatency = 0; @@ -1452,7 +1335,7 @@ status_t MediaPlayerService::AudioOutput::open( mStreamType, sampleRate, format, - (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, + (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, frameCount, 0 /* flags */, CallbackWrapper, @@ -1464,7 +1347,7 @@ status_t MediaPlayerService::AudioOutput::open( mStreamType, sampleRate, format, - (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, + (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, frameCount, 0, NULL, @@ -1583,8 +1466,15 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( size_t actualSize = (*me->mCallback)( me, buffer->raw, buffer->size, me->mCallbackCookie); - buffer->size = actualSize; + if (actualSize == 0 && buffer->size > 0) { + // We've reached EOS but the audio track is not stopped yet, + // keep playing silence. + memset(buffer->raw, 0, buffer->size); + actualSize = buffer->size; + } + + buffer->size = actualSize; } int MediaPlayerService::AudioOutput::getSessionId() @@ -1750,7 +1640,8 @@ status_t MediaPlayerService::AudioCache::wait() return mError; } -void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2) +void MediaPlayerService::AudioCache::notify( + void* cookie, int msg, int ext1, int ext2, const Parcel *obj) { LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); AudioCache* p = static_cast<AudioCache*>(cookie); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index ff6ccf5..8bab471 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -30,6 +30,8 @@ #include <media/MediaPlayerInterface.h> #include <media/Metadata.h> +#include <system/audio.h> + namespace android { class IMediaRecorder; @@ -130,7 +132,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual ssize_t bufferSize() const { return frameSize() * mFrameCount; } virtual ssize_t frameCount() const { return mFrameCount; } virtual ssize_t channelCount() const { return (ssize_t)mChannelCount; } - virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); } + virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AUDIO_FORMAT_PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); } virtual uint32_t latency() const; virtual float msecsPerFrame() const; virtual status_t getPosition(uint32_t *position); @@ -156,7 +158,8 @@ class MediaPlayerService : public BnMediaPlayerService sp<IMemoryHeap> getHeap() const { return mHeap; } - static void notify(void* cookie, int msg, int ext1, int ext2); + static void notify(void* cookie, int msg, + int ext1, int ext2, const Parcel *obj); virtual status_t dump(int fd, const Vector<String16>& args) const; private: @@ -276,6 +279,8 @@ private: Parcel *reply); virtual status_t setAuxEffectSendLevel(float level); virtual status_t attachAuxEffect(int effectId); + virtual status_t setParameter(int key, const Parcel &request); + virtual status_t getParameter(int key, Parcel *reply); sp<MediaPlayerBase> createPlayer(player_type playerType); @@ -287,7 +292,8 @@ private: status_t setDataSource(const sp<IStreamSource> &source); - static void notify(void* cookie, int msg, int ext1, int ext2); + static void notify(void* cookie, int msg, + int ext1, int ext2, const Parcel *obj); pid_t pid() const { return mPid; } virtual status_t dump(int fd, const Vector<String16>& args) const; diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 1a1780c..29cc019 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -35,6 +35,8 @@ #include <media/AudioTrack.h> +#include <system/audio.h> + #include "MediaRecorderClient.h" #include "MediaPlayerService.h" @@ -102,7 +104,7 @@ status_t MediaRecorderClient::setAudioSource(int as) LOGE("recorder is not initialized"); return NO_INIT; } - return mRecorder->setAudioSource((audio_source)as); + return mRecorder->setAudioSource((audio_source_t)as); } status_t MediaRecorderClient::setOutputFormat(int of) diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 5fcf2a7..8f776b4 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -120,7 +120,8 @@ static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType) return p; } -status_t MetadataRetrieverClient::setDataSource(const char *url) +status_t MetadataRetrieverClient::setDataSource( + const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource(%s)", url); Mutex::Autolock lock(mLock); @@ -131,7 +132,7 @@ status_t MetadataRetrieverClient::setDataSource(const char *url) LOGV("player type = %d", playerType); sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); if (p == NULL) return NO_INIT; - status_t ret = p->setDataSource(url); + status_t ret = p->setDataSource(url, headers); if (ret == NO_ERROR) mRetriever = p; return ret; } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index b834715..f08f933 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -41,7 +41,10 @@ public: // Implements IMediaMetadataRetriever interface // These methods are called in IMediaMetadataRetriever.cpp? virtual void disconnect(); - virtual status_t setDataSource(const char *url); + + virtual status_t setDataSource( + const char *url, const KeyedVector<String8, String8> *headers); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option); virtual sp<IMemory> extractAlbumArt(); diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp index 1b0b05f..589c625 100644 --- a/media/libmediaplayerservice/MidiFile.cpp +++ b/media/libmediaplayerservice/MidiFile.cpp @@ -30,6 +30,8 @@ #include <sys/types.h> #include <sys/stat.h> +#include <system/audio.h> + #include "MidiFile.h" #ifdef HAVE_GETTID @@ -58,7 +60,7 @@ static const S_EAS_LIB_CONFIG* pLibConfig = NULL; MidiFile::MidiFile() : mEasData(NULL), mEasHandle(NULL), mAudioBuffer(NULL), mPlayTime(-1), mDuration(-1), mState(EAS_STATE_ERROR), - mStreamType(AudioSystem::MUSIC), mLoop(false), mExit(false), + mStreamType(AUDIO_STREAM_MUSIC), mLoop(false), mExit(false), mPaused(false), mRender(false), mTid(-1) { LOGV("constructor"); @@ -423,7 +425,7 @@ status_t MidiFile::setLooping(int loop) } status_t MidiFile::createOutputTrack() { - if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AudioSystem::PCM_16_BIT, 2) != NO_ERROR) { + if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AUDIO_FORMAT_PCM_16_BIT, 2) != NO_ERROR) { LOGE("mAudioSink open failed"); return ERROR_OPEN_FAILED; } diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index a98231c..b35696f 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -55,6 +55,13 @@ public: virtual status_t invoke(const Parcel& request, Parcel *reply) { return INVALID_OPERATION; } + virtual status_t setParameter(int key, const Parcel &request) { + return INVALID_OPERATION; + } + virtual status_t getParameter(int key, Parcel *reply) { + return INVALID_OPERATION; + } + private: status_t createOutputTrack(); diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp index ad95fac..aaf2d18 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp +++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp @@ -35,7 +35,8 @@ void MidiMetadataRetriever::clearMetadataValues() mMetadataValues[0][0] = '\0'; } -status_t MidiMetadataRetriever::setDataSource(const char *url) +status_t MidiMetadataRetriever::setDataSource( + const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource: %s", url? url: "NULL pointer"); Mutex::Autolock lock(mLock); @@ -43,8 +44,7 @@ status_t MidiMetadataRetriever::setDataSource(const char *url) if (mMidiPlayer == 0) { mMidiPlayer = new MidiFile(); } - // TODO: support headers in MetadataRetriever interface! - return mMidiPlayer->setDataSource(url, NULL /* headers */); + return mMidiPlayer->setDataSource(url, headers); } status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h index 73ff347..4cee42d 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.h +++ b/media/libmediaplayerservice/MidiMetadataRetriever.h @@ -31,7 +31,9 @@ public: MidiMetadataRetriever() {} ~MidiMetadataRetriever() {} - virtual status_t setDataSource(const char *url); + virtual status_t setDataSource( + const char *url, const KeyedVector<String8, String8> *headers); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual const char* extractMetadata(int keyCode); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index c5cbd23..02ec911 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -110,7 +110,7 @@ bool StagefrightPlayer::isPlaying() { } status_t StagefrightPlayer::seekTo(int msec) { - LOGV("seekTo"); + LOGV("seekTo %.2f secs", msec / 1E3); status_t err = mPlayer->seekTo((int64_t)msec * 1000); @@ -177,6 +177,16 @@ void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) { mPlayer->setAudioSink(audioSink); } +status_t StagefrightPlayer::setParameter(int key, const Parcel &request) { + LOGV("setParameter"); + return mPlayer->setParameter(key, request); +} + +status_t StagefrightPlayer::getParameter(int key, Parcel *reply) { + LOGV("getParameter"); + return mPlayer->getParameter(key, reply); +} + status_t StagefrightPlayer::getMetadata( const media::Metadata::Filter& ids, Parcel *records) { using media::Metadata; diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h index e2796d2..ddd37e4 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -55,6 +55,8 @@ public: virtual player_type playerType(); virtual status_t invoke(const Parcel &request, Parcel *reply); virtual void setAudioSink(const sp<AudioSink> &audioSink); + virtual status_t setParameter(int key, const Parcel &request); + virtual status_t getParameter(int key, Parcel *reply); virtual status_t getMetadata( const media::Metadata::Filter& ids, Parcel *records); diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index e3dfabb..978571c 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -26,6 +26,7 @@ #include <media/IMediaPlayerService.h> #include <media/stagefright/AudioSource.h> #include <media/stagefright/AMRWriter.h> +#include <media/stagefright/AACWriter.h> #include <media/stagefright/CameraSource.h> #include <media/stagefright/VideoSourceDownSampler.h> #include <media/stagefright/CameraSourceTimeLapse.h> @@ -46,6 +47,8 @@ #include <ctype.h> #include <unistd.h> +#include <system/audio.h> + #include "ARTPWriter.h" namespace android { @@ -64,7 +67,7 @@ static void addBatteryData(uint32_t params) { StagefrightRecorder::StagefrightRecorder() : mWriter(NULL), mWriterAux(NULL), mOutputFd(-1), mOutputFdAux(-1), - mAudioSource(AUDIO_SOURCE_LIST_END), + mAudioSource(AUDIO_SOURCE_CNT), mVideoSource(VIDEO_SOURCE_LIST_END), mStarted(false) { @@ -82,10 +85,10 @@ status_t StagefrightRecorder::init() { return OK; } -status_t StagefrightRecorder::setAudioSource(audio_source as) { +status_t StagefrightRecorder::setAudioSource(audio_source_t as) { LOGV("setAudioSource: %d", as); if (as < AUDIO_SOURCE_DEFAULT || - as >= AUDIO_SOURCE_LIST_END) { + as >= AUDIO_SOURCE_CNT) { LOGE("Invalid audio source: %d", as); return BAD_VALUE; } @@ -590,6 +593,26 @@ status_t StagefrightRecorder::setParamAuxVideoEncodingBitRate(int32_t bitRate) { return OK; } +status_t StagefrightRecorder::setParamGeoDataLongitude( + int32_t longitudex10000) { + + if (longitudex10000 > 1800000 || longitudex10000 < -1800000) { + return BAD_VALUE; + } + mLongitudex10000 = longitudex10000; + return OK; +} + +status_t StagefrightRecorder::setParamGeoDataLatitude( + int32_t latitudex10000) { + + if (latitudex10000 > 900000 || latitudex10000 < -900000) { + return BAD_VALUE; + } + mLatitudex10000 = latitudex10000; + return OK; +} + status_t StagefrightRecorder::setParameter( const String8 &key, const String8 &value) { LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); @@ -618,6 +641,16 @@ status_t StagefrightRecorder::setParameter( if (safe_strtoi32(value.string(), &use64BitOffset)) { return setParam64BitFileOffset(use64BitOffset != 0); } + } else if (key == "param-geotag-longitude") { + int32_t longitudex10000; + if (safe_strtoi32(value.string(), &longitudex10000)) { + return setParamGeoDataLongitude(longitudex10000); + } + } else if (key == "param-geotag-latitude") { + int32_t latitudex10000; + if (safe_strtoi32(value.string(), &latitudex10000)) { + return setParamGeoDataLatitude(latitudex10000); + } } else if (key == "param-track-time-status") { int64_t timeDurationUs; if (safe_strtoi64(value.string(), &timeDurationUs)) { @@ -800,7 +833,7 @@ status_t StagefrightRecorder::start() { mStarted = true; uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (mAudioSource != AUDIO_SOURCE_CNT) { params |= IMediaPlayerService::kBatteryDataTrackAudio; } if (mVideoSource != VIDEO_SOURCE_LIST_END) { @@ -870,15 +903,21 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { } status_t StagefrightRecorder::startAACRecording() { - CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF || - mOutputFormat == OUTPUT_FORMAT_AAC_ADTS); + // FIXME: + // Add support for OUTPUT_FORMAT_AAC_ADIF + CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADTS); CHECK(mAudioEncoder == AUDIO_ENCODER_AAC); - CHECK(mAudioSource != AUDIO_SOURCE_LIST_END); + CHECK(mAudioSource != AUDIO_SOURCE_CNT); - CHECK(0 == "AACWriter is not implemented yet"); + mWriter = new AACWriter(mOutputFd); + status_t status = startRawAudioRecording(); + if (status != OK) { + mWriter.clear(); + mWriter = NULL; + } - return OK; + return status; } status_t StagefrightRecorder::startAMRRecording() { @@ -900,7 +939,17 @@ status_t StagefrightRecorder::startAMRRecording() { } } - if (mAudioSource >= AUDIO_SOURCE_LIST_END) { + mWriter = new AMRWriter(mOutputFd); + status_t status = startRawAudioRecording(); + if (status != OK) { + mWriter.clear(); + mWriter = NULL; + } + return status; +} + +status_t StagefrightRecorder::startRawAudioRecording() { + if (mAudioSource >= AUDIO_SOURCE_CNT) { LOGE("Invalid audio source: %d", mAudioSource); return BAD_VALUE; } @@ -915,7 +964,7 @@ status_t StagefrightRecorder::startAMRRecording() { return UNKNOWN_ERROR; } - mWriter = new AMRWriter(mOutputFd); + CHECK(mWriter != 0); mWriter->addSource(audioEncoder); if (mMaxFileDurationUs != 0) { @@ -933,9 +982,9 @@ status_t StagefrightRecorder::startAMRRecording() { status_t StagefrightRecorder::startRTPRecording() { CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP); - if ((mAudioSource != AUDIO_SOURCE_LIST_END + if ((mAudioSource != AUDIO_SOURCE_CNT && mVideoSource != VIDEO_SOURCE_LIST_END) - || (mAudioSource == AUDIO_SOURCE_LIST_END + || (mAudioSource == AUDIO_SOURCE_CNT && mVideoSource == VIDEO_SOURCE_LIST_END)) { // Must have exactly one source. return BAD_VALUE; @@ -947,7 +996,7 @@ status_t StagefrightRecorder::startRTPRecording() { sp<MediaSource> source; - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (mAudioSource != AUDIO_SOURCE_CNT) { source = createAudioSource(); } else { @@ -975,7 +1024,7 @@ status_t StagefrightRecorder::startMPEG2TSRecording() { sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd); - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (mAudioSource != AUDIO_SOURCE_CNT) { if (mAudioEncoder != AUDIO_ENCODER_AAC) { return ERROR_UNSUPPORTED; } @@ -1383,7 +1432,7 @@ status_t StagefrightRecorder::setupMPEG4Recording( // Audio source is added at the end if it exists. // This help make sure that the "recoding" sound is suppressed for // camcorder applications in the recorded files. - if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) { + if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) { err = setupAudioEncoder(writer); if (err != OK) return err; *totalBitRate += mAudioBitRate; @@ -1393,6 +1442,10 @@ status_t StagefrightRecorder::setupMPEG4Recording( reinterpret_cast<MPEG4Writer *>(writer.get())-> setInterleaveDuration(mInterleaveDurationUs); } + if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) { + reinterpret_cast<MPEG4Writer *>(writer.get())-> + setGeoData(mLatitudex10000, mLongitudex10000); + } if (mMaxFileDurationUs != 0) { writer->setMaxFileDuration(mMaxFileDurationUs); } @@ -1400,6 +1453,12 @@ status_t StagefrightRecorder::setupMPEG4Recording( writer->setMaxFileSize(mMaxFileSizeBytes); } + mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId); + if (mStartTimeOffsetMs > 0) { + reinterpret_cast<MPEG4Writer *>(writer.get())-> + setStartTimeOffsetMs(mStartTimeOffsetMs); + } + writer->setListener(mListener); *mediaWriter = writer; return OK; @@ -1504,7 +1563,7 @@ status_t StagefrightRecorder::pause() { mStarted = false; uint32_t params = 0; - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (mAudioSource != AUDIO_SOURCE_CNT) { params |= IMediaPlayerService::kBatteryDataTrackAudio; } if (mVideoSource != VIDEO_SOURCE_LIST_END) { @@ -1555,7 +1614,7 @@ status_t StagefrightRecorder::stop() { mStarted = false; uint32_t params = 0; - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (mAudioSource != AUDIO_SOURCE_CNT) { params |= IMediaPlayerService::kBatteryDataTrackAudio; } if (mVideoSource != VIDEO_SOURCE_LIST_END) { @@ -1581,7 +1640,7 @@ status_t StagefrightRecorder::reset() { stop(); // No audio or video source by default - mAudioSource = AUDIO_SOURCE_LIST_END; + mAudioSource = AUDIO_SOURCE_CNT; mVideoSource = VIDEO_SOURCE_LIST_END; // Default parameters @@ -1606,6 +1665,7 @@ status_t StagefrightRecorder::reset() { mAudioTimeScale = -1; mVideoTimeScale = -1; mCameraId = 0; + mStartTimeOffsetMs = -1; mVideoEncoderProfile = -1; mVideoEncoderLevel = -1; mMaxFileDurationUs = 0; @@ -1619,6 +1679,8 @@ status_t StagefrightRecorder::reset() { mIsMetaDataStoredInVideoBuffers = false; mEncoderProfiles = MediaProfiles::getInstance(); mRotationDegrees = 0; + mLatitudex10000 = -3600000; + mLongitudex10000 = -3600000; mOutputFd = -1; mOutputFdAux = -1; @@ -1692,6 +1754,8 @@ status_t StagefrightRecorder::dump( result.append(buffer); snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); result.append(buffer); + snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs); + result.append(buffer); snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); result.append(buffer); snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 2c440c1..aa67aa7 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -22,6 +22,8 @@ #include <camera/CameraParameters.h> #include <utils/String8.h> +#include <system/audio.h> + namespace android { class Camera; @@ -39,7 +41,7 @@ struct StagefrightRecorder : public MediaRecorderBase { virtual ~StagefrightRecorder(); virtual status_t init(); - virtual status_t setAudioSource(audio_source as); + virtual status_t setAudioSource(audio_source_t as); virtual status_t setVideoSource(video_source vs); virtual status_t setOutputFormat(output_format of); virtual status_t setAudioEncoder(audio_encoder ae); @@ -67,9 +69,10 @@ private: sp<Surface> mPreviewSurface; sp<IMediaRecorderClient> mListener; sp<MediaWriter> mWriter, mWriterAux; + int mOutputFd, mOutputFdAux; sp<AudioSource> mAudioSourceNode; - audio_source mAudioSource; + audio_source_t mAudioSource; video_source mVideoSource; output_format mOutputFormat; audio_encoder mAudioEncoder; @@ -94,6 +97,9 @@ private: int64_t mMaxFileDurationUs; int64_t mTrackEveryTimeDurationUs; int32_t mRotationDegrees; // Clockwise + int32_t mLatitudex10000; + int32_t mLongitudex10000; + int32_t mStartTimeOffsetMs; bool mCaptureTimeLapse; int64_t mTimeBetweenTimeLapseFrameCaptureUs; @@ -102,7 +108,6 @@ private: sp<CameraSourceTimeLapse> mCameraSourceTimeLapse; String8 mParams; - int mOutputFd, mOutputFdAux; bool mIsMetaDataStoredInVideoBuffers; MediaProfiles *mEncoderProfiles; @@ -121,6 +126,7 @@ private: status_t startMPEG4Recording(); status_t startAMRRecording(); status_t startAACRecording(); + status_t startRawAudioRecording(); status_t startRTPRecording(); status_t startMPEG2TSRecording(); sp<MediaSource> createAudioSource(); @@ -157,6 +163,8 @@ private: status_t setParamMaxFileDurationUs(int64_t timeUs); status_t setParamMaxFileSizeBytes(int64_t bytes); status_t setParamMovieTimeScale(int32_t timeScale); + status_t setParamGeoDataLongitude(int32_t longitudex10000); + status_t setParamGeoDataLatitude(int32_t latitudex10000); void clipVideoBitRate(); void clipVideoFrameRate(); void clipVideoFrameWidth(); diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h index d9c3db3..802a11b 100644 --- a/media/libmediaplayerservice/TestPlayerStub.h +++ b/media/libmediaplayerservice/TestPlayerStub.h @@ -99,6 +99,12 @@ class TestPlayerStub : public MediaPlayerInterface { virtual status_t invoke(const android::Parcel& in, android::Parcel *out) { return mPlayer->invoke(in, out); } + virtual status_t setParameter(int key, const Parcel &request) { + return mPlayer->setParameter(key, request); + } + virtual status_t getParameter(int key, Parcel *reply) { + return mPlayer->getParameter(key, reply); + } // @return true if the current build is 'eng' or 'test' and the diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk index c20e279..e761509 100644 --- a/media/libmediaplayerservice/nuplayer/Android.mk +++ b/media/libmediaplayerservice/nuplayer/Android.mk @@ -8,7 +8,6 @@ LOCAL_SRC_FILES:= \ NuPlayerDriver.cpp \ NuPlayerRenderer.cpp \ NuPlayerStreamListener.cpp \ - DecoderWrapper.cpp \ StreamingSource.cpp \ LOCAL_C_INCLUDES := \ diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp deleted file mode 100644 index 802d1fb..0000000 --- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//#define LOG_NDEBUG 0 -#define LOG_TAG "DecoderWrapper" -#include <utils/Log.h> - -#include "DecoderWrapper.h" - -#include "AACDecoder.h" - -#include <media/stagefright/foundation/hexdump.h> -#include <media/stagefright/foundation/ABuffer.h> -#include <media/stagefright/foundation/ADebug.h> -#include <media/stagefright/foundation/AMessage.h> -#include <media/stagefright/ACodec.h> -#include <media/stagefright/MediaBuffer.h> -#include <media/stagefright/MediaDefs.h> -#include <media/stagefright/MediaSource.h> -#include <media/stagefright/MetaData.h> - -namespace android { - -struct DecoderWrapper::WrapperSource : public MediaSource { - WrapperSource( - const sp<MetaData> &meta, - const sp<AMessage> ¬ify); - - virtual status_t start(MetaData *params); - virtual status_t stop(); - virtual sp<MetaData> getFormat(); - - virtual status_t read( - MediaBuffer **buffer, const ReadOptions *options); - - void queueBuffer(const sp<ABuffer> &buffer); - void queueEOS(status_t finalResult); - void clear(); - -protected: - virtual ~WrapperSource(); - -private: - Mutex mLock; - Condition mCondition; - - sp<MetaData> mMeta; - sp<AMessage> mNotify; - - List<sp<ABuffer> > mQueue; - status_t mFinalResult; - - DISALLOW_EVIL_CONSTRUCTORS(WrapperSource); -}; - -DecoderWrapper::WrapperSource::WrapperSource( - const sp<MetaData> &meta, const sp<AMessage> ¬ify) - : mMeta(meta), - mNotify(notify), - mFinalResult(OK) { -} - -DecoderWrapper::WrapperSource::~WrapperSource() { -} - -status_t DecoderWrapper::WrapperSource::start(MetaData *params) { - return OK; -} - -status_t DecoderWrapper::WrapperSource::stop() { - return OK; -} - -sp<MetaData> DecoderWrapper::WrapperSource::getFormat() { - return mMeta; -} - -status_t DecoderWrapper::WrapperSource::read( - MediaBuffer **out, const ReadOptions *options) { - Mutex::Autolock autoLock(mLock); - - bool requestedBuffer = false; - - while (mQueue.empty() && mFinalResult == OK) { - if (!requestedBuffer) { - mNotify->dup()->post(); - requestedBuffer = true; - } - - mCondition.wait(mLock); - } - - if (mQueue.empty()) { - return mFinalResult; - } - - sp<ABuffer> src = *mQueue.begin(); - mQueue.erase(mQueue.begin()); - - MediaBuffer *dst = new MediaBuffer(src->size()); - memcpy(dst->data(), src->data(), src->size()); - - int64_t timeUs; - CHECK(src->meta()->findInt64("timeUs", &timeUs)); - - dst->meta_data()->setInt64(kKeyTime, timeUs); - - *out = dst; - - return OK; -} - -void DecoderWrapper::WrapperSource::queueBuffer(const sp<ABuffer> &buffer) { - Mutex::Autolock autoLock(mLock); - mQueue.push_back(buffer); - mCondition.broadcast(); -} - -void DecoderWrapper::WrapperSource::queueEOS(status_t finalResult) { - CHECK_NE(finalResult, (status_t)OK); - - Mutex::Autolock autoLock(mLock); - mFinalResult = finalResult; - mCondition.broadcast(); -} - -void DecoderWrapper::WrapperSource::clear() { - Mutex::Autolock autoLock(mLock); - mQueue.clear(); - mFinalResult = OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -struct DecoderWrapper::WrapperReader : public AHandler { - WrapperReader( - const sp<MediaSource> &decoder, - const sp<AMessage> ¬ify); - - void start(); - void stop(); - void readMore(bool flush = false); - -protected: - virtual ~WrapperReader(); - - virtual void onMessageReceived(const sp<AMessage> &msg); - -private: - enum { - kWhatRead - }; - - sp<MediaSource> mDecoder; - sp<AMessage> mNotify; - bool mEOS; - bool mSentFormat; - - void sendFormatChange(); - - DISALLOW_EVIL_CONSTRUCTORS(WrapperReader); -}; - -DecoderWrapper::WrapperReader::WrapperReader( - const sp<MediaSource> &decoder, const sp<AMessage> ¬ify) - : mDecoder(decoder), - mNotify(notify), - mEOS(false), - mSentFormat(false) { -} - -DecoderWrapper::WrapperReader::~WrapperReader() { -} - -void DecoderWrapper::WrapperReader::start() { - CHECK_EQ(mDecoder->start(), (status_t)OK); - readMore(); -} - -void DecoderWrapper::WrapperReader::stop() { - CHECK_EQ(mDecoder->stop(), (status_t)OK); -} - -void DecoderWrapper::WrapperReader::readMore(bool flush) { - if (!flush && mEOS) { - return; - } - - sp<AMessage> msg = new AMessage(kWhatRead, id()); - msg->setInt32("flush", static_cast<int32_t>(flush)); - msg->post(); -} - -void DecoderWrapper::WrapperReader::onMessageReceived( - const sp<AMessage> &msg) { - switch (msg->what()) { - case kWhatRead: - { - int32_t flush; - CHECK(msg->findInt32("flush", &flush)); - - MediaSource::ReadOptions options; - if (flush) { - // Dummy seek - options.setSeekTo(0); - mEOS = false; - } - - CHECK(!mEOS); - - MediaBuffer *src; - status_t err = mDecoder->read(&src, &options); - - if (err == OK) { - if (!mSentFormat) { - sendFormatChange(); - mSentFormat = true; - } - - sp<AMessage> notify = mNotify->dup(); - - sp<AMessage> realNotify; - CHECK(notify->findMessage("real-notify", &realNotify)); - - realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer); - - sp<ABuffer> dst = new ABuffer(src->range_length()); - memcpy(dst->data(), - (const uint8_t *)src->data() + src->range_offset(), - src->range_length()); - - int64_t timeUs; - CHECK(src->meta_data()->findInt64(kKeyTime, &timeUs)); - src->release(); - src = NULL; - - dst->meta()->setInt64("timeUs", timeUs); - - realNotify->setObject("buffer", dst); - - notify->post(); - } else if (err == INFO_FORMAT_CHANGED) { - sendFormatChange(); - - readMore(false /* flush */); - } else { - sp<AMessage> notify = mNotify->dup(); - - sp<AMessage> realNotify; - CHECK(notify->findMessage("real-notify", &realNotify)); - - realNotify->setInt32("what", ACodec::kWhatEOS); - mEOS = true; - - notify->post(); - } - break; - } - - default: - TRESPASS(); - break; - } -} - -void DecoderWrapper::WrapperReader::sendFormatChange() { - sp<AMessage> notify = mNotify->dup(); - - sp<AMessage> realNotify; - CHECK(notify->findMessage("real-notify", &realNotify)); - - realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged); - - sp<MetaData> meta = mDecoder->getFormat(); - - const char *mime; - CHECK(meta->findCString(kKeyMIMEType, &mime)); - - realNotify->setString("mime", mime); - - if (!strncasecmp("audio/", mime, 6)) { - int32_t numChannels; - CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); - - int32_t sampleRate; - CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); - - realNotify->setInt32("channel-count", numChannels); - realNotify->setInt32("sample-rate", sampleRate); - } else { - CHECK(!strncasecmp("video/", mime, 6)); - - int32_t width, height; - CHECK(meta->findInt32(kKeyWidth, &width)); - CHECK(meta->findInt32(kKeyHeight, &height)); - - realNotify->setInt32("width", width); - realNotify->setInt32("height", height); - - int32_t cropLeft, cropTop, cropRight, cropBottom; - if (!meta->findRect( - kKeyCropRect, - &cropLeft, &cropTop, &cropRight, &cropBottom)) { - cropLeft = 0; - cropTop = 0; - cropRight = width - 1; - cropBottom = height - 1; - } - - realNotify->setRect("crop", cropLeft, cropTop, cropRight, cropBottom); - } - - notify->post(); - - mSentFormat = true; -} - -//////////////////////////////////////////////////////////////////////////////// - -DecoderWrapper::DecoderWrapper() - : mNumOutstandingInputBuffers(0), - mNumOutstandingOutputBuffers(0), - mNumPendingDecodes(0), - mFlushing(false) { -} - -DecoderWrapper::~DecoderWrapper() { -} - -void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) { - mNotify = msg; -} - -void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) { - msg->setWhat(kWhatSetup); - msg->setTarget(id()); - msg->post(); -} - -void DecoderWrapper::initiateShutdown() { - (new AMessage(kWhatShutdown, id()))->post(); -} - -void DecoderWrapper::signalFlush() { - (new AMessage(kWhatFlush, id()))->post(); -} - -void DecoderWrapper::signalResume() { - (new AMessage(kWhatResume, id()))->post(); -} - -void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) { - switch (msg->what()) { - case kWhatSetup: - onSetup(msg); - break; - - case kWhatShutdown: - onShutdown(); - break; - - case kWhatInputDataRequested: - { - postFillBuffer(); - ++mNumOutstandingInputBuffers; - break; - } - - case kWhatInputBufferFilled: - { - CHECK_GT(mNumOutstandingInputBuffers, 0); - --mNumOutstandingInputBuffers; - - if (mFlushing) { - mSource->queueEOS(INFO_DISCONTINUITY); - - completeFlushIfPossible(); - break; - } - - sp<RefBase> obj; - if (!msg->findObject("buffer", &obj)) { - int32_t err = OK; - CHECK(msg->findInt32("err", &err)); - - mSource->queueEOS(err); - break; - } - - sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); - - mSource->queueBuffer(buffer); - break; - } - - case kWhatFillBufferDone: - { - sp<AMessage> notify; - CHECK(msg->findMessage("real-notify", ¬ify)); - - int32_t what; - CHECK(notify->findInt32("what", &what)); - - if (what == ACodec::kWhatDrainThisBuffer) { - CHECK_GT(mNumPendingDecodes, 0); - --mNumPendingDecodes; - - sp<AMessage> reply = - new AMessage(kWhatOutputBufferDrained, id()); - - notify->setMessage("reply", reply); - - ++mNumOutstandingOutputBuffers; - } else if (what == ACodec::kWhatEOS) { - CHECK_GT(mNumPendingDecodes, 0); - --mNumPendingDecodes; - - if (mFlushing) { - completeFlushIfPossible(); - break; - } - } - - notify->post(); - break; - } - - case kWhatOutputBufferDrained: - { - CHECK_GT(mNumOutstandingOutputBuffers, 0); - --mNumOutstandingOutputBuffers; - - if (mFlushing) { - completeFlushIfPossible(); - break; - } - - ++mNumPendingDecodes; - mReader->readMore(); - break; - } - - case kWhatFlush: - { - onFlush(); - break; - } - - case kWhatResume: - { - onResume(); - break; - } - - default: - TRESPASS(); - break; - } -} - -void DecoderWrapper::onSetup(const sp<AMessage> &msg) { - AString mime; - CHECK(msg->findString("mime", &mime)); - - CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)); - - int32_t numChannels, sampleRate; - CHECK(msg->findInt32("channel-count", &numChannels)); - CHECK(msg->findInt32("sample-rate", &sampleRate)); - - sp<RefBase> obj; - CHECK(msg->findObject("esds", &obj)); - sp<ABuffer> esds = static_cast<ABuffer *>(obj.get()); - - sp<MetaData> meta = new MetaData; - meta->setCString(kKeyMIMEType, mime.c_str()); - meta->setInt32(kKeySampleRate, sampleRate); - meta->setInt32(kKeyChannelCount, numChannels); - meta->setData(kKeyESDS, 0, esds->data(), esds->size()); - - mSource = new WrapperSource( - meta, new AMessage(kWhatInputDataRequested, id())); - - sp<MediaSource> decoder = new AACDecoder(mSource); - - mReaderLooper = new ALooper; - mReaderLooper->setName("DecoderWrapper looper"); - - mReaderLooper->start( - false, /* runOnCallingThread */ - false, /* canCallJava */ - PRIORITY_AUDIO); - - sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id()); - notify->setMessage("real-notify", mNotify); - - mReader = new WrapperReader(decoder, notify); - mReaderLooper->registerHandler(mReader); - - mReader->start(); - ++mNumPendingDecodes; -} - -void DecoderWrapper::onShutdown() { - mReaderLooper->stop(); - mReaderLooper.clear(); - - mReader->stop(); - mReader.clear(); - - mSource.clear(); - - mNumOutstandingInputBuffers = 0; - mNumOutstandingOutputBuffers = 0; - mNumPendingDecodes = 0; - mFlushing = false; - - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", ACodec::kWhatShutdownCompleted); - notify->post(); -} - -void DecoderWrapper::postFillBuffer() { - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", ACodec::kWhatFillThisBuffer); - sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); - notify->setMessage("reply", reply); - notify->post(); -} - -void DecoderWrapper::onFlush() { - CHECK(!mFlushing); - mFlushing = true; - - completeFlushIfPossible(); -} - -void DecoderWrapper::completeFlushIfPossible() { - CHECK(mFlushing); - - if (mNumOutstandingInputBuffers > 0 - || mNumOutstandingOutputBuffers > 0 - || mNumPendingDecodes > 0) { - return; - } - - mFlushing = false; - - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", ACodec::kWhatFlushCompleted); - notify->post(); -} - -void DecoderWrapper::onResume() { - CHECK(!mFlushing); - - ++mNumPendingDecodes; - - mSource->clear(); - mReader->readMore(true /* flush */); -} - -} // namespace android diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h deleted file mode 100644 index b9be12c..0000000 --- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DECODER_WRAPPER_H_ - -#define DECODER_WRAPPER_H_ - -#include <media/stagefright/foundation/AHandler.h> - -namespace android { - -struct MediaSource; - -struct DecoderWrapper : public AHandler { - DecoderWrapper(); - - void setNotificationMessage(const sp<AMessage> &msg); - void initiateSetup(const sp<AMessage> &msg); - void initiateShutdown(); - void signalFlush(); - void signalResume(); - -protected: - virtual ~DecoderWrapper(); - - virtual void onMessageReceived(const sp<AMessage> &msg); - -private: - struct WrapperSource; - struct WrapperReader; - - enum { - kWhatSetup, - kWhatInputBufferFilled, - kWhatOutputBufferDrained, - kWhatShutdown, - kWhatFillBufferDone, - kWhatInputDataRequested, - kWhatFlush, - kWhatResume, - }; - - sp<AMessage> mNotify; - - sp<WrapperSource> mSource; - - sp<ALooper> mReaderLooper; - sp<WrapperReader> mReader; - - int32_t mNumOutstandingInputBuffers; - int32_t mNumOutstandingOutputBuffers; - int32_t mNumPendingDecodes; - bool mFlushing; - - void onSetup(const sp<AMessage> &msg); - void onShutdown(); - void onFlush(); - void onResume(); - - void postFillBuffer(); - void completeFlushIfPossible(); - - DISALLOW_EVIL_CONSTRUCTORS(DecoderWrapper); -}; - -} // namespace android - -#endif // DECODER_WRAPPER_H_ - diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index d07ea1b..576a850 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -33,11 +33,25 @@ namespace android { -NuPlayer::HTTPLiveSource::HTTPLiveSource(const char *url, uint32_t flags) +NuPlayer::HTTPLiveSource::HTTPLiveSource( + const char *url, + const KeyedVector<String8, String8> *headers) : mURL(url), - mFlags(flags), + mFlags(0), mEOS(false), mOffset(0) { + if (headers) { + mExtraHeaders = *headers; + + ssize_t index = + mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log")); + + if (index >= 0) { + mFlags |= kFlagIncognito; + + mExtraHeaders.removeItemsAt(index); + } + } } NuPlayer::HTTPLiveSource::~HTTPLiveSource() { @@ -55,7 +69,8 @@ void NuPlayer::HTTPLiveSource::start() { mLiveLooper->registerHandler(mLiveSession); - mLiveSession->connect(mURL.c_str()); + mLiveSession->connect( + mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); mTSParser = new ATSParser; } diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index a8ce7f4..7a337e9 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -27,11 +27,9 @@ struct ATSParser; struct LiveSession; struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { - enum Flags { - // Don't log any URLs. - kFlagIncognito = 1, - }; - HTTPLiveSource(const char *url, uint32_t flags = 0); + HTTPLiveSource( + const char *url, + const KeyedVector<String8, String8> *headers); virtual void start(); @@ -49,7 +47,13 @@ protected: virtual ~HTTPLiveSource(); private: + enum Flags { + // Don't log any URLs. + kFlagIncognito = 1, + }; + AString mURL; + KeyedVector<String8, String8> mExtraHeaders; uint32_t mFlags; bool mEOS; off64_t mOffset; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index d439f6e..effa703 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -72,17 +72,7 @@ void NuPlayer::setDataSource( const char *url, const KeyedVector<String8, String8> *headers) { sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); - uint32_t flags = 0; - - if (headers) { - ssize_t index = headers->indexOfKey(String8("x-hide-urls-from-log")); - - if (index >= 0) { - flags |= HTTPLiveSource::kFlagIncognito; - } - } - - msg->setObject("source", new HTTPLiveSource(url, flags)); + msg->setObject("source", new HTTPLiveSource(url, headers)); msg->post(); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 517acc9..81b41ef 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -20,7 +20,6 @@ #include "NuPlayerDecoder.h" -#include "DecoderWrapper.h" #include "ESDS.h" #include <media/stagefright/foundation/ABuffer.h> @@ -47,7 +46,6 @@ NuPlayer::Decoder::~Decoder() { void NuPlayer::Decoder::configure(const sp<MetaData> &meta) { CHECK(mCodec == NULL); - CHECK(mWrapper == NULL); const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); @@ -61,19 +59,11 @@ void NuPlayer::Decoder::configure(const sp<MetaData> &meta) { format->setObject("native-window", mNativeWindow); } - if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { - mWrapper = new DecoderWrapper; - looper()->registerHandler(mWrapper); + mCodec = new ACodec; + looper()->registerHandler(mCodec); - mWrapper->setNotificationMessage(notifyMsg); - mWrapper->initiateSetup(format); - } else { - mCodec = new ACodec; - looper()->registerHandler(mCodec); - - mCodec->setNotificationMessage(notifyMsg); - mCodec->initiateSetup(format); - } + mCodec->setNotificationMessage(notifyMsg); + mCodec->initiateSetup(format); } void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { @@ -214,7 +204,6 @@ sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) { msg->setObject("csd", buffer); } else if (meta->findData(kKeyESDS, &type, &data, &size)) { -#if 0 ESDS esds((const char *)data, size); CHECK_EQ(esds.InitCheck(), (status_t)OK); @@ -230,12 +219,6 @@ sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) { buffer->meta()->setInt32("csd", true); mCSD.push(buffer); -#else - sp<ABuffer> buffer = new ABuffer(size); - memcpy(buffer->data(), data, size); - - msg->setObject("esds", buffer); -#endif } return msg; @@ -270,27 +253,18 @@ void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) { void NuPlayer::Decoder::signalFlush() { if (mCodec != NULL) { mCodec->signalFlush(); - } else { - CHECK(mWrapper != NULL); - mWrapper->signalFlush(); } } void NuPlayer::Decoder::signalResume() { if (mCodec != NULL) { mCodec->signalResume(); - } else { - CHECK(mWrapper != NULL); - mWrapper->signalResume(); } } void NuPlayer::Decoder::initiateShutdown() { if (mCodec != NULL) { mCodec->initiateShutdown(); - } else { - CHECK(mWrapper != NULL); - mWrapper->initiateShutdown(); } } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index 732f090..fabc606 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -25,7 +25,6 @@ namespace android { struct ABuffer; -struct DecoderWrapper; struct NuPlayer::Decoder : public AHandler { Decoder(const sp<AMessage> ¬ify, @@ -51,7 +50,6 @@ private: sp<NativeWindowWrapper> mNativeWindow; sp<ACodec> mCodec; - sp<DecoderWrapper> mWrapper; Vector<sp<ABuffer> > mCSD; size_t mCSDIndex; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 0eca958..e1213f4 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -246,6 +246,14 @@ void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) { mPlayer->setAudioSink(audioSink); } +status_t NuPlayerDriver::setParameter(int key, const Parcel &request) { + return INVALID_OPERATION; +} + +status_t NuPlayerDriver::getParameter(int key, Parcel *reply) { + return INVALID_OPERATION; +} + status_t NuPlayerDriver::getMetadata( const media::Metadata::Filter& ids, Parcel *records) { return INVALID_OPERATION; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h index 67d0f3e..145fd80 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h @@ -52,6 +52,8 @@ struct NuPlayerDriver : public MediaPlayerInterface { virtual player_type playerType(); virtual status_t invoke(const Parcel &request, Parcel *reply); virtual void setAudioSink(const sp<AudioSink> &audioSink); + virtual status_t setParameter(int key, const Parcel &request); + virtual status_t getParameter(int key, Parcel *reply); virtual status_t getMetadata( const media::Metadata::Filter& ids, Parcel *records); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 369a3a8..828e008 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -198,18 +198,21 @@ void NuPlayer::Renderer::signalAudioSinkChanged() { } void NuPlayer::Renderer::onDrainAudioQueue() { - uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - ssize_t numFramesAvailableToWrite = - mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); + for (;;) { + uint32_t numFramesPlayed; + CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - CHECK_GE(numFramesAvailableToWrite, 0); + ssize_t numFramesAvailableToWrite = + mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); - size_t numBytesAvailableToWrite = - numFramesAvailableToWrite * mAudioSink->frameSize(); + size_t numBytesAvailableToWrite = + numFramesAvailableToWrite * mAudioSink->frameSize(); + + if (numBytesAvailableToWrite == 0) { + break; + } - while (numBytesAvailableToWrite > 0) { if (mAudioQueue.empty()) { break; } @@ -264,10 +267,10 @@ void NuPlayer::Renderer::onDrainAudioQueue() { if (entry->mOffset == entry->mBuffer->size()) { entry->mNotifyConsumed->post(); mAudioQueue.erase(mAudioQueue.begin()); + entry = NULL; } - numBytesAvailableToWrite -= copy; mNumFramesWritten += copy / mAudioSink->frameSize(); } |
