Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22106,6 +22106,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float); api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -23710,6 +23710,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float); api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22197,6 +22197,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float); media/java/android/media/MediaMuxer.java +29 −8 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ final public class MediaMuxer { public @interface Format {} // All the native functions are listed here. private static native long nativeSetup(@NonNull FileDescriptor fd, int format); private static native long nativeSetup(@NonNull FileDescriptor fd, int format) throws IllegalArgumentException, IOException; private static native void nativeRelease(long nativeObject); private static native void nativeStart(long nativeObject); private static native void nativeStop(long nativeObject); Loading Loading @@ -134,19 +135,13 @@ final public class MediaMuxer { if (path == null) { throw new IllegalArgumentException("path must not be null"); } if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM) { throw new IllegalArgumentException("format is invalid"); } // Use RandomAccessFile so we can open the file with RW access; // RW access allows the native writer to memory map the output file. RandomAccessFile file = null; try { file = new RandomAccessFile(path, "rws"); FileDescriptor fd = file.getFD(); mNativeObject = nativeSetup(fd, format); mState = MUXER_STATE_INITIALIZED; mCloseGuard.open("release"); setUpMediaMuxer(fd, format); } finally { if (file != null) { file.close(); Loading @@ -154,6 +149,32 @@ final public class MediaMuxer { } } /** * Constructor. * Creates a media muxer that writes to the specified FileDescriptor. File descriptor * must be seekable and writable. Application should not use the file referenced * by this file descriptor until {@link #stop}. It is the application's responsibility * to close the file descriptor. It is safe to do so as soon as this call returns. * @param fd The FileDescriptor of the output media file. * @param format The format of the output media file. * @see android.media.MediaMuxer.OutputFormat * @throws IllegalArgumentException if fd is invalid or format is not supported. * @throws IOException if failed to open the file for write. */ public MediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException { setUpMediaMuxer(fd, format); } private void setUpMediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException { if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM) { throw new IllegalArgumentException("format: " + format + " is invalid"); } mNativeObject = nativeSetup(fd, format); mState = MUXER_STATE_INITIALIZED; mCloseGuard.open("release"); } /** * Sets the orientation hint for output video playback. * <p>This method should be called before {@link #start}. Calling this Loading media/jni/android_media_MediaMuxer.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include "jni.h" #include "JNIHelp.h" #include <unistd.h> #include <fcntl.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> Loading Loading @@ -138,6 +141,28 @@ static jlong android_media_MediaMuxer_native_setup( int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); ALOGV("native_setup: fd %d", fd); // It appears that if an invalid file descriptor is passed through // binder calls, the server-side of the inter-process function call // is skipped. As a result, the check at the server-side to catch // the invalid file descritpor never gets invoked. This is to workaround // this issue by checking the file descriptor first before passing // it through binder call. int flags = fcntl(fd, F_GETFL); if (flags == -1) { ALOGE("Fail to get File Status Flags err: %s", strerror(errno)); jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid file descriptor"); return 0; } // fd must be in read-write mode or write-only mode. if ((flags & (O_RDWR | O_WRONLY)) == 0) { ALOGE("File descriptor is not in read-write mode or write-only mode"); jniThrowException(env, "java/io/IOException", "File descriptor is not in read-write mode or write-only mode"); return 0; } MediaMuxer::OutputFormat fileFormat = static_cast<MediaMuxer::OutputFormat>(format); sp<MediaMuxer> muxer = new MediaMuxer(fd, fileFormat); Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22106,6 +22106,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float);
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -23710,6 +23710,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float);
api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -22197,6 +22197,7 @@ package android.media { public final class MediaMuxer { ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException; ctor public MediaMuxer(java.io.FileDescriptor, int) throws java.io.IOException; method public int addTrack(android.media.MediaFormat); method public void release(); method public void setLocation(float, float);
media/java/android/media/MediaMuxer.java +29 −8 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ final public class MediaMuxer { public @interface Format {} // All the native functions are listed here. private static native long nativeSetup(@NonNull FileDescriptor fd, int format); private static native long nativeSetup(@NonNull FileDescriptor fd, int format) throws IllegalArgumentException, IOException; private static native void nativeRelease(long nativeObject); private static native void nativeStart(long nativeObject); private static native void nativeStop(long nativeObject); Loading Loading @@ -134,19 +135,13 @@ final public class MediaMuxer { if (path == null) { throw new IllegalArgumentException("path must not be null"); } if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM) { throw new IllegalArgumentException("format is invalid"); } // Use RandomAccessFile so we can open the file with RW access; // RW access allows the native writer to memory map the output file. RandomAccessFile file = null; try { file = new RandomAccessFile(path, "rws"); FileDescriptor fd = file.getFD(); mNativeObject = nativeSetup(fd, format); mState = MUXER_STATE_INITIALIZED; mCloseGuard.open("release"); setUpMediaMuxer(fd, format); } finally { if (file != null) { file.close(); Loading @@ -154,6 +149,32 @@ final public class MediaMuxer { } } /** * Constructor. * Creates a media muxer that writes to the specified FileDescriptor. File descriptor * must be seekable and writable. Application should not use the file referenced * by this file descriptor until {@link #stop}. It is the application's responsibility * to close the file descriptor. It is safe to do so as soon as this call returns. * @param fd The FileDescriptor of the output media file. * @param format The format of the output media file. * @see android.media.MediaMuxer.OutputFormat * @throws IllegalArgumentException if fd is invalid or format is not supported. * @throws IOException if failed to open the file for write. */ public MediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException { setUpMediaMuxer(fd, format); } private void setUpMediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException { if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM) { throw new IllegalArgumentException("format: " + format + " is invalid"); } mNativeObject = nativeSetup(fd, format); mState = MUXER_STATE_INITIALIZED; mCloseGuard.open("release"); } /** * Sets the orientation hint for output video playback. * <p>This method should be called before {@link #start}. Calling this Loading
media/jni/android_media_MediaMuxer.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include "jni.h" #include "JNIHelp.h" #include <unistd.h> #include <fcntl.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> Loading Loading @@ -138,6 +141,28 @@ static jlong android_media_MediaMuxer_native_setup( int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); ALOGV("native_setup: fd %d", fd); // It appears that if an invalid file descriptor is passed through // binder calls, the server-side of the inter-process function call // is skipped. As a result, the check at the server-side to catch // the invalid file descritpor never gets invoked. This is to workaround // this issue by checking the file descriptor first before passing // it through binder call. int flags = fcntl(fd, F_GETFL); if (flags == -1) { ALOGE("Fail to get File Status Flags err: %s", strerror(errno)); jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid file descriptor"); return 0; } // fd must be in read-write mode or write-only mode. if ((flags & (O_RDWR | O_WRONLY)) == 0) { ALOGE("File descriptor is not in read-write mode or write-only mode"); jniThrowException(env, "java/io/IOException", "File descriptor is not in read-write mode or write-only mode"); return 0; } MediaMuxer::OutputFormat fileFormat = static_cast<MediaMuxer::OutputFormat>(format); sp<MediaMuxer> muxer = new MediaMuxer(fd, fileFormat); Loading