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

Commit 38eea1b8 authored by Pannag Sanketi's avatar Pannag Sanketi Committed by Android (Google) Code Review
Browse files

Merge "Renaming SurfaceEncoder to SurfaceMediaSource"

parents 67d7704b f48987db
Loading
Loading
Loading
Loading
+17 −18
Original line number Original line Diff line number Diff line
@@ -14,8 +14,8 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#ifndef ANDROID_GUI_SURFACEENCODER_H
#ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H
#define ANDROID_GUI_SURFACEENCODER_H
#define ANDROID_GUI_SURFACEMEDIASOURCE_H


#include <gui/ISurfaceTexture.h>
#include <gui/ISurfaceTexture.h>


@@ -31,7 +31,7 @@ class IGraphicBufferAlloc;
class String8;
class String8;
class GraphicBuffer;
class GraphicBuffer;


class SurfaceEncoder : public BnSurfaceTexture, public MediaSource,
class SurfaceMediaSource : public BnSurfaceTexture, public MediaSource,
                                            public MediaBufferObserver {
                                            public MediaBufferObserver {
public:
public:
    enum { MIN_UNDEQUEUED_BUFFERS = 3 };
    enum { MIN_UNDEQUEUED_BUFFERS = 3 };
@@ -44,16 +44,16 @@ public:


    struct FrameAvailableListener : public virtual RefBase {
    struct FrameAvailableListener : public virtual RefBase {
        // onFrameAvailable() is called from queueBuffer() is the FIFO is
        // onFrameAvailable() is called from queueBuffer() is the FIFO is
        // empty. You can use SurfaceEncoder::getQueuedCount() to
        // empty. You can use SurfaceMediaSource::getQueuedCount() to
        // figure out if there are more frames waiting.
        // figure out if there are more frames waiting.
        // This is called without any lock held can be called concurrently by
        // This is called without any lock held can be called concurrently by
        // multiple threads.
        // multiple threads.
        virtual void onFrameAvailable() = 0;
        virtual void onFrameAvailable() = 0;
    };
    };


    SurfaceEncoder(uint32_t bufW, uint32_t bufH);
    SurfaceMediaSource(uint32_t bufW, uint32_t bufH);


    virtual ~SurfaceEncoder();
    virtual ~SurfaceMediaSource();




    // For the MediaSource interface for use by StageFrightRecorder:
    // For the MediaSource interface for use by StageFrightRecorder:
@@ -78,7 +78,7 @@ public:


    // setBufferCount updates the number of available buffer slots.  After
    // setBufferCount updates the number of available buffer slots.  After
    // calling this all buffer slots are both unallocated and owned by the
    // calling this all buffer slots are both unallocated and owned by the
    // SurfaceEncoder object (i.e. they are not owned by the client).
    // SurfaceMediaSource object (i.e. they are not owned by the client).
    virtual status_t setBufferCount(int bufferCount);
    virtual status_t setBufferCount(int bufferCount);


    virtual sp<GraphicBuffer> requestBuffer(int buf);
    virtual sp<GraphicBuffer> requestBuffer(int buf);
@@ -91,7 +91,7 @@ public:
    virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
    virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
            uint32_t format, uint32_t usage);
            uint32_t format, uint32_t usage);


    // queueBuffer returns a filled buffer to the SurfaceEncoder. In addition, a
    // queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
    // timestamp must be provided for the buffer. The timestamp is in
    // timestamp must be provided for the buffer. The timestamp is in
    // nanoseconds, and must be monotonically increasing. Its other semantics
    // nanoseconds, and must be monotonically increasing. Its other semantics
    // (zero point, etc) are client-dependent and should be documented by the
    // (zero point, etc) are client-dependent and should be documented by the
