Merge change 22986 into eclair

* changes:
  Squashed commit of the following:
This commit is contained in:
Android (Google) Code Review
2009-08-27 15:24:35 -07:00
11 changed files with 3 additions and 2436 deletions

View File

@@ -38,23 +38,3 @@ LOCAL_CFLAGS += -Wno-multichar
LOCAL_MODULE:= record
include $(BUILD_EXECUTABLE)
################################################################################
# include $(CLEAR_VARS)
#
# LOCAL_SRC_FILES:= \
# play.cpp
#
# LOCAL_SHARED_LIBRARIES := \
# libstagefright
#
# LOCAL_C_INCLUDES:= \
# frameworks/base/media/libstagefright \
# $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
#
# LOCAL_CFLAGS += -Wno-multichar
#
# LOCAL_MODULE:= play
#
# include $(BUILD_EXECUTABLE)

View File

@@ -1,295 +0,0 @@
/*
* Copyright (C) 2009 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.
*/
#include <binder/ProcessState.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/TimedEventQueue.h>
#include <media/stagefright/MPEG4Extractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXDecoder.h>
using namespace android;
struct NewPlayer {
NewPlayer();
~NewPlayer();
void setSource(const char *uri);
void start();
void pause();
void stop();
private:
struct PlayerEvent : public TimedEventQueue::Event {
PlayerEvent(NewPlayer *player,
void (NewPlayer::*method)(int64_t realtime_us))
: mPlayer(player),
mMethod(method) {
}
virtual void fire(TimedEventQueue *queue, int64_t realtime_us) {
(mPlayer->*mMethod)(realtime_us);
}
private:
NewPlayer *mPlayer;
void (NewPlayer::*mMethod)(int64_t realtime_us);
PlayerEvent(const PlayerEvent &);
PlayerEvent &operator=(const PlayerEvent &);
};
struct PlayVideoFrameEvent : public TimedEventQueue::Event {
PlayVideoFrameEvent(NewPlayer *player, MediaBuffer *buffer)
: mPlayer(player),
mBuffer(buffer) {
}
virtual ~PlayVideoFrameEvent() {
if (mBuffer != NULL) {
mBuffer->release();
mBuffer = NULL;
}
}
virtual void fire(TimedEventQueue *queue, int64_t realtime_us) {
mPlayer->onPlayVideoFrame(realtime_us, mBuffer);
mBuffer = NULL;
}
private:
NewPlayer *mPlayer;
MediaBuffer *mBuffer;
PlayVideoFrameEvent(const PlayVideoFrameEvent &);
PlayVideoFrameEvent &operator=(const PlayVideoFrameEvent &);
};
OMXClient mClient;
MPEG4Extractor *mExtractor;
MediaSource *mAudioSource;
OMXDecoder *mAudioDecoder;
MediaSource *mVideoSource;
OMXDecoder *mVideoDecoder;
int32_t mVideoWidth, mVideoHeight;
TimedEventQueue mQueue;
wp<TimedEventQueue::Event> mPlayVideoFrameEvent;
int64_t mMediaTimeUsStart;
int64_t mRealTimeUsStart;
void setAudioSource(MediaSource *source);
void setVideoSource(MediaSource *source);
int64_t approxRealTime(int64_t mediatime_us) const;
void onStart(int64_t realtime_us);
void onPause(int64_t realtime_us);
void onFetchVideoFrame(int64_t realtime_us);
void onPlayVideoFrame(int64_t realtime_us, MediaBuffer *buffer);
static int64_t getMediaBufferTimeUs(MediaBuffer *buffer);
NewPlayer(const NewPlayer &);
NewPlayer &operator=(const NewPlayer &);
};
NewPlayer::NewPlayer()
: mExtractor(NULL),
mAudioSource(NULL),
mAudioDecoder(NULL),
mVideoSource(NULL),
mVideoDecoder(NULL),
mVideoWidth(0),
mVideoHeight(0) {
status_t err = mClient.connect();
assert(err == OK);
}
NewPlayer::~NewPlayer() {
stop();
mClient.disconnect();
}
void NewPlayer::setSource(const char *uri) {
stop();
mExtractor = new MPEG4Extractor(new MmapSource(uri));
int num_tracks;
status_t err = mExtractor->countTracks(&num_tracks);
assert(err == OK);
for (int i = 0; i < num_tracks; ++i) {
const sp<MetaData> meta = mExtractor->getTrackMetaData(i);
assert(meta != NULL);
const char *mime;
if (!meta->findCString(kKeyMIMEType, &mime)) {
continue;
}
bool is_audio = false;
bool is_acceptable = false;
if (!strncasecmp(mime, "audio/", 6)) {
is_audio = true;
is_acceptable = (mAudioSource == NULL);
} else if (!strncasecmp(mime, "video/", 6)) {
is_acceptable = (mVideoSource == NULL);
}
if (!is_acceptable) {
continue;
}
MediaSource *source;
if (mExtractor->getTrack(i, &source) != OK) {
continue;
}
if (is_audio) {
setAudioSource(source);
} else {
setVideoSource(source);
}
}
}
void NewPlayer::setAudioSource(MediaSource *source) {
mAudioSource = source;
sp<MetaData> meta = source->getFormat();
mAudioDecoder = OMXDecoder::Create(&mClient, meta);
mAudioDecoder->setSource(source);
}
void NewPlayer::setVideoSource(MediaSource *source) {
mVideoSource = source;
sp<MetaData> meta = source->getFormat();
bool success = meta->findInt32(kKeyWidth, &mVideoWidth);
assert(success);
success = meta->findInt32(kKeyHeight, &mVideoHeight);
assert(success);
mVideoDecoder = OMXDecoder::Create(&mClient, meta);
mVideoDecoder->setSource(source);
}
void NewPlayer::start() {
mQueue.start();
mQueue.postEvent(new PlayerEvent(this, &NewPlayer::onStart));
}
void NewPlayer::pause() {
mQueue.postEvent(new PlayerEvent(this, &NewPlayer::onPause));
}
void NewPlayer::stop() {
mQueue.stop();
delete mVideoDecoder;
mVideoDecoder = NULL;
delete mVideoSource;
mVideoSource = NULL;
mVideoWidth = mVideoHeight = 0;
delete mAudioDecoder;
mAudioDecoder = NULL;
delete mAudioSource;
mAudioSource = NULL;
delete mExtractor;
mExtractor = NULL;
}
int64_t NewPlayer::approxRealTime(int64_t mediatime_us) const {
return mRealTimeUsStart + (mediatime_us - mMediaTimeUsStart);
}
void NewPlayer::onStart(int64_t realtime_us) {
mRealTimeUsStart = TimedEventQueue::getRealTimeUs();
if (mVideoDecoder != NULL) {
mQueue.postEvent(new PlayerEvent(this, &NewPlayer::onFetchVideoFrame));
}
}
void NewPlayer::onFetchVideoFrame(int64_t realtime_us) {
MediaBuffer *buffer;
status_t err = mVideoDecoder->read(&buffer);
assert(err == OK);
int64_t mediatime_us = getMediaBufferTimeUs(buffer);
sp<TimedEventQueue::Event> event = new PlayVideoFrameEvent(this, buffer);
mPlayVideoFrameEvent = event;
mQueue.postTimedEvent(event, approxRealTime(mediatime_us));
}
// static
int64_t NewPlayer::getMediaBufferTimeUs(MediaBuffer *buffer) {
int32_t units, scale;
bool success =
buffer->meta_data()->findInt32(kKeyTimeUnits, &units);
assert(success);
success =
buffer->meta_data()->findInt32(kKeyTimeScale, &scale);
assert(success);
return (int64_t)units * 1000000 / scale;
}
void NewPlayer::onPlayVideoFrame(int64_t realtime_us, MediaBuffer *buffer) {
LOGI("playing video frame (mediatime: %.2f sec)\n",
getMediaBufferTimeUs(buffer) / 1E6);
fflush(stdout);
buffer->release();
buffer = NULL;
mQueue.postEvent(new PlayerEvent(this, &NewPlayer::onFetchVideoFrame));
}
void NewPlayer::onPause(int64_t realtime_us) {
}
int main(int argc, char **argv) {
android::ProcessState::self()->startThreadPool();
if (argc != 2) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
return 1;
}
NewPlayer player;
player.setSource(argv[1]);
player.start();
sleep(10);
player.stop();
return 0;
}

