diff options
Diffstat (limited to 'media')
35 files changed, 531 insertions, 217 deletions
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index 7d8222f..bbeb854 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -35,13 +35,14 @@ namespace android { // --------------------------------------------------------------------------- -AudioEffect::AudioEffect() - : mStatus(NO_INIT) +AudioEffect::AudioEffect(const String16& opPackageName) + : mStatus(NO_INIT), mOpPackageName(opPackageName) { } AudioEffect::AudioEffect(const effect_uuid_t *type, + const String16& opPackageName, const effect_uuid_t *uuid, int32_t priority, effect_callback_t cbf, @@ -49,12 +50,13 @@ AudioEffect::AudioEffect(const effect_uuid_t *type, int sessionId, audio_io_handle_t io ) - : mStatus(NO_INIT) + : mStatus(NO_INIT), mOpPackageName(opPackageName) { mStatus = set(type, uuid, priority, cbf, user, sessionId, io); } AudioEffect::AudioEffect(const char *typeStr, + const String16& opPackageName, const char *uuidStr, int32_t priority, effect_callback_t cbf, @@ -62,7 +64,7 @@ AudioEffect::AudioEffect(const char *typeStr, int sessionId, audio_io_handle_t io ) - : mStatus(NO_INIT) + : mStatus(NO_INIT), mOpPackageName(opPackageName) { effect_uuid_t type; effect_uuid_t *pType = NULL; @@ -128,7 +130,7 @@ status_t AudioEffect::set(const effect_uuid_t *type, mIEffectClient = new EffectClient(this); iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor, - mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled); + mIEffectClient, priority, io, mSessionId, mOpPackageName, &mStatus, &mId, &enabled); if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) { ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus); diff --git a/media/libmedia/AudioPolicy.cpp b/media/libmedia/AudioPolicy.cpp index 786eb63..9d07011 100644 --- a/media/libmedia/AudioPolicy.cpp +++ b/media/libmedia/AudioPolicy.cpp @@ -68,7 +68,7 @@ status_t AudioMix::readFromParcel(Parcel *parcel) mFormat.format = (audio_format_t)parcel->readInt32(); mRouteFlags = parcel->readInt32(); mRegistrationId = parcel->readString8(); - mFlags = (uint32_t)parcel->readInt32(); + mCbFlags = (uint32_t)parcel->readInt32(); size_t size = (size_t)parcel->readInt32(); if (size > MAX_CRITERIA_PER_MIX) { size = MAX_CRITERIA_PER_MIX; @@ -90,7 +90,7 @@ status_t AudioMix::writeToParcel(Parcel *parcel) const parcel->writeInt32(mFormat.format); parcel->writeInt32(mRouteFlags); parcel->writeString8(mRegistrationId); - parcel->writeInt32(mFlags); + parcel->writeInt32(mCbFlags); size_t size = mCriteria.size(); if (size > MAX_CRITERIA_PER_MIX) { size = MAX_CRITERIA_PER_MIX; diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 9f5c4c5..9a61977 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -65,8 +65,8 @@ status_t AudioRecord::getMinFrameCount( // --------------------------------------------------------------------------- -AudioRecord::AudioRecord() - : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), +AudioRecord::AudioRecord(const String16 &opPackageName) + : mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE) { @@ -77,6 +77,7 @@ AudioRecord::AudioRecord( uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, + const String16& opPackageName, size_t frameCount, callback_t cbf, void* user, @@ -85,7 +86,9 @@ AudioRecord::AudioRecord( transfer_type transferType, audio_input_flags_t flags, const audio_attributes_t* pAttributes) - : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), + : mStatus(NO_INIT), + mOpPackageName(opPackageName), + mSessionId(AUDIO_SESSION_ALLOCATE), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mProxy(NULL), @@ -136,9 +139,9 @@ status_t AudioRecord::set( const audio_attributes_t* pAttributes) { ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " - "notificationFrames %u, sessionId %d, transferType %d, flags %#x", + "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s", inputSource, sampleRate, format, channelMask, frameCount, notificationFrames, - sessionId, transferType, flags); + sessionId, transferType, flags, String8(mOpPackageName).string()); switch (transferType) { case TRANSFER_DEFAULT: @@ -235,7 +238,7 @@ status_t AudioRecord::set( } // create the IAudioRecord - status_t status = openRecord_l(0 /*epoch*/); + status_t status = openRecord_l(0 /*epoch*/, mOpPackageName); if (status != NO_ERROR) { if (mAudioRecordThread != 0) { @@ -435,7 +438,7 @@ audio_port_handle_t AudioRecord::getInputDevice() { // ------------------------------------------------------------------------- // must be called with mLock held -status_t AudioRecord::openRecord_l(size_t epoch) +status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) { const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); if (audioFlinger == 0) { @@ -502,8 +505,10 @@ status_t AudioRecord::openRecord_l(size_t epoch) sp<IMemory> iMem; // for cblk sp<IMemory> bufferMem; sp<IAudioRecord> record = audioFlinger->openRecord(input, - mSampleRate, mFormat, + mSampleRate, + mFormat, mChannelMask, + opPackageName, &temp, &trackFlags, tid, @@ -1032,7 +1037,7 @@ status_t AudioRecord::restoreRecord_l(const char *from) // It will also delete the strong references on previous IAudioRecord and IMemory size_t position = mProxy->getPosition(); mNewPosition = position + mUpdatePeriod; - status_t result = openRecord_l(position); + status_t result = openRecord_l(position, mOpPackageName); if (result == NO_ERROR) { if (mActive) { // callback thread or sync event hasn't changed diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 3478441..928856d 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -37,6 +37,7 @@ Mutex AudioSystem::gLockAPS; sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; +dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; // Cached values for output handles DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSystem::gOutputs(NULL); @@ -536,12 +537,18 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle } } -void AudioSystem::setErrorCallback(audio_error_callback cb) +/*static*/ void AudioSystem::setErrorCallback(audio_error_callback cb) { Mutex::Autolock _l(gLock); gAudioErrorCallback = cb; } +/*static*/ void AudioSystem::setDynPolicyCallback(dynamic_policy_callback cb) +{ + Mutex::Autolock _l(gLock); + gDynPolicyCallback = cb; +} + // client singleton for AudioPolicyService binder interface // protected by gLockAPS sp<IAudioPolicyService> AudioSystem::gAudioPolicyService; @@ -943,6 +950,7 @@ status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callBack return gAudioPolicyServiceClient->addAudioPortCallback(callBack); } +/*static*/ status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callBack) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); @@ -955,7 +963,6 @@ status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callB return gAudioPolicyServiceClient->removeAudioPortCallback(callBack); } - status_t AudioSystem::acquireSoundTriggerSession(audio_session_t *session, audio_io_handle_t *ioHandle, audio_devices_t *device) @@ -1053,7 +1060,16 @@ void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate( String8 regId, int32_t state) { - ALOGV("TODO propagate onDynamicPolicyMixStateUpdate(%s, %d)", regId.string(), state); + ALOGV("AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(%s, %d)", regId.string(), state); + dynamic_policy_callback cb = NULL; + { + Mutex::Autolock _l(AudioSystem::gLock); + cb = gDynPolicyCallback; + } + + if (cb != NULL) { + cb(DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE, regId, state); + } } void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 38055f9..d48532e 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -174,6 +174,7 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, + const String16& opPackageName, size_t *pFrameCount, track_flags_t *flags, pid_t tid, @@ -190,6 +191,7 @@ public: data.writeInt32(sampleRate); data.writeInt32(format); data.writeInt32(channelMask); + data.writeString16(opPackageName); size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0; data.writeInt64(frameCount); track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT; @@ -702,6 +704,7 @@ public: int32_t priority, audio_io_handle_t output, int sessionId, + const String16& opPackageName, status_t *status, int *id, int *enabled) @@ -722,6 +725,7 @@ public: data.writeInt32(priority); data.writeInt32((int32_t) output); data.writeInt32(sessionId); + data.writeString16(opPackageName); status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply); if (lStatus != NO_ERROR) { @@ -950,6 +954,7 @@ status_t BnAudioFlinger::onTransact( uint32_t sampleRate = data.readInt32(); audio_format_t format = (audio_format_t) data.readInt32(); audio_channel_mask_t channelMask = data.readInt32(); + const String16& opPackageName = data.readString16(); size_t frameCount = data.readInt64(); track_flags_t flags = (track_flags_t) data.readInt32(); pid_t tid = (pid_t) data.readInt32(); @@ -959,9 +964,8 @@ status_t BnAudioFlinger::onTransact( sp<IMemory> buffers; status_t status; sp<IAudioRecord> record = openRecord(input, - sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId, - ¬ificationFrames, - cblk, buffers, &status); + sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid, + &sessionId, ¬ificationFrames, cblk, buffers, &status); LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR)); reply->writeInt64(frameCount); reply->writeInt32(flags); @@ -1247,12 +1251,13 @@ status_t BnAudioFlinger::onTransact( int32_t priority = data.readInt32(); audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); int sessionId = data.readInt32(); + const String16 opPackageName = data.readString16(); status_t status; int id; int enabled; sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId, - &status, &id, &enabled); + opPackageName, &status, &id, &enabled); reply->writeInt32(status); reply->writeInt32(id); reply->writeInt32(enabled); diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index aa7b2e1..05f8670 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -78,10 +78,11 @@ public: return interface_cast<IMediaPlayer>(reply.readStrongBinder()); } - virtual sp<IMediaRecorder> createMediaRecorder() + virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); + data.writeString16(opPackageName); remote()->transact(CREATE_MEDIA_RECORDER, data, &reply); return interface_cast<IMediaRecorder>(reply.readStrongBinder()); } @@ -128,11 +129,12 @@ public: return remote()->transact(PULL_BATTERY_DATA, data, reply); } - virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, - const String8& iface) + virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, + const sp<IRemoteDisplayClient>& client, const String8& iface) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); + data.writeString16(opPackageName); data.writeStrongBinder(IInterface::asBinder(client)); data.writeString8(iface); remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply); @@ -166,7 +168,8 @@ status_t BnMediaPlayerService::onTransact( } break; case CREATE_MEDIA_RECORDER: { CHECK_INTERFACE(IMediaPlayerService, data, reply); - sp<IMediaRecorder> recorder = createMediaRecorder(); + const String16 opPackageName = data.readString16(); + sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName); reply->writeStrongBinder(IInterface::asBinder(recorder)); return NO_ERROR; } break; @@ -214,10 +217,11 @@ status_t BnMediaPlayerService::onTransact( } break; case LISTEN_FOR_REMOTE_DISPLAY: { CHECK_INTERFACE(IMediaPlayerService, data, reply); + const String16 opPackageName = data.readString16(); sp<IRemoteDisplayClient> client( interface_cast<IRemoteDisplayClient>(data.readStrongBinder())); String8 iface(data.readString8()); - sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface)); + sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface)); reply->writeStrongBinder(IInterface::asBinder(display)); return NO_ERROR; } break; diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp index 9d69b6a..dc46038 100644 --- a/media/libmedia/Visualizer.cpp +++ b/media/libmedia/Visualizer.cpp @@ -34,11 +34,12 @@ namespace android { // --------------------------------------------------------------------------- -Visualizer::Visualizer (int32_t priority, +Visualizer::Visualizer (const String16& opPackageName, + int32_t priority, effect_callback_t cbf, void* user, int sessionId) - : AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId), + : AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId), mCaptureRate(CAPTURE_RATE_DEF), mCaptureSize(CAPTURE_SIZE_DEF), mSampleRate(44100000), diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp index a2d6e53..9470936 100644 --- a/media/libmedia/mediarecorder.cpp +++ b/media/libmedia/mediarecorder.cpp @@ -594,13 +594,13 @@ status_t MediaRecorder::release() return INVALID_OPERATION; } -MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL) +MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL) { ALOGV("constructor"); const sp<IMediaPlayerService>& service(getMediaPlayerService()); if (service != NULL) { - mMediaRecorder = service->createMediaRecorder(); + mMediaRecorder = service->createMediaRecorder(opPackageName); } if (mMediaRecorder != NULL) { mCurrentState = MEDIA_RECORDER_IDLE; diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 3bc763f..9567eff 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -307,10 +307,10 @@ MediaPlayerService::~MediaPlayerService() ALOGV("MediaPlayerService destroyed"); } -sp<IMediaRecorder> MediaPlayerService::createMediaRecorder() +sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName) { pid_t pid = IPCThreadState::self()->getCallingPid(); - sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); + sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName); wp<MediaRecorderClient> w = recorder; Mutex::Autolock lock(mLock); mMediaRecorderClients.add(w); @@ -381,12 +381,13 @@ sp<IHDCP> MediaPlayerService::makeHDCP(bool createEncryptionModule) { } sp<IRemoteDisplay> MediaPlayerService::listenForRemoteDisplay( + const String16 &opPackageName, const sp<IRemoteDisplayClient>& client, const String8& iface) { if (!checkPermission("android.permission.CONTROL_WIFI_DISPLAY")) { return NULL; } - return new RemoteDisplay(client, iface.string()); + return new RemoteDisplay(opPackageName, client, iface.string()); } status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 6ddfe14..1a3ce92 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -188,7 +188,7 @@ public: static void instantiate(); // IMediaPlayerService interface - virtual sp<IMediaRecorder> createMediaRecorder(); + virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName); void removeMediaRecorderClient(wp<MediaRecorderClient> client); virtual sp<IMediaMetadataRetriever> createMetadataRetriever(); @@ -200,8 +200,8 @@ public: virtual sp<IDrm> makeDrm(); virtual sp<IHDCP> makeHDCP(bool createEncryptionModule); - virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, - const String8& iface); + virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, + const sp<IRemoteDisplayClient>& client, const String8& iface); virtual status_t dump(int fd, const Vector<String16>& args); void removeClient(wp<Client> client); diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 319ebb0..40e9d1c 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -290,11 +290,12 @@ status_t MediaRecorderClient::release() return NO_ERROR; } -MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid) +MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid, + const String16& opPackageName) { ALOGV("Client constructor"); mPid = pid; - mRecorder = new StagefrightRecorder; + mRecorder = new StagefrightRecorder(opPackageName); mMediaPlayerService = service; } diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h index b45344b..e03ec3f 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.h +++ b/media/libmediaplayerservice/MediaRecorderClient.h @@ -62,7 +62,8 @@ private: MediaRecorderClient( const sp<MediaPlayerService>& service, - pid_t pid); + pid_t pid, + const String16& opPackageName); virtual ~MediaRecorderClient(); pid_t mPid; diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp index eb959b4..0eb4b5d 100644 --- a/media/libmediaplayerservice/RemoteDisplay.cpp +++ b/media/libmediaplayerservice/RemoteDisplay.cpp @@ -26,13 +26,14 @@ namespace android { RemoteDisplay::RemoteDisplay( + const String16 &opPackageName, const sp<IRemoteDisplayClient> &client, const char *iface) : mLooper(new ALooper), mNetSession(new ANetworkSession) { mLooper->setName("wfd_looper"); - mSource = new WifiDisplaySource(mNetSession, client); + mSource = new WifiDisplaySource(opPackageName, mNetSession, client); mLooper->registerHandler(mSource); mNetSession->start(); diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h index 1a48981..d4573e9 100644 --- a/media/libmediaplayerservice/RemoteDisplay.h +++ b/media/libmediaplayerservice/RemoteDisplay.h @@ -33,6 +33,7 @@ struct WifiDisplaySource; struct RemoteDisplay : public BnRemoteDisplay { RemoteDisplay( + const String16 &opPackageName, const sp<IRemoteDisplayClient> &client, const char *iface); diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 8a0b060..aa19a25 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -69,8 +69,9 @@ static void addBatteryData(uint32_t params) { } -StagefrightRecorder::StagefrightRecorder() - : mWriter(NULL), +StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName) + : MediaRecorderBase(opPackageName), + mWriter(NULL), mOutputFd(-1), mAudioSource(AUDIO_SOURCE_CNT), mVideoSource(VIDEO_SOURCE_LIST_END), @@ -905,6 +906,7 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { sp<AudioSource> audioSource = new AudioSource( mAudioSource, + mOpPackageName, mSampleRate, mAudioChannels); diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 8fa5bfa..1425f59 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -40,7 +40,7 @@ class SurfaceMediaSource; struct ALooper; struct StagefrightRecorder : public MediaRecorderBase { - StagefrightRecorder(); + StagefrightRecorder(const String16 &opPackageName); virtual ~StagefrightRecorder(); virtual status_t init(); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index c7df5a0..4fcee90 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -806,6 +806,11 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { return err; mNumUndequeuedBuffers = minUndequeuedBuffers; + if (!mStoreMetaDataInOutputBuffers) { + static_cast<Surface*>(mNativeWindow.get()) + ->getIGraphicBufferProducer()->allowAllocation(true); + } + ALOGV("[%s] Allocating %u buffers from a native window of size %u on " "output port", mComponentName.c_str(), bufferCount, bufferSize); @@ -864,6 +869,11 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { } } + if (!mStoreMetaDataInOutputBuffers) { + static_cast<Surface*>(mNativeWindow.get()) + ->getIGraphicBufferProducer()->allowAllocation(false); + } + return err; } @@ -4909,7 +4919,10 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { CHECK(mCodec->mNode == 0); OMXClient client; - CHECK_EQ(client.connect(), (status_t)OK); + if (client.connect() != OK) { + mCodec->signalError(OMX_ErrorUndefined, NO_INIT); + return false; + } sp<IOMX> omx = client.interface(); diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index 804f131..e5a6a9b 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -50,7 +50,8 @@ static void AudioRecordCallbackFunction(int event, void *user, void *info) { } AudioSource::AudioSource( - audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount) + audio_source_t inputSource, const String16 &opPackageName, uint32_t sampleRate, + uint32_t channelCount) : mStarted(false), mSampleRate(sampleRate), mPrevSampleTimeUs(0), @@ -78,6 +79,7 @@ AudioSource::AudioSource( mRecord = new AudioRecord( inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_in_mask_from_count(channelCount), + opPackageName, (size_t) (bufCount * frameCount), AudioRecordCallbackFunction, this, diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index 55e3c19..2e54e8c 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -282,6 +282,41 @@ MP3Extractor::MP3Extractor( mFirstFramePos = pos; mFixedHeader = header; + mMeta = new MetaData; + sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); + + if (seeker == NULL) { + mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos); + } else { + mSeeker = seeker; + int encd = seeker->getEncoderDelay(); + int encp = seeker->getEncoderPadding(); + if (encd != 0 || encp != 0) { + mMeta->setInt32(kKeyEncoderDelay, encd); + mMeta->setInt32(kKeyEncoderPadding, encp); + } + } + + if (mSeeker != NULL) { + // While it is safe to send the XING/VBRI frame to the decoder, this will + // result in an extra 1152 samples being output. In addition, the bitrate + // of the Xing header might not match the rest of the file, which could + // lead to problems when seeking. The real first frame to decode is after + // the XING/VBRI frame, so skip there. + size_t frame_size; + int sample_rate; + int num_channels; + int bitrate; + GetMPEGAudioFrameSize( + header, &frame_size, &sample_rate, &num_channels, &bitrate); + pos += frame_size; + if (!Resync(mDataSource, 0, &pos, &post_id3_pos, &header)) { + // mInitCheck will remain NO_INIT + return; + } + mFirstFramePos = pos; + mFixedHeader = header; + } size_t frame_size; int sample_rate; @@ -292,8 +327,6 @@ MP3Extractor::MP3Extractor( unsigned layer = 4 - ((header >> 17) & 3); - mMeta = new MetaData; - switch (layer) { case 1: mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); @@ -312,27 +345,6 @@ MP3Extractor::MP3Extractor( mMeta->setInt32(kKeyBitRate, bitrate * 1000); mMeta->setInt32(kKeyChannelCount, num_channels); - sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); - - if (seeker == NULL) { - mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos); - } else { - mSeeker = seeker; - int encd = seeker->getEncoderDelay(); - int encp = seeker->getEncoderPadding(); - if (encd != 0 || encp != 0) { - mMeta->setInt32(kKeyEncoderDelay, encd); - mMeta->setInt32(kKeyEncoderPadding, encp); - } - } - - if (mSeeker != NULL) { - // While it is safe to send the XING/VBRI frame to the decoder, this will - // result in an extra 1152 samples being output. The real first frame to - // decode is after the XING/VBRI frame, so skip there. - mFirstFramePos += frame_size; - } - int64_t durationUs; if (mSeeker == NULL || !mSeeker->getDuration(&durationUs)) { diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index aa0d2e6..8a2dc35 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -392,6 +392,10 @@ status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { tmp.erase(tmp.size() - 7, 7); } const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); + if (mcl == NULL) { + mCodec = NULL; // remove the codec. + return NO_INIT; // if called from Java should raise IOException + } ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); if (codecIdx >= 0) { const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index 26798ae..f12a913 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -80,6 +80,10 @@ sp<IMediaCodecList> MediaCodecList::getLocalInstance() { infos.push_back(gCodecList->getCodecInfo(i)); } } + } else { + // failure to initialize may be temporary. retry on next call. + delete gCodecList; + gCodecList = NULL; } } } @@ -168,7 +172,7 @@ void MediaCodecList::parseTopLevelXMLFile(const char *codecs_xml, bool ignore_er OMXClient client; mInitCheck = client.connect(); if (mInitCheck != OK) { - return; + return; // this may fail if IMediaPlayerService is not available. } mOMX = client.interface(); parseXMLFile(codecs_xml); @@ -882,14 +886,16 @@ status_t MediaCodecList::addLimit(const char **attrs) { return -EINVAL; } - // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio: range + // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio, + // measured-frame-rate, measured-blocks-per-second: range // quality: range + default + [scale] // complexity: range + default bool found; if (name == "aspect-ratio" || name == "bitrate" || name == "block-count" || name == "blocks-per-second" || name == "complexity" - || name == "frame-rate" || name == "quality" || name == "size") { + || name == "frame-rate" || name == "quality" || name == "size" + || name == "measured-blocks-per-second" || name == "measured-frame-rate") { AString min, max; if (msg->findString("min", &min) && msg->findString("max", &max)) { min.append("-"); diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp index 230c1f7..06a598f 100644 --- a/media/libstagefright/OMXClient.cpp +++ b/media/libstagefright/OMXClient.cpp @@ -400,10 +400,16 @@ status_t OMXClient::connect() { sp<IBinder> binder = sm->getService(String16("media.player")); sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); - CHECK(service.get() != NULL); + if (service.get() == NULL) { + ALOGE("Cannot obtain IMediaPlayerService"); + return NO_INIT; + } mOMX = service->getOMX(); - CHECK(mOMX.get() != NULL); + if (mOMX.get() == NULL) { + ALOGE("Cannot obtain IOMX"); + return NO_INIT; + } if (!mOMX->livesLocally(0 /* node */, getpid())) { ALOGI("Using client-side OMX mux."); diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index 0d8e64a..7b089b0 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -181,6 +181,11 @@ status_t convertMetaDataToMessage( msg->setInt32("rotation-degrees", rotationDegrees); } + int32_t fps; + if (meta->findInt32(kKeyFrameRate, &fps)) { + msg->setInt32("frame-rate", fps); + } + uint32_t type; const void *data; size_t size; @@ -588,6 +593,11 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { meta->setInt32(kKeyMaxHeight, maxHeight); } + int32_t fps; + if (msg->findInt32("frame-rate", &fps)) { + meta->setInt32(kKeyFrameRate, fps); + } + // reassemble the csd data into its original form sp<ABuffer> csd0; if (msg->findBuffer("csd-0", &csd0)) { diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index ddca437..70d2c69 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -925,6 +925,11 @@ void MatroskaExtractor::addTracks() { ALOGV("codec id = %s", codecID); ALOGV("codec name = %s", track->GetCodecNameAsUTF8()); + if (codecID == NULL) { + ALOGW("unknown codecID is not supported."); + continue; + } + size_t codecPrivateSize; const unsigned char *codecPrivate = track->GetCodecPrivate(codecPrivateSize); @@ -941,10 +946,7 @@ void MatroskaExtractor::addTracks() { const mkvparser::VideoTrack *vtrack = static_cast<const mkvparser::VideoTrack *>(track); - if (codecID == NULL) { - ALOGW("unknown codecID is not supported."); - continue; - } else if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { + if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 5411821..0d071b2 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -302,9 +302,13 @@ bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) { // The two checks below shouldn't happen, // we already checked above the stream count matches ssize_t index = newType2PIDs.indexOfKey(temp[i]->type()); - CHECK(index >= 0); + if (index < 0) { + return false; + } Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index); - CHECK(newPIDs.size() > 0); + if (newPIDs.isEmpty()) { + return false; + } // get the next PID for temp[i]->type() in the new PID map Vector<int32_t>::iterator it = newPIDs.begin(); @@ -335,13 +339,11 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { return ERROR_MALFORMED; } - CHECK_EQ(br->getBits(1), 0u); + br->skipBits(1); // '0' MY_LOGV(" reserved = %u", br->getBits(2)); unsigned section_length = br->getBits(12); ALOGV(" section_length = %u", section_length); - CHECK_EQ(section_length & 0xc00, 0u); - CHECK_LE(section_length, 1021u); MY_LOGV(" program_number = %u", br->getBits(16)); MY_LOGV(" reserved = %u", br->getBits(2)); @@ -358,7 +360,6 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { unsigned program_info_length = br->getBits(12); ALOGV(" program_info_length = %u", program_info_length); - CHECK_EQ(program_info_length & 0xc00, 0u); br->skipBits(program_info_length * 8); // skip descriptors @@ -369,8 +370,7 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { // final CRC. size_t infoBytesRemaining = section_length - 9 - program_info_length - 4; - while (infoBytesRemaining > 0) { - CHECK_GE(infoBytesRemaining, 5u); + while (infoBytesRemaining >= 5) { unsigned streamType = br->getBits(8); ALOGV(" stream_type = 0x%02x", streamType); @@ -384,9 +384,6 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { unsigned ES_info_length = br->getBits(12); ALOGV(" ES_info_length = %u", ES_info_length); - CHECK_EQ(ES_info_length & 0xc00, 0u); - - CHECK_GE(infoBytesRemaining - 5, ES_info_length); #if 0 br->skipBits(ES_info_length * 8); // skip descriptors @@ -398,13 +395,13 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { unsigned descLength = br->getBits(8); ALOGV(" len = %u", descLength); - CHECK_GE(info_bytes_remaining, 2 + descLength); - + if (info_bytes_remaining < descLength) { + return ERROR_MALFORMED; + } br->skipBits(descLength * 8); info_bytes_remaining -= descLength + 2; } - CHECK_EQ(info_bytes_remaining, 0u); #endif StreamInfo info; @@ -415,7 +412,9 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) { infoBytesRemaining -= 5 + ES_info_length; } - CHECK_EQ(infoBytesRemaining, 0u); + if (infoBytesRemaining != 0) { + ALOGW("Section data remains unconsumed"); + } MY_LOGV(" CRC = 0x%08x", br->getBits(32)); bool PIDsChanged = false; @@ -680,7 +679,10 @@ status_t ATSParser::Stream::parse( } size_t payloadSizeBits = br->numBitsLeft(); - CHECK_EQ(payloadSizeBits % 8, 0u); + if (payloadSizeBits % 8 != 0u) { + ALOGE("Wrong value"); + return BAD_VALUE; + } size_t neededSize = mBuffer->size() + payloadSizeBits / 8; if (mBuffer->capacity() < neededSize) { @@ -797,8 +799,6 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { return ERROR_MALFORMED; } - CHECK_EQ(packet_startcode_prefix, 0x000001u); - unsigned stream_id = br->getBits(8); ALOGV("stream_id = 0x%02x", stream_id); @@ -813,7 +813,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { && stream_id != 0xff // program_stream_directory && stream_id != 0xf2 // DSMCC && stream_id != 0xf8) { // H.222.1 type E - CHECK_EQ(br->getBits(2), 2u); + if (br->getBits(2) != 2u) { + return ERROR_MALFORMED; + } MY_LOGV("PES_scrambling_control = %u", br->getBits(2)); MY_LOGV("PES_priority = %u", br->getBits(1)); @@ -847,34 +849,51 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { uint64_t PTS = 0, DTS = 0; if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { - CHECK_GE(optional_bytes_remaining, 5u); + if (optional_bytes_remaining < 5u) { + return ERROR_MALFORMED; + } if (br->getBits(4) != PTS_DTS_flags) { - ALOGE("PES data Error!"); return ERROR_MALFORMED; } PTS = ((uint64_t)br->getBits(3)) << 30; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } PTS |= ((uint64_t)br->getBits(15)) << 15; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } PTS |= br->getBits(15); - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0); optional_bytes_remaining -= 5; if (PTS_DTS_flags == 3) { - CHECK_GE(optional_bytes_remaining, 5u); + if (optional_bytes_remaining < 5u) { + return ERROR_MALFORMED; + } - CHECK_EQ(br->getBits(4), 1u); + if (br->getBits(4) != 1u) { + return ERROR_MALFORMED; + } DTS = ((uint64_t)br->getBits(3)) << 30; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } DTS |= ((uint64_t)br->getBits(15)) << 15; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } DTS |= br->getBits(15); - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("DTS = %" PRIu64, DTS); @@ -883,31 +902,47 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { } if (ESCR_flag) { - CHECK_GE(optional_bytes_remaining, 6u); + if (optional_bytes_remaining < 6u) { + return ERROR_MALFORMED; + } br->getBits(2); uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } ESCR |= ((uint64_t)br->getBits(15)) << 15; - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } ESCR |= br->getBits(15); - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("ESCR = %" PRIu64, ESCR); MY_LOGV("ESCR_extension = %u", br->getBits(9)); - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } optional_bytes_remaining -= 6; } if (ES_rate_flag) { - CHECK_GE(optional_bytes_remaining, 3u); + if (optional_bytes_remaining < 3u) { + return ERROR_MALFORMED; + } - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } MY_LOGV("ES_rate = %u", br->getBits(22)); - CHECK_EQ(br->getBits(1), 1u); + if (br->getBits(1) != 1u) { + return ERROR_MALFORMED; + } optional_bytes_remaining -= 3; } @@ -917,7 +952,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { // ES data follows. if (PES_packet_length != 0) { - CHECK_GE(PES_packet_length, PES_header_data_length + 3); + if (PES_packet_length < PES_header_data_length + 3) { + return ERROR_MALFORMED; + } unsigned dataLength = PES_packet_length - 3 - PES_header_data_length; @@ -930,7 +967,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { return ERROR_MALFORMED; } - CHECK_GE(br->numBitsLeft(), dataLength * 8); + if (br->numBitsLeft() < dataLength * 8) { + return ERROR_MALFORMED; + } onPayloadData( PTS_DTS_flags, PTS, DTS, br->data(), dataLength); @@ -942,15 +981,21 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) { br->data(), br->numBitsLeft() / 8); size_t payloadSizeBits = br->numBitsLeft(); - CHECK_EQ(payloadSizeBits % 8, 0u); + if (payloadSizeBits % 8 != 0u) { + return ERROR_MALFORMED; + } ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8); } } else if (stream_id == 0xbe) { // padding_stream - CHECK_NE(PES_packet_length, 0u); + if (PES_packet_length == 0u) { + return ERROR_MALFORMED; + } br->skipBits(PES_packet_length * 8); } else { - CHECK_NE(PES_packet_length, 0u); + if (PES_packet_length == 0u) { + return ERROR_MALFORMED; + } br->skipBits(PES_packet_length * 8); } @@ -1082,7 +1127,10 @@ ATSParser::~ATSParser() { } status_t ATSParser::feedTSPacket(const void *data, size_t size) { - CHECK_EQ(size, kTSPacketSize); + if (size != kTSPacketSize) { + ALOGE("Wrong TS packet size"); + return BAD_VALUE; + } ABitReader br((const uint8_t *)data, kTSPacketSize); return parseTS(&br); @@ -1108,14 +1156,23 @@ void ATSParser::signalDiscontinuity( } } else if (type == DISCONTINUITY_ABSOLUTE_TIME) { int64_t timeUs; - CHECK(extra->findInt64("timeUs", &timeUs)); + if (!extra->findInt64("timeUs", &timeUs)) { + ALOGE("timeUs not found"); + return; + } - CHECK(mPrograms.empty()); + if (!mPrograms.empty()) { + ALOGE("mPrograms is not empty"); + return; + } mAbsoluteTimeAnchorUs = timeUs; return; } else if (type == DISCONTINUITY_TIME_OFFSET) { int64_t offset; - CHECK(extra->findInt64("offset", &offset)); + if (!extra->findInt64("offset", &offset)) { + ALOGE("offset not found"); + return; + } mTimeOffsetValid = true; mTimeOffsetUs = offset; @@ -1128,7 +1185,10 @@ void ATSParser::signalDiscontinuity( } void ATSParser::signalEOS(status_t finalResult) { - CHECK_NE(finalResult, (status_t)OK); + if (finalResult == (status_t) OK) { + ALOGE("finalResult not OK"); + return; + } for (size_t i = 0; i < mPrograms.size(); ++i) { mPrograms.editItemAt(i)->signalEOS(finalResult); @@ -1144,14 +1204,12 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { } unsigned section_syntax_indictor = br->getBits(1); ALOGV(" section_syntax_indictor = %u", section_syntax_indictor); - CHECK_EQ(section_syntax_indictor, 1u); - CHECK_EQ(br->getBits(1), 0u); + br->skipBits(1); // '0' MY_LOGV(" reserved = %u", br->getBits(2)); unsigned section_length = br->getBits(12); ALOGV(" section_length = %u", section_length); - CHECK_EQ(section_length & 0xc00, 0u); MY_LOGV(" transport_stream_id = %u", br->getBits(16)); MY_LOGV(" reserved = %u", br->getBits(2)); @@ -1161,7 +1219,6 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { MY_LOGV(" last_section_number = %u", br->getBits(8)); size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */); - CHECK_EQ((numProgramBytes % 4), 0u); for (size_t i = 0; i < numProgramBytes / 4; ++i) { unsigned program_number = br->getBits(16); @@ -1221,7 +1278,9 @@ status_t ATSParser::parsePID( br->skipBits(skip * 8); } - CHECK((br->numBitsLeft() % 8) == 0); + if (br->numBitsLeft() % 8 != 0) { + return ERROR_MALFORMED; + } status_t err = section->append(br->data(), br->numBitsLeft() / 8); if (err != OK) { @@ -1291,7 +1350,7 @@ status_t ATSParser::parsePID( return OK; } -void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { +status_t ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { unsigned adaptation_field_length = br->getBits(8); if (adaptation_field_length > 0) { @@ -1307,6 +1366,9 @@ void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { size_t numBitsRead = 4; if (PCR_flag) { + if (adaptation_field_length * 8 < 52) { + return ERROR_MALFORMED; + } br->skipBits(4); uint64_t PCR_base = br->getBits(32); PCR_base = (PCR_base << 1) | br->getBits(1); @@ -1337,10 +1399,9 @@ void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { numBitsRead += 52; } - CHECK_GE(adaptation_field_length * 8, numBitsRead); - br->skipBits(adaptation_field_length * 8 - numBitsRead); } + return OK; } status_t ATSParser::parseTS(ABitReader *br) { @@ -1375,15 +1436,16 @@ status_t ATSParser::parseTS(ABitReader *br) { // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter); - if (adaptation_field_control == 2 || adaptation_field_control == 3) { - parseAdaptationField(br, PID); - } - status_t err = OK; - if (adaptation_field_control == 1 || adaptation_field_control == 3) { - err = parsePID( - br, PID, continuity_counter, payload_unit_start_indicator); + if (adaptation_field_control == 2 || adaptation_field_control == 3) { + err = parseAdaptationField(br, PID); + } + if (err == OK) { + if (adaptation_field_control == 1 || adaptation_field_control == 3) { + err = parsePID( + br, PID, continuity_counter, payload_unit_start_indicator); + } } ++mNumTSPacketsParsed; diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 87ab1a0..4def333 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -133,7 +133,7 @@ private: unsigned continuity_counter, unsigned payload_unit_start_indicator); - void parseAdaptationField(ABitReader *br, unsigned PID); + status_t parseAdaptationField(ABitReader *br, unsigned PID); status_t parseTS(ABitReader *br); void updatePCR(unsigned PID, uint64_t PCR, size_t byteOffsetFromStart); diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index f28a1fd..7b5b46a 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -421,8 +421,8 @@ status_t ElementaryStreamQueue::appendData( } default: - TRESPASS(); - break; + ALOGE("Unknown mode: %d", mMode); + return ERROR_MALFORMED; } } @@ -503,7 +503,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() { case METADATA: return dequeueAccessUnitMetadata(); default: - CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO); + if (mMode != MPEG_AUDIO) { + ALOGE("Unknown mode"); + return NULL; + } return dequeueAccessUnitMPEGAudio(); } } @@ -540,7 +543,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() { memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize); int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("negative timeUs"); + return NULL; + } accessUnit->meta()->setInt64("timeUs", timeUs); accessUnit->meta()->setInt32("isSync", 1); @@ -560,15 +566,24 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() { } ABitReader bits(mBuffer->data(), 4); - CHECK_EQ(bits.getBits(8), 0xa0); + if (bits.getBits(8) != 0xa0) { + ALOGE("Unexpected bit values"); + return NULL; + } unsigned numAUs = bits.getBits(8); bits.skipBits(8); unsigned quantization_word_length __unused = 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 (audio_sampling_frequency != 2) { + ALOGE("Wrong sampling freq"); + return NULL; + } + if (num_channels != 1u) { + ALOGE("Wrong channel #"); + return NULL; + } if (mFormat == NULL) { mFormat = new MetaData; @@ -590,7 +605,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() { memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize); int64_t timeUs = fetchTimestamp(payloadSize + 4); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("Negative timeUs"); + return NULL; + } accessUnit->meta()->setInt64("timeUs", timeUs); accessUnit->meta()->setInt32("isSync", 1); @@ -614,14 +632,19 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { return NULL; } - CHECK(!mRangeInfos.empty()); + if (mRangeInfos.empty()) { + return NULL; + } const RangeInfo &info = *mRangeInfos.begin(); if (mBuffer->size() < info.mLength) { return NULL; } - CHECK_GE(info.mTimestampUs, 0ll); + if (info.mTimestampUs < 0ll) { + ALOGE("Negative info.mTimestampUs"); + return NULL; + } // The idea here is consume all AAC frames starting at offsets before // info.mLength so we can assign a meaningful timestamp without @@ -638,17 +661,26 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { // adts_fixed_header - CHECK_EQ(bits.getBits(12), 0xfffu); + if (bits.getBits(12) != 0xfffu) { + ALOGE("Wrong atds_fixed_header"); + return NULL; + } bits.skipBits(3); // ID, layer bool protection_absent __unused = bits.getBits(1) != 0; if (mFormat == NULL) { unsigned profile = bits.getBits(2); - CHECK_NE(profile, 3u); + if (profile == 3u) { + ALOGE("profile should not be 3"); + return NULL; + } unsigned sampling_freq_index = bits.getBits(4); bits.getBits(1); // private_bit unsigned channel_configuration = bits.getBits(3); - CHECK_NE(channel_configuration, 0u); + if (channel_configuration == 0u) { + ALOGE("channel_config should not be 0"); + return NULL; + } bits.skipBits(2); // original_copy, home mFormat = MakeAACCodecSpecificData( @@ -658,8 +690,14 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { int32_t sampleRate; int32_t numChannels; - CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate)); - CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels)); + if (!mFormat->findInt32(kKeySampleRate, &sampleRate)) { + ALOGE("SampleRate not found"); + return NULL; + } + if (!mFormat->findInt32(kKeyChannelCount, &numChannels)) { + ALOGE("ChannelCount not found"); + return NULL; + } ALOGI("found AAC codec config (%d Hz, %d channels)", sampleRate, numChannels); @@ -682,7 +720,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { if (number_of_raw_data_blocks_in_frame != 0) { // To be implemented. - TRESPASS(); + ALOGE("Should not reach here."); + return NULL; } if (offset + aac_frame_length > mBuffer->size()) { @@ -714,7 +753,9 @@ int64_t ElementaryStreamQueue::fetchTimestamp(size_t size) { bool first = true; while (size > 0) { - CHECK(!mRangeInfos.empty()); + if (mRangeInfos.empty()) { + return timeUs; + } RangeInfo *info = &*mRangeInfos.begin(); @@ -813,7 +854,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f; if (nalType == 6 && pos.nalSize > 0) { - CHECK_LT(seiIndex, sei->size() / sizeof(NALPosition)); + if (seiIndex >= sei->size() / sizeof(NALPosition)) { + ALOGE("Wrong seiIndex"); + return NULL; + } NALPosition &seiPos = ((NALPosition *)sei->data())[seiIndex++]; seiPos.nalOffset = dstOffset + 4; seiPos.nalSize = pos.nalSize; @@ -851,7 +895,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { mBuffer->setRange(0, mBuffer->size() - nextScan); int64_t timeUs = fetchTimestamp(nextScan); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("Negative timeUs"); + return NULL; + } accessUnit->meta()->setInt64("timeUs", timeUs); if (foundIDR) { @@ -873,7 +920,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { totalSize += nalSize; } - CHECK_EQ(err, (status_t)-EAGAIN); + if (err != (status_t)-EAGAIN) { + ALOGE("Unexpeted err"); + return NULL; + } return NULL; } @@ -890,9 +940,12 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { size_t frameSize; int samplingRate, numChannels, bitrate, numSamples; - CHECK(GetMPEGAudioFrameSize( + if (!GetMPEGAudioFrameSize( header, &frameSize, &samplingRate, &numChannels, - &bitrate, &numSamples)); + &bitrate, &numSamples)) { + ALOGE("Failed to get audio frame size"); + return NULL; + } if (size < frameSize) { return NULL; @@ -910,7 +963,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { mBuffer->setRange(0, mBuffer->size() - frameSize); int64_t timeUs = fetchTimestamp(frameSize); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("Negative timeUs"); + return NULL; + } accessUnit->meta()->setInt64("timeUs", timeUs); accessUnit->meta()->setInt32("isSync", 1); @@ -932,7 +988,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); break; default: - TRESPASS(); + return NULL; } mFormat->setInt32(kKeySampleRate, samplingRate); @@ -943,7 +999,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { } static void EncodeSize14(uint8_t **_ptr, size_t size) { - CHECK_LE(size, 0x3fff); + if (size > 0x3fff) { + ALOGE("Wrong size"); + return; + } uint8_t *ptr = *_ptr; @@ -1018,7 +1077,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() { // seqHeader without/with extension if (mFormat == NULL) { - CHECK_GE(size, 7u); + if (size < 7u) { + ALOGE("Size too small"); + return NULL; + } unsigned width = (data[4] << 4) | data[5] >> 4; @@ -1078,7 +1140,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() { mBuffer->setRange(0, mBuffer->size() - offset); int64_t timeUs = fetchTimestamp(offset); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("Negative timeUs"); + return NULL; + } offset = 0; @@ -1111,7 +1176,7 @@ static ssize_t getNextChunkSize( } if (memcmp(kStartCode, data, 3)) { - TRESPASS(); + return -EAGAIN; } size_t offset = 3; @@ -1171,25 +1236,37 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { case EXPECT_VISUAL_OBJECT_START: { - CHECK_EQ(chunkType, 0xb5); + if (chunkType != 0xb5) { + ALOGE("Unexpected chunkType"); + return NULL; + } state = EXPECT_VO_START; break; } case EXPECT_VO_START: { - CHECK_LE(chunkType, 0x1f); + if (chunkType > 0x1f) { + ALOGE("Unexpected chunkType"); + return NULL; + } state = EXPECT_VOL_START; break; } case EXPECT_VOL_START: { - CHECK((chunkType & 0xf0) == 0x20); + if ((chunkType & 0xf0) != 0x20) { + ALOGE("Wrong chunkType"); + return NULL; + } - CHECK(ExtractDimensionsFromVOLHeader( + if (!ExtractDimensionsFromVOLHeader( &data[offset], chunkSize, - &width, &height)); + &width, &height)) { + ALOGE("Failed to get dimension"); + return NULL; + } state = WAIT_FOR_VOP_START; break; @@ -1242,7 +1319,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { mBuffer->setRange(0, size); int64_t timeUs = fetchTimestamp(offset); - CHECK_GE(timeUs, 0ll); + if (timeUs < 0ll) { + ALOGE("Negative timeus"); + return NULL; + } offset = 0; @@ -1266,7 +1346,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { } default: - TRESPASS(); + ALOGE("Unknown state: %d", state); + return NULL; } if (discard) { diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp index 6496d67..6d9fe9d 100644 --- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp @@ -265,7 +265,10 @@ ssize_t MPEG2PSExtractor::dequeuePES() { } unsigned PES_packet_length = U16_AT(mBuffer->data() + 4); - CHECK_NE(PES_packet_length, 0u); + if (PES_packet_length == 0u) { + ALOGE("PES_packet_length is 0"); + return -EAGAIN; + } size_t n = PES_packet_length + 6; @@ -286,7 +289,10 @@ ssize_t MPEG2PSExtractor::dequeuePES() { return ERROR_MALFORMED; } - CHECK_EQ(packet_startcode_prefix, 0x000001u); + if (packet_startcode_prefix != 0x000001u) { + ALOGE("Wrong PES prefix"); + return ERROR_MALFORMED; + } unsigned stream_id = br.getBits(8); ALOGV("stream_id = 0x%02x", stream_id); @@ -366,8 +372,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() { && stream_id != 0xff // program_stream_directory && stream_id != 0xf2 // DSMCC && stream_id != 0xf8) { // H.222.1 type E - CHECK_EQ(br.getBits(2), 2u); - + /* unsigned PES_marker_bits = */br.getBits(2); // should be 0x2(hex) /* unsigned PES_scrambling_control = */br.getBits(2); /* unsigned PES_priority = */br.getBits(1); /* unsigned data_alignment_indicator = */br.getBits(1); @@ -400,16 +405,26 @@ ssize_t MPEG2PSExtractor::dequeuePES() { uint64_t PTS = 0, DTS = 0; if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { - CHECK_GE(optional_bytes_remaining, 5u); + if (optional_bytes_remaining < 5u) { + return ERROR_MALFORMED; + } - CHECK_EQ(br.getBits(4), PTS_DTS_flags); + if (br.getBits(4) != PTS_DTS_flags) { + return ERROR_MALFORMED; + } PTS = ((uint64_t)br.getBits(3)) << 30; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } PTS |= ((uint64_t)br.getBits(15)) << 15; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } PTS |= br.getBits(15); - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("PTS = %" PRIu64, PTS); // ALOGI("PTS = %.2f secs", PTS / 90000.0f); @@ -417,16 +432,26 @@ ssize_t MPEG2PSExtractor::dequeuePES() { optional_bytes_remaining -= 5; if (PTS_DTS_flags == 3) { - CHECK_GE(optional_bytes_remaining, 5u); + if (optional_bytes_remaining < 5u) { + return ERROR_MALFORMED; + } - CHECK_EQ(br.getBits(4), 1u); + if (br.getBits(4) != 1u) { + return ERROR_MALFORMED; + } DTS = ((uint64_t)br.getBits(3)) << 30; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } DTS |= ((uint64_t)br.getBits(15)) << 15; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } DTS |= br.getBits(15); - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("DTS = %" PRIu64, DTS); @@ -435,31 +460,47 @@ ssize_t MPEG2PSExtractor::dequeuePES() { } if (ESCR_flag) { - CHECK_GE(optional_bytes_remaining, 6u); + if (optional_bytes_remaining < 6u) { + return ERROR_MALFORMED; + } br.getBits(2); uint64_t ESCR = ((uint64_t)br.getBits(3)) << 30; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } ESCR |= ((uint64_t)br.getBits(15)) << 15; - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } ESCR |= br.getBits(15); - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } ALOGV("ESCR = %" PRIu64, ESCR); /* unsigned ESCR_extension = */br.getBits(9); - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } optional_bytes_remaining -= 6; } if (ES_rate_flag) { - CHECK_GE(optional_bytes_remaining, 3u); + if (optional_bytes_remaining < 3u) { + return ERROR_MALFORMED; + } - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } /* unsigned ES_rate = */br.getBits(22); - CHECK_EQ(br.getBits(1), 1u); + if (br.getBits(1) != 1u) { + return ERROR_MALFORMED; + } optional_bytes_remaining -= 3; } @@ -472,7 +513,9 @@ ssize_t MPEG2PSExtractor::dequeuePES() { // ES data follows. - CHECK_GE(PES_packet_length, PES_header_data_length + 3); + if (PES_packet_length < PES_header_data_length + 3) { + return ERROR_MALFORMED; + } unsigned dataLength = PES_packet_length - 3 - PES_header_data_length; @@ -485,7 +528,9 @@ ssize_t MPEG2PSExtractor::dequeuePES() { return ERROR_MALFORMED; } - CHECK_GE(br.numBitsLeft(), dataLength * 8); + if (br.numBitsLeft() < dataLength * 8) { + return ERROR_MALFORMED; + } ssize_t index = mTracks.indexOfKey(stream_id); if (index < 0 && mScanning) { @@ -525,10 +570,14 @@ ssize_t MPEG2PSExtractor::dequeuePES() { return err; } } else if (stream_id == 0xbe) { // padding_stream - CHECK_NE(PES_packet_length, 0u); + if (PES_packet_length == 0u) { + return ERROR_MALFORMED; + } br.skipBits(PES_packet_length * 8); } else { - CHECK_NE(PES_packet_length, 0u); + if (PES_packet_length == 0u) { + return ERROR_MALFORMED; + } br.skipBits(PES_packet_length * 8); } diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index 74cb5d8..f5c33cf 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -131,7 +131,10 @@ sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { bool seekable = true; if (mSourceImpls.size() > 1) { - CHECK_EQ(mSourceImpls.size(), 2u); + if (mSourceImpls.size() != 2u) { + ALOGE("Wrong size"); + return NULL; + } sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat(); const char *mime; diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp index fd889f9..3860e9b 100644 --- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp +++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp @@ -19,6 +19,7 @@ #include <gtest/gtest.h> #include <utils/String8.h> +#include <utils/String16.h> #include <utils/Errors.h> #include <fcntl.h> #include <unistd.h> @@ -466,7 +467,7 @@ void SurfaceMediaSourceGLTest::oneBufferPassGL(int num) { // Set up the MediaRecorder which runs in the same process as mediaserver sp<MediaRecorder> SurfaceMediaSourceGLTest::setUpMediaRecorder(int fd, int videoSource, int outputFormat, int videoEncoder, int width, int height, int fps) { - sp<MediaRecorder> mr = new MediaRecorder(); + sp<MediaRecorder> mr = new MediaRecorder(String16()); mr->setVideoSource(videoSource); mr->setOutputFormat(outputFormat); mr->setVideoEncoder(videoEncoder); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index 5e2f0bf..ed5a404 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -345,12 +345,14 @@ bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { //////////////////////////////////////////////////////////////////////////////// WifiDisplaySource::PlaybackSession::PlaybackSession( + const String16 &opPackageName, const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify, const in_addr &interfaceAddr, const sp<IHDCP> &hdcp, const char *path) - : mNetSession(netSession), + : mOpPackageName(opPackageName), + mNetSession(netSession), mNotify(notify), mInterfaceAddr(interfaceAddr), mHDCP(hdcp), @@ -1069,6 +1071,7 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource( status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) { sp<AudioSource> audioSource = new AudioSource( AUDIO_SOURCE_REMOTE_SUBMIX, + mOpPackageName, 48000 /* sampleRate */, 2 /* channelCount */); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index 4cd1a75..f6673df 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -22,6 +22,8 @@ #include "VideoFormats.h" #include "WifiDisplaySource.h" +#include <utils/String16.h> + namespace android { struct ABuffer; @@ -36,6 +38,7 @@ struct NuMediaExtractor; // display. struct WifiDisplaySource::PlaybackSession : public AHandler { PlaybackSession( + const String16 &opPackageName, const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify, const struct in_addr &interfaceAddr, @@ -96,6 +99,8 @@ private: kWhatPullExtractorSample, }; + String16 mOpPackageName; + sp<ANetworkSession> mNetSession; sp<AMessage> mNotify; in_addr mInterfaceAddr; diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index 332fe16..e26165e 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -50,10 +50,12 @@ const int64_t WifiDisplaySource::kPlaybackSessionTimeoutUs; const AString WifiDisplaySource::sUserAgent = MakeUserAgent(); WifiDisplaySource::WifiDisplaySource( + const String16 &opPackageName, const sp<ANetworkSession> &netSession, const sp<IRemoteDisplayClient> &client, const char *path) - : mState(INITIALIZED), + : mOpPackageName(opPackageName), + mState(INITIALIZED), mNetSession(netSession), mClient(client), mSessionID(0), @@ -1245,7 +1247,7 @@ status_t WifiDisplaySource::onSetupRequest( sp<PlaybackSession> playbackSession = new PlaybackSession( - mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str()); + mOpPackageName, mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str()); looper()->registerHandler(playbackSession); diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index c417cf5..c25a675 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -25,6 +25,8 @@ #include <netinet/in.h> +#include <utils/String16.h> + namespace android { struct AReplyToken; @@ -38,6 +40,7 @@ struct WifiDisplaySource : public AHandler { static const unsigned kWifiDisplayDefaultPort = 7236; WifiDisplaySource( + const String16 &opPackageName, const sp<ANetworkSession> &netSession, const sp<IRemoteDisplayClient> &client, const char *path = NULL); @@ -114,6 +117,8 @@ private: static const AString sUserAgent; + String16 mOpPackageName; + State mState; VideoFormats mSupportedSourceVideoFormats; sp<ANetworkSession> mNetSession; diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp index 80c1c2f..cd0c462 100644 --- a/media/ndk/NdkMediaCodec.cpp +++ b/media/ndk/NdkMediaCodec.cpp @@ -154,6 +154,10 @@ static AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool } else { mData->mCodec = android::MediaCodec::CreateByComponentName(mData->mLooper, name); } + if (mData->mCodec == NULL) { // failed to create codec + AMediaCodec_delete(mData); + return NULL; + } mData->mHandler = new CodecHandler(mData); mData->mLooper->registerHandler(mData->mHandler); mData->mGeneration = 1; @@ -180,17 +184,21 @@ AMediaCodec* AMediaCodec_createEncoderByType(const char *name) { EXPORT media_status_t AMediaCodec_delete(AMediaCodec *mData) { - if (mData->mCodec != NULL) { - mData->mCodec->release(); - mData->mCodec.clear(); - } + if (mData != NULL) { + if (mData->mCodec != NULL) { + mData->mCodec->release(); + mData->mCodec.clear(); + } - if (mData->mLooper != NULL) { - mData->mLooper->unregisterHandler(mData->mHandler->id()); - mData->mLooper->stop(); - mData->mLooper.clear(); + if (mData->mLooper != NULL) { + if (mData->mHandler != NULL) { + mData->mLooper->unregisterHandler(mData->mHandler->id()); + } + mData->mLooper->stop(); + mData->mLooper.clear(); + } + delete mData; } - delete mData; return AMEDIA_OK; } |