summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/MediaPlayer.java40
-rw-r--r--media/jni/android_media_MediaMetadataRetriever.cpp2
-rw-r--r--media/jni/android_media_MediaPlayer.cpp21
-rw-r--r--media/jni/android_media_MediaRecorder.cpp10
-rw-r--r--media/jni/android_media_MediaScanner.cpp8
-rw-r--r--media/jni/soundpool/android_media_SoundPool.cpp2
-rw-r--r--media/libmedia/IMediaPlayerClient.cpp12
-rw-r--r--media/libmedia/mediaplayer.cpp7
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp8
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h6
-rw-r--r--media/libstagefright/AwesomePlayer.cpp77
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp3
-rw-r--r--media/libstagefright/include/AwesomePlayer.h5
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 &);
};