diff options
Diffstat (limited to 'media')
| -rw-r--r-- | media/java/android/media/MediaPlayer.java | 40 | ||||
| -rw-r--r-- | media/jni/android_media_MediaMetadataRetriever.cpp | 2 | ||||
| -rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 21 | ||||
| -rw-r--r-- | media/jni/android_media_MediaRecorder.cpp | 10 | ||||
| -rw-r--r-- | media/jni/android_media_MediaScanner.cpp | 8 | ||||
| -rw-r--r-- | media/jni/soundpool/android_media_SoundPool.cpp | 2 | ||||
| -rw-r--r-- | media/libmedia/IMediaPlayerClient.cpp | 12 | ||||
| -rw-r--r-- | media/libmedia/mediaplayer.cpp | 7 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 8 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 6 | ||||
| -rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 77 | ||||
| -rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 3 | ||||
| -rw-r--r-- | media/libstagefright/include/AwesomePlayer.h | 5 |
13 files changed, 150 insertions, 51 deletions
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 0b0d145..1e4b585 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1120,6 +1120,7 @@ public class MediaPlayer mOnErrorListener = null; mOnInfoListener = null; mOnVideoSizeChangedListener = null; + mOnTimedTextListener = null; _release(); } @@ -1301,6 +1302,7 @@ public class MediaPlayer private static final int MEDIA_BUFFERING_UPDATE = 3; private static final int MEDIA_SEEK_COMPLETE = 4; private static final int MEDIA_SET_VIDEO_SIZE = 5; + private static final int MEDIA_TIMED_TEXT = 99; private static final int MEDIA_ERROR = 100; private static final int MEDIA_INFO = 200; @@ -1369,6 +1371,11 @@ public class MediaPlayer } // No real default action so far. return; + case MEDIA_TIMED_TEXT: + if (mOnTimedTextListener != null) { + mOnTimedTextListener.onTimedText(mMediaPlayer, (String)msg.obj); + } + return; case MEDIA_NOP: // interface test message - ignore break; @@ -1545,6 +1552,39 @@ public class MediaPlayer private OnVideoSizeChangedListener mOnVideoSizeChangedListener; + /** + * Interface definition of a callback to be invoked when a + * timed text is available for display. + * {@hide} + */ + public interface OnTimedTextListener + { + /** + * Called to indicate the video size + * + * @param mp the MediaPlayer associated with this callback + * @param text the timed text sample which contains the + * text needed to be displayed. + * {@hide} + */ + public void onTimedText(MediaPlayer mp, String text); + } + + /** + * Register a callback to be invoked when a timed text is available + * for display. + * + * @param listener the callback that will be run + * {@hide} + */ + public void setOnTimedTextListener(OnTimedTextListener listener) + { + mOnTimedTextListener = listener; + } + + private OnTimedTextListener mOnTimedTextListener; + + /* Do not change these values without updating their counterparts * in include/media/mediaplayer.h! */ diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index a219623..2ba9b3f 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -241,7 +241,7 @@ static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jo jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } - int fd = getParcelFileDescriptorFD(env, fileDescriptor); + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (offset < 0 || length < 0 || fd < 0) { if (offset < 0) { LOGE("negative offset (%lld)", offset); diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index ecbd288..23a77d4 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -69,7 +69,7 @@ class JNIMediaPlayerListener: public MediaPlayerListener public: JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz); ~JNIMediaPlayerListener(); - void notify(int msg, int ext1, int ext2); + virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL); private: JNIMediaPlayerListener(); jclass mClass; // Reference to MediaPlayer class @@ -102,10 +102,23 @@ JNIMediaPlayerListener::~JNIMediaPlayerListener() env->DeleteGlobalRef(mClass); } -void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2) +void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj) { JNIEnv *env = AndroidRuntime::getJNIEnv(); - env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, 0); + if (obj && obj->dataSize() > 0) { + jbyteArray jArray = env->NewByteArray(obj->dataSize()); + if (jArray != NULL) { + jbyte *nArray = env->GetByteArrayElements(jArray, NULL); + memcpy(nArray, obj->data(), obj->dataSize()); + env->ReleaseByteArrayElements(jArray, nArray, 0); + env->CallStaticVoidMethod(mClass, fields.post_event, mObject, + msg, ext1, ext2, jArray); + env->DeleteLocalRef(jArray); + } + } else { + env->CallStaticVoidMethod(mClass, fields.post_event, mObject, + msg, ext1, ext2, NULL); + } } // ---------------------------------------------------------------------------- @@ -325,7 +338,7 @@ android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fil jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } - int fd = getParcelFileDescriptorFD(env, fileDescriptor); + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); LOGV("setDataSourceFD: fd %d", fd); process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." ); } diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index a8a46c1..2c24695 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -253,7 +253,7 @@ android_media_MediaRecorder_setOutputFileFD(JNIEnv *env, jobject thiz, jobject f jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } - int fd = getParcelFileDescriptorFD(env, fileDescriptor); + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); sp<MediaRecorder> mr = getMediaRecorder(env, thiz); status_t opStatus = mr->setOutputFile(fd, offset, length); process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed."); @@ -267,7 +267,7 @@ android_media_MediaRecorder_setOutputFileAuxFD(JNIEnv *env, jobject thiz, jobjec jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } - int fd = getParcelFileDescriptorFD(env, fileDescriptor); + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); sp<MediaRecorder> mr = getMediaRecorder(env, thiz); status_t opStatus = mr->setOutputFileAuxiliary(fd); process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed."); @@ -404,38 +404,32 @@ android_media_MediaRecorder_native_init(JNIEnv *env) clazz = env->FindClass("android/media/MediaRecorder"); if (clazz == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaRecorder"); return; } fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); if (fields.context == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mNativeContext"); return; } fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;"); if (fields.surface == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mSurface"); return; } jclass surface = env->FindClass("android/view/Surface"); if (surface == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface"); return; } fields.surface_native = env->GetFieldID(surface, ANDROID_VIEW_SURFACE_JNI_ID, "I"); if (fields.surface_native == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface"); return; } fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); if (fields.post_event == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "MediaRecorder.postEventFromNative"); return; } } diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp index 06058dc..a3dd136 100644 --- a/media/jni/android_media_MediaScanner.cpp +++ b/media/jni/android_media_MediaScanner.cpp @@ -303,7 +303,7 @@ android_media_MediaScanner_extractAlbumArt( return NULL; } - int fd = getParcelFileDescriptorFD(env, fileDescriptor); + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); char* data = mp->extractAlbumArt(fd); if (!data) { return NULL; @@ -335,15 +335,11 @@ android_media_MediaScanner_native_init(JNIEnv *env) LOGV("native_init"); jclass clazz = env->FindClass(kClassMediaScanner); if (clazz == NULL) { - const char* err = "Can't find android/media/MediaScanner"; - jniThrowException(env, kRunTimeException, err); return; } fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); if (fields.context == NULL) { - const char* err = "Can't find MediaScanner.mNativeContext"; - jniThrowException(env, kRunTimeException, err); return; } } @@ -426,5 +422,3 @@ int register_android_media_MediaScanner(JNIEnv *env) return AndroidRuntime::registerNativeMethods(env, kClassMediaScanner, gMethods, NELEM(gMethods)); } - - diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp index 447f931..03d3388 100644 --- a/media/jni/soundpool/android_media_SoundPool.cpp +++ b/media/jni/soundpool/android_media_SoundPool.cpp @@ -60,7 +60,7 @@ android_media_SoundPool_load_FD(JNIEnv *env, jobject thiz, jobject fileDescripto LOGV("android_media_SoundPool_load_FD"); SoundPool *ap = MusterSoundPool(env, thiz); if (ap == NULL) return 0; - return ap->load(getParcelFileDescriptorFD(env, fileDescriptor), + return ap->load(jniGetFDFromFileDescriptor(env, fileDescriptor), int64_t(offset), int64_t(length), int(priority)); } diff --git a/media/libmedia/IMediaPlayerClient.cpp b/media/libmedia/IMediaPlayerClient.cpp index bf51829..1f135c4 100644 --- a/media/libmedia/IMediaPlayerClient.cpp +++ b/media/libmedia/IMediaPlayerClient.cpp @@ -35,13 +35,16 @@ public: { } - virtual void notify(int msg, int ext1, int ext2) + virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor()); data.writeInt32(msg); data.writeInt32(ext1); data.writeInt32(ext2); + if (obj && obj->dataSize() > 0) { + data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); + } remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); } }; @@ -59,7 +62,12 @@ status_t BnMediaPlayerClient::onTransact( int msg = data.readInt32(); int ext1 = data.readInt32(); int ext2 = data.readInt32(); - notify(msg, ext1, ext2); + Parcel obj; + if (data.dataAvail() > 0) { + obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); + } + + notify(msg, ext1, ext2, &obj); return NO_ERROR; } break; default: diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 0ee0249..e80e742 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -551,7 +551,7 @@ status_t MediaPlayer::attachAuxEffect(int effectId) return mPlayer->attachAuxEffect(effectId); } -void MediaPlayer::notify(int msg, int ext1, int ext2) +void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) { LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); bool send = true; @@ -641,6 +641,9 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) mVideoWidth = ext1; mVideoHeight = ext2; break; + case MEDIA_TIMED_TEXT: + LOGV("Received timed text message"); + break; default: LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); break; @@ -653,7 +656,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) if ((listener != 0) && send) { Mutex::Autolock _l(mNotifyLock); LOGV("callback application"); - listener->notify(msg, ext1, ext2); + listener->notify(msg, ext1, ext2, obj); LOGV("back from callback"); } } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 9c9ac97..6b97708 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1022,7 +1022,8 @@ status_t MediaPlayerService::Client::attachAuxEffect(int effectId) return NO_ERROR; } -void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) +void MediaPlayerService::Client::notify( + void* cookie, int msg, int ext1, int ext2, const Parcel *obj) { Client* client = static_cast<Client*>(cookie); @@ -1039,7 +1040,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); } @@ -1623,7 +1624,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..5539a37 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -156,7 +156,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: @@ -287,7 +288,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/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 93d4236..1bfdd8e 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define DEBUG_HDCP +#undef DEBUG_HDCP //#define LOG_NDEBUG 0 #define LOG_TAG "AwesomePlayer" @@ -184,7 +184,8 @@ AwesomePlayer::AwesomePlayer() mFlags(0), mExtractorFlags(0), mVideoBuffer(NULL), - mDecryptHandle(NULL) { + mDecryptHandle(NULL), + mLastVideoTimeUs(-1) { CHECK_EQ(mClient.connect(), (status_t)OK); DataSource::RegisterDefaultSniffers(); @@ -470,28 +471,13 @@ void AwesomePlayer::reset_l() { mVideoRenderer.clear(); - if (mVideoBuffer) { - mVideoBuffer->release(); - mVideoBuffer = NULL; - } - if (mRTSPController != NULL) { mRTSPController->disconnect(); mRTSPController.clear(); } if (mVideoSource != NULL) { - mVideoSource->stop(); - - // The following hack is necessary to ensure that the OMX - // component is completely released by the time we may try - // to instantiate it again. - wp<MediaSource> tmp = mVideoSource; - mVideoSource.clear(); - while (tmp.promote() != NULL) { - usleep(1000); - } - IPCThreadState::self()->flushCommands(); + shutdownVideoDecoder_l(); } mDurationUs = -1; @@ -510,6 +496,7 @@ void AwesomePlayer::reset_l() { mFileSource.clear(); mBitrate = -1; + mLastVideoTimeUs = -1; } void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) { @@ -1012,7 +999,7 @@ void AwesomePlayer::setSurface(const sp<Surface> &surface) { Mutex::Autolock autoLock(mLock); mSurface = surface; - mNativeWindow = surface; + setNativeWindow_l(surface); } void AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) { @@ -1020,9 +1007,57 @@ void AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) mSurface.clear(); if (surfaceTexture != NULL) { - mNativeWindow = new SurfaceTextureClient(surfaceTexture); + setNativeWindow_l(new SurfaceTextureClient(surfaceTexture)); } +} +void AwesomePlayer::shutdownVideoDecoder_l() { + if (mVideoBuffer) { + mVideoBuffer->release(); + mVideoBuffer = NULL; + } + + mVideoSource->stop(); + + // The following hack is necessary to ensure that the OMX + // component is completely released by the time we may try + // to instantiate it again. + wp<MediaSource> tmp = mVideoSource; + mVideoSource.clear(); + while (tmp.promote() != NULL) { + usleep(1000); + } + IPCThreadState::self()->flushCommands(); +} + +void AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) { + mNativeWindow = native; + + if (mVideoSource == NULL) { + return; + } + + LOGI("attempting to reconfigure to use new surface"); + + bool wasPlaying = (mFlags & PLAYING) != 0; + + pause_l(); + mVideoRenderer.clear(); + + shutdownVideoDecoder_l(); + + CHECK_EQ(initVideoDecoder(), (status_t)OK); + + if (mLastVideoTimeUs >= 0) { + mSeeking = SEEK; + mSeekNotificationSent = true; + mSeekTimeUs = mLastVideoTimeUs; + mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS); + } + + if (wasPlaying) { + play_l(); + } } void AwesomePlayer::setAudioSink( @@ -1412,6 +1447,8 @@ void AwesomePlayer::onVideoEvent() { int64_t timeUs; CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); + mLastVideoTimeUs = timeUs; + if (mSeeking == SEEK_VIDEO_ONLY) { if (mSeekTimeUs > timeUs) { LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us", diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 4095fbf..7621f2c 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -146,7 +146,8 @@ static VideoFrame *extractVideoFrameWithCodecFlags( int64_t thumbNailTime; if (frameTimeUs < 0) { - if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { + if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime) + || thumbNailTime < 0) { thumbNailTime = 0; } options.setSeekTo(thumbNailTime, mode); diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 7fd7724..8c61064 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -218,6 +218,8 @@ private: DrmManagerClient *mDrmManagerClient; sp<DecryptHandle> mDecryptHandle; + int64_t mLastVideoTimeUs; + status_t setDataSource_l( const char *uri, const KeyedVector<String8, String8> *headers = NULL); @@ -267,6 +269,9 @@ private: status_t startAudioPlayer_l(); + void shutdownVideoDecoder_l(); + void setNativeWindow_l(const sp<ANativeWindow> &native); + AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); }; |
