summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/CamcorderProfile.java26
-rw-r--r--media/java/android/media/IRemoteControlDisplay.aidl2
-rw-r--r--media/java/android/media/RemoteControlClient.java23
-rw-r--r--media/jni/android_media_MediaProfiles.cpp16
-rw-r--r--media/libmedia/MediaProfiles.cpp6
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp4
6 files changed, 58 insertions, 19 deletions
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index b2234e2..51a45cd 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -81,6 +81,16 @@ public class CamcorderProfile
public static final int QUALITY_1080P = 6;
/**
+ * Quality level corresponding to the QVGA (320x240) resolution.
+ * {@hide}
+ */
+ public static final int QUALITY_QVGA = 7;
+
+ // Start and end of quality list
+ private static final int QUALITY_LIST_START = QUALITY_LOW;
+ private static final int QUALITY_LIST_END = QUALITY_QVGA;
+
+ /**
* Time lapse quality level corresponding to the lowest available resolution.
*/
public static final int QUALITY_TIME_LAPSE_LOW = 1000;
@@ -116,6 +126,16 @@ public class CamcorderProfile
public static final int QUALITY_TIME_LAPSE_1080P = 1006;
/**
+ * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
+ * {@hide}
+ */
+ public static final int QUALITY_TIME_LAPSE_QVGA = 1007;
+
+ // Start and end of timelapse quality list
+ private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
+ private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_QVGA;
+
+ /**
* Default recording duration in seconds before the session is terminated.
* This is useful for applications like MMS has limited file size requirement.
*/
@@ -238,8 +258,10 @@ public class CamcorderProfile
* @see #QUALITY_TIME_LAPSE_1080P
*/
public static CamcorderProfile get(int cameraId, int quality) {
- if (!((quality >= QUALITY_LOW && quality <= QUALITY_1080P) ||
- (quality >= QUALITY_TIME_LAPSE_LOW && quality <= QUALITY_TIME_LAPSE_1080P))) {
+ if (!((quality >= QUALITY_LIST_START &&
+ quality <= QUALITY_LIST_END) ||
+ (quality >= QUALITY_TIME_LAPSE_LIST_START &&
+ quality <= QUALITY_TIME_LAPSE_LIST_END))) {
String errMessage = "Unsupported quality level: " + quality;
throw new IllegalArgumentException(errMessage);
}
diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl
index e15b07c..204de3c 100644
--- a/media/java/android/media/IRemoteControlDisplay.aidl
+++ b/media/java/android/media/IRemoteControlDisplay.aidl
@@ -40,7 +40,7 @@ oneway interface IRemoteControlDisplay
void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent,
boolean clearing);
- void setPlaybackState(int generationId, int state);
+ void setPlaybackState(int generationId, int state, long stateChangeTimeMs);
void setTransportControlFlags(int generationId, int transportControlFlags);
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 5dea87f..198ae4c 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
import java.lang.IllegalArgumentException;
@@ -494,11 +495,15 @@ public class RemoteControlClient
*/
public void setPlaybackState(int state) {
synchronized(mCacheLock) {
- // store locally
- mPlaybackState = state;
-
- // send to remote control display if conditions are met
- sendPlaybackState_syncCacheLock();
+ if (mPlaybackState != state) {
+ // store locally
+ mPlaybackState = state;
+ // keep track of when the state change occurred
+ mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
+
+ // send to remote control display if conditions are met
+ sendPlaybackState_syncCacheLock();
+ }
}
}
@@ -534,6 +539,11 @@ public class RemoteControlClient
*/
private int mPlaybackState = PLAYSTATE_NONE;
/**
+ * Time of last play state change
+ * Access synchronized on mCacheLock
+ */
+ private long mPlaybackStateChangeTimeMs = 0;
+ /**
* Cache for the artwork bitmap.
* Access synchronized on mCacheLock
* Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be
@@ -716,7 +726,8 @@ public class RemoteControlClient
private void sendPlaybackState_syncCacheLock() {
if ((mCurrentClientGenId == mInternalClientGenId) && (mRcDisplay != null)) {
try {
- mRcDisplay.setPlaybackState(mInternalClientGenId, mPlaybackState);
+ mRcDisplay.setPlaybackState(mInternalClientGenId, mPlaybackState,
+ mPlaybackStateChangeTimeMs);
} catch (RemoteException e) {
Log.e(TAG, "Error in setPlaybackState(), dead display "+e);
detachFromDisplay_syncCacheLock();
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index e5e688c..7ed0050 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -161,13 +161,19 @@ android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject th
return cap;
}
+static bool isCamcorderQualityKnown(int quality)
+{
+ return ((quality >= CAMCORDER_QUALITY_LIST_START &&
+ quality <= CAMCORDER_QUALITY_LIST_END) ||
+ (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START &&
+ quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END));
+}
+
static jobject
android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality)
{
LOGV("native_get_camcorder_profile: %d %d", id, quality);
- if (!((quality >= CAMCORDER_QUALITY_LOW && quality <= CAMCORDER_QUALITY_1080P) ||
- (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LOW &&
- quality <= CAMCORDER_QUALITY_TIME_LAPSE_1080P))) {
+ if (!isCamcorderQualityKnown(quality)) {
jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality");
return NULL;
}
@@ -216,9 +222,7 @@ static jboolean
android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality)
{
LOGV("native_has_camcorder_profile: %d %d", id, quality);
- if (!((quality >= CAMCORDER_QUALITY_LOW && quality <= CAMCORDER_QUALITY_1080P) ||
- (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LOW &&
- quality <= CAMCORDER_QUALITY_TIME_LAPSE_1080P))) {
+ if (!isCamcorderQualityKnown(quality)) {
return false;
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 5a8bc60..ad55ff8 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -67,6 +67,7 @@ const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = {
{"480p", CAMCORDER_QUALITY_480P},
{"720p", CAMCORDER_QUALITY_720P},
{"1080p", CAMCORDER_QUALITY_1080P},
+ {"qvga", CAMCORDER_QUALITY_QVGA},
{"timelapselow", CAMCORDER_QUALITY_TIME_LAPSE_LOW},
{"timelapsehigh", CAMCORDER_QUALITY_TIME_LAPSE_HIGH},
@@ -74,7 +75,8 @@ const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = {
{"timelapsecif", CAMCORDER_QUALITY_TIME_LAPSE_CIF},
{"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P},
{"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P},
- {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P}
+ {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P},
+ {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA},
};
/*static*/ void
@@ -1139,7 +1141,7 @@ int MediaProfiles::getStartTimeOffsetMs(int cameraId) const {
if (index >= 0) {
offsetTimeMs = mStartTimeOffsets.valueFor(cameraId);
}
- LOGV("%s: offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
+ LOGV("offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
return offsetTimeMs;
}
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 306f1f6..2b27ee2 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -764,8 +764,8 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer,
// If the loop was exited as a result of stopping the recording,
// it is OK
if (mStopped) {
- LOGV("Read: SurfaceMediaSource is stopped. Returning NO_INIT;");
- return NO_INIT;
+ LOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
+ return ERROR_END_OF_STREAM;
}
// Update the current buffer info