@@ -123,21 +123,21 @@ public:
    // modes (S.Encoder vis-a-vis SurfaceTexture)
    // modes (S.Encoder vis-a-vis SurfaceTexture)
    virtual status_t setSynchronousMode(bool enabled);
    virtual status_t setSynchronousMode(bool enabled);


    // connect attempts to connect a client API to the SurfaceEncoder.  This
    // connect attempts to connect a client API to the SurfaceMediaSource.  This
    // must be called before any other ISurfaceTexture methods are called except
    // must be called before any other ISurfaceTexture methods are called except
    // for getAllocator.
    // for getAllocator.
    //
    //
    // This method will fail if the connect was previously called on the
    // This method will fail if the connect was previously called on the
    // SurfaceEncoder and no corresponding disconnect call was made.
    // SurfaceMediaSource and no corresponding disconnect call was made.
    virtual status_t connect(int api);
    virtual status_t connect(int api);


    // disconnect attempts to disconnect a client API from the SurfaceEncoder.
    // disconnect attempts to disconnect a client API from the SurfaceMediaSource.
    // Calling this method will cause any subsequent calls to other
    // Calling this method will cause any subsequent calls to other
    // ISurfaceTexture methods to fail except for getAllocator and connect.
    // ISurfaceTexture methods to fail except for getAllocator and connect.
    // Successfully calling connect after this will allow the other methods to
    // Successfully calling connect after this will allow the other methods to
    // succeed again.
    // succeed again.
    //
    //
    // This method will fail if the the SurfaceEncoder is not currently
    // This method will fail if the the SurfaceMediaSource is not currently
    // connected to the specified client API.
    // connected to the specified client API.
    virtual status_t disconnect(int api);
    virtual status_t disconnect(int api);


@@ -164,7 +164,7 @@ public:
    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);


    // getAllocator retrieves the binder object that must be referenced as long
    // getAllocator retrieves the binder object that must be referenced as long
    // as the GraphicBuffers dequeued from this SurfaceEncoder are referenced.
    // as the GraphicBuffers dequeued from this SurfaceMediaSource are referenced.
    // Holding this binder reference prevents SurfaceFlinger from freeing the
    // Holding this binder reference prevents SurfaceFlinger from freeing the
    // buffers before the client is done with them.
    // buffers before the client is done with them.
    sp<IBinder> getAllocator();
    sp<IBinder> getAllocator();
@@ -280,7 +280,7 @@ private:


    // mCurrentSlot is the buffer slot index of the buffer that is currently
    // mCurrentSlot is the buffer slot index of the buffer that is currently
    // being used by buffer consumer
    // being used by buffer consumer
    // (e.g. StageFrightRecorder in the case of SurfaceEncoder or GLTexture
    // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
    // in the case of SurfaceTexture).
    // in the case of SurfaceTexture).
    // It is initialized to INVALID_BUFFER_SLOT,
    // It is initialized to INVALID_BUFFER_SLOT,
    // indicating that no buffer slot is currently bound to the texture. Note,
    // indicating that no buffer slot is currently bound to the texture. Note,
@@ -327,7 +327,7 @@ private:
    Fifo mQueue;
    Fifo mQueue;


    // mMutex is the mutex used to prevent concurrent access to the member
    // mMutex is the mutex used to prevent concurrent access to the member
    // variables of SurfaceEncoder objects. It must be locked whenever the
    // variables of SurfaceMediaSource objects. It must be locked whenever the
    // member variables are accessed.
    // member variables are accessed.
    mutable Mutex mMutex;
    mutable Mutex mMutex;


@@ -344,11 +344,10 @@ private:
    Condition mFrameCompleteCondition;
    Condition mFrameCompleteCondition;


    // Avoid copying and equating and default constructor
    // Avoid copying and equating and default constructor
    DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceEncoder);
    DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);

};
};


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
}; // namespace android
}; // namespace android


#endif // ANDROID_GUI_SURFACETEXTURE_H
#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
+1 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ LOCAL_SRC_FILES:= \
        SampleTable.cpp                   \
        SampleTable.cpp                   \
        StagefrightMediaScanner.cpp       \
        StagefrightMediaScanner.cpp       \
        StagefrightMetadataRetriever.cpp  \
        StagefrightMetadataRetriever.cpp  \
        SurfaceEncoder.cpp                \
        SurfaceMediaSource.cpp            \
        ThrottledSource.cpp               \
        ThrottledSource.cpp               \
        TimeSource.cpp                    \
        TimeSource.cpp                    \
        TimedEventQueue.cpp               \
        TimedEventQueue.cpp               \
