summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/AudioManager.java13
-rw-r--r--media/java/android/media/AudioService.java188
-rw-r--r--media/java/android/media/Metadata.java2
-rw-r--r--media/java/android/media/RemoteControlClient.java114
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp6
-rw-r--r--media/libmedia/MediaScanner.cpp60
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp16
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h4
-rw-r--r--media/libstagefright/ACodec.cpp40
-rw-r--r--media/libstagefright/AVIExtractor.cpp65
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp11
-rw-r--r--media/libstagefright/include/AVIExtractor.h11
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java19
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaItemThumbnailTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java16
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java4
17 files changed, 386 insertions, 189 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 25c4200..cd8bb1d 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1717,12 +1717,11 @@ public class AudioManager {
/**
- * @hide
- * CANDIDATE FOR SDK
* Registers the remote control client for providing information to display on the remote
* controls.
- * @param rcClient the remote control client associated responsible
- * for providing the information to display on the remote control.
+ * @param rcClient The remote control client from which remote controls will receive
+ * information to display.
+ * @see RemoteControlClient
*/
public void registerRemoteControlClient(RemoteControlClient rcClient) {
if ((rcClient == null) || (rcClient.getRcEventReceiver() == null)) {
@@ -1741,11 +1740,9 @@ public class AudioManager {
}
/**
- * @hide
- * CANDIDATE FOR SDK
* Unregisters the remote control client that was providing information to display on the
- * remotes.
- * @param rcClient the remote control client to unregister
+ * remote controls.
+ * @param rcClient The remote control client to unregister.
* @see #registerRemoteControlClient(RemoteControlClient)
*/
public void unregisterRemoteControlClient(RemoteControlClient rcClient) {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 9d9b6ea..f5e1416 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -343,9 +343,8 @@ public class AudioService extends IAudioService.Stub {
readPersistedSettings();
mSettingsObserver = new SettingsObserver();
createStreamStates();
- // Call setMode() to initialize mSetModeDeathHandlers
- mMode = AudioSystem.MODE_INVALID;
- setMode(AudioSystem.MODE_NORMAL, null);
+
+ mMode = AudioSystem.MODE_NORMAL;
mMediaServerOk = true;
// Call setRingerModeInt() to apply correct mute
@@ -768,37 +767,27 @@ public class AudioService extends IAudioService.Stub {
private int mPid;
private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client
- SetModeDeathHandler(IBinder cb) {
+ SetModeDeathHandler(IBinder cb, int pid) {
mCb = cb;
- mPid = Binder.getCallingPid();
+ mPid = pid;
}
public void binderDied() {
+ IBinder newModeOwner = null;
synchronized(mSetModeDeathHandlers) {
Log.w(TAG, "setMode() client died");
int index = mSetModeDeathHandlers.indexOf(this);
if (index < 0) {
Log.w(TAG, "unregistered setMode() client died");
} else {
- mSetModeDeathHandlers.remove(this);
- // If dead client was a the top of client list,
- // apply next mode in the stack
- if (index == 0) {
- // mSetModeDeathHandlers is never empty as the initial entry
- // created when AudioService starts is never removed
- SetModeDeathHandler hdlr = mSetModeDeathHandlers.get(0);
- int mode = hdlr.getMode();
- if (AudioService.this.mMode != mode) {
- if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
- AudioService.this.mMode = mode;
- if (mode != AudioSystem.MODE_NORMAL) {
- disconnectBluetoothSco(mCb);
- }
- }
- }
- }
+ newModeOwner = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid);
}
}
+ // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
+ // SCO connections not started by the application changing the mode
+ if (newModeOwner != null) {
+ disconnectBluetoothSco(newModeOwner);
+ }
}
public int getPid() {
@@ -828,60 +817,97 @@ public class AudioService extends IAudioService.Stub {
return;
}
- synchronized (mSettingsLock) {
+ IBinder newModeOwner = null;
+ synchronized(mSetModeDeathHandlers) {
if (mode == AudioSystem.MODE_CURRENT) {
mode = mMode;
}
- if (mode != mMode) {
+ newModeOwner = setModeInt(mode, cb, Binder.getCallingPid());
+ }
+ // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
+ // SCO connections not started by the application changing the mode
+ if (newModeOwner != null) {
+ disconnectBluetoothSco(newModeOwner);
+ }
+ }
- // automatically handle audio focus for mode changes
- handleFocusForCalls(mMode, mode, cb);
+ // must be called synchronized on mSetModeDeathHandlers
+ // setModeInt() returns a non null IBInder if the audio mode was successfully set to
+ // any mode other than NORMAL.
+ IBinder setModeInt(int mode, IBinder cb, int pid) {
+ IBinder newModeOwner = null;
+ if (cb == null) {
+ Log.e(TAG, "setModeInt() called with null binder");
+ return newModeOwner;
+ }
- if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
- mMode = mode;
+ SetModeDeathHandler hdlr = null;
+ Iterator iter = mSetModeDeathHandlers.iterator();
+ while (iter.hasNext()) {
+ SetModeDeathHandler h = (SetModeDeathHandler)iter.next();
+ if (h.getPid() == pid) {
+ hdlr = h;
+ // Remove from client list so that it is re-inserted at top of list
+ iter.remove();
+ hdlr.getBinder().unlinkToDeath(hdlr, 0);
+ break;
+ }
+ }
+ int status = AudioSystem.AUDIO_STATUS_OK;
+ do {
+ if (mode == AudioSystem.MODE_NORMAL) {
+ // get new mode from client at top the list if any
+ if (!mSetModeDeathHandlers.isEmpty()) {
+ hdlr = mSetModeDeathHandlers.get(0);
+ cb = hdlr.getBinder();
+ mode = hdlr.getMode();
+ }
+ } else {
+ if (hdlr == null) {
+ hdlr = new SetModeDeathHandler(cb, pid);
+ }
+ // Register for client death notification
+ try {
+ cb.linkToDeath(hdlr, 0);
+ } catch (RemoteException e) {
+ // Client has died!
+ Log.w(TAG, "setMode() could not link to "+cb+" binder death");
+ }
- synchronized(mSetModeDeathHandlers) {
- SetModeDeathHandler hdlr = null;
- Iterator iter = mSetModeDeathHandlers.iterator();
- while (iter.hasNext()) {
- SetModeDeathHandler h = (SetModeDeathHandler)iter.next();
- if (h.getBinder() == cb) {
- hdlr = h;
- // Remove from client list so that it is re-inserted at top of list
- iter.remove();
- break;
- }
- }
- if (hdlr == null) {
- hdlr = new SetModeDeathHandler(cb);
- // cb is null when setMode() is called by AudioService constructor
- if (cb != null) {
- // Register for client death notification
- try {
- cb.linkToDeath(hdlr, 0);
- } catch (RemoteException e) {
- // Client has died!
- Log.w(TAG, "setMode() could not link to "+cb+" binder death");
- }
- }
- }
- // Last client to call setMode() is always at top of client list
- // as required by SetModeDeathHandler.binderDied()
- mSetModeDeathHandlers.add(0, hdlr);
- hdlr.setMode(mode);
- }
+ // Last client to call setMode() is always at top of client list
+ // as required by SetModeDeathHandler.binderDied()
+ mSetModeDeathHandlers.add(0, hdlr);
+ hdlr.setMode(mode);
+ }
- // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
- // SCO connections not started by the application changing the mode
- if (mode != AudioSystem.MODE_NORMAL) {
- disconnectBluetoothSco(cb);
+ if (mode != mMode) {
+ status = AudioSystem.setPhoneState(mode);
+ if (status == AudioSystem.AUDIO_STATUS_OK) {
+ // automatically handle audio focus for mode changes
+ handleFocusForCalls(mMode, mode, cb);
+ mMode = mode;
+ } else {
+ if (hdlr != null) {
+ mSetModeDeathHandlers.remove(hdlr);
+ cb.unlinkToDeath(hdlr, 0);
}
+ // force reading new top of mSetModeDeathHandlers stack
+ mode = AudioSystem.MODE_NORMAL;
}
+ } else {
+ status = AudioSystem.AUDIO_STATUS_OK;
+ }
+ } while (status != AudioSystem.AUDIO_STATUS_OK && !mSetModeDeathHandlers.isEmpty());
+
+ if (status == AudioSystem.AUDIO_STATUS_OK) {
+ if (mode != AudioSystem.MODE_NORMAL) {
+ newModeOwner = cb;
}
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[STREAM_VOLUME_ALIAS[streamType]].mIndex;
setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, true, false);
}
+ return newModeOwner;
}
/** pre-condition: oldMode != newMode */
@@ -1345,28 +1371,30 @@ public class AudioService extends IAudioService.Stub {
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
// Accept SCO audio activation only in NORMAL audio mode or if the mode is
// currently controlled by the same client process.
- if ((AudioService.this.mMode == AudioSystem.MODE_NORMAL ||
- mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) &&
- (mScoAudioState == SCO_STATE_INACTIVE ||
- mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
- if (mScoAudioState == SCO_STATE_INACTIVE) {
- if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (mBluetoothHeadset.startScoUsingVirtualVoiceCall(
- mBluetoothHeadsetDevice)) {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- } else {
- broadcastScoConnectionState(
- AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+ synchronized(mSetModeDeathHandlers) {
+ if ((mSetModeDeathHandlers.isEmpty() ||
+ mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) &&
+ (mScoAudioState == SCO_STATE_INACTIVE ||
+ mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
+ if (mScoAudioState == SCO_STATE_INACTIVE) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
+ if (mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+ mBluetoothHeadsetDevice)) {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ } else {
+ broadcastScoConnectionState(
+ AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+ }
+ } else if (getBluetoothHeadset()) {
+ mScoAudioState = SCO_STATE_ACTIVATE_REQ;
}
- } else if (getBluetoothHeadset()) {
- mScoAudioState = SCO_STATE_ACTIVATE_REQ;
+ } else {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
}
} else {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
+ broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
}
- } else {
- broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
}
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED &&
(mScoAudioState == SCO_STATE_ACTIVE_INTERNAL ||
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java
index 591a8b9..b566653 100644
--- a/media/java/android/media/Metadata.java
+++ b/media/java/android/media/Metadata.java
@@ -39,6 +39,8 @@ import java.util.TimeZone;
The caller is expected to know the type of the metadata and call
the right get* method to fetch its value.
+
+ @hide
*/
public class Metadata
{
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index d7b85e4..daa25e0 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -17,7 +17,6 @@
package android.media;
import android.content.ComponentName;
-import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -31,15 +30,14 @@ import android.os.RemoteException;
import android.util.Log;
import java.lang.IllegalArgumentException;
-import java.util.HashMap;
/**
- * @hide
- * CANDIDATE FOR SDK
* RemoteControlClient enables exposing information meant to be consumed by remote controls
- * capable of displaying metadata, album art and media transport control buttons.
- * A remote control client object is associated with a media button event receiver
- * when registered through
+ * capable of displaying metadata, artwork and media transport control buttons.
+ * A remote control client object is associated with a media button event receiver. This
+ * event receiver must have been previously registered with
+ * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the
+ * RemoteControlClient can be registered through
* {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
*/
public class RemoteControlClient
@@ -110,7 +108,8 @@ public class RemoteControlClient
public final static int PLAYSTATE_ERROR = 9;
/**
* @hide
- * The value of a playback state when none has been declared
+ * The value of a playback state when none has been declared.
+ * Intentionally hidden as an application shouldn't set such a playback state value.
*/
public final static int PLAYSTATE_NONE = 0;
@@ -122,7 +121,7 @@ public class RemoteControlClient
*/
public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
/**
- * Flag indicating a RemoteControlClient makes use of the "rewing" media key.
+ * Flag indicating a RemoteControlClient makes use of the "rewind" media key.
*
* @see #setTransportControlFlags(int)
* @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
@@ -173,7 +172,9 @@ public class RemoteControlClient
/**
* @hide
- * The flags for when no media keys are declared supported
+ * The flags for when no media keys are declared supported.
+ * Intentionally hidden as an application shouldn't set the transport control flags
+ * to this value.
*/
public final static int FLAGS_KEY_MEDIA_NONE = 0;
@@ -184,29 +185,29 @@ public class RemoteControlClient
public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0;
/**
* @hide
- * FIXME doc not valid
* Flag used to signal that the transport control buttons supported by the
- * RemoteControlClient have changed.
+ * RemoteControlClient are requested.
* This can for instance happen when playback is at the end of a playlist, and the "next"
* operation is not supported anymore.
*/
public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1;
/**
* @hide
- * FIXME doc not valid
- * Flag used to signal that the playback state of the RemoteControlClient has changed.
+ * Flag used to signal that the playback state of the RemoteControlClient is requested.
*/
public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2;
/**
* @hide
- * FIXME doc not valid
- * Flag used to signal that the album art for the RemoteControlClient has changed.
+ * Flag used to signal that the album art for the RemoteControlClient is requested.
*/
public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3;
/**
* Class constructor.
- * @param mediaButtonEventReceiver the receiver for the media button events.
+ * @param mediaButtonEventReceiver The receiver for the media button events. It needs to have
+ * been registered with {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
+ * before this new RemoteControlClient can itself be registered with
+ * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
* @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
* @see AudioManager#registerRemoteControlClient(RemoteControlClient)
*/
@@ -227,8 +228,11 @@ public class RemoteControlClient
/**
* Class constructor for a remote control client whose internal event handling
* happens on a user-provided Looper.
- * @param mediaButtonEventReceiver the receiver for the media button events.
- * @param looper the Looper running the event loop.
+ * @param mediaButtonEventReceiver The receiver for the media button events. It needs to have
+ * been registered with {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
+ * before this new RemoteControlClient can itself be registered with
+ * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
+ * @param looper The Looper running the event loop.
* @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
* @see AudioManager#registerRemoteControlClient(RemoteControlClient)
*/
@@ -257,11 +261,28 @@ public class RemoteControlClient
/**
* Class used to modify metadata in a {@link RemoteControlClient} object.
+ * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor,
+ * on which you set the metadata for the RemoteControlClient instance. Once all the information
+ * has been set, use {@link #apply()} to make it the new metadata that should be displayed
+ * for the associated client. Once the metadata has been "applied", you cannot reuse this
+ * instance of the MetadataEditor.
*/
public class MetadataEditor {
+ /**
+ * @hide
+ */
protected boolean mMetadataChanged;
+ /**
+ * @hide
+ */
protected boolean mArtworkChanged;
+ /**
+ * @hide
+ */
protected Bitmap mEditorArtwork;
+ /**
+ * @hide
+ */
protected Bundle mEditorMetadata;
private boolean mApplied = false;
@@ -277,13 +298,18 @@ public class RemoteControlClient
/**
* The metadata key for the content artwork / album art.
*/
- public final static int METADATA_KEY_ARTWORK = 100;
+ public final static int BITMAP_KEY_ARTWORK = 100;
+ /**
+ * @hide
+ * TODO(jmtrivi) have lockscreen and music move to the new key name
+ */
+ public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK;
/**
* Adds textual information to be displayed.
* Note that none of the information added after {@link #apply()} has been called,
* will be displayed.
- * @param key the identifier of a the metadata field to set. Valid values are
+ * @param key The identifier of a the metadata field to set. Valid values are
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
@@ -294,11 +320,11 @@ public class RemoteControlClient
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
- * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER},
- * .
- * @param value the text for the given key, or {@code null} to signify there is no valid
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
+ * @param value The text for the given key, or {@code null} to signify there is no valid
* information for the field.
- * @return FIXME description
+ * @return Returns a reference to the same MetadataEditor object, so you can chain put
+ * calls together.
*/
public synchronized MetadataEditor putString(int key, String value)
throws IllegalArgumentException {
@@ -315,15 +341,18 @@ public class RemoteControlClient
}
/**
- * FIXME javadoc
+ * Adds numerical information to be displayed.
+ * Note that none of the information added after {@link #apply()} has been called,
+ * will be displayed.
* @param key the identifier of a the metadata field to set. Valid values are
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
* expressed in milliseconds),
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
- * @param value FIXME javadoc
- * @return FIXME javadoc
+ * @param value The long value for the given key
+ * @return Returns a reference to the same MetadataEditor object, so you can chain put
+ * calls together.
* @throws IllegalArgumentException
*/
public synchronized MetadataEditor putLong(int key, long value)
@@ -342,9 +371,11 @@ public class RemoteControlClient
/**
* Sets the album / artwork picture to be displayed on the remote control.
- * @param key FIXME description
- * @param bitmap the bitmap for the artwork, or null if there isn't any.
- * @return FIXME description
+ * @param key the identifier of the bitmap to set. The only valid value is
+ * {@link #BITMAP_KEY_ARTWORK}
+ * @param bitmap The bitmap for the artwork, or null if there isn't any.
+ * @return Returns a reference to the same MetadataEditor object, so you can chain put
+ * calls together.
* @throws IllegalArgumentException
* @see android.graphics.Bitmap
*/
@@ -354,7 +385,7 @@ public class RemoteControlClient
Log.e(TAG, "Can't edit a previously applied MetadataEditor");
return this;
}
- if (key != METADATA_KEY_ARTWORK) {
+ if (key != BITMAP_KEY_ARTWORK) {
throw(new IllegalArgumentException("Invalid type 'Bitmap' for key "+ key));
}
if ((mArtworkExpectedWidth > 0) && (mArtworkExpectedHeight > 0)) {
@@ -369,7 +400,8 @@ public class RemoteControlClient
}
/**
- * FIXME description
+ * Clears all the metadata that has been set since the MetadataEditor instance was
+ * created with {@link RemoteControlClient#editMetadata(boolean)}.
*/
public synchronized void clear() {
if (mApplied) {
@@ -381,7 +413,10 @@ public class RemoteControlClient
}
/**
- * FIXME description
+ * Associates all the metadata that has been set since the MetadataEditor instance was
+ * created with {@link RemoteControlClient#editMetadata(boolean)}, or since
+ * {@link #clear()} was called, with the RemoteControlClient. Once "applied",
+ * this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
*/
public synchronized void apply() {
if (mApplied) {
@@ -408,9 +443,10 @@ public class RemoteControlClient
}
/**
- * FIXME description
- * @param startEmpty
- * @return
+ * Creates a {@link MetadataEditor}.
+ * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
+ * was previously applied to the RemoteControlClient, or true if it is to be created empty.
+ * @return a new MetadataEditor instance.
*/
public MetadataEditor editMetadata(boolean startEmpty) {
MetadataEditor editor = new MetadataEditor();
@@ -430,7 +466,7 @@ public class RemoteControlClient
/**
* Sets the current playback state.
- * @param state the current playback state, one of the following values:
+ * @param state The current playback state, one of the following values:
* {@link #PLAYSTATE_STOPPED},
* {@link #PLAYSTATE_PAUSED},
* {@link #PLAYSTATE_PLAYING},
@@ -453,7 +489,7 @@ public class RemoteControlClient
/**
* Sets the flags for the media transport control buttons that this client supports.
- * @param a combination of the following flags:
+ * @param transportControlFlags A combination of the following flags:
* {@link #FLAG_KEY_MEDIA_PREVIOUS},
* {@link #FLAG_KEY_MEDIA_REWIND},
* {@link #FLAG_KEY_MEDIA_PLAY},
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 4e954fc..ed4e92e 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -2328,6 +2328,10 @@ static int videoEditor_getPixelsList(
break;
}
env->CallVoidMethod(callback, mid, (jint)k);
+ if (env->ExceptionCheck()) {
+ err = M4ERR_ALLOC;
+ break;
+ }
}
env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
@@ -2338,7 +2342,7 @@ static int videoEditor_getPixelsList(
env->ReleaseStringUTFChars(path, pString);
}
- if (err != M4NO_ERROR) {
+ if (err != M4NO_ERROR && !env->ExceptionCheck()) {
jniThrowException(env, "java/lang/RuntimeException",\
"ThumbnailGetPixels32 failed");
}
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 41f8593..19dedfc 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaScanner"
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <media/mediascanner.h>
@@ -26,11 +27,14 @@
namespace android {
MediaScanner::MediaScanner()
- : mLocale(NULL) {
+ : mLocale(NULL), mSkipList(NULL), mSkipIndex(NULL) {
+ loadSkipList();
}
MediaScanner::~MediaScanner() {
setLocale(NULL);
+ free(mSkipList);
+ free(mSkipIndex);
}
void MediaScanner::setLocale(const char *locale) {
@@ -47,6 +51,33 @@ const char *MediaScanner::locale() const {
return mLocale;
}
+void MediaScanner::loadSkipList() {
+ mSkipList = (char *)malloc(PROPERTY_VALUE_MAX * sizeof(char));
+ if (mSkipList) {
+ property_get("testing.mediascanner.skiplist", mSkipList, "");
+ }
+ if (!mSkipList || (strlen(mSkipList) == 0)) {
+ free(mSkipList);
+ mSkipList = NULL;
+ return;
+ }
+ mSkipIndex = (int *)malloc(PROPERTY_VALUE_MAX * sizeof(int));
+ if (mSkipIndex) {
+ // dup it because strtok will modify the string
+ char *skipList = strdup(mSkipList);
+ if (skipList) {
+ char * path = strtok(skipList, ",");
+ int i = 0;
+ while (path) {
+ mSkipIndex[i++] = strlen(path);
+ path = strtok(NULL, ",");
+ }
+ mSkipIndex[i] = -1;
+ free(skipList);
+ }
+ }
+}
+
MediaScanResult MediaScanner::processDirectory(
const char *path, MediaScannerClient &client) {
int pathLength = strlen(path);
@@ -75,12 +106,39 @@ MediaScanResult MediaScanner::processDirectory(
return result;
}
+bool MediaScanner::shouldSkipDirectory(char *path) {
+ if (path && mSkipList && mSkipIndex) {
+ int len = strlen(path);
+ int idx = 0;
+ // track the start position of next path in the comma
+ // separated list obtained from getprop
+ int startPos = 0;
+ while (mSkipIndex[idx] != -1) {
+ // no point to match path name if strlen mismatch
+ if ((len == mSkipIndex[idx])
+ // pick out the path segment from comma separated list
+ // to compare against current path parameter
+ && (strncmp(path, &mSkipList[startPos], len) == 0)) {
+ return true;
+ }
+ startPos += mSkipIndex[idx] + 1; // extra char for the delimiter
+ idx++;
+ }
+ }
+ return false;
+}
+
MediaScanResult MediaScanner::doProcessDirectory(
char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) {
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
+ if (shouldSkipDirectory(path)) {
+ LOGD("Skipping: %s", path);
+ return MEDIA_SCAN_RESULT_OK;
+ }
+
// Treat all files as non-media in directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
strcpy(fileSpot, ".nomedia");
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 8f213da..bf83849 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -26,6 +26,9 @@
namespace android {
+// static
+const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
+
NuPlayer::Renderer::Renderer(
const sp<MediaPlayerBase::AudioSink> &sink,
const sp<AMessage> &notify)
@@ -43,7 +46,8 @@ NuPlayer::Renderer::Renderer(
mHasAudio(false),
mHasVideo(false),
mSyncQueues(false),
- mPaused(false) {
+ mPaused(false),
+ mLastPositionUpdateUs(-1ll) {
}
NuPlayer::Renderer::~Renderer() {
@@ -190,7 +194,7 @@ void NuPlayer::Renderer::postDrainAudioQueue() {
mDrainAudioQueuePending = true;
sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
msg->setInt32("generation", mAudioQueueGeneration);
- msg->post(10000);
+ msg->post();
}
void NuPlayer::Renderer::signalAudioSinkChanged() {
@@ -198,7 +202,6 @@ void NuPlayer::Renderer::signalAudioSinkChanged() {
}
void NuPlayer::Renderer::onDrainAudioQueue() {
-
for (;;) {
if (mAudioQueue.empty()) {
break;
@@ -562,6 +565,13 @@ void NuPlayer::Renderer::notifyPosition() {
}
int64_t nowUs = ALooper::GetNowUs();
+
+ if (mLastPositionUpdateUs >= 0
+ && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs) {
+ return;
+ }
+ mLastPositionUpdateUs = nowUs;
+
int64_t positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs;
sp<AMessage> notify = mNotify->dup();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 2713031..3a641a2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -74,6 +74,8 @@ private:
status_t mFinalResult;
};
+ static const int64_t kMinPositionUpdateDelayUs;
+
sp<MediaPlayerBase::AudioSink> mAudioSink;
sp<AMessage> mNotify;
List<QueueEntry> mAudioQueue;
@@ -98,6 +100,8 @@ private:
bool mPaused;
+ int64_t mLastPositionUpdateUs;
+
void onDrainAudioQueue();
void postDrainAudioQueue();
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e9dc61c..2ba2273 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1131,6 +1131,13 @@ void ACodec::sendFormatChange() {
mSentFormat = true;
}
+void ACodec::signalError(OMX_ERRORTYPE error) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", ACodec::kWhatError);
+ notify->setInt32("omx-error", error);
+ notify->post();
+}
+
////////////////////////////////////////////////////////////////////////////////
ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
@@ -1252,10 +1259,7 @@ bool ACodec::BaseState::onOMXEvent(
LOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatError);
- notify->setInt32("omx-error", data1);
- notify->post();
+ mCodec->signalError((OMX_ERRORTYPE)data1);
return true;
}
@@ -1548,12 +1552,14 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
&& msg->findInt32("render", &render) && render != 0) {
// The client wants this buffer to be rendered.
- CHECK_EQ(mCodec->mNativeWindow->queueBuffer(
+ if (mCodec->mNativeWindow->queueBuffer(
mCodec->mNativeWindow.get(),
- info->mGraphicBuffer.get()),
- 0);
-
- info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
+ info->mGraphicBuffer.get()) == OK) {
+ info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
+ } else {
+ mCodec->signalError();
+ info->mStatus = BufferInfo::OWNED_BY_US;
+ }
} else {
info->mStatus = BufferInfo::OWNED_BY_US;
}
@@ -1692,11 +1698,7 @@ void ACodec::UninitializedState::onSetup(
if (node == NULL) {
LOGE("Unable to instantiate a decoder for type '%s'.", mime.c_str());
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatError);
- notify->setInt32("omx-error", OMX_ErrorComponentNotFound);
- notify->post();
-
+ mCodec->signalError(OMX_ErrorComponentNotFound);
return;
}
@@ -1744,10 +1746,7 @@ void ACodec::LoadedToIdleState::stateEntered() {
"(error 0x%08x)",
err);
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatError);
- notify->setInt32("omx-error", OMX_ErrorUndefined);
- notify->post();
+ mCodec->signalError();
}
}
@@ -2063,10 +2062,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
"port reconfiguration (error 0x%08x)",
err);
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatError);
- notify->setInt32("omx-error", OMX_ErrorUndefined);
- notify->post();
+ mCodec->signalError();
}
return true;
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index 6313ca3..4e46414 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -117,14 +117,12 @@ status_t AVIExtractor::AVISource::read(
}
}
- int64_t timeUs =
- (mSampleIndex * 1000000ll * mTrack.mRate) / mTrack.mScale;
-
off64_t offset;
size_t size;
bool isKey;
+ int64_t timeUs;
status_t err = mExtractor->getSampleInfo(
- mTrackIndex, mSampleIndex, &offset, &size, &isKey);
+ mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
++mSampleIndex;
@@ -396,6 +394,8 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
uint32_t rate = U32LE_AT(&data[20]);
uint32_t scale = U32LE_AT(&data[24]);
+ uint32_t sampleSize = U32LE_AT(&data[44]);
+
const char *mime = NULL;
Track::Kind kind = Track::OTHER;
@@ -427,6 +427,7 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
track->mMeta = meta;
track->mRate = rate;
track->mScale = scale;
+ track->mBytesPerSample = sampleSize;
track->mKind = kind;
track->mNumSyncSamples = 0;
track->mThumbnailSampleSize = 0;
@@ -612,11 +613,12 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
off64_t offset;
size_t size;
bool isKey;
- status_t err = getSampleInfo(0, 0, &offset, &size, &isKey);
+ int64_t timeUs;
+ status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
if (err != OK) {
mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
- err = getSampleInfo(0, 0, &offset, &size, &isKey);
+ err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
if (err != OK) {
return err;
@@ -630,8 +632,9 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
for (size_t i = 0; i < mTracks.size(); ++i) {
Track *track = &mTracks.editItemAt(i);
- int64_t durationUs =
- (track->mSamples.size() * 1000000ll * track->mRate) / track->mScale;
+ int64_t durationUs;
+ CHECK_EQ((status_t)OK,
+ getSampleTime(i, track->mSamples.size() - 1, &durationUs));
LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
@@ -645,9 +648,10 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
if (!strncasecmp("video/", mime.c_str(), 6)
&& track->mThumbnailSampleIndex >= 0) {
- int64_t thumbnailTimeUs =
- (track->mThumbnailSampleIndex * 1000000ll * track->mRate)
- / track->mScale;
+ int64_t thumbnailTimeUs;
+ CHECK_EQ((status_t)OK,
+ getSampleTime(i, track->mThumbnailSampleIndex,
+ &thumbnailTimeUs));
track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
@@ -659,6 +663,21 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
}
}
}
+
+ if (track->mBytesPerSample != 0) {
+ // Assume all chunks are the same size for now.
+
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ int64_t sampleTimeUs;
+ CHECK_EQ((status_t)OK,
+ getSampleInfo(
+ i, 0,
+ &offset, &size, &isKey, &sampleTimeUs));
+
+ track->mRate *= size / track->mBytesPerSample;
+ }
}
mFoundIndex = true;
@@ -720,7 +739,9 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
off64_t offset;
size_t size;
bool isKey;
- status_t err = getSampleInfo(trackIndex, 0, &offset, &size, &isKey);
+ int64_t timeUs;
+ status_t err =
+ getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);
if (err != OK) {
return err;
@@ -762,7 +783,8 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
status_t AVIExtractor::getSampleInfo(
size_t trackIndex, size_t sampleIndex,
- off64_t *offset, size_t *size, bool *isKey) {
+ off64_t *offset, size_t *size, bool *isKey,
+ int64_t *sampleTimeUs) {
if (trackIndex >= mTracks.size()) {
return -ERANGE;
}
@@ -801,9 +823,20 @@ status_t AVIExtractor::getSampleInfo(
*isKey = info.mIsKey;
+ *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
+
return OK;
}
+status_t AVIExtractor::getSampleTime(
+ size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ return getSampleInfo(
+ trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
+}
+
status_t AVIExtractor::getSampleIndexAtTime(
size_t trackIndex,
int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
@@ -911,7 +944,11 @@ bool SniffAVI(
if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
- *confidence = 0.2;
+
+ // Just a tad over the mp3 extractor's confidence, since
+ // these .avi files may contain .mp3 content that otherwise would
+ // mistakenly lead to us identifying the entire file as a .mp3 file.
+ *confidence = 0.21;
return true;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index fb49d7b..9ab470b 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -50,7 +50,7 @@ namespace android {
// Treat time out as an error if we have not received any output
// buffers after 3 seconds.
-const static int64_t kBufferFilledEventTimeOutUs = 3000000000LL;
+const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
struct CodecInfo {
const char *mime;
@@ -2325,9 +2325,14 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
{
CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
data1, data2);
- CHECK(mFilledBuffers.empty());
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
+ // There is no need to check whether mFilledBuffers is empty or not
+ // when the OMX_EventPortSettingsChanged is not meant for reallocating
+ // the output buffers.
+ if (data1 == kPortIndexOutput) {
+ CHECK(mFilledBuffers.empty());
+ }
onPortSettingsChanged(data1);
} else if (data1 == kPortIndexOutput &&
(data2 == OMX_IndexConfigCommonOutputCrop ||
@@ -3220,7 +3225,7 @@ status_t OMXCodec::waitForBufferFilled_l() {
// for video encoding.
return mBufferFilled.wait(mLock);
}
- status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutUs);
+ status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
if (err != OK) {
CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
index 375a94d..b575347 100644
--- a/media/libstagefright/include/AVIExtractor.h
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -54,6 +54,11 @@ private:
uint32_t mRate;
uint32_t mScale;
+ // If bytes per sample == 0, each chunk represents a single sample,
+ // otherwise each chunk should me a multiple of bytes-per-sample in
+ // size.
+ uint32_t mBytesPerSample;
+
enum Kind {
AUDIO,
VIDEO,
@@ -84,7 +89,11 @@ private:
status_t getSampleInfo(
size_t trackIndex, size_t sampleIndex,
- off64_t *offset, size_t *size, bool *isKey);
+ off64_t *offset, size_t *size, bool *isKey,
+ int64_t *sampleTimeUs);
+
+ status_t getSampleTime(
+ size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs);
status_t getSampleIndexAtTime(
size_t trackIndex,
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
index b1ad315..b1d049e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
@@ -95,6 +95,25 @@ public class MediaProfileReader
return audioEncoderMap.get(audioEncoder);
}
+ public static int getMinFrameRateForCodec(int codec) {
+ return getMinOrMaxFrameRateForCodec(codec, false);
+ }
+
+ public static int getMaxFrameRateForCodec(int codec) {
+ return getMinOrMaxFrameRateForCodec(codec, true);
+ }
+
+ private static int getMinOrMaxFrameRateForCodec(int codec, boolean max) {
+ for (VideoEncoderCap cap: videoEncoders) {
+ if (cap.mCodec == codec) {
+ if (max) return cap.mMaxFrameRate;
+ else return cap.mMinFrameRate;
+ }
+ }
+ // Should never reach here
+ throw new IllegalArgumentException("Unsupported video codec " + codec);
+ }
+
private MediaProfileReader() {} // Don't call me
private static void initVideoEncoderMap() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaItemThumbnailTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaItemThumbnailTest.java
index 154f691..d5b67aa 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaItemThumbnailTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaItemThumbnailTest.java
@@ -657,7 +657,7 @@ public class MediaItemThumbnailTest extends
public void testThumbnailListForH264WVGAWithCount() throws Exception {
final String videoItemFilename = INPUT_FILE_PATH +
"H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
- final int tnCount = 100;
+ final int tnCount = 70;
final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
final MediaVideoItem mediaVideoItem =
mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 82df669..796b52c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -247,7 +247,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFra
mCamera.unlock();
mRecorder.setCamera(mCamera);
Thread.sleep(1000);
- recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263,
+ int codec = MediaRecorder.VideoEncoder.H263;
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
+ recordVideo(frameRate, 352, 288, codec,
MediaRecorder.OutputFormat.THREE_GPP,
MediaNames.RECORDED_PORTRAIT_H263, true);
mCamera.lock();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 0f79515..0b887b9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -365,16 +365,6 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med
assertTrue("H264 playback memory test", memoryResult);
}
- private int getMaxFrameRateForVideoEncoder(int codec) {
- int frameRate = -1;
- for (VideoEncoderCap cap: videoEncoders) {
- if (cap.mCodec == MediaRecorder.VideoEncoder.H263) {
- frameRate = cap.mMaxFrameRate;
- }
- }
- return frameRate;
- }
-
// Test case 4: Capture the memory usage after every 20 video only recorded
@LargeTest
public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
@@ -384,7 +374,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med
File videoH263RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut, true));
output.write("H263 video record only\n");
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
assertTrue("H263 video recording frame rate", frameRate != -1);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
@@ -406,7 +396,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med
File videoMp4RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut, true));
output.write("MPEG4 video record only\n");
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.MPEG_4_SP);
assertTrue("MPEG4 video recording frame rate", frameRate != -1);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
@@ -428,7 +418,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med
File videoRecordAudioMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut, true));
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
assertTrue("H263 video recording frame rate", frameRate != -1);
output.write("Audio and h263 video record\n");
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index ae0589c..e6177ba 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -205,7 +205,7 @@ public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<Me
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(filename);
- mRecorder.setVideoFrameRate(20);
+ mRecorder.setVideoFrameRate(MediaRecorderStressTestRunner.mFrameRate);
mRecorder.setVideoSize(176,144);
Log.v(TAG, "setEncoder");
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
@@ -269,7 +269,7 @@ public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<Me
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(filename);
- mRecorder.setVideoFrameRate(20);
+ mRecorder.setVideoFrameRate(MediaRecorderStressTestRunner.mFrameRate);
mRecorder.setVideoSize(176,144);
Log.v(TAG, "Media recorder setEncoder");
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);