Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7dd5763d authored by Gil Dobjanschi's avatar Gil Dobjanschi Committed by Android (Google) Code Review
Browse files

Merge "Bug fix: 3421011 ANR during delete video clip" into honeycomb

parents 59301777 3f1c5739
Loading
Loading
Loading
Loading
+25 −54
Original line number Diff line number Diff line
@@ -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 {
    void releaseNativeHelper() throws InterruptedException {
        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;
        }
    }

    /**
@@ -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());
        }
@@ -3918,31 +3910,10 @@ 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");
        }
+99 −16
Original line number Diff line number Diff line
@@ -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,12 +689,27 @@ public class VideoEditorImpl implements VideoEditor {
     */
    public void release() {
        stopPreview();

        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();
            }
        }
    }

    /*
     * {@inheritDoc}
@@ -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();
    }
}