OSDN Git Service

Refactored MediaBufferPuller class from VideoEditorVideoEncoder class
authorJames Dong <jdong@google.com>
Tue, 6 Mar 2012 18:59:23 +0000 (10:59 -0800)
committerJames Dong <jdong@google.com>
Tue, 6 Mar 2012 20:05:33 +0000 (12:05 -0800)
o MediaBufferPull class will be useful for the audio encoder also once we switch
  to use OMX-based audio encoder.
o This is the part one for fixing bug 5947347

Change-Id: Icddfeb636f7a59ad766220ef0d3155abace73ad3

libvideoeditor/vss/stagefrightshells/src/Android.mk
libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.cpp [new file with mode: 0644]
libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.h [new file with mode: 0644]
libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp

index e81f8da..ea742cb 100755 (executable)
@@ -18,6 +18,7 @@ LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+    MediaBufferPuller.cpp \
     VideoEditorVideoDecoder.cpp \
     VideoEditorAudioDecoder.cpp \
     VideoEditorMp3Reader.cpp \
diff --git a/libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.cpp b/libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.cpp
new file mode 100644 (file)
index 0000000..acc8268
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaBufferPuller"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include "MediaBufferPuller.h"
+
+namespace android {
+
+
+MediaBufferPuller::MediaBufferPuller(const sp<MediaSource>& source)
+    : mSource(source),
+      mAskToStart(false),
+      mAskToStop(false),
+      mAcquireStopped(false),
+      mReleaseStopped(false),
+      mSourceError(OK) {
+
+    androidCreateThread(acquireThreadStart, this);
+    androidCreateThread(releaseThreadStart, this);
+}
+
+MediaBufferPuller::~MediaBufferPuller() {
+    stop();
+}
+
+bool MediaBufferPuller::hasMediaSourceReturnedError() const {
+    Mutex::Autolock autolock(mLock);
+    return ((mSourceError != OK) ? true : false);
+}
+void MediaBufferPuller::start() {
+    Mutex::Autolock autolock(mLock);
+    mAskToStart = true;
+    mAcquireCond.signal();
+    mReleaseCond.signal();
+}
+
+void MediaBufferPuller::stop() {
+    Mutex::Autolock autolock(mLock);
+    mAskToStop = true;
+    mAcquireCond.signal();
+    mReleaseCond.signal();
+    while (!mAcquireStopped || !mReleaseStopped) {
+        mUserCond.wait(mLock);
+    }
+
+    // Release remaining buffers
+    for (size_t i = 0; i < mBuffers.size(); i++) {
+        mBuffers.itemAt(i)->release();
+    }
+
+    for (size_t i = 0; i < mReleaseBuffers.size(); i++) {
+        mReleaseBuffers.itemAt(i)->release();
+    }
+
+    mBuffers.clear();
+    mReleaseBuffers.clear();
+}
+
+MediaBuffer* MediaBufferPuller::getBufferNonBlocking() {
+    Mutex::Autolock autolock(mLock);
+    if (mBuffers.empty()) {
+        return NULL;
+    } else {
+        MediaBuffer* b = mBuffers.itemAt(0);
+        mBuffers.removeAt(0);
+        return b;
+    }
+}
+
+MediaBuffer* MediaBufferPuller::getBufferBlocking() {
+    Mutex::Autolock autolock(mLock);
+    while (mBuffers.empty() && !mAcquireStopped) {
+        mUserCond.wait(mLock);
+    }
+
+    if (mBuffers.empty()) {
+        return NULL;
+    } else {
+        MediaBuffer* b = mBuffers.itemAt(0);
+        mBuffers.removeAt(0);
+        return b;
+    }
+}
+
+void MediaBufferPuller::putBuffer(MediaBuffer* buffer) {
+    Mutex::Autolock autolock(mLock);
+    mReleaseBuffers.push(buffer);
+    mReleaseCond.signal();
+}
+
+int MediaBufferPuller::acquireThreadStart(void* arg) {
+    MediaBufferPuller* self = (MediaBufferPuller*)arg;
+    self->acquireThreadFunc();
+    return 0;
+}
+
+int MediaBufferPuller::releaseThreadStart(void* arg) {
+    MediaBufferPuller* self = (MediaBufferPuller*)arg;
+    self->releaseThreadFunc();
+    return 0;
+}
+
+void MediaBufferPuller::acquireThreadFunc() {
+    mLock.lock();
+
+    // Wait for the start signal
+    while (!mAskToStart && !mAskToStop) {
+        mAcquireCond.wait(mLock);
+    }
+
+    // Loop until we are asked to stop, or there is nothing more to read
+    while (!mAskToStop) {
+        MediaBuffer* pBuffer;
+        mLock.unlock();
+        status_t result = mSource->read(&pBuffer, NULL);
+        mLock.lock();
+        mSourceError = result;
+        if (result != OK) {
+            break;
+        }
+        mBuffers.push(pBuffer);
+        mUserCond.signal();
+    }
+
+    mAcquireStopped = true;
+    mUserCond.signal();
+    mLock.unlock();
+}
+
+void MediaBufferPuller::releaseThreadFunc() {
+    mLock.lock();
+
+    // Wait for the start signal
+    while (!mAskToStart && !mAskToStop) {
+        mReleaseCond.wait(mLock);
+    }
+
+    // Loop until we are asked to stop
+    while (1) {
+        if (mReleaseBuffers.empty()) {
+            if (mAskToStop) {
+                break;
+            } else {
+                mReleaseCond.wait(mLock);
+                continue;
+            }
+        }
+        MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0);
+        mReleaseBuffers.removeAt(0);
+        mLock.unlock();
+        pBuffer->release();
+        mLock.lock();
+    }
+
+    mReleaseStopped = true;
+    mUserCond.signal();
+    mLock.unlock();
+}
+
+};  // namespace android
diff --git a/libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.h b/libvideoeditor/vss/stagefrightshells/src/MediaBufferPuller.h
new file mode 100644 (file)
index 0000000..ed72a53
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MEDIA_BUFFER_PULLER_H
+#define _MEDIA_BUFFER_PULLER_H
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+
+namespace android {
+
+struct MediaSource;
+struct MediaBuffer;
+
+/*
+ * An object of this class can pull a list of media buffers
+ * from a MediaSource repeatedly. The user can then get the
+ * buffers from that list.
+ */
+struct MediaBufferPuller {
+public:
+    MediaBufferPuller(const sp<MediaSource>& source);
+    ~MediaBufferPuller();
+
+    // Start to build up the list of the buffers.
+    void start();
+
+    // Release the list of the available buffers, and stop
+    // pulling buffers from the MediaSource.
+    void stop();
+
+    // Get a buffer from the list. If there is no buffer available
+    // at the time this method is called, NULL is returned.
+    MediaBuffer* getBufferBlocking();
+
+    // Get a buffer from the list. If there is no buffer available
+    // at the time this method is called, it blocks waiting for
+    // a buffer to become available or until stop() is called.
+    MediaBuffer* getBufferNonBlocking();
+
+    // Add a buffer to the end of the list available media buffers
+    void putBuffer(MediaBuffer* buffer);
+
+    // Check whether the source returned an error or not.
+    bool hasMediaSourceReturnedError() const;
+
+private:
+    static int acquireThreadStart(void* arg);
+    void acquireThreadFunc();
+
+    static int releaseThreadStart(void* arg);
+    void releaseThreadFunc();
+
+    sp<MediaSource> mSource;
+    Vector<MediaBuffer*> mBuffers;
+    Vector<MediaBuffer*> mReleaseBuffers;
+
+    mutable Mutex mLock;
+    Condition mUserCond;     // for the user of this class
+    Condition mAcquireCond;  // for the acquire thread
+    Condition mReleaseCond;  // for the release thread
+
+    bool mAskToStart;      // Asks the threads to start
+    bool mAskToStop;       // Asks the threads to stop
+    bool mAcquireStopped;  // The acquire thread has stopped
+    bool mReleaseStopped;  // The release thread has stopped
+    status_t mSourceError; // Error returned by MediaSource read
+
+    // Don't call me!
+    MediaBufferPuller(const MediaBufferPuller&);
+    MediaBufferPuller& operator=(const MediaBufferPuller&);
+};
+
+}  // namespace android
+
+#endif  // _MEDIA_BUFFER_PULLER_H
index 9311e94..4787680 100755 (executable)
 #include "M4SYS_AccessUnit.h"
 #include "VideoEditorVideoEncoder.h"
 #include "VideoEditorUtils.h"
