diff options
18 files changed, 675 insertions, 341 deletions
diff --git a/api/current.xml b/api/current.xml index a06140bb63b4..4006e67a0f05 100644 --- a/api/current.xml +++ b/api/current.xml @@ -86147,6 +86147,385 @@ </parameter> </method> </interface> +<class name="MediaMetadataRetriever" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="MediaMetadataRetriever" + type="android.media.MediaMetadataRetriever" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="extractMetadata" + return="java.lang.String" + abstract="false" + native="true" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="keyCode" type="int"> +</parameter> +</method> +<method name="getEmbeddedPicture" + return="byte[]" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getFrameAtTime" + return="android.graphics.Bitmap" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="timeUs" type="long"> +</parameter> +<parameter name="option" type="int"> +</parameter> +</method> +<method name="getFrameAtTime" + return="android.graphics.Bitmap" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="timeUs" type="long"> +</parameter> +</method> +<method name="getFrameAtTime" + return="android.graphics.Bitmap" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="release" + return="void" + abstract="false" + native="true" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="setDataSource" + return="void" + abstract="false" + native="true" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="path" type="java.lang.String"> +</parameter> +<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> +</exception> +</method> +<method name="setDataSource" + return="void" + abstract="false" + native="true" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="fd" type="java.io.FileDescriptor"> +</parameter> +<parameter name="offset" type="long"> +</parameter> +<parameter name="length" type="long"> +</parameter> +<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> +</exception> +</method> +<method name="setDataSource" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="fd" type="java.io.FileDescriptor"> +</parameter> +<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> +</exception> +</method> +<method name="setDataSource" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="context" type="android.content.Context"> +</parameter> +<parameter name="uri" type="android.net.Uri"> +</parameter> +<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> +</exception> +<exception name="SecurityException" type="java.lang.SecurityException"> +</exception> +</method> +<field name="METADATA_KEY_ALBUM" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_ALBUMARTIST" + type="int" + transient="false" + volatile="false" + value="13" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_ARTIST" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_AUTHOR" + type="int" + transient="false" + volatile="false" + value="3" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_CD_TRACK_NUMBER" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_COMPILATION" + type="int" + transient="false" + volatile="false" + value="15" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_COMPOSER" + type="int" + transient="false" + volatile="false" + value="4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_DATE" + type="int" + transient="false" + volatile="false" + value="5" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_DISC_NUMBER" + type="int" + transient="false" + volatile="false" + value="14" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_DURATION" + type="int" + transient="false" + volatile="false" + value="9" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_GENRE" + type="int" + transient="false" + volatile="false" + value="6" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_MIMETYPE" + type="int" + transient="false" + volatile="false" + value="12" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_NUM_TRACKS" + type="int" + transient="false" + volatile="false" + value="10" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_TITLE" + type="int" + transient="false" + volatile="false" + value="7" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_WRITER" + type="int" + transient="false" + volatile="false" + value="11" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="METADATA_KEY_YEAR" + type="int" + transient="false" + volatile="false" + value="8" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OPTION_CLOSEST" + type="int" + transient="false" + volatile="false" + value="3" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OPTION_CLOSEST_SYNC" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OPTION_NEXT_SYNC" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="OPTION_PREVIOUS_SYNC" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +</class> <class name="MediaPlayer" extends="java.lang.Object" abstract="false" diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index f55b7460c866..ff924314dfd8 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -596,21 +596,19 @@ int main(int argc, char **argv) { const char *filename = argv[k]; CHECK_EQ(retriever->setDataSource(filename), (status_t)OK); - CHECK_EQ(retriever->setMode( - METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL), - (status_t)OK); - - sp<IMemory> mem = retriever->captureFrame(); + sp<IMemory> mem = + retriever->getFrameAtTime(-1, + MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); if (mem != NULL) { - printf("captureFrame(%s) => OK\n", filename); + printf("getFrameAtTime(%s) => OK\n", filename); } else { mem = retriever->extractAlbumArt(); if (mem != NULL) { printf("extractAlbumArt(%s) => OK\n", filename); } else { - printf("both captureFrame and extractAlbumArt " + printf("both getFrameAtTime and extractAlbumArt " "failed on file '%s'.\n", filename); } } diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 9baba8e8fdbd..8e3cdbbead0b 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -32,9 +32,7 @@ public: virtual void disconnect() = 0; virtual status_t setDataSource(const char* srcUrl) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; - virtual status_t setMode(int mode) = 0; - virtual status_t getMode(int* mode) const = 0; - virtual sp<IMemory> captureFrame() = 0; + virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0; virtual sp<IMemory> extractAlbumArt() = 0; virtual const char* extractMetadata(int keyCode) = 0; }; diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index ff57774165ba..04491224c21e 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -32,9 +32,7 @@ public: virtual ~MediaMetadataRetrieverBase() {} virtual status_t setDataSource(const char *url) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; - virtual status_t setMode(int mode) = 0; - virtual status_t getMode(int* mode) const = 0; - virtual VideoFrame* captureFrame() = 0; + virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0; virtual MediaAlbumArt* extractAlbumArt() = 0; virtual const char* extractMetadata(int keyCode) = 0; }; @@ -43,35 +41,12 @@ public: class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase { public: - MediaMetadataRetrieverInterface() - : mMode(0) { - } + MediaMetadataRetrieverInterface() {} virtual ~MediaMetadataRetrieverInterface() {} - - // @param mode The intended mode of operations: - // can be any of the following: - // METADATA_MODE_NOOP: Experimental - just add and remove data source. - // METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only. - // METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only. - // METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame - // capture and meta data retrieval. - virtual status_t setMode(int mode) { - if (mode < METADATA_MODE_NOOP || - mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) { - return BAD_VALUE; - } - - mMode = mode; - return NO_ERROR; - } - - virtual status_t getMode(int* mode) const { *mode = mMode; return NO_ERROR; } - virtual VideoFrame* captureFrame() { return NULL; } + virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) { return NULL; } virtual MediaAlbumArt* extractAlbumArt() { return NULL; } virtual const char* extractMetadata(int keyCode) { return NULL; } - - uint32_t mMode; }; }; // namespace android diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index ddc07f60da71..e905006929c3 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -42,37 +42,14 @@ enum { METADATA_KEY_YEAR = 8, METADATA_KEY_DURATION = 9, METADATA_KEY_NUM_TRACKS = 10, - METADATA_KEY_IS_DRM_CRIPPLED = 11, - METADATA_KEY_CODEC = 12, - METADATA_KEY_RATING = 13, - METADATA_KEY_COMMENT = 14, - METADATA_KEY_COPYRIGHT = 15, - METADATA_KEY_BIT_RATE = 16, - METADATA_KEY_FRAME_RATE = 17, - METADATA_KEY_VIDEO_FORMAT = 18, - METADATA_KEY_VIDEO_HEIGHT = 19, - METADATA_KEY_VIDEO_WIDTH = 20, - METADATA_KEY_WRITER = 21, - METADATA_KEY_MIMETYPE = 22, - METADATA_KEY_DISC_NUMBER = 23, - METADATA_KEY_ALBUMARTIST = 24, - METADATA_KEY_COMPILATION = 25, + METADATA_KEY_WRITER = 11, + METADATA_KEY_MIMETYPE = 12, + METADATA_KEY_ALBUMARTIST = 13, + METADATA_KEY_DISC_NUMBER = 14, + METADATA_KEY_COMPILATION = 15, // Add more here... }; -// The intended mode of operations:$ -// METADATA_MODE_NOOP: Experimental - just add and remove data source.$ -// METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only.$ -// METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only.$ -// METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame capture -// and meta data retrieval.$ -enum { - METADATA_MODE_NOOP = 0x00, - METADATA_MODE_METADATA_RETRIEVAL_ONLY = 0x01, - METADATA_MODE_FRAME_CAPTURE_ONLY = 0x02, - METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL = 0x03 -}; - class MediaMetadataRetriever: public RefBase { public: @@ -81,9 +58,7 @@ public: void disconnect(); status_t setDataSource(const char* dataSourceUrl); status_t setDataSource(int fd, int64_t offset, int64_t length); - status_t setMode(int mode); - status_t getMode(int* mode); - sp<IMemory> captureFrame(); + sp<IMemory> getFrameAtTime(int64_t timeUs, int option); sp<IMemory> extractAlbumArt(); const char* extractMetadata(int keyCode); diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index 008528d43236..77e939ed12df 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -29,7 +29,6 @@ import java.io.IOException; /** * MediaMetadataRetriever class provides a unified interface for retrieving * frame and meta data from an input media file. - * {@hide} */ public class MediaMetadataRetriever { @@ -42,41 +41,13 @@ public class MediaMetadataRetriever @SuppressWarnings("unused") private int mNativeContext; + private static final int EMBEDDED_PICTURE_TYPE_ANY = 0xFFFF; + public MediaMetadataRetriever() { native_setup(); } /** - * Call this method before setDataSource() so that the mode becomes - * effective for subsequent operations. This method can be called only once - * at the beginning if the intended mode of operation for a - * MediaMetadataRetriever object remains the same for its whole lifetime, - * and thus it is unnecessary to call this method each time setDataSource() - * is called. If this is not never called (which is allowed), by default the - * intended mode of operation is to both capture frame and retrieve meta - * data (i.e., MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY). - * Often, this may not be what one wants, since doing this has negative - * performance impact on execution time of a call to setDataSource(), since - * both types of operations may be time consuming. - * - * @param mode The intended mode of operation. Can be any combination of - * MODE_GET_METADATA_ONLY and MODE_CAPTURE_FRAME_ONLY: - * 1. MODE_GET_METADATA_ONLY & MODE_CAPTURE_FRAME_ONLY: - * For neither frame capture nor meta data retrieval - * 2. MODE_GET_METADATA_ONLY: For meta data retrieval only - * 3. MODE_CAPTURE_FRAME_ONLY: For frame capture only - * 4. MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY: - * For both frame capture and meta data retrieval - */ - public native void setMode(int mode); - - /** - * @return the current mode of operation. A negative return value indicates - * some runtime error has occurred. - */ - public native int getMode(); - - /** * Sets the data source (file pathname) to use. Call this * method before the rest of the methods in this class. This method may be * time-consuming. @@ -190,22 +161,99 @@ public class MediaMetadataRetriever /** * Call this method after setDataSource(). This method finds a - * representative frame if successful and returns it as a bitmap. This is - * useful for generating a thumbnail for an input media source. - * + * representative frame close to the given time position by considering + * the given option if possible, and returns it as a bitmap. This is + * useful for generating a thumbnail for an input data source or just + * obtain and display a frame at the given time position. + * + * @param timeUs The time position where the frame will be retrieved. + * When retrieving the frame at the given time position, there is no + * guarantee that the data source has a frame located at the position. + * When this happens, a frame nearby will be returned. If timeUs is + * negative, time position and option will ignored, and any frame + * that the implementation considers as representative may be returned. + * + * @param option a hint on how the frame is found. Use + * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame + * that has a timestamp earlier than or the same as timeUs. Use + * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame + * that has a timestamp later than or the same as timeUs. Use + * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame + * that has a timestamp closest to or the same as timeUs. Use + * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may + * or may not be a sync frame but is closest to or the same as timeUs. + * {@link #OPTION_CLOSEST} often has larger performance overhead compared + * to the other options if there is no sync frame located at timeUs. + * * @return A Bitmap containing a representative video frame, which * can be null, if such a frame cannot be retrieved. */ - public native Bitmap captureFrame(); + public Bitmap getFrameAtTime(long timeUs, int option) { + if (option < OPTION_PREVIOUS_SYNC || + option > OPTION_CLOSEST) { + throw new IllegalArgumentException("Unsupported option: " + option); + } + + return _getFrameAtTime(timeUs, option); + } + + /** + * Call this method after setDataSource(). This method finds a + * representative frame close to the given time position if possible, + * and returns it as a bitmap. This is useful for generating a thumbnail + * for an input data source. Call this method if one does not care + * how the frame is found as long as it is close to the given time; + * otherwise, please call {@link #getFrameAtTime(long, int)}. + * + * @param timeUs The time position where the frame will be retrieved. + * When retrieving the frame at the given time position, there is no + * guarentee that the data source has a frame located at the position. + * When this happens, a frame nearby will be returned. If timeUs is + * negative, time position and option will ignored, and any frame + * that the implementation considers as representative may be returned. + * + * @return A Bitmap containing a representative video frame, which + * can be null, if such a frame cannot be retrieved. + * + * @see #getFrameAtTime(long, int) + */ + public Bitmap getFrameAtTime(long timeUs) { + return getFrameAtTime(timeUs, OPTION_CLOSEST_SYNC); + } + + /** + * Call this method after setDataSource(). This method finds a + * representative frame at any time position if possible, + * and returns it as a bitmap. This is useful for generating a thumbnail + * for an input data source. Call this method if one does not + * care about where the frame is located; otherwise, please call + * {@link #getFrameAtTime(long)} or {@link #getFrameAtTime(long, int)} + * + * @return A Bitmap containing a representative video frame, which + * can be null, if such a frame cannot be retrieved. + * + * @see #getFrameAtTime(long) + * @see #getFrameAtTime(long, int) + */ + public Bitmap getFrameAtTime() { + return getFrameAtTime(-1, OPTION_CLOSEST_SYNC); + } + + private native Bitmap _getFrameAtTime(long timeUs, int option); + /** * Call this method after setDataSource(). This method finds the optional - * graphic or album art associated (embedded or external url linked) the - * related data source. + * graphic or album art associated associated with the data source. If + * there are more than one pictures, (any) one of them is returned. * * @return null if no such graphic is found. */ - public native byte[] extractAlbumArt(); + public byte[] getEmbeddedPicture() { + return getEmbeddedPicture(EMBEDDED_PICTURE_TYPE_ANY); + } + + private native byte[] getEmbeddedPicture(int pictureType); /** * Call it when one is done with the object. This method releases the memory @@ -226,38 +274,129 @@ public class MediaMetadataRetriever } } - public static final int MODE_GET_METADATA_ONLY = 0x01; - public static final int MODE_CAPTURE_FRAME_ONLY = 0x02; + /** + * Option used in method {@link #getFrameAtTime(long, int)} to get a + * frame at a specified location. + * + * @see #getFrameAtTime(long, int) + */ + /* Do not change these option values without updating their counterparts + * in include/media/stagefright/MediaSource.h! + */ + /** + * This option is used with {@link #getFrameAtTime(long, int)} to retrieve + * a sync (or key) frame associated with a data source that is located + * right before or at the given time. + * + * @see #getFrameAtTime(long, int) + */ + public static final int OPTION_PREVIOUS_SYNC = 0x00; + /** + * This option is used with {@link #getFrameAtTime(long, int)} to retrieve + * a sync (or key) frame associated with a data source that is located + * right after or at the given time. + * + * @see #getFrameAtTime(long, int) + */ + public static final int OPTION_NEXT_SYNC = 0x01; + /** + * This option is used with {@link #getFrameAtTime(long, int)} to retrieve + * a sync (or key) frame associated with a data source that is located + * closest to (in time) or at the given time. + * + * @see #getFrameAtTime(long, int) + */ + public static final int OPTION_CLOSEST_SYNC = 0x02; + /** + * This option is used with {@link #getFrameAtTime(long, int)} to retrieve + * a frame (not necessarily a key frame) associated with a data source that + * is located closest to or at the given time. + * + * @see #getFrameAtTime(long, int) + */ + public static final int OPTION_CLOSEST = 0x03; /* - * Do not change these values without updating their counterparts - * in include/media/mediametadataretriever.h! + * Do not change these metadata key values without updating their + * counterparts in include/media/mediametadataretriever.h! + */ + /** + * The metadata key to retrieve the numberic string describing the + * order of the audio data source on its original recording. */ public static final int METADATA_KEY_CD_TRACK_NUMBER = 0; + /** + * The metadata key to retrieve the information about the album title + * of the data source. + */ public static final int METADATA_KEY_ALBUM = 1; + /** + * The metadata key to retrieve the information about the artist of + * the data source. + */ public static final int METADATA_KEY_ARTIST = 2; + /** + * The metadata key to retrieve the information about the author of + * the data source. + */ public static final int METADATA_KEY_AUTHOR = 3; + /** + * The metadata key to retrieve the information about the composer of + * the data source. + */ public static final int METADATA_KEY_COMPOSER = 4; + /** + * The metadata key to retrieve the date when the data source was created + * or modified. + */ public static final int METADATA_KEY_DATE = 5; + /** + * The metadata key to retrieve the content type or genre of the data + * source. + */ public static final int METADATA_KEY_GENRE = 6; + /** + * The metadata key to retrieve the data source title. + */ public static final int METADATA_KEY_TITLE = 7; + /** + * The metadata key to retrieve the year when the data source was created + * or modified. + */ public static final int METADATA_KEY_YEAR = 8; + /** + * The metadata key to retrieve the playback duration of the data source. + */ public static final int METADATA_KEY_DURATION = 9; + /** + * The metadata key to retrieve the number of tracks, such as audio, video, + * text, in the data source, such as a mp4 or 3gpp file. + */ public static final int METADATA_KEY_NUM_TRACKS = 10; - public static final int METADATA_KEY_IS_DRM_CRIPPLED = 11; - public static final int METADATA_KEY_CODEC = 12; - public static final int METADATA_KEY_RATING = 13; - public static final int METADATA_KEY_COMMENT = 14; - public static final int METADATA_KEY_COPYRIGHT = 15; - public static final int METADATA_KEY_BIT_RATE = 16; - public static final int METADATA_KEY_FRAME_RATE = 17; - public static final int METADATA_KEY_VIDEO_FORMAT = 18; - public static final int METADATA_KEY_VIDEO_HEIGHT = 19; - public static final int METADATA_KEY_VIDEO_WIDTH = 20; - public static final int METADATA_KEY_WRITER = 21; - public static final int METADATA_KEY_MIMETYPE = 22; - public static final int METADATA_KEY_DISCNUMBER = 23; - public static final int METADATA_KEY_ALBUMARTIST = 24; - public static final int METADATA_KEY_COMPILATION = 25; + /** + * The metadata key to retrieve the information of the writer (such as + * lyricist) of the data source. + */ + public static final int METADATA_KEY_WRITER = 11; + /** + * The metadata key to retrieve the mime type of the data source. Some + * example mime types include: "video/mp4", "audio/mp4", "audio/amr-wb", + * etc. + */ + public static final int METADATA_KEY_MIMETYPE = 12; + /** + * The metadata key to retrieve the information about the performers or + * artist associated with the data source. + */ + public static final int METADATA_KEY_ALBUMARTIST = 13; + /** + * The metadata key to retrieve the numberic string that describes which + * part of a set the audio data source comes from. + */ + public static final int METADATA_KEY_DISC_NUMBER = 14; + /** + * The metadata key to retrieve the music album compilation status. + */ + public static final int METADATA_KEY_COMPILATION = 15; // Add more here... } diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java index 3d85e31ed055..494b4cbf0b5d 100644 --- a/media/java/android/media/ThumbnailUtils.java +++ b/media/java/android/media/ThumbnailUtils.java @@ -146,9 +146,8 @@ public class ThumbnailUtils { Bitmap bitmap = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { - retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); retriever.setDataSource(filePath); - bitmap = retriever.captureFrame(); + bitmap = retriever.getFrameAtTime(-1); } catch (IllegalArgumentException ex) { // Assume this is a corrupt video file } catch (RuntimeException ex) { diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index 63e9dc867569..c5e58f7b7033 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -131,33 +131,9 @@ static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jo process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed"); } -static void android_media_MediaMetadataRetriever_setMode(JNIEnv *env, jobject thiz, jint mode) +static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option) { - LOGV("setMode"); - MediaMetadataRetriever* retriever = getRetriever(env, thiz); - if (retriever == 0) { - jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); - return; - } - process_media_retriever_call(env, retriever->setMode(mode), "java/lang/RuntimeException", "setMode failed"); -} - -static int android_media_MediaMetadataRetriever_getMode(JNIEnv *env, jobject thiz) -{ - LOGV("getMode"); - MediaMetadataRetriever* retriever = getRetriever(env, thiz); - if (retriever == 0) { - jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); - return -1; // Error - } - int mode = -1; - retriever->getMode(&mode); - return mode; -} - -static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jobject thiz) -{ - LOGV("captureFrame"); + LOGV("getFrameAtTime: %lld us option: %d", timeUs, option); MediaMetadataRetriever* retriever = getRetriever(env, thiz); if (retriever == 0) { jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); @@ -166,12 +142,12 @@ static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jo // Call native method to retrieve a video frame VideoFrame *videoFrame = NULL; - sp<IMemory> frameMemory = retriever->captureFrame(); + sp<IMemory> frameMemory = retriever->getFrameAtTime(timeUs, option); if (frameMemory != 0) { // cast the shared structure to a VideoFrame object videoFrame = static_cast<VideoFrame *>(frameMemory->pointer()); } if (videoFrame == NULL) { - LOGE("captureFrame: videoFrame is a NULL pointer"); + LOGE("getFrameAtTime: videoFrame is a NULL pointer"); return NULL; } @@ -213,7 +189,7 @@ static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jo // Create a SkBitmap to hold the pixels SkBitmap *bitmap = new SkBitmap(); if (bitmap == NULL) { - LOGE("captureFrame: cannot instantiate a SkBitmap object."); + LOGE("getFrameAtTime: cannot instantiate a SkBitmap object."); return NULL; } bitmap->setConfig(SkBitmap::kRGB_565_Config, videoFrame->mDisplayWidth, videoFrame->mDisplayHeight); @@ -242,21 +218,26 @@ static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jo false); // filter } -static jbyteArray android_media_MediaMetadataRetriever_extractAlbumArt(JNIEnv *env, jobject thiz) +static jbyteArray android_media_MediaMetadataRetriever_getEmbeddedPicture( + JNIEnv *env, jobject thiz, jint pictureType) { - LOGV("extractAlbumArt"); + LOGV("getEmbeddedPicture: %d", pictureType); MediaMetadataRetriever* retriever = getRetriever(env, thiz); if (retriever == 0) { jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); return NULL; } MediaAlbumArt* mediaAlbumArt = NULL; + + // FIXME: + // Use pictureType to retrieve the intended embedded picture and also change + // the method name to getEmbeddedPicture(). sp<IMemory> albumArtMemory = retriever->extractAlbumArt(); if (albumArtMemory != 0) { // cast the shared structure to a MediaAlbumArt object mediaAlbumArt = static_cast<MediaAlbumArt *>(albumArtMemory->pointer()); } if (mediaAlbumArt == NULL) { - LOGE("extractAlbumArt: Call to extractAlbumArt failed."); + LOGE("getEmbeddedPicture: Call to getEmbeddedPicture failed."); return NULL; } @@ -264,7 +245,7 @@ static jbyteArray android_media_MediaMetadataRetriever_extractAlbumArt(JNIEnv *e char* data = (char*) mediaAlbumArt + sizeof(MediaAlbumArt); jbyteArray array = env->NewByteArray(len); if (!array) { // OutOfMemoryError exception has already been thrown. - LOGE("extractAlbumArt: OutOfMemoryError is thrown."); + LOGE("getEmbeddedPicture: OutOfMemoryError is thrown."); } else { jbyte* bytes = env->GetByteArrayElements(array, NULL); if (bytes != NULL) { @@ -365,11 +346,9 @@ static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobje static JNINativeMethod nativeMethods[] = { {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaMetadataRetriever_setDataSource}, {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD}, - {"setMode", "(I)V", (void *)android_media_MediaMetadataRetriever_setMode}, - {"getMode", "()I", (void *)android_media_MediaMetadataRetriever_getMode}, - {"captureFrame", "()Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_captureFrame}, + {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime}, {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata}, - {"extractAlbumArt", "()[B", (void *)android_media_MediaMetadataRetriever_extractAlbumArt}, + {"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture}, {"release", "()V", (void *)android_media_MediaMetadataRetriever_release}, {"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize}, {"native_setup", "()V", (void *)android_media_MediaMetadataRetriever_native_setup}, diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp index e529d251ec86..d5298c91cc08 100644 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ b/media/libmedia/IMediaMetadataRetriever.cpp @@ -81,9 +81,7 @@ enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_DATA_SOURCE_URL, SET_DATA_SOURCE_FD, - SET_MODE, - GET_MODE, - CAPTURE_FRAME, + GET_FRAME_AT_TIME, EXTRACT_ALBUM_ART, EXTRACT_METADATA, }; @@ -124,32 +122,17 @@ public: return reply.readInt32(); } - status_t setMode(int mode) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); - data.writeInt32(mode); - remote()->transact(SET_MODE, data, &reply); - return reply.readInt32(); - } - - status_t getMode(int* mode) const - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); - remote()->transact(GET_MODE, data, &reply); - *mode = reply.readInt32(); - return reply.readInt32(); - } - - sp<IMemory> captureFrame() + sp<IMemory> getFrameAtTime(int64_t timeUs, int option) { + LOGV("getTimeAtTime: time(%lld us) and option(%d)", timeUs, option); Parcel data, reply; data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); + data.writeInt64(timeUs); + data.writeInt32(option); #ifndef DISABLE_GROUP_SCHEDULE_HACK sendSchedPolicy(data); #endif - remote()->transact(CAPTURE_FRAME, data, &reply); + remote()->transact(GET_FRAME_AT_TIME, data, &reply); status_t ret = reply.readInt32(); if (ret != NO_ERROR) { return NULL; @@ -216,26 +199,15 @@ status_t BnMediaMetadataRetriever::onTransact( reply->writeInt32(setDataSource(fd, offset, length)); return NO_ERROR; } break; - case SET_MODE: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - int mode = data.readInt32(); - reply->writeInt32(setMode(mode)); - return NO_ERROR; - } break; - case GET_MODE: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - int mode; - status_t status = getMode(&mode); - reply->writeInt32(mode); - reply->writeInt32(status); - return NO_ERROR; - } break; - case CAPTURE_FRAME: { + case GET_FRAME_AT_TIME: { CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); + int64_t timeUs = data.readInt64(); + int option = data.readInt32(); + LOGV("getTimeAtTime: time(%lld us) and option(%d)", timeUs, option); #ifndef DISABLE_GROUP_SCHEDULE_HACK setSchedPolicy(data); #endif - sp<IMemory> bitmap = captureFrame(); + sp<IMemory> bitmap = getFrameAtTime(timeUs, option); if (bitmap != 0) { // Don't send NULL across the binder interface reply->writeInt32(NO_ERROR); reply->writeStrongBinder(bitmap->asBinder()); diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index e2712ba44dbd..8dfcb3bae14b 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -123,37 +123,15 @@ status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t l return mRetriever->setDataSource(fd, offset, length); } -status_t MediaMetadataRetriever::setMode(int mode) +sp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option) { - LOGV("setMode(%d)", mode); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - LOGE("retriever is not initialized"); - return INVALID_OPERATION; - } - return mRetriever->setMode(mode); -} - -status_t MediaMetadataRetriever::getMode(int* mode) -{ - LOGV("getMode"); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - LOGE("retriever is not initialized"); - return INVALID_OPERATION; - } - return mRetriever->getMode(mode); -} - -sp<IMemory> MediaMetadataRetriever::captureFrame() -{ - LOGV("captureFrame"); + LOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option); Mutex::Autolock _l(mLock); if (mRetriever == 0) { LOGE("retriever is not initialized"); return NULL; } - return mRetriever->captureFrame(); + return mRetriever->getFrameAtTime(timeUs, option); } const char* MediaMetadataRetriever::extractMetadata(int keyCode) diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 39fce81d6c7e..713e44145b87 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -65,7 +65,6 @@ MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid) mThumbnail = NULL; mAlbumArt = NULL; mRetriever = NULL; - mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL; } MetadataRetrieverClient::~MetadataRetrieverClient() @@ -80,7 +79,7 @@ status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& args) con char buffer[SIZE]; String8 result; result.append(" MetadataRetrieverClient\n"); - snprintf(buffer, 255, " pid(%d) mode(%d)\n", mPid, mMode); + snprintf(buffer, 255, " pid(%d)\n", mPid); result.append(buffer); write(fd, result.string(), result.size()); write(fd, "\n", 1); @@ -94,7 +93,6 @@ void MetadataRetrieverClient::disconnect() mRetriever.clear(); mThumbnail.clear(); mAlbumArt.clear(); - mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL; IPCThreadState::self()->flushCommands(); } @@ -140,10 +138,7 @@ status_t MetadataRetrieverClient::setDataSource(const char *url) LOGV("player type = %d", playerType); sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); if (p == NULL) return NO_INIT; - status_t ret = p->setMode(mMode); - if (ret == NO_ERROR) { - ret = p->setDataSource(url); - } + status_t ret = p->setDataSource(url); if (ret == NO_ERROR) mRetriever = p; return ret; } @@ -181,55 +176,22 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t ::close(fd); return NO_INIT; } - status_t status = p->setMode(mMode); - if (status == NO_ERROR) { - p->setDataSource(fd, offset, length); - } + status_t status = p->setDataSource(fd, offset, length); if (status == NO_ERROR) mRetriever = p; ::close(fd); return status; } -status_t MetadataRetrieverClient::setMode(int mode) -{ - LOGV("setMode"); - Mutex::Autolock lock(mLock); - if (mode < METADATA_MODE_NOOP || - mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) { - LOGE("invalid mode %d", mode); - return BAD_VALUE; - } - mMode = mode; - return NO_ERROR; -} - -status_t MetadataRetrieverClient::getMode(int* mode) const -{ - LOGV("getMode"); - Mutex::Autolock lock(mLock); - - // TODO: - // This may not be necessary. - // If setDataSource() has not been called, return the cached value - // otherwise, return the value retrieved from the retriever - if (mRetriever == NULL) { - *mode = mMode; - } else { - mRetriever->getMode(mode); - } - return NO_ERROR; -} - -sp<IMemory> MetadataRetrieverClient::captureFrame() +sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option) { - LOGV("captureFrame"); + LOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option); Mutex::Autolock lock(mLock); mThumbnail.clear(); if (mRetriever == NULL) { LOGE("retriever is not initialized"); return NULL; } - VideoFrame *frame = mRetriever->captureFrame(); + VideoFrame *frame = mRetriever->getFrameAtTime(timeUs, option); if (frame == NULL) { LOGE("failed to capture a video frame"); return NULL; diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index 4aab94fa7573..b834715d0e98 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -43,9 +43,7 @@ public: virtual void disconnect(); virtual status_t setDataSource(const char *url); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setMode(int mode); - virtual status_t getMode(int* mode) const; - virtual sp<IMemory> captureFrame(); + virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option); virtual sp<IMemory> extractAlbumArt(); virtual const char* extractMetadata(int keyCode); @@ -60,7 +58,6 @@ private: mutable Mutex mLock; sp<MediaMetadataRetrieverBase> mRetriever; pid_t mPid; - int mMode; // Keep the shared memory copy of album art and capture frame (for thumbnail) sp<IMemory> mAlbumArt; diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp index d3aa2f689b90..10c6e4105f7b 100644 --- a/media/libstagefright/StagefrightMediaScanner.cpp +++ b/media/libstagefright/StagefrightMediaScanner.cpp @@ -130,9 +130,7 @@ status_t StagefrightMediaScanner::processFile( return HandleMIDI(path, &client); } - if (mRetriever->setDataSource(path) == OK - && mRetriever->setMode( - METADATA_MODE_METADATA_RETRIEVAL_ONLY) == OK) { + if (mRetriever->setDataSource(path) == OK) { const char *value; if ((value = mRetriever->extractMetadata( METADATA_KEY_MIMETYPE)) != NULL) { @@ -181,9 +179,7 @@ char *StagefrightMediaScanner::extractAlbumArt(int fd) { } lseek(fd, 0, SEEK_SET); - if (mRetriever->setDataSource(fd, 0, size) == OK - && mRetriever->setMode( - METADATA_MODE_FRAME_CAPTURE_ONLY) == OK) { + if (mRetriever->setDataSource(fd, 0, size) == OK) { sp<IMemory> mem = mRetriever->extractAlbumArt(); if (mem != NULL) { diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index ac208cd252e6..e8f483925c11 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -108,7 +108,10 @@ status_t StagefrightMetadataRetriever::setDataSource( static VideoFrame *extractVideoFrameWithCodecFlags( OMXClient *client, const sp<MetaData> &trackMeta, - const sp<MediaSource> &source, uint32_t flags) { + const sp<MediaSource> &source, + uint32_t flags, + int64_t frameTimeUs, + int seekMode) { sp<MediaSource> decoder = OMXCodec::Create( client->interface(), source->getFormat(), false, source, @@ -130,11 +133,22 @@ static VideoFrame *extractVideoFrameWithCodecFlags( // and spurious empty buffers. MediaSource::ReadOptions options; + if (seekMode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC || + seekMode > MediaSource::ReadOptions::SEEK_CLOSEST) { + + LOGE("Unknown seek mode: %d", seekMode); + return NULL; + } + + MediaSource::ReadOptions::SeekMode mode = + static_cast<MediaSource::ReadOptions::SeekMode>(seekMode); + int64_t thumbNailTime; - if (trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { - options.setSeekTo(thumbNailTime); + if (frameTimeUs < 0 && trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { + options.setSeekTo(thumbNailTime, mode); } else { thumbNailTime = -1; + options.setSeekTo(frameTimeUs, mode); } MediaBuffer *buffer = NULL; @@ -226,14 +240,10 @@ static VideoFrame *extractVideoFrameWithCodecFlags( return frame; } -VideoFrame *StagefrightMetadataRetriever::captureFrame() { - LOGV("captureFrame"); - - if (0 == (mMode & METADATA_MODE_FRAME_CAPTURE_ONLY)) { - LOGV("captureFrame disabled by mode (0x%08x)", mMode); +VideoFrame *StagefrightMetadataRetriever::getFrameAtTime( + int64_t timeUs, int option) { - return NULL; - } + LOGV("getFrameAtTime: %lld us option: %d", timeUs, option); if (mExtractor.get() == NULL) { LOGV("no extractor."); @@ -270,13 +280,15 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { VideoFrame *frame = extractVideoFrameWithCodecFlags( - &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs); + &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs, + timeUs, option); if (frame == NULL) { LOGV("Software decoder failed to extract thumbnail, " "trying hardware decoder."); - frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0); + frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0, + timeUs, option); } return frame; @@ -285,12 +297,6 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() { LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO"); - if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) { - LOGV("extractAlbumArt/metadata retrieval disabled by mode"); - - return NULL; - } - if (mExtractor == NULL) { return NULL; } @@ -309,12 +315,6 @@ MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() { } const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) { - if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) { - LOGV("extractAlbumArt/metadata retrieval disabled by mode"); - - return NULL; - } - if (mExtractor == NULL) { return NULL; } diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h index b80387f21dce..07b1ec8afdd7 100644 --- a/media/libstagefright/include/StagefrightMetadataRetriever.h +++ b/media/libstagefright/include/StagefrightMetadataRetriever.h @@ -35,7 +35,7 @@ struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface { virtual status_t setDataSource(const char *url); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual VideoFrame *captureFrame(); + virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option); virtual MediaAlbumArt *extractAlbumArt(); virtual const char *extractMetadata(int keyCode); diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java index 0c0974c37443..2eea206bacd4 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java @@ -532,7 +532,7 @@ public class CodecTest { e.printStackTrace(); return false; } - Bitmap outThumbnail = mMediaMetadataRetriever.captureFrame(); + Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1); //Verify the thumbnail Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath); diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java index 95dbb979176e..6ded74df6e4e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java @@ -202,7 +202,6 @@ public class MediaMetadataTest extends AndroidTestCase { } String value = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); try { retriever.setDataSource(meta_data_file[fileIndex][0]); } catch(Exception e) { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java index 7174e2bab6cc..dec21d74c07b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java @@ -36,13 +36,12 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { // Test album art extraction. @MediumTest - public static void testAlbumArt() throws Exception { - Log.v(TAG, "testAlbumArt starts."); + public static void testGetEmbeddedPicture() throws Exception { + Log.v(TAG, "testGetEmbeddedPicture starts."); MediaMetadataRetriever retriever = new MediaMetadataRetriever(); boolean supportWMA = MediaProfileReader.getWMAEnable(); boolean hasFailed = false; boolean supportWMV = MediaProfileReader.getWMVEnable(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) { try { Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]); @@ -53,13 +52,13 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { continue; } retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]); - byte[] albumArt = retriever.extractAlbumArt(); + byte[] albumArt = retriever.getEmbeddedPicture(); // TODO: // A better test would be to compare the retrieved album art with the // known result. if (albumArt == null) { // Do we have expect in JUnit? - Log.e(TAG, "Fails to extract album art for " + MediaNames.ALBUMART_TEST_FILES[i]); + Log.e(TAG, "Fails to get embedded picture for " + MediaNames.ALBUMART_TEST_FILES[i]); hasFailed = true; } } catch(Exception e) { @@ -69,7 +68,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { Thread.yield(); // Don't be evil } retriever.release(); - Log.v(TAG, "testAlbumArt completes."); + Log.v(TAG, "testGetEmbeddedPicture completes."); assertTrue(!hasFailed); } @@ -92,7 +91,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { continue; } retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]); - Bitmap bitmap = retriever.captureFrame(); + Bitmap bitmap = retriever.getFrameAtTime(-1); assertTrue(bitmap != null); try { java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg"); @@ -120,7 +119,6 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { boolean supportWMV = MediaProfileReader.getWMVEnable(); boolean hasFailed = false; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) { try { Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]); @@ -148,12 +146,9 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { public static void testBasicNormalMethodCallSequence() throws Exception { boolean hasFailed = false; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); try { retriever.setDataSource(MediaNames.TEST_PATH_1); - /* - * captureFrame() fails due to lack of permission to access hardware decoder devices - Bitmap bitmap = retriever.captureFrame(); + Bitmap bitmap = retriever.getFrameAtTime(-1); assertTrue(bitmap != null); try { java.io.OutputStream stream = new FileOutputStream("/sdcard/thumbnailout.jpg"); @@ -162,7 +157,6 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { } catch (Exception e) { throw new Exception("Fails to convert the bitmap to a JPEG file for " + MediaNames.TEST_PATH_1, e); } - */ extractAllSupportedMetadataValues(retriever); } catch(Exception e) { Log.e(TAG, "Fails to setDataSource for " + MediaNames.TEST_PATH_1, e); @@ -172,18 +166,17 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { assertTrue(!hasFailed); } - // If setDataSource() has not been called, both captureFrame() and extractMetadata() must + // If setDataSource() has not been called, both getFrameAtTime() and extractMetadata() must // return null. @MediumTest public static void testBasicAbnormalMethodCallSequence() { boolean hasFailed = false; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) != null) { Log.e(TAG, "No album metadata expected, but is available"); hasFailed = true; } - if (retriever.captureFrame() != null) { + if (retriever.getFrameAtTime(-1) != null) { Log.e(TAG, "No frame expected, but is available"); hasFailed = true; } @@ -194,7 +187,6 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { @MediumTest public static void testSetDataSource() { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); boolean hasFailed = false; // Null pointer argument @@ -259,14 +251,13 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { // By default, capture frame and retrieve metadata MediaMetadataRetriever retriever = new MediaMetadataRetriever(); boolean hasFailed = false; - // retriever.setDataSource(MediaNames.TEST_PATH_1); - // assertTrue(retriever.captureFrame() != null); - // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); + retriever.setDataSource(MediaNames.TEST_PATH_1); + assertTrue(retriever.getFrameAtTime(-1) != null); + assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); // Do not capture frame or retrieve metadata - retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY & MediaMetadataRetriever.MODE_GET_METADATA_ONLY); retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.captureFrame() != null) { + if (retriever.getFrameAtTime(-1) != null) { Log.e(TAG, "No frame expected, but is available"); hasFailed = true; } @@ -276,23 +267,20 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase { } // Capture frame only - // retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); - // retriever.setDataSource(MediaNames.TEST_PATH_1); - // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null); + retriever.setDataSource(MediaNames.TEST_PATH_1); + assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null); // Retriever metadata only - retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY); retriever.setDataSource(MediaNames.TEST_PATH_1); - if (retriever.captureFrame() != null) { + if (retriever.getFrameAtTime(-1) != null) { Log.e(TAG, "No frame expected, but is available"); hasFailed = true; } // Capture frame and retrieve metadata - // retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY | MediaMetadataRetriever.MODE_GET_METADATA_ONLY); - // retriever.setDataSource(MediaNames.TEST_PATH_1); - // assertTrue(retriever.captureFrame() != null); - // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); + retriever.setDataSource(MediaNames.TEST_PATH_1); + assertTrue(retriever.getFrameAtTime(-1) != null); + assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null); retriever.release(); assertTrue(!hasFailed); } |