View File

@@ -26,7 +26,6 @@
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/OMXDecoder.h>
using namespace android;
@@ -87,8 +86,6 @@ private:
DummySource &operator=(const DummySource &);
};
#define USE_OMX_CODEC 1
sp<MediaSource> createSource(const char *filename) {
sp<MediaSource> source;
@@ -140,13 +137,8 @@ int main(int argc, char **argv) {
sp<MetaData> meta = source->getFormat();
#if USE_OMX_CODEC
sp<OMXCodec> decoder = OMXCodec::Create(
client.interface(), meta, false /* createEncoder */, source);
#else
sp<OMXDecoder> decoder = OMXDecoder::Create(
&client, meta, false /* createEncoder */, source);
#endif
int width, height;
bool success = meta->findInt32(kKeyWidth, &width);
@@ -164,14 +156,9 @@ int main(int argc, char **argv) {
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
#if USE_OMX_CODEC
sp<OMXCodec> encoder =
OMXCodec::Create(
client.interface(), enc_meta, true /* createEncoder */, decoder);
#else
sp<OMXDecoder> encoder = OMXDecoder::Create(
&client, enc_meta, true /* createEncoder */, decoder);
#endif
#if 1
sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");

View File

@@ -33,7 +33,6 @@
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/OMXDecoder.h>
#include "JPEGSource.h"
@@ -50,18 +49,11 @@ static int64_t getNowUs() {
return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
}
#define USE_OMX_CODEC 1
static void playSource(OMXClient *client, const sp<MediaSource> &source) {
sp<MetaData> meta = source->getFormat();
#if !USE_OMX_CODEC
sp<OMXDecoder> decoder = OMXDecoder::Create(
client, meta, false /* createEncoder */, source);
#else
sp<OMXCodec> decoder = OMXCodec::Create(
client->interface(), meta, false /* createEncoder */, source);
#endif
if (decoder == NULL) {
return;

View File

@@ -119,12 +119,6 @@ struct omx_message {
EMPTY_BUFFER_DONE,
FILL_BUFFER_DONE,
// reserved for OMXDecoder use.
START,
INITIAL_FILL_BUFFER,
// reserved for OMXObserver use.
QUIT_OBSERVER,
} type;
IOMX::node_id node;
@@ -137,28 +131,21 @@ struct omx_message {
OMX_U32 data2;
} event_data;
// if type == EMPTY_BUFFER_DONE || type == FILL_BUFFER
// || type == INITIAL_FILL_BUFFER
// if type == EMPTY_BUFFER_DONE
struct {
IOMX::buffer_id buffer;
} buffer_data;
// if type == EMPTY_BUFFER || type == FILL_BUFFER_DONE
// if type == FILL_BUFFER_DONE
struct {
IOMX::buffer_id buffer;
OMX_U32 range_offset;
OMX_U32 range_length;
OMX_U32 flags;
OMX_TICKS timestamp;
OMX_PTR platform_private; // ignored if type == EMPTY_BUFFER
OMX_PTR platform_private;
} extended_buffer_data;
// if type == SEND_COMMAND
struct {
OMX_COMMANDTYPE cmd;
OMX_S32 param;
} send_command_data;
} u;
};

View File

@@ -20,62 +20,11 @@
#include <media/IOMX.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/threads.h>
namespace android {
class OMXObserver {
public:
OMXObserver();
virtual ~OMXObserver();
void postMessage(const omx_message &msg);
protected:
virtual void onOMXMessage(const omx_message &msg) = 0;
private:
friend class OMXClient;
pthread_t mThread;
Mutex mLock;
Condition mQueueNotEmpty;
List<omx_message> mQueue;
void start();
void stop();
static void *ThreadWrapper(void *me);
void threadEntry();
OMXObserver(const OMXObserver &);
OMXObserver &operator=(const OMXObserver &);
};
class OMXClient;
class OMXClientReflector : public BnOMXObserver {
public:
OMXClientReflector(OMXClient *client);
virtual void on_message(const omx_message &msg);
void reset();
private:
OMXClient *mClient;
OMXClientReflector(const OMXClientReflector &);
OMXClientReflector &operator=(const OMXClientReflector &);
};
class OMXClient {
public:
friend class OMXClientReflector;
OMXClient();
~OMXClient();
status_t connect();
void disconnect();
@@ -84,18 +33,8 @@ public:
return mOMX;
}
status_t registerObserver(IOMX::node_id node, OMXObserver *observer);
void unregisterObserver(IOMX::node_id node);
private:
sp<IOMX> mOMX;
Mutex mLock;
KeyedVector<IOMX::node_id, OMXObserver *> mObservers;
sp<OMXClientReflector> mReflector;
bool onOMXMessage(const omx_message &msg);
OMXClient(const OMXClient &);
OMXClient &operator=(const OMXClient &);

View File

@@ -1,185 +0,0 @@
/*
* Copyright (C) 2009 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 OMX_DECODER_H_
#define OMX_DECODER_H_
#include <binder/MemoryDealer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/OMXClient.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/threads.h>
#include <OMX_Video.h>
namespace android {
class OMXMediaBuffer;
class OMXDecoder : public MediaSource,
public OMXObserver,
public MediaBufferObserver {
public:
static sp<OMXDecoder> Create(
OMXClient *client, const sp<MetaData> &data,
bool createEncoder,
const sp<MediaSource> &source);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp<MetaData> getFormat();
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
void addCodecSpecificData(const void *data, size_t size);
// from OMXObserver
virtual void onOMXMessage(const omx_message &msg);
// from MediaBufferObserver
virtual void signalBufferReturned(MediaBuffer *buffer);
protected:
virtual ~OMXDecoder();
private:
enum {
kPortIndexInput = 0,
kPortIndexOutput = 1
};
enum PortStatus {
kPortStatusActive = 0,
kPortStatusDisabled = 1,
kPortStatusShutdown = 2,
kPortStatusFlushing = 3,
kPortStatusFlushingToDisabled = 4,
kPortStatusFlushingToShutdown = 5,
};
enum Quirks {
kWantsNALFragments = 1,
kDoesntReturnBuffersOnDisable = 2,
kDoesntFlushOnExecutingToIdle = 4,
kDoesntProperlyFlushAllPortsAtOnce = 8,
kRequiresAllocateBufferOnInputPorts = 16,
kRequiresAllocateBufferOnOutputPorts = 32,
kRequiresLoadedToIdleAfterAllocation = 64,
kMeasuresTimeInMilliseconds = 128,
};
OMXClient *mClient;
sp<IOMX> mOMX;
IOMX::node_id mNode;
char *mComponentName;
char *mMIME;
bool mIsMP3;
bool mIsAVC;
bool mIsEncoder;
uint32_t mQuirks;
sp<MediaSource> mSource;
sp<MetaData> mOutputFormat;
Mutex mLock;
Condition mOutputBufferAvailable;
List<MediaBuffer *> mOutputBuffers;
struct CodecSpecificData {
void *data;
size_t size;
};
List<CodecSpecificData> mCodecSpecificData;
List<CodecSpecificData>::iterator mCodecSpecificDataIterator;
volatile OMX_STATETYPE mState;
OMX_U32 mPortStatusMask;
bool mShutdownInitiated;
typedef List<IOMX::buffer_id> BufferList;
Vector<BufferList> mBuffers;
KeyedVector<IOMX::buffer_id, sp<IMemory> > mBufferMap;
KeyedVector<IOMX::buffer_id, OMXMediaBuffer *> mMediaBufferMap;
sp<MemoryDealer> mDealer;
bool mSeeking;
int64_t mSeekTimeUs;
bool mStarted;
status_t mErrorCondition;
bool mReachedEndOfInput;
OMXDecoder(OMXClient *client, IOMX::node_id node,
const char *mime, const char *codec,
bool is_encoder,
uint32_t quirks,
const sp<MediaSource> &source);
void setPortStatus(OMX_U32 port_index, PortStatus status);
PortStatus getPortStatus(OMX_U32 port_index) const;
void allocateBuffers(OMX_U32 port_index);
void setAMRFormat();
void setAACFormat();
status_t setVideoPortFormatType(
OMX_U32 portIndex,
OMX_VIDEO_CODINGTYPE compressionFormat,
OMX_COLOR_FORMATTYPE colorFormat);
void setVideoOutputFormat(const char *mime, OMX_U32 width, OMX_U32 height);
void setVideoInputFormat(const char *mime, OMX_U32 width, OMX_U32 height);
void setup();
void dumpPortDefinition(OMX_U32 port_index);
void onStart();
void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
void onEventCmdComplete(OMX_COMMANDTYPE type, OMX_U32 data);
void onEventPortSettingsChanged(OMX_U32 port_index);
void onStateChanged(OMX_STATETYPE to);
void onEmptyBufferDone(IOMX::buffer_id buffer);
void onFillBufferDone(const omx_message &msg);
void onRealEmptyBufferDone(IOMX::buffer_id buffer);
void onRealFillBufferDone(const omx_message &msg);
void initiateShutdown();
void freeInputBuffer(IOMX::buffer_id buffer);
void freeOutputBuffer(IOMX::buffer_id buffer);
void freePortBuffers(OMX_U32 port_index);
void postStart();
void postEmptyBufferDone(IOMX::buffer_id buffer);
void postInitialFillBuffer(IOMX::buffer_id buffer);
OMXDecoder(const OMXDecoder &);
OMXDecoder &operator=(const OMXDecoder &);
};
} // namespace android
#endif // OMX_DECODER_H_

View File

@@ -26,7 +26,6 @@ LOCAL_SRC_FILES:= \
AudioPlayer.cpp \
ESDS.cpp \
OMXClient.cpp \
OMXDecoder.cpp \
string.cpp
LOCAL_C_INCLUDES:= \

View File

@@ -33,14 +33,11 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/OMXDecoder.h>
#include <media/stagefright/ShoutcastSource.h>
#include <media/stagefright/TimeSource.h>
#include <ui/PixelFormat.h>
#include <ui/Surface.h>
#define USE_OMX_CODEC 1
namespace android {
MediaPlayerImpl::MediaPlayerImpl(const char *uri)
@@ -406,13 +403,8 @@ void MediaPlayerImpl::setAudioSource(const sp<MediaSource> &source) {
sp<MetaData> meta = source->getFormat();
#if !USE_OMX_CODEC
mAudioDecoder = OMXDecoder::Create(
&mClient, meta, false /* createEncoder */, source);
#else
mAudioDecoder = OMXCodec::Create(
mClient.interface(), meta, false /* createEncoder */, source);
#endif
}
void MediaPlayerImpl::setVideoSource(const sp<MediaSource> &source) {
@@ -427,13 +419,8 @@ void MediaPlayerImpl::setVideoSource(const sp<MediaSource> &source) {
success = meta->findInt32(kKeyHeight, &mVideoHeight);
CHECK(success);
#if !USE_OMX_CODEC
mVideoDecoder = OMXDecoder::Create(
&mClient, meta, false /* createEncoder */, source);
#else
mVideoDecoder = OMXCodec::Create(
mClient.interface(), meta, false /* createEncoder */, source);
#endif
if (mISurface.get() != NULL || mSurface.get() != NULL) {
depopulateISurface();

View File

@@ -18,11 +18,8 @@
#define LOG_TAG "OMXClient"
#include <utils/Log.h>
#include <sys/socket.h>
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
#include <media/IOMX.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/OMXClient.h>
@@ -31,13 +28,7 @@ namespace android {
OMXClient::OMXClient() {
}
OMXClient::~OMXClient() {
disconnect();
}
status_t OMXClient::connect() {
Mutex::Autolock autoLock(mLock);
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
@@ -47,175 +38,10 @@ status_t OMXClient::connect() {
mOMX = service->createOMX();
CHECK(mOMX.get() != NULL);
mReflector = new OMXClientReflector(this);
return OK;
}
void OMXClient::disconnect() {
Mutex::Autolock autoLock(mLock);
if (mReflector.get() != NULL) {
return;
}
CHECK(mObservers.isEmpty());
mReflector->reset();
mReflector.clear();
}
status_t OMXClient::registerObserver(
IOMX::node_id node, OMXObserver *observer) {
Mutex::Autolock autoLock(&mLock);
ssize_t index = mObservers.indexOfKey(node);
if (index >= 0) {
return UNKNOWN_ERROR;
}
mObservers.add(node, observer);
observer->start();
mOMX->observe_node(node, mReflector);
return OK;
}
void OMXClient::unregisterObserver(IOMX::node_id node) {
Mutex::Autolock autoLock(mLock);
ssize_t index = mObservers.indexOfKey(node);
CHECK(index >= 0);
if (index < 0) {
return;
}
OMXObserver *observer = mObservers.valueAt(index);
observer->stop();
mObservers.removeItemsAt(index);
}
bool OMXClient::onOMXMessage(const omx_message &msg) {
bool done = false;
switch (msg.type) {
case omx_message::EVENT:
{
LOGV("OnEvent node:%p event:%d data1:%ld data2:%ld",
msg.u.event_data.node,
msg.u.event_data.event,
msg.u.event_data.data1,
msg.u.event_data.data2);
break;
}
case omx_message::FILL_BUFFER_DONE:
{
LOGV("FillBufferDone %p", msg.u.extended_buffer_data.buffer);
break;
}
case omx_message::EMPTY_BUFFER_DONE:
{
LOGV("EmptyBufferDone %p", msg.u.buffer_data.buffer);
break;
}
default:
LOGE("received unknown omx_message type %d", msg.type);
break;
}
Mutex::Autolock autoLock(mLock);
ssize_t index = mObservers.indexOfKey(msg.node);
if (index >= 0) {
mObservers.editValueAt(index)->postMessage(msg);
}
return done;
}
////////////////////////////////////////////////////////////////////////////////
OMXObserver::OMXObserver() {
}
OMXObserver::~OMXObserver() {
}
void OMXObserver::start() {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int err = pthread_create(&mThread, &attr, ThreadWrapper, this);
CHECK_EQ(err, 0);
pthread_attr_destroy(&attr);
}
void OMXObserver::stop() {
omx_message msg;
msg.type = omx_message::QUIT_OBSERVER;
postMessage(msg);
void *dummy;
pthread_join(mThread, &dummy);
}
void OMXObserver::postMessage(const omx_message &msg) {
Mutex::Autolock autoLock(mLock);
mQueue.push_back(msg);
mQueueNotEmpty.signal();
}
// static
void *OMXObserver::ThreadWrapper(void *me) {
static_cast<OMXObserver *>(me)->threadEntry();
return NULL;
}
void OMXObserver::threadEntry() {
for (;;) {
omx_message msg;
{
Mutex::Autolock autoLock(mLock);
while (mQueue.empty()) {
mQueueNotEmpty.wait(mLock);
}
msg = *mQueue.begin();
mQueue.erase(mQueue.begin());
}
if (msg.type == omx_message::QUIT_OBSERVER) {
break;
}
onOMXMessage(msg);
}
}
////////////////////////////////////////////////////////////////////////////////
OMXClientReflector::OMXClientReflector(OMXClient *client)
: mClient(client) {
}
void OMXClientReflector::on_message(const omx_message &msg) {
if (mClient != NULL) {
mClient->onOMXMessage(msg);
}
}
void OMXClientReflector::reset() {
mClient = NULL;
}
} // namespace android

File diff suppressed because it is too large Load Diff