+#include "MediaBufferPuller.h"
 #include <I420ColorConverter.h>
 
+#include <unistd.h>
 #include "utils/Log.h"
 #include "utils/Vector.h"
 #include <media/stagefright/foundation/ADebug.h>
@@ -248,194 +250,6 @@ int32_t VideoEditorVideoEncoderSource::getNumberOfBuffersInQueue() {
     Mutex::Autolock autolock(mLock);
     return mNbBuffer;
 }
-/********************
- *      PULLER      *
- ********************/
-
-// Pulls media buffers from a MediaSource repeatedly.
-// The user can then get the buffers from that list.
-class VideoEditorVideoEncoderPuller {
-public:
-    VideoEditorVideoEncoderPuller(sp<MediaSource> source);
-    ~VideoEditorVideoEncoderPuller();
-    void start();
-    void stop();
-    MediaBuffer* getBufferBlocking();
-    MediaBuffer* getBufferNonBlocking();
-    void putBuffer(MediaBuffer* buffer);
-    bool hasMediaSourceReturnedError();
-private:
-    static int acquireThreadStart(void* arg);
-    void acquireThreadFunc();
-
-    static int releaseThreadStart(void* arg);
-    void releaseThreadFunc();
-
-    sp<MediaSource> mSource;
-    Vector<MediaBuffer*> mBuffers;
-    Vector<MediaBuffer*> mReleaseBuffers;
-
-    Mutex mLock;
-    Condition mUserCond;     // for the user of this class
-    Condition mAcquireCond;  // for the acquire thread
-    Condition mReleaseCond;  // for the release thread
-
-    bool mAskToStart;      // Asks the threads to start
-    bool mAskToStop;       // Asks the threads to stop
-    bool mAcquireStopped;  // The acquire thread has stopped
-    bool mReleaseStopped;  // The release thread has stopped
-    status_t mSourceError; // Error returned by MediaSource read
-};
-
-VideoEditorVideoEncoderPuller::VideoEditorVideoEncoderPuller(
-    sp<MediaSource> source) {
-    mSource = source;
-    mAskToStart = false;
-    mAskToStop = false;
-    mAcquireStopped = false;
-    mReleaseStopped = false;
-    mSourceError = OK;
-    androidCreateThread(acquireThreadStart, this);
-    androidCreateThread(releaseThreadStart, this);
-}
-
-VideoEditorVideoEncoderPuller::~VideoEditorVideoEncoderPuller() {
-    stop();
-}
-
-bool VideoEditorVideoEncoderPuller::hasMediaSourceReturnedError() {
-    Mutex::Autolock autolock(mLock);
-    return ((mSourceError != OK) ? true : false);
-}
-void VideoEditorVideoEncoderPuller::start() {
-    Mutex::Autolock autolock(mLock);
-    mAskToStart = true;
-    mAcquireCond.signal();
-    mReleaseCond.signal();
-}
-
-void VideoEditorVideoEncoderPuller::stop() {
-    Mutex::Autolock autolock(mLock);
-    mAskToStop = true;
-    mAcquireCond.signal();
-    mReleaseCond.signal();
-    while (!mAcquireStopped || !mReleaseStopped) {
-        mUserCond.wait(mLock);
-    }
-
-    // Release remaining buffers
-    for (size_t i = 0; i < mBuffers.size(); i++) {
-        mBuffers.itemAt(i)->release();
-    }
-
-    for (size_t i = 0; i < mReleaseBuffers.size(); i++) {
-        mReleaseBuffers.itemAt(i)->release();
-    }
-
-    mBuffers.clear();
-    mReleaseBuffers.clear();
-}
-
-MediaBuffer* VideoEditorVideoEncoderPuller::getBufferNonBlocking() {
-    Mutex::Autolock autolock(mLock);
-    if (mBuffers.empty()) {
-        return NULL;
-    } else {
-        MediaBuffer* b = mBuffers.itemAt(0);
-        mBuffers.removeAt(0);
-        return b;
-    }
-}
-
-MediaBuffer* VideoEditorVideoEncoderPuller::getBufferBlocking() {
-    Mutex::Autolock autolock(mLock);
-    while (mBuffers.empty() && !mAcquireStopped) {
-        mUserCond.wait(mLock);
-    }
-
-    if (mBuffers.empty()) {
-        return NULL;
-    } else {
-        MediaBuffer* b = mBuffers.itemAt(0);
-        mBuffers.removeAt(0);
-        return b;
-    }
-}
-
-void VideoEditorVideoEncoderPuller::putBuffer(MediaBuffer* buffer) {
-    Mutex::Autolock autolock(mLock);
-    mReleaseBuffers.push(buffer);
-    mReleaseCond.signal();
-}
-
-int VideoEditorVideoEncoderPuller::acquireThreadStart(void* arg) {
-    VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg;
-    self->acquireThreadFunc();
-    return 0;
-}
-
-int VideoEditorVideoEncoderPuller::releaseThreadStart(void* arg) {
-    VideoEditorVideoEncoderPuller* self = (VideoEditorVideoEncoderPuller*)arg;
-    self->releaseThreadFunc();
-    return 0;
-}
-
-void VideoEditorVideoEncoderPuller::acquireThreadFunc() {
-    mLock.lock();
-
-    // Wait for the start signal
-    while (!mAskToStart && !mAskToStop) {
-        mAcquireCond.wait(mLock);
-    }
-
-    // Loop until we are asked to stop, or there is nothing more to read
-    while (!mAskToStop) {
-        MediaBuffer* pBuffer;
-        mLock.unlock();
-        status_t result = mSource->read(&pBuffer, NULL);
-        mLock.lock();
-        mSourceError = result;
-        if (result != OK) {
-            break;
-        }
-        mBuffers.push(pBuffer);
-        mUserCond.signal();
-    }
-
-    mAcquireStopped = true;
-    mUserCond.signal();
-    mLock.unlock();
-}
-
-void VideoEditorVideoEncoderPuller::releaseThreadFunc() {
-    mLock.lock();
-
-    // Wait for the start signal
-    while (!mAskToStart && !mAskToStop) {
-        mReleaseCond.wait(mLock);
-    }
-
-    // Loop until we are asked to stop
-    while (1) {
-        if (mReleaseBuffers.empty()) {
-            if (mAskToStop) {
-                break;
-            } else {
-                mReleaseCond.wait(mLock);
-                continue;
-            }
-        }
-        MediaBuffer* pBuffer = mReleaseBuffers.itemAt(0);
-        mReleaseBuffers.removeAt(0);
-        mLock.unlock();
-        pBuffer->release();
-        mLock.lock();
-    }
-
-    mReleaseStopped = true;
-    mUserCond.signal();
-    mLock.unlock();
-}
 
 /**
  ******************************************************************************
@@ -468,7 +282,7 @@ typedef struct {
     OMXClient                         mClient;
     sp<MediaSource>                   mEncoder;
     OMX_COLOR_FORMATTYPE              mEncoderColorFormat;
-    VideoEditorVideoEncoderPuller*    mPuller;
+    MediaBufferPuller*                mPuller;
     I420ColorConverter*               mI420ColorConverter;
 
     uint32_t                          mNbInputFrames;
@@ -902,7 +716,7 @@ M4OSA_ERR VideoEditorVideoEncoder_open(M4ENCODER_Context pContext,
         pEncoderContext->mEncoderSource, NULL, codecFlags);
     VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE);
     ALOGV("VideoEditorVideoEncoder_open : DONE");
-    pEncoderContext->mPuller = new VideoEditorVideoEncoderPuller(
+    pEncoderContext->mPuller = new MediaBufferPuller(
         pEncoderContext->mEncoder);
 
     // Set the new state