diff options
| -rw-r--r-- | media/java/android/media/videoeditor/MediaArtistNativeHelper.java | 79 | ||||
| -rwxr-xr-x | media/java/android/media/videoeditor/VideoEditorImpl.java | 115 |
2 files changed, 124 insertions, 70 deletions
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java index 297c4dfdf8f7..6b3f223de23b 100644 --- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java +++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java @@ -23,7 +23,6 @@ import java.nio.IntBuffer; import java.util.Iterator; import java.util.List; import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -58,6 +57,10 @@ class MediaArtistNativeHelper { private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG); private final VideoEditor mVideoEditor; + /* + * Semaphore to control preview calls + */ + private final Semaphore mLock; private EditSettings mStoryBoardSettings; @@ -79,11 +82,6 @@ class MediaArtistNativeHelper { private int mProgressToApp; - /* - * Semaphore to control preview calls - */ - private final Semaphore mLock = new Semaphore(1, true); - private String mRenderPreviewOverlayFile; private int mRenderPreviewRenderingMode; @@ -1775,9 +1773,10 @@ class MediaArtistNativeHelper { * * @param projectPath The path where the VideoEditor stores all files * related to the project + * @param lock The semaphore * @param veObj The video editor reference */ - public MediaArtistNativeHelper(String projectPath, VideoEditor veObj) { + public MediaArtistNativeHelper(String projectPath, Semaphore lock, VideoEditor veObj) { mProjectPath = projectPath; if (veObj != null) { mVideoEditor = veObj; @@ -1785,8 +1784,11 @@ class MediaArtistNativeHelper { mVideoEditor = null; throw new IllegalArgumentException("video editor object is null"); } - if (mStoryBoardSettings == null) + if (mStoryBoardSettings == null) { mStoryBoardSettings = new EditSettings(); + } + + mLock = lock; _init(mProjectPath, "null"); mAudioTrackPCMFilePath = null; @@ -1932,16 +1934,8 @@ class MediaArtistNativeHelper { /** * Release the native helper object */ - void releaseNativeHelper() { - try { - release(); - } catch (IllegalStateException ex) { - Log.e(TAG, "Illegal State exeption caught in releaseNativeHelper"); - throw ex; - } catch (RuntimeException ex) { - Log.e(TAG, "Runtime exeption caught in releaseNativeHelper"); - throw ex; - } + void releaseNativeHelper() throws InterruptedException { + release(); } /** @@ -3735,18 +3729,15 @@ class MediaArtistNativeHelper { */ Bitmap getPixels(String inputFile, int width, int height, long timeMS) { if (inputFile == null) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Invalid input file"); } - int newWidth = 0; - int newHeight = 0; - Bitmap tempBitmap = null; - /* Make width and height as even */ - newWidth = (width + 1) & 0xFFFFFFFE; - newHeight = (height + 1) & 0xFFFFFFFE; + final int newWidth = (width + 1) & 0xFFFFFFFE; + final int newHeight = (height + 1) & 0xFFFFFFFE; /* Create a temp bitmap for resized thumbnails */ + Bitmap tempBitmap = null; if ((newWidth != width) || (newHeight != height)) { tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); } @@ -3770,6 +3761,7 @@ class MediaArtistNativeHelper { if (tempBitmap != null) { tempBitmap.recycle(); } + return bitmap; } @@ -3787,17 +3779,15 @@ class MediaArtistNativeHelper { * * @return The frames as bitmaps in bitmap array **/ - public Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs, + Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs, int thumbnailCount) { int[] rgb888 = null; int thumbnailSize = 0; - int newWidth = 0; - int newHeight = 0; Bitmap tempBitmap = null; /* Make width and height as even */ - newWidth = (width + 1) & 0xFFFFFFFE; - newHeight = (height + 1) & 0xFFFFFFFE; + final int newWidth = (width + 1) & 0xFFFFFFFE; + final int newHeight = (height + 1) & 0xFFFFFFFE; thumbnailSize = newWidth * newHeight * 4; /* Create a temp bitmap for resized thumbnails */ @@ -3820,7 +3810,8 @@ class MediaArtistNativeHelper { bitmaps = new Bitmap[MAX_THUMBNAIL_PERMITTED]; thumbnailCount = MAX_THUMBNAIL_PERMITTED; } catch (Throwable ex) { - throw new RuntimeException("Memory allocation fails, thumbnail count too large: "+thumbnailCount); + throw new RuntimeException("Memory allocation fails, thumbnail count too large: " + + thumbnailCount); } } IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize); @@ -3848,6 +3839,7 @@ class MediaArtistNativeHelper { if (tempBitmap != null) { tempBitmap.recycle(); } + return bitmaps; } @@ -3908,7 +3900,7 @@ class MediaArtistNativeHelper { * * @throws InterruptedException */ - void lock() throws InterruptedException { + private void lock() throws InterruptedException { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "lock: grabbing semaphore", new Throwable()); } @@ -3919,30 +3911,9 @@ class MediaArtistNativeHelper { } /** - * Tries to grab the semaphore with a specified time out which arbitrates access to the editor - * - * @param timeoutMs time out in ms. - * - * @return true if the semaphore is acquired, false otherwise - * @throws InterruptedException - */ - boolean lock(long timeoutMs) throws InterruptedException { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "lock: grabbing semaphore with timeout " + timeoutMs, new Throwable()); - } - - boolean acquireSem = mLock.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "lock: grabbed semaphore status " + acquireSem); - } - - return acquireSem; - } - - /** * Release the semaphore which arbitrates access to the editor */ - void unlock() { + private void unlock() { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "unlock: releasing semaphore"); } diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java index 33a86544b8dd..3019057ff7f2 100755 --- a/media/java/android/media/videoeditor/VideoEditorImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorImpl.java @@ -27,6 +27,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -118,11 +121,12 @@ public class VideoEditorImpl implements VideoEditor { /* * Instance variables */ - private long mDurationMs; + private final Semaphore mLock; private final String mProjectPath; private final List<MediaItem> mMediaItems = new ArrayList<MediaItem>(); private final List<AudioTrack> mAudioTracks = new ArrayList<AudioTrack>(); private final List<Transition> mTransitions = new ArrayList<Transition>(); + private long mDurationMs; private int mAspectRatio; /* @@ -138,7 +142,8 @@ public class VideoEditorImpl implements VideoEditor { * related to the project */ public VideoEditorImpl(String projectPath) throws IOException { - mMANativeHelper = new MediaArtistNativeHelper(projectPath, this); + mLock = new Semaphore(1, true); + mMANativeHelper = new MediaArtistNativeHelper(projectPath, mLock, this); mProjectPath = projectPath; final File projectXml = new File(projectPath, PROJECT_FILENAME); if (projectXml.exists()) { @@ -417,15 +422,20 @@ public class VideoEditorImpl implements VideoEditor { boolean semAcquireDone = false; try { - mMANativeHelper.lock(); + lock(); semAcquireDone = true; + + if (mMANativeHelper == null) { + throw new IllegalStateException("The video editor is not initialized"); + } + mMANativeHelper.export(filename, mProjectPath, height,bitrate, mMediaItems, mTransitions, mAudioTracks, listener); } catch (InterruptedException ex) { Log.e(TAG, "Sem acquire NOT successful in export"); } finally { if (semAcquireDone) { - mMANativeHelper.unlock(); + unlock(); } } } @@ -436,9 +446,13 @@ public class VideoEditorImpl implements VideoEditor { public void generatePreview(MediaProcessingProgressListener listener) { boolean semAcquireDone = false; try { - mMANativeHelper.lock(); + lock(); semAcquireDone = true; + if (mMANativeHelper == null) { + throw new IllegalStateException("The video editor is not initialized"); + } + if ((mMediaItems.size() > 0) || (mAudioTracks.size() > 0)) { mMANativeHelper.previewStoryBoard(mMediaItems, mTransitions, mAudioTracks, listener); @@ -447,7 +461,7 @@ public class VideoEditorImpl implements VideoEditor { Log.e(TAG, "Sem acquire NOT successful in previewStoryBoard"); } finally { if (semAcquireDone) { - mMANativeHelper.unlock(); + unlock(); } } } @@ -675,11 +689,26 @@ public class VideoEditorImpl implements VideoEditor { */ public void release() { stopPreview(); - mMediaItems.clear(); - mAudioTracks.clear(); - mTransitions.clear(); - mMANativeHelper.releaseNativeHelper(); - mMANativeHelper = null; + + boolean semAcquireDone = false; + try { + lock(); + semAcquireDone = true; + + if (mMANativeHelper != null) { + mMediaItems.clear(); + mAudioTracks.clear(); + mTransitions.clear(); + mMANativeHelper.releaseNativeHelper(); + mMANativeHelper = null; + } + } catch (Exception ex) { + Log.e(TAG, "Sem acquire NOT successful in export", ex); + } finally { + if (semAcquireDone) { + unlock(); + } + } } /* @@ -854,11 +883,15 @@ public class VideoEditorImpl implements VideoEditor { boolean semAcquireDone = false; try { - semAcquireDone = mMANativeHelper.lock(ENGINE_ACCESS_MAX_TIMEOUT_MS); + semAcquireDone = lock(ENGINE_ACCESS_MAX_TIMEOUT_MS); if (semAcquireDone == false) { throw new IllegalStateException("Timeout waiting for semaphore"); } + if (mMANativeHelper == null) { + throw new IllegalStateException("The video editor is not initialized"); + } + if (mMediaItems.size() > 0) { final Rect frame = surfaceHolder.getSurfaceFrame(); result = mMANativeHelper.renderPreviewFrame(surface, @@ -871,7 +904,7 @@ public class VideoEditorImpl implements VideoEditor { throw new IllegalStateException("The thread was interrupted"); } finally { if (semAcquireDone) { - mMANativeHelper.unlock(); + unlock(); } } return result; @@ -1568,11 +1601,15 @@ public class VideoEditorImpl implements VideoEditor { boolean semAcquireDone = false; if (!mPreviewInProgress) { try{ - semAcquireDone = mMANativeHelper.lock(ENGINE_ACCESS_MAX_TIMEOUT_MS); + semAcquireDone = lock(ENGINE_ACCESS_MAX_TIMEOUT_MS); if (semAcquireDone == false) { throw new IllegalStateException("Timeout waiting for semaphore"); } + if (mMANativeHelper == null) { + throw new IllegalStateException("The video editor is not initialized"); + } + if (mMediaItems.size() > 0) { mPreviewInProgress = true; mMANativeHelper.previewStoryBoard(mMediaItems, mTransitions, @@ -1581,7 +1618,7 @@ public class VideoEditorImpl implements VideoEditor { callbackAfterFrameCount, listener); } /** - * release on complete by calling stopPreview + * Release The lock on complete by calling stopPreview */ } catch (InterruptedException ex) { Log.w(TAG, "The thread was interrupted", new Throwable()); @@ -1605,7 +1642,7 @@ public class VideoEditorImpl implements VideoEditor { */ } finally { mPreviewInProgress = false; - mMANativeHelper.unlock(); + unlock(); } return result; } @@ -1791,4 +1828,50 @@ public class VideoEditorImpl implements VideoEditor { Log.w(TAG, "Native helper was not ready!"); } } + + /** + * Grab the semaphore which arbitrates access to the editor + * + * @throws InterruptedException + */ + private void lock() throws InterruptedException { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "lock: grabbing semaphore", new Throwable()); + } + mLock.acquire(); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "lock: grabbed semaphore"); + } + } + + /** + * Tries to grab the semaphore with a specified time out which arbitrates access to the editor + * + * @param timeoutMs time out in ms. + * + * @return true if the semaphore is acquired, false otherwise + * @throws InterruptedException + */ + private boolean lock(long timeoutMs) throws InterruptedException { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "lock: grabbing semaphore with timeout " + timeoutMs, new Throwable()); + } + + boolean acquireSem = mLock.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "lock: grabbed semaphore status " + acquireSem); + } + + return acquireSem; + } + + /** + * Release the semaphore which arbitrates access to the editor + */ + private void unlock() { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "unlock: releasing semaphore"); + } + mLock.release(); + } } |