+42 −42
Original line number Original line Diff line number Diff line
@@ -15,9 +15,9 @@
 */
 */


// #define LOG_NDEBUG 0
// #define LOG_NDEBUG 0
#define LOG_TAG "SurfaceEncoder"
#define LOG_TAG "SurfaceMediaSource"


#include <media/stagefright/SurfaceEncoder.h>
#include <media/stagefright/SurfaceMediaSource.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBuffer.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaDefs.h>
@@ -34,7 +34,7 @@


namespace android {
namespace android {


SurfaceEncoder::SurfaceEncoder(uint32_t bufW, uint32_t bufH) :
SurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
    mDefaultWidth(bufW),
    mDefaultWidth(bufW),
    mDefaultHeight(bufH),
    mDefaultHeight(bufH),
    mPixelFormat(0),
    mPixelFormat(0),
@@ -47,25 +47,25 @@ SurfaceEncoder::SurfaceEncoder(uint32_t bufW, uint32_t bufH) :
    mConnectedApi(NO_CONNECTED_API),
    mConnectedApi(NO_CONNECTED_API),
    mFrameRate(30),
    mFrameRate(30),
    mStarted(false)     {
    mStarted(false)     {
    LOGV("SurfaceEncoder::SurfaceEncoder");
    LOGV("SurfaceMediaSource::SurfaceMediaSource");
    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
}
}


SurfaceEncoder::~SurfaceEncoder() {
SurfaceMediaSource::~SurfaceMediaSource() {
    LOGV("SurfaceEncoder::~SurfaceEncoder");
    LOGV("SurfaceMediaSource::~SurfaceMediaSource");
    if (mStarted) {
    if (mStarted) {
        stop();
        stop();
    }
    }
    freeAllBuffers();
    freeAllBuffers();
}
}


size_t SurfaceEncoder::getQueuedCount() const {
size_t SurfaceMediaSource::getQueuedCount() const {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return mQueue.size();
    return mQueue.size();
}
}


status_t SurfaceEncoder::setBufferCountServerLocked(int bufferCount) {
status_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
    if (bufferCount > NUM_BUFFER_SLOTS)
    if (bufferCount > NUM_BUFFER_SLOTS)
        return BAD_VALUE;
        return BAD_VALUE;


@@ -100,13 +100,13 @@ status_t SurfaceEncoder::setBufferCountServerLocked(int bufferCount) {
}
}


// Called from the consumer side
// Called from the consumer side
status_t SurfaceEncoder::setBufferCountServer(int bufferCount) {
status_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return setBufferCountServerLocked(bufferCount);
    return setBufferCountServerLocked(bufferCount);
}
}


status_t SurfaceEncoder::setBufferCount(int bufferCount) {
status_t SurfaceMediaSource::setBufferCount(int bufferCount) {
    LOGV("SurfaceEncoder::setBufferCount");
    LOGV("SurfaceMediaSource::setBufferCount");
    if (bufferCount > NUM_BUFFER_SLOTS) {
    if (bufferCount > NUM_BUFFER_SLOTS) {
        LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
        LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
        return BAD_VALUE;
        return BAD_VALUE;
@@ -147,8 +147,8 @@ status_t SurfaceEncoder::setBufferCount(int bufferCount) {
    return OK;
    return OK;
}
}


sp<GraphicBuffer> SurfaceEncoder::requestBuffer(int buf) {
sp<GraphicBuffer> SurfaceMediaSource::requestBuffer(int buf) {
    LOGV("SurfaceEncoder::requestBuffer");
    LOGV("SurfaceMediaSource::requestBuffer");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    if (buf < 0 || mBufferCount <= buf) {
    if (buf < 0 || mBufferCount <= buf) {
        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
@@ -159,7 +159,7 @@ sp<GraphicBuffer> SurfaceEncoder::requestBuffer(int buf) {
    return mSlots[buf].mGraphicBuffer;
    return mSlots[buf].mGraphicBuffer;
}
}


status_t SurfaceEncoder::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
                                            uint32_t format, uint32_t usage) {
                                            uint32_t format, uint32_t usage) {
    LOGV("dequeueBuffer");
    LOGV("dequeueBuffer");


@@ -347,7 +347,7 @@ status_t SurfaceEncoder::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
    return returnFlags;
    return returnFlags;
}
}


status_t SurfaceEncoder::setSynchronousMode(bool enabled) {
status_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);


    status_t err = OK;
    status_t err = OK;
@@ -369,8 +369,8 @@ status_t SurfaceEncoder::setSynchronousMode(bool enabled) {
    return err;
    return err;
}
}


status_t SurfaceEncoder::connect(int api) {
status_t SurfaceMediaSource::connect(int api) {
    LOGV("SurfaceEncoder::connect");
    LOGV("SurfaceMediaSource::connect");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    int err = NO_ERROR;
    int err = NO_ERROR;
    switch (api) {
    switch (api) {
@@ -391,8 +391,8 @@ status_t SurfaceEncoder::connect(int api) {
    return err;
    return err;
}
}


status_t SurfaceEncoder::disconnect(int api) {
status_t SurfaceMediaSource::disconnect(int api) {
    LOGV("SurfaceEncoder::disconnect");
    LOGV("SurfaceMediaSource::disconnect");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    int err = NO_ERROR;
    int err = NO_ERROR;
    switch (api) {
    switch (api) {
@@ -413,7 +413,7 @@ status_t SurfaceEncoder::disconnect(int api) {
    return err;
    return err;
}
}


status_t SurfaceEncoder::queueBuffer(int buf, int64_t timestamp,
status_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
    LOGV("queueBuffer");
    LOGV("queueBuffer");


@@ -475,13 +475,13 @@ status_t SurfaceEncoder::queueBuffer(int buf, int64_t timestamp,
// The buffer is NOT made available for dequeueing immediately. We need to
// The buffer is NOT made available for dequeueing immediately. We need to
// wait to hear from StageFrightRecorder to set the buffer FREE
// wait to hear from StageFrightRecorder to set the buffer FREE
// Make sure this is called when the mutex is locked
// Make sure this is called when the mutex is locked
status_t SurfaceEncoder::onFrameReceivedLocked() {
status_t SurfaceMediaSource::onFrameReceivedLocked() {
    LOGV("On Frame Received");
    LOGV("On Frame Received");
    // Signal the encoder that a new frame has arrived
    // Signal the encoder that a new frame has arrived
    mFrameAvailableCondition.signal();
    mFrameAvailableCondition.signal();


    // call back the listener
    // call back the listener
    // TODO: The listener may not be needed in SurfaceEncoder at all.
    // TODO: The listener may not be needed in SurfaceMediaSource at all.
    // This can be made a SurfaceTexture specific thing
    // This can be made a SurfaceTexture specific thing
    sp<FrameAvailableListener> listener;
    sp<FrameAvailableListener> listener;
    if (mSynchronousMode || mQueue.empty()) {
    if (mSynchronousMode || mQueue.empty()) {
@@ -495,8 +495,8 @@ status_t SurfaceEncoder::onFrameReceivedLocked() {
}
}




void SurfaceEncoder::cancelBuffer(int buf) {
void SurfaceMediaSource::cancelBuffer(int buf) {
    LOGV("SurfaceEncoder::cancelBuffer");
    LOGV("SurfaceMediaSource::cancelBuffer");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    if (buf < 0 || buf >= mBufferCount) {
    if (buf < 0 || buf >= mBufferCount) {
        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
@@ -511,27 +511,27 @@ void SurfaceEncoder::cancelBuffer(int buf) {
    mDequeueCondition.signal();
    mDequeueCondition.signal();
}
}


nsecs_t SurfaceEncoder::getTimestamp() {
nsecs_t SurfaceMediaSource::getTimestamp() {
    LOGV("SurfaceEncoder::getTimestamp");
    LOGV("SurfaceMediaSource::getTimestamp");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return mCurrentTimestamp;
    return mCurrentTimestamp;
}
}




void SurfaceEncoder::setFrameAvailableListener(
void SurfaceMediaSource::setFrameAvailableListener(
        const sp<FrameAvailableListener>& listener) {
        const sp<FrameAvailableListener>& listener) {
    LOGV("SurfaceEncoder::setFrameAvailableListener");
    LOGV("SurfaceMediaSource::setFrameAvailableListener");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    mFrameAvailableListener = listener;
    mFrameAvailableListener = listener;
}
}


sp<IBinder> SurfaceEncoder::getAllocator() {
sp<IBinder> SurfaceMediaSource::getAllocator() {
    LOGV("getAllocator");
    LOGV("getAllocator");
    return mGraphicBufferAlloc->asBinder();
    return mGraphicBufferAlloc->asBinder();
}
}




void SurfaceEncoder::freeAllBuffers() {
void SurfaceMediaSource::freeAllBuffers() {
    LOGV("freeAllBuffers");
    LOGV("freeAllBuffers");
    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
        mSlots[i].mGraphicBuffer = 0;
        mSlots[i].mGraphicBuffer = 0;
@@ -539,12 +539,12 @@ void SurfaceEncoder::freeAllBuffers() {
    }
    }
}
}


sp<GraphicBuffer> SurfaceEncoder::getCurrentBuffer() const {
sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return mCurrentBuf;
    return mCurrentBuf;
}
}


int SurfaceEncoder::query(int what, int* outValue)
int SurfaceMediaSource::query(int what, int* outValue)
{
{
    LOGV("query");
    LOGV("query");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
@@ -574,13 +574,13 @@ int SurfaceEncoder::query(int what, int* outValue)
    return NO_ERROR;
    return NO_ERROR;
}
}


void SurfaceEncoder::dump(String8& result) const
void SurfaceMediaSource::dump(String8& result) const
{
{
    char buffer[1024];
    char buffer[1024];
    dump(result, "", buffer, 1024);
    dump(result, "", buffer, 1024);
}
}


void SurfaceEncoder::dump(String8& result, const char* prefix,
void SurfaceMediaSource::dump(String8& result, const char* prefix,
        char* buffer, size_t SIZE) const
        char* buffer, size_t SIZE) const
{
{
    Mutex::Autolock _l(mMutex);
    Mutex::Autolock _l(mMutex);
@@ -625,18 +625,18 @@ void SurfaceEncoder::dump(String8& result, const char* prefix,
    }
    }
}
}


void SurfaceEncoder::setFrameRate(uint32_t fps)
void SurfaceMediaSource::setFrameRate(uint32_t fps)
{
{
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    mFrameRate = fps;
    mFrameRate = fps;
}
}


uint32_t SurfaceEncoder::getFrameRate( ) const {
uint32_t SurfaceMediaSource::getFrameRate( ) const {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return mFrameRate;
    return mFrameRate;
}
}


status_t SurfaceEncoder::start(MetaData *params)
status_t SurfaceMediaSource::start(MetaData *params)
{
{
    LOGV("start");
    LOGV("start");
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
@@ -646,7 +646,7 @@ status_t SurfaceEncoder::start(MetaData *params)
}
}




status_t SurfaceEncoder::stop()
status_t SurfaceMediaSource::stop()
{
{
    LOGV("Stop");
    LOGV("Stop");


@@ -658,7 +658,7 @@ status_t SurfaceEncoder::stop()
    return OK;
    return OK;
}
}


sp<MetaData> SurfaceEncoder::getFormat()
sp<MetaData> SurfaceMediaSource::getFormat()
{
{
    LOGV("getFormat");
    LOGV("getFormat");
    Mutex::Autolock autoLock(mMutex);
    Mutex::Autolock autoLock(mMutex);
@@ -678,7 +678,7 @@ sp<MetaData> SurfaceEncoder::getFormat()
    return meta;
    return meta;
}
}


status_t SurfaceEncoder::read( MediaBuffer **buffer,
status_t SurfaceMediaSource::read( MediaBuffer **buffer,
                                const ReadOptions *options)
                                const ReadOptions *options)
{
{
    LOGV("Read. Size of queued buffer: %d", mQueue.size());
    LOGV("Read. Size of queued buffer: %d", mQueue.size());
@@ -716,7 +716,7 @@ status_t SurfaceEncoder::read( MediaBuffer **buffer,
    return OK;
    return OK;
}
}


void SurfaceEncoder::signalBufferReturned(MediaBuffer *buffer) {
void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
    LOGV("signalBufferReturned");
    LOGV("signalBufferReturned");


    bool foundBuffer = false;
    bool foundBuffer = false;
+2 −2
Original line number Original line Diff line number Diff line
@@ -4,12 +4,12 @@ include $(CLEAR_VARS)


ifneq ($(TARGET_SIMULATOR),true)
ifneq ($(TARGET_SIMULATOR),true)


LOCAL_MODULE := SurfaceEncoder_test
LOCAL_MODULE := SurfaceMediaSource_test


LOCAL_MODULE_TAGS := tests
LOCAL_MODULE_TAGS := tests


LOCAL_SRC_FILES := \
LOCAL_SRC_FILES := \
    SurfaceEncoder_test.cpp \
    SurfaceMediaSource_test.cpp \
	DummyRecorder.cpp \
	DummyRecorder.cpp \


LOCAL_SHARED_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
+31 −33
Original line number Original line Diff line number Diff line
@@ -14,14 +14,14 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#define LOG_TAG "SurfaceEncoder_test"
#define LOG_TAG "SurfaceMediaSource_test"
// #define LOG_NDEBUG 0
// #define LOG_NDEBUG 0


#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <utils/String8.h>
#include <utils/String8.h>
#include <utils/Errors.h>
#include <utils/Errors.h>


#include <media/stagefright/SurfaceEncoder.h>
#include <media/stagefright/SurfaceMediaSource.h>


#include <gui/SurfaceTextureClient.h>
#include <gui/SurfaceTextureClient.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBuffer.h>
@@ -45,10 +45,10 @@
namespace android {
namespace android {




class SurfaceEncoderTest : public ::testing::Test {
class SurfaceMediaSourceTest : public ::testing::Test {
public:
public:


    SurfaceEncoderTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
    SurfaceMediaSourceTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
    sp<MPEG4Writer>  setUpWriter(OMXClient &client );
    sp<MPEG4Writer>  setUpWriter(OMXClient &client );
    void oneBufferPass(int width, int height );
    void oneBufferPass(int width, int height );
    static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
    static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
@@ -57,16 +57,16 @@ public:
protected:
protected:


    virtual void SetUp() {
    virtual void SetUp() {
        mSE = new SurfaceEncoder(mYuvTexWidth, mYuvTexHeight);
        mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
        mSE->setSynchronousMode(true);
        mSMS->setSynchronousMode(true);
        mSTC = new SurfaceTextureClient(mSE);
        mSTC = new SurfaceTextureClient(mSMS);
        mANW = mSTC;
        mANW = mSTC;


    }
    }




    virtual void TearDown() {
    virtual void TearDown() {
        mSE.clear();
        mSMS.clear();
        mSTC.clear();
        mSTC.clear();
        mANW.clear();
        mANW.clear();
    }
    }
@@ -74,13 +74,13 @@ protected:
    const int mYuvTexWidth;//  = 64;
    const int mYuvTexWidth;//  = 64;
    const int mYuvTexHeight;// = 66;
    const int mYuvTexHeight;// = 66;


    sp<SurfaceEncoder> mSE;
    sp<SurfaceMediaSource> mSMS;
    sp<SurfaceTextureClient> mSTC;
    sp<SurfaceTextureClient> mSTC;
    sp<ANativeWindow> mANW;
    sp<ANativeWindow> mANW;


};
};


void SurfaceEncoderTest::oneBufferPass(int width, int height ) {
void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
    LOGV("One Buffer Pass");
    LOGV("One Buffer Pass");
    ANativeWindowBuffer* anb;
    ANativeWindowBuffer* anb;
    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
@@ -92,13 +92,13 @@ void SurfaceEncoderTest::oneBufferPass(int width, int height ) {
    // Fill the buffer with the a checkerboard pattern
    // Fill the buffer with the a checkerboard pattern
    uint8_t* img = NULL;
    uint8_t* img = NULL;
    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    SurfaceEncoderTest::fillYV12Buffer(img, width, height, buf->getStride());
    SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
    buf->unlock();
    buf->unlock();


    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
}
}


sp<MPEG4Writer> SurfaceEncoderTest::setUpWriter(OMXClient &client ) {
sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) {
    // Writing to a file
    // Writing to a file
    const char *fileName = "/sdcard/outputSurfEnc.mp4";
    const char *fileName = "/sdcard/outputSurfEnc.mp4";
    sp<MetaData> enc_meta = new MetaData;
    sp<MetaData> enc_meta = new MetaData;
@@ -107,7 +107,7 @@ sp<MPEG4Writer> SurfaceEncoderTest::setUpWriter(OMXClient &client ) {


    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);


    sp<MetaData> meta = mSE->getFormat();
    sp<MetaData> meta = mSMS->getFormat();


    int32_t width, height, stride, sliceHeight, colorFormat;
    int32_t width, height, stride, sliceHeight, colorFormat;
    CHECK(meta->findInt32(kKeyWidth, &width));
    CHECK(meta->findInt32(kKeyWidth, &width));
@@ -129,7 +129,7 @@ sp<MPEG4Writer> SurfaceEncoderTest::setUpWriter(OMXClient &client ) {


    sp<MediaSource> encoder =
    sp<MediaSource> encoder =
        OMXCodec::Create(
        OMXCodec::Create(
                client.interface(), enc_meta, true /* createEncoder */, mSE);
                client.interface(), enc_meta, true /* createEncoder */, mSMS);


    sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
    sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
    writer->addSource(encoder);
    writer->addSource(encoder);
@@ -138,7 +138,7 @@ sp<MPEG4Writer> SurfaceEncoderTest::setUpWriter(OMXClient &client ) {
}
}


// Fill a YV12 buffer with a multi-colored checkerboard pattern
// Fill a YV12 buffer with a multi-colored checkerboard pattern
void SurfaceEncoderTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
void SurfaceMediaSourceTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
    const int blockWidth = w > 16 ? w / 16 : 1;
    const int blockWidth = w > 16 ? w / 16 : 1;
    const int blockHeight = h > 16 ? h / 16 : 1;
    const int blockHeight = h > 16 ? h / 16 : 1;
    const int yuvTexOffsetY = 0;
    const int yuvTexOffsetY = 0;
@@ -168,7 +168,7 @@ void SurfaceEncoderTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride)
}
}


// Fill a YV12 buffer with red outside a given rectangle and green inside it.
// Fill a YV12 buffer with red outside a given rectangle and green inside it.
void SurfaceEncoderTest::fillYV12BufferRect(uint8_t* buf, int w,
void SurfaceMediaSourceTest::fillYV12BufferRect(uint8_t* buf, int w,
                  int h, int stride, const android_native_rect_t& rect) {
                  int h, int stride, const android_native_rect_t& rect) {
    const int yuvTexOffsetY = 0;
    const int yuvTexOffsetY = 0;
    int yuvTexStrideY = stride;
    int yuvTexStrideY = stride;
@@ -190,7 +190,7 @@ void SurfaceEncoderTest::fillYV12BufferRect(uint8_t* buf, int w,
            }
            }
        }
        }
    }
    }
}  ///////// End of class SurfaceEncoderTest
}  ///////// End of class SurfaceMediaSourceTest


///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Class to imitate the recording     /////////////////////////////
// Class to imitate the recording     /////////////////////////////
@@ -219,8 +219,8 @@ struct SimpleDummyRecorder {


///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//           TESTS
//           TESTS
// Just pass one buffer from the native_window to the SurfaceEncoder
// Just pass one buffer from the native_window to the SurfaceMediaSource
TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
    LOGV("Testing OneBufferPass ******************************");
    LOGV("Testing OneBufferPass ******************************");


    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
@@ -233,7 +233,7 @@ TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
}
}


// Pass the buffer with the wrong height and weight and should not be accepted
// Pass the buffer with the wrong height and weight and should not be accepted
TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
    LOGV("Testing Wrong size BufferPass ******************************");
    LOGV("Testing Wrong size BufferPass ******************************");


    // setting the client side buffer size different than the server size
    // setting the client side buffer size different than the server size
@@ -250,16 +250,15 @@ TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPas
}
}




// pass multiple buffers from the native_window the SurfaceEncoder
// pass multiple buffers from the native_window the SurfaceMediaSource
// A dummy writer is used to simulate actual MPEG4Writer
// A dummy writer is used to simulate actual MPEG4Writer
TEST_F(SurfaceEncoderTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
TEST_F(SurfaceMediaSourceTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
    LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
    LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
            0, 0, HAL_PIXEL_FORMAT_YV12));
            0, 0, HAL_PIXEL_FORMAT_YV12));
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));

    SimpleDummyRecorder writer(mSMS);
    SimpleDummyRecorder writer(mSE);
    writer.start();
    writer.start();


    int32_t nFramesCount = 0;
    int32_t nFramesCount = 0;
@@ -273,20 +272,19 @@ TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPass)
    writer.stop();
    writer.stop();
}
}


// Delayed pass of multiple buffers from the native_window the SurfaceEncoder
// Delayed pass of multiple buffers from the native_window the SurfaceMediaSource
// A dummy writer is used to simulate actual MPEG4Writer
// A dummy writer is used to simulate actual MPEG4Writer
TEST_F(SurfaceEncoderTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
TEST_F(SurfaceMediaSourceTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
    LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
    LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
            0, 0, HAL_PIXEL_FORMAT_YV12));
            0, 0, HAL_PIXEL_FORMAT_YV12));
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));

    SimpleDummyRecorder writer(mSMS);
    SimpleDummyRecorder writer(mSE);
    writer.start();
    writer.start();


    int32_t nFramesCount = 1;
    int32_t nFramesCount = 1;
    const int FRAMES_LAG = mSE->getBufferCount() - 1;
    const int FRAMES_LAG = mSMS->getBufferCount() - 1;
    while (nFramesCount <= 300) {
    while (nFramesCount <= 300) {
        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
        oneBufferPass(mYuvTexWidth, mYuvTexHeight);
        // Forcing the writer to lag behind a few frames
        // Forcing the writer to lag behind a few frames
@@ -298,16 +296,16 @@ TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLa
    writer.stop();
    writer.stop();
}
}


// pass multiple buffers from the native_window the SurfaceEncoder
// pass multiple buffers from the native_window the SurfaceMediaSource
// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
    LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
    LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
            0, 0, HAL_PIXEL_FORMAT_YV12));
            0, 0, HAL_PIXEL_FORMAT_YV12));
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));


    DummyRecorder writer(mSE);
    DummyRecorder writer(mSMS);
    writer.start();
    writer.start();


    int32_t nFramesCount = 0;
    int32_t nFramesCount = 0;
@@ -321,7 +319,7 @@ TEST_F(SurfaceEncoderTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThr


// Test to examine the actual encoding. Temporarily disabled till the
// Test to examine the actual encoding. Temporarily disabled till the
// colorformat and encoding from GRAlloc data is resolved
// colorformat and encoding from GRAlloc data is resolved
TEST_F(SurfaceEncoderTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
    LOGV("Testing the whole pipeline with actual Recorder");
    LOGV("Testing the whole pipeline with actual Recorder");
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
            0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // ));
            0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // ));