Merge change Ie80e2381 into eclair

* changes:
  DO NOT MERGE: Squashed commit of the following:
This commit is contained in:
Android (Google) Code Review
2009-11-05 16:50:34 -05:00
22 changed files with 956 additions and 497 deletions

View File

@@ -283,7 +283,7 @@ int main(int argc, char **argv) {
CHECK(service.get() != NULL);
sp<IOMX> omx = service->createOMX();
sp<IOMX> omx = service->getOMX();
CHECK(omx.get() != NULL);
const char *kMimeTypes[] = {
@@ -329,11 +329,11 @@ int main(int argc, char **argv) {
CHECK(service.get() != NULL);
sp<IOMX> omx = service->createOMX();
sp<IOMX> omx = service->getOMX();
CHECK(omx.get() != NULL);
List<String8> list;
omx->list_nodes(&list);
omx->listNodes(&list);
for (List<String8>::iterator it = list.begin();
it != list.end(); ++it) {

View File

@@ -42,7 +42,7 @@ public:
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IOMX> createOMX() = 0;
virtual sp<IOMX> getOMX() = 0;
// Take a peek at currently playing audio, for visualization purposes.
// This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available.

View File

@@ -42,57 +42,57 @@ public:
typedef void *buffer_id;
typedef void *node_id;
virtual status_t list_nodes(List<String8> *list) = 0;
virtual status_t listNodes(List<String8> *list) = 0;
virtual status_t allocate_node(const char *name, node_id *node) = 0;
virtual status_t free_node(node_id node) = 0;
virtual status_t allocateNode(
const char *name, const sp<IOMXObserver> &observer,
node_id *node) = 0;
virtual status_t send_command(
virtual status_t freeNode(node_id node) = 0;
virtual status_t sendCommand(
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) = 0;
virtual status_t get_parameter(
virtual status_t getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) = 0;
virtual status_t set_parameter(
virtual status_t setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) = 0;
virtual status_t get_config(
virtual status_t getConfig(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) = 0;
virtual status_t set_config(
virtual status_t setConfig(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) = 0;
virtual status_t use_buffer(
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) = 0;
virtual status_t allocate_buffer(
virtual status_t allocateBuffer(
node_id node, OMX_U32 port_index, size_t size,
buffer_id *buffer) = 0;
virtual status_t allocate_buffer_with_backup(
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) = 0;
virtual status_t free_buffer(
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer) = 0;
virtual status_t observe_node(
node_id node, const sp<IOMXObserver> &observer) = 0;
virtual status_t fillBuffer(node_id node, buffer_id buffer) = 0;
virtual void fill_buffer(node_id node, buffer_id buffer) = 0;
virtual void empty_buffer(
virtual status_t emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp) = 0;
virtual status_t get_extension_index(
virtual status_t getExtensionIndex(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index) = 0;
@@ -162,7 +162,7 @@ class IOMXObserver : public IInterface {
public:
DECLARE_META_INTERFACE(OMXObserver);
virtual void on_message(const omx_message &msg) = 0;
virtual void onMessage(const omx_message &msg) = 0;
};
class IOMXRenderer : public IInterface {

View File

@@ -21,7 +21,7 @@
#include <sys/types.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/string.h>
#include <media/stagefright/stagefright_string.h>
#include <utils/KeyedVector.h>
namespace android {

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
#ifndef STRING_H_
#ifndef STAGEFRIGHT_STRING_H_
#define STRING_H_
#define STAGEFRIGHT_STRING_H_
#include <utils/String8.h>
@@ -51,4 +51,4 @@ private:
} // namespace android
#endif // STRING_H_
#endif // STAGEFRIGHT_STRING_H_

View File

@@ -35,7 +35,7 @@ enum {
DECODE_FD,
CREATE_MEDIA_RECORDER,
CREATE_METADATA_RETRIEVER,
CREATE_OMX,
GET_OMX,
SNOOP
};
@@ -123,10 +123,10 @@ public:
return interface_cast<IMemory>(reply.readStrongBinder());
}
virtual sp<IOMX> createOMX() {
virtual sp<IOMX> getOMX() {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
remote()->transact(CREATE_OMX, data, &reply);
remote()->transact(GET_OMX, data, &reply);
return interface_cast<IOMX>(reply.readStrongBinder());
}
};
@@ -207,9 +207,9 @@ status_t BnMediaPlayerService::onTransact(
reply->writeStrongBinder(retriever->asBinder());
return NO_ERROR;
} break;
case CREATE_OMX: {
case GET_OMX: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IOMX> omx = createOMX();
sp<IOMX> omx = getOMX();
reply->writeStrongBinder(omx->asBinder());
return NO_ERROR;
} break;

View File

@@ -24,7 +24,6 @@ enum {
ALLOC_BUFFER,
ALLOC_BUFFER_WITH_BACKUP,
FREE_BUFFER,
OBSERVE_NODE,
FILL_BUFFER,
EMPTY_BUFFER,
GET_EXTENSION_INDEX,
@@ -76,7 +75,7 @@ public:
: BpInterface<IOMX>(impl) {
}
virtual status_t list_nodes(List<String8> *list) {
virtual status_t listNodes(List<String8> *list) {
list->clear();
Parcel data, reply;
@@ -93,10 +92,12 @@ public:
return OK;
}
virtual status_t allocate_node(const char *name, node_id *node) {
virtual status_t allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeCString(name);
data.writeStrongBinder(observer->asBinder());
remote()->transact(ALLOCATE_NODE, data, &reply);
status_t err = reply.readInt32();
@@ -109,7 +110,7 @@ public:
return err;
}
virtual status_t free_node(node_id node) {
virtual status_t freeNode(node_id node) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeIntPtr((intptr_t)node);
@@ -118,7 +119,7 @@ public:
return reply.readInt32();
}
virtual status_t send_command(
virtual status_t sendCommand(
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
@@ -130,7 +131,7 @@ public:
return reply.readInt32();
}
virtual status_t get_parameter(
virtual status_t getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) {
Parcel data, reply;
@@ -151,7 +152,7 @@ public:
return OK;
}
virtual status_t set_parameter(
virtual status_t setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) {
Parcel data, reply;
@@ -165,7 +166,7 @@ public:
return reply.readInt32();
}
virtual status_t get_config(
virtual status_t getConfig(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) {
Parcel data, reply;
@@ -186,7 +187,7 @@ public:
return OK;
}
virtual status_t set_config(
virtual status_t setConfig(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) {
Parcel data, reply;
@@ -200,7 +201,7 @@ public:
return reply.readInt32();
}
virtual status_t use_buffer(
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) {
Parcel data, reply;
@@ -222,7 +223,7 @@ public:
return err;
}
virtual status_t allocate_buffer(
virtual status_t allocateBuffer(
node_id node, OMX_U32 port_index, size_t size,
buffer_id *buffer) {
Parcel data, reply;
@@ -244,7 +245,7 @@ public:
return err;
}
virtual status_t allocate_buffer_with_backup(
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) {
Parcel data, reply;
@@ -266,7 +267,7 @@ public:
return err;
}
virtual status_t free_buffer(
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
@@ -278,26 +279,17 @@ public:
return reply.readInt32();
}
virtual status_t observe_node(
node_id node, const sp<IOMXObserver> &observer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeIntPtr((intptr_t)node);
data.writeStrongBinder(observer->asBinder());
remote()->transact(OBSERVE_NODE, data, &reply);
return reply.readInt32();
}
virtual void fill_buffer(node_id node, buffer_id buffer) {
virtual status_t fillBuffer(node_id node, buffer_id buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeIntPtr((intptr_t)node);
data.writeIntPtr((intptr_t)buffer);
remote()->transact(FILL_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
return reply.readInt32();
}
virtual void empty_buffer(
virtual status_t emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
@@ -311,9 +303,11 @@ public:
data.writeInt32(flags);
data.writeInt64(timestamp);
remote()->transact(EMPTY_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
return reply.readInt32();
}
virtual status_t get_extension_index(
virtual status_t getExtensionIndex(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index) {
@@ -375,7 +369,7 @@ status_t BnOMX::onTransact(
CHECK_INTERFACE(IOMX, data, reply);
List<String8> list;
list_nodes(&list);
listNodes(&list);
reply->writeInt32(list.size());
for (List<String8>::iterator it = list.begin();
@@ -390,8 +384,14 @@ status_t BnOMX::onTransact(
{
CHECK_INTERFACE(IOMX, data, reply);
const char *name = data.readCString();
sp<IOMXObserver> observer =
interface_cast<IOMXObserver>(data.readStrongBinder());
node_id node;
status_t err = allocate_node(data.readCString(), &node);
status_t err = allocateNode(name, observer, &node);
reply->writeInt32(err);
if (err == OK) {
reply->writeIntPtr((intptr_t)node);
@@ -406,7 +406,7 @@ status_t BnOMX::onTransact(
node_id node = (void*)data.readIntPtr();
reply->writeInt32(free_node(node));
reply->writeInt32(freeNode(node));
return NO_ERROR;
}
@@ -421,7 +421,7 @@ status_t BnOMX::onTransact(
static_cast<OMX_COMMANDTYPE>(data.readInt32());
OMX_S32 param = data.readInt32();
reply->writeInt32(send_command(node, cmd, param));
reply->writeInt32(sendCommand(node, cmd, param));
return NO_ERROR;
}
@@ -439,7 +439,7 @@ status_t BnOMX::onTransact(
void *params = malloc(size);
data.read(params, size);
status_t err = get_parameter(node, index, params, size);
status_t err = getParameter(node, index, params, size);
reply->writeInt32(err);
@@ -463,7 +463,7 @@ status_t BnOMX::onTransact(
size_t size = data.readInt32();
void *params = const_cast<void *>(data.readInplace(size));
reply->writeInt32(set_parameter(node, index, params, size));
reply->writeInt32(setParameter(node, index, params, size));
return NO_ERROR;
}
@@ -481,7 +481,7 @@ status_t BnOMX::onTransact(
void *params = malloc(size);
data.read(params, size);
status_t err = get_config(node, index, params, size);
status_t err = getConfig(node, index, params, size);
reply->writeInt32(err);
@@ -505,7 +505,7 @@ status_t BnOMX::onTransact(
size_t size = data.readInt32();
void *params = const_cast<void *>(data.readInplace(size));
reply->writeInt32(set_config(node, index, params, size));
reply->writeInt32(setConfig(node, index, params, size));
return NO_ERROR;
}
@@ -520,7 +520,7 @@ status_t BnOMX::onTransact(
interface_cast<IMemory>(data.readStrongBinder());
buffer_id buffer;
status_t err = use_buffer(node, port_index, params, &buffer);
status_t err = useBuffer(node, port_index, params, &buffer);
reply->writeInt32(err);
if (err == OK) {
@@ -539,7 +539,7 @@ status_t BnOMX::onTransact(
size_t size = data.readInt32();
buffer_id buffer;
status_t err = allocate_buffer(node, port_index, size, &buffer);
status_t err = allocateBuffer(node, port_index, size, &buffer);
reply->writeInt32(err);
if (err == OK) {
@@ -559,7 +559,7 @@ status_t BnOMX::onTransact(
interface_cast<IMemory>(data.readStrongBinder());
buffer_id buffer;
status_t err = allocate_buffer_with_backup(
status_t err = allocateBufferWithBackup(
node, port_index, params, &buffer);
reply->writeInt32(err);
@@ -578,19 +578,7 @@ status_t BnOMX::onTransact(
node_id node = (void*)data.readIntPtr();
OMX_U32 port_index = data.readInt32();
buffer_id buffer = (void*)data.readIntPtr();
reply->writeInt32(free_buffer(node, port_index, buffer));
return NO_ERROR;
}
case OBSERVE_NODE:
{
CHECK_INTERFACE(IOMX, data, reply);
node_id node = (void*)data.readIntPtr();
sp<IOMXObserver> observer =
interface_cast<IOMXObserver>(data.readStrongBinder());
reply->writeInt32(observe_node(node, observer));
reply->writeInt32(freeBuffer(node, port_index, buffer));
return NO_ERROR;
}
@@ -601,7 +589,7 @@ status_t BnOMX::onTransact(
node_id node = (void*)data.readIntPtr();
buffer_id buffer = (void*)data.readIntPtr();
fill_buffer(node, buffer);
reply->writeInt32(fillBuffer(node, buffer));
return NO_ERROR;
}
@@ -617,9 +605,10 @@ status_t BnOMX::onTransact(
OMX_U32 flags = data.readInt32();
OMX_TICKS timestamp = data.readInt64();
empty_buffer(
node, buffer, range_offset, range_length,
flags, timestamp);
reply->writeInt32(
emptyBuffer(
node, buffer, range_offset, range_length,
flags, timestamp));
return NO_ERROR;
}
@@ -632,7 +621,7 @@ status_t BnOMX::onTransact(
const char *parameter_name = data.readCString();
OMX_INDEXTYPE index;
status_t err = get_extension_index(node, parameter_name, &index);
status_t err = getExtensionIndex(node, parameter_name, &index);
reply->writeInt32(err);
@@ -683,7 +672,7 @@ public:
: BpInterface<IOMXObserver>(impl) {
}
virtual void on_message(const omx_message &msg) {
virtual void onMessage(const omx_message &msg) {
Parcel data, reply;
data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
data.write(&msg, sizeof(msg));
@@ -705,7 +694,7 @@ status_t BnOMXObserver::onTransact(
data.read(&msg, sizeof(msg));
// XXX Could use readInplace maybe?
on_message(msg);
onMessage(msg);
return NO_ERROR;
}

View File

@@ -50,7 +50,7 @@ LOCAL_C_INCLUDES := external/tremor/Tremor \
$(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
$(TOP)/frameworks/base/media/libstagefright/omx
$(TOP)/frameworks/base/media/libstagefright/include
LOCAL_MODULE:= libmediaplayerservice

View File

@@ -284,8 +284,14 @@ sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClie
return c;
}
sp<IOMX> MediaPlayerService::createOMX() {
return new OMX;
sp<IOMX> MediaPlayerService::getOMX() {
Mutex::Autolock autoLock(mLock);
if (mOMX.get() == NULL) {
mOMX = new OMX;
}
return mOMX;
}
status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const

View File

@@ -185,7 +185,7 @@ public:
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> snoop();
virtual sp<IOMX> createOMX();
virtual sp<IOMX> getOMX();
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -284,6 +284,7 @@ private:
SortedVector< wp<Client> > mClients;
SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
int32_t mNextConnId;
sp<IOMX> mOMX;
};
// ----------------------------------------------------------------------------

View File

@@ -138,6 +138,12 @@ status_t MetadataRetrieverClient::setDataSource(const char *url)
return UNKNOWN_ERROR;
}
player_type playerType = getPlayerType(url);
#if !defined(NO_OPENCORE) && defined(BUILD_WITH_FULL_STAGEFRIGHT)
if (playerType == STAGEFRIGHT_PLAYER) {
// Stagefright doesn't support metadata in this branch yet.
playerType = PV_PLAYER;
}
#endif
LOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) return NO_INIT;
@@ -176,6 +182,12 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
}
player_type playerType = getPlayerType(fd, offset, length);
#if !defined(NO_OPENCORE) && defined(BUILD_WITH_FULL_STAGEFRIGHT)
if (playerType == STAGEFRIGHT_PLAYER) {
// Stagefright doesn't support metadata in this branch yet.
playerType = PV_PLAYER;
}
#endif
LOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) {

View File

@@ -33,7 +33,7 @@ LOCAL_SRC_FILES += \
TimeSource.cpp \
TimedEventQueue.cpp \
AudioPlayer.cpp \
string.cpp
stagefright_string.cpp
endif

View File

@@ -19,7 +19,7 @@
#include <media/stagefright/HTTPDataSource.h>
#include <media/stagefright/HTTPStream.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/string.h>
#include <media/stagefright/stagefright_string.h>
namespace android {

View File

@@ -35,7 +35,7 @@ status_t OMXClient::connect() {
CHECK(service.get() != NULL);
mOMX = service->createOMX();
mOMX = service->getOMX();
CHECK(mOMX.get() != NULL);
return OK;

View File

@@ -85,12 +85,15 @@ static const CodecInfo kEncoderInfo[] = {
#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
struct OMXCodecObserver : public BnOMXObserver {
OMXCodecObserver(const wp<OMXCodec> &target)
: mTarget(target) {
OMXCodecObserver() {
}
void setCodec(const sp<OMXCodec> &target) {
mTarget = target;
}
// from IOMXObserver
virtual void on_message(const omx_message &msg) {
virtual void onMessage(const omx_message &msg) {
sp<OMXCodec> codec = mTarget.promote();
if (codec.get() != NULL) {
@@ -177,6 +180,7 @@ sp<OMXCodec> OMXCodec::Create(
CHECK(success);
const char *componentName = NULL;
sp<OMXCodecObserver> observer = new OMXCodecObserver;
IOMX::node_id node = 0;
for (int index = 0;; ++index) {
if (createEncoder) {
@@ -200,7 +204,7 @@ sp<OMXCodec> OMXCodec::Create(
LOGV("Attempting to allocate OMX node '%s'", componentName);
status_t err = omx->allocate_node(componentName, &node);
status_t err = omx->allocateNode(componentName, observer, &node);
if (err == OK) {
LOGI("Successfully allocated OMX node '%s'", componentName);
break;
@@ -248,6 +252,8 @@ sp<OMXCodec> OMXCodec::Create(
omx, node, quirks, createEncoder, mime, componentName,
source);
observer->setCodec(codec);
uint32_t type;
const void *data;
size_t size;
@@ -330,7 +336,9 @@ sp<OMXCodec> OMXCodec::Create(
if (!strcmp(componentName, "OMX.TI.Video.Decoder")
&& (profile != kAVCProfileBaseline || level > 39)) {
// This stream exceeds the decoder's capabilities.
// This stream exceeds the decoder's capabilities. The decoder
// does not handle this gracefully and would clobber the heap
// and wreak havoc instead...
LOGE("Profile and/or level exceed the decoder's capabilities.");
return NULL;
@@ -405,7 +413,7 @@ void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
InitOMXParams(&def);
def.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -414,7 +422,7 @@ void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
}
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -432,7 +440,7 @@ status_t OMXCodec::setVideoPortFormatType(
OMX_U32 index = 0;
for (;;) {
format.nIndex = index;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
@@ -477,8 +485,8 @@ status_t OMXCodec::setVideoPortFormatType(
return UNKNOWN_ERROR;
}
CODEC_LOGI("found a match.");
status_t err = mOMX->set_parameter(
CODEC_LOGV("found a match.");
status_t err = mOMX->setParameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
@@ -521,7 +529,7 @@ void OMXCodec::setVideoInputFormat(
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -533,7 +541,7 @@ void OMXCodec::setVideoInputFormat(
video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -542,7 +550,7 @@ void OMXCodec::setVideoInputFormat(
InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -556,7 +564,7 @@ void OMXCodec::setVideoInputFormat(
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -587,7 +595,7 @@ void OMXCodec::setVideoOutputFormat(
format.nPortIndex = kPortIndexOutput;
format.nIndex = 0;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
CHECK_EQ(err, OK);
@@ -600,7 +608,7 @@ void OMXCodec::setVideoOutputFormat(
|| format.eColorFormat == OMX_COLOR_FormatCbYCrY
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
CHECK_EQ(err, OK);
@@ -613,7 +621,7 @@ void OMXCodec::setVideoOutputFormat(
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -633,7 +641,7 @@ void OMXCodec::setVideoOutputFormat(
video_def->eColorFormat = OMX_COLOR_FormatUnused;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -642,7 +650,7 @@ void OMXCodec::setVideoOutputFormat(
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
@@ -655,7 +663,7 @@ void OMXCodec::setVideoOutputFormat(
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -683,9 +691,6 @@ OMXCodec::OMXCodec(
mPortStatus[kPortIndexInput] = ENABLED;
mPortStatus[kPortIndexOutput] = ENABLED;
mObserver = new OMXCodecObserver(this);
mOMX->observe_node(mNode, mObserver);
setComponentRole();
}
@@ -743,7 +748,7 @@ void OMXCodec::setComponentRole(
roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
status_t err = omx->set_parameter(
status_t err = omx->setParameter(
node, OMX_IndexParamStandardComponentRole,
&roleParams, sizeof(roleParams));
@@ -760,10 +765,7 @@ void OMXCodec::setComponentRole() {
OMXCodec::~OMXCodec() {
CHECK(mState == LOADED || mState == ERROR);
status_t err = mOMX->observe_node(mNode, NULL);
CHECK_EQ(err, OK);
err = mOMX->free_node(mNode);
status_t err = mOMX->freeNode(mNode);
CHECK_EQ(err, OK);
mNode = NULL;
@@ -785,7 +787,7 @@ status_t OMXCodec::init() {
status_t err;
if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
CHECK_EQ(err, OK);
setState(LOADED_TO_IDLE);
}
@@ -794,7 +796,7 @@ status_t OMXCodec::init() {
CHECK_EQ(err, OK);
if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
CHECK_EQ(err, OK);
setState(LOADED_TO_IDLE);
@@ -831,7 +833,7 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
InitOMXParams(&def);
def.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err != OK) {
@@ -848,14 +850,14 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
IOMX::buffer_id buffer;
if (portIndex == kPortIndexInput
&& (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
err = mOMX->allocate_buffer_with_backup(
err = mOMX->allocateBufferWithBackup(
mNode, portIndex, mem, &buffer);
} else if (portIndex == kPortIndexOutput
&& (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
err = mOMX->allocate_buffer_with_backup(
err = mOMX->allocateBufferWithBackup(
mNode, portIndex, mem, &buffer);
} else {
err = mOMX->use_buffer(mNode, portIndex, mem, &buffer);
err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
}
if (err != OK) {
@@ -922,7 +924,7 @@ void OMXCodec::on_message(const omx_message &msg) {
CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
status_t err =
mOMX->free_buffer(mNode, kPortIndexInput, buffer);
mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
CHECK_EQ(err, OK);
buffers->removeAt(i);
@@ -968,7 +970,7 @@ void OMXCodec::on_message(const omx_message &msg) {
CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
status_t err =
mOMX->free_buffer(mNode, kPortIndexOutput, buffer);
mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
CHECK_EQ(err, OK);
buffers->removeAt(i);
@@ -1138,7 +1140,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
status_t err =
mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
CHECK_EQ(err, OK);
}
} else {
@@ -1178,7 +1180,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) {
{
CODEC_LOGV("Now Idle.");
if (mState == LOADED_TO_IDLE) {
status_t err = mOMX->send_command(
status_t err = mOMX->sendCommand(
mNode, OMX_CommandStateSet, OMX_StateExecuting);
CHECK_EQ(err, OK);
@@ -1195,7 +1197,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) {
countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
mPortBuffers[kPortIndexOutput].size());
status_t err = mOMX->send_command(
status_t err = mOMX->sendCommand(
mNode, OMX_CommandStateSet, OMX_StateLoaded);
CHECK_EQ(err, OK);
@@ -1278,7 +1280,7 @@ status_t OMXCodec::freeBuffersOnPort(
CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
status_t err =
mOMX->free_buffer(mNode, portIndex, info->mBuffer);
mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
if (err != OK) {
stickyErr = err;
@@ -1338,7 +1340,7 @@ bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
}
status_t err =
mOMX->send_command(mNode, OMX_CommandFlush, portIndex);
mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
CHECK_EQ(err, OK);
return true;
@@ -1351,7 +1353,7 @@ void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
mPortStatus[portIndex] = DISABLING;
status_t err =
mOMX->send_command(mNode, OMX_CommandPortDisable, portIndex);
mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
CHECK_EQ(err, OK);
freeBuffersOnPort(portIndex, true);
@@ -1364,7 +1366,7 @@ void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
mPortStatus[portIndex] = ENABLING;
status_t err =
mOMX->send_command(mNode, OMX_CommandPortEnable, portIndex);
mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
CHECK_EQ(err, OK);
}
@@ -1416,10 +1418,11 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
}
mOMX->empty_buffer(
status_t err = mOMX->emptyBuffer(
mNode, info->mBuffer, 0, size,
OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
0);
CHECK_EQ(err, OK);
info->mOwnedByComponent = true;
@@ -1472,16 +1475,21 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
}
}
mOMX->empty_buffer(
mNode, info->mBuffer, 0, srcLength,
flags, timestamp);
info->mOwnedByComponent = true;
if (srcBuffer != NULL) {
srcBuffer->release();
srcBuffer = NULL;
}
err = mOMX->emptyBuffer(
mNode, info->mBuffer, 0, srcLength,
flags, timestamp);
if (err != OK) {
setState(ERROR);
return;
}
info->mOwnedByComponent = true;
}
void OMXCodec::fillOutputBuffer(BufferInfo *info) {
@@ -1494,7 +1502,8 @@ void OMXCodec::fillOutputBuffer(BufferInfo *info) {
}
CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
mOMX->fill_buffer(mNode, info->mBuffer);
status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
CHECK_EQ(err, OK);
info->mOwnedByComponent = true;
}
@@ -1538,7 +1547,7 @@ void OMXCodec::setRawAudioFormat(
InitOMXParams(&pcmParams);
pcmParams.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
CHECK_EQ(err, OK);
@@ -1559,7 +1568,7 @@ void OMXCodec::setRawAudioFormat(
pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
}
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
CHECK_EQ(err, OK);
@@ -1572,14 +1581,14 @@ void OMXCodec::setAMRFormat() {
def.nPortIndex = kPortIndexInput;
status_t err =
mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
CHECK_EQ(err, OK);
def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -1603,14 +1612,14 @@ void OMXCodec::setAMRWBFormat() {
def.nPortIndex = kPortIndexInput;
status_t err =
mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
CHECK_EQ(err, OK);
def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -1635,7 +1644,7 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
InitOMXParams(&profile);
profile.nPortIndex = kPortIndexInput;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
@@ -1643,7 +1652,7 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
profile.nSampleRate = sampleRate;
profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
}
@@ -1667,7 +1676,7 @@ void OMXCodec::setImageOutputFormat(
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -1716,7 +1725,7 @@ void OMXCodec::setImageOutputFormat(
def.nBufferCountActual = def.nBufferCountMin;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -1727,7 +1736,7 @@ void OMXCodec::setJPEGInputFormat(
InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -1741,7 +1750,7 @@ void OMXCodec::setJPEGInputFormat(
def.nBufferSize = compressedSize;
def.nBufferCountActual = def.nBufferCountMin;
err = mOMX->set_parameter(
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
}
@@ -1831,7 +1840,7 @@ status_t OMXCodec::stop() {
mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
status_t err =
mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
CHECK_EQ(err, OK);
}
@@ -1868,9 +1877,24 @@ status_t OMXCodec::read(
return UNKNOWN_ERROR;
}
bool seeking = false;
int64_t seekTimeUs;
if (options && options->getSeekTo(&seekTimeUs)) {
seeking = true;
}
if (mInitialBufferSubmit) {
mInitialBufferSubmit = false;
if (seeking) {
CHECK(seekTimeUs >= 0);
mSeekTimeUs = seekTimeUs;
// There's no reason to trigger the code below, there's
// nothing to flush yet.
seeking = false;
}
drainInputBuffers();
if (mState == EXECUTING) {
@@ -1880,8 +1904,7 @@ status_t OMXCodec::read(
}
}
int64_t seekTimeUs;
if (options && options->getSeekTo(&seekTimeUs)) {
if (seeking) {
CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
mSignalledEOS = false;
@@ -2163,7 +2186,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
InitOMXParams(&def);
def.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -2229,7 +2252,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
InitOMXParams(&params);
params.nPortIndex = portIndex;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
CHECK_EQ(err, OK);
@@ -2248,7 +2271,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
InitOMXParams(&amr);
amr.nPortIndex = portIndex;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
CHECK_EQ(err, OK);
@@ -2280,7 +2303,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
status_t err = mOMX->get_parameter(
status_t err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -2306,7 +2329,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
InitOMXParams(&params);
params.nPortIndex = kPortIndexOutput;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
CHECK_EQ(err, OK);
@@ -2338,7 +2361,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
InitOMXParams(&amr);
amr.nPortIndex = kPortIndexOutput;
err = mOMX->get_parameter(
err = mOMX->getParameter(
mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
CHECK_EQ(err, OK);
@@ -2435,8 +2458,9 @@ status_t QueryCodecs(
return OK;
}
sp<OMXCodecObserver> observer = new OMXCodecObserver;
IOMX::node_id node;
status_t err = omx->allocate_node(componentName, &node);
status_t err = omx->allocateNode(componentName, observer, &node);
if (err != OK) {
continue;
@@ -2454,7 +2478,7 @@ status_t QueryCodecs(
param.nPortIndex = queryDecoders ? 0 : 1;
for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
err = omx->get_parameter(
err = omx->getParameter(
node, OMX_IndexParamVideoProfileLevelQuerySupported,
&param, sizeof(param));
@@ -2469,7 +2493,7 @@ status_t QueryCodecs(
caps->mProfileLevels.push(profileLevel);
}
CHECK_EQ(omx->free_node(node), OK);
CHECK_EQ(omx->freeNode(node), OK);
}
}

View File

@@ -23,7 +23,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/ShoutcastSource.h>
#include <media/stagefright/string.h>
#include <media/stagefright/stagefright_string.h>
namespace android {

View File

@@ -19,66 +19,67 @@
#include <media/IOMX.h>
#include <utils/threads.h>
#include <utils/KeyedVector.h>
namespace android {
class NodeMeta;
class OMXNodeInstance;
class OMX : public BnOMX {
class OMX : public BnOMX,
public IBinder::DeathRecipient {
public:
OMX();
virtual status_t list_nodes(List<String8> *list);
virtual status_t listNodes(List<String8> *list);
virtual status_t allocate_node(const char *name, node_id *node);
virtual status_t free_node(node_id node);
virtual status_t allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node);
virtual status_t send_command(
virtual status_t freeNode(node_id node);
virtual status_t sendCommand(
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param);
virtual status_t get_parameter(
virtual status_t getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size);
virtual status_t set_parameter(
virtual status_t setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size);
virtual status_t get_config(
virtual status_t getConfig(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size);
virtual status_t set_config(
virtual status_t setConfig(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size);
virtual status_t use_buffer(
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer);
virtual status_t allocate_buffer(
virtual status_t allocateBuffer(
node_id node, OMX_U32 port_index, size_t size,
buffer_id *buffer);
virtual status_t allocate_buffer_with_backup(
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer);
virtual status_t free_buffer(
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer);
virtual status_t observe_node(
node_id node, const sp<IOMXObserver> &observer);
virtual status_t fillBuffer(node_id node, buffer_id buffer);
virtual void fill_buffer(node_id node, buffer_id buffer);
virtual void empty_buffer(
virtual status_t emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp);
virtual status_t get_extension_index(
virtual status_t getExtensionIndex(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index);
@@ -90,44 +91,38 @@ public:
size_t encodedWidth, size_t encodedHeight,
size_t displayWidth, size_t displayHeight);
private:
static OMX_CALLBACKTYPE kCallbacks;
virtual void binderDied(const wp<IBinder> &the_late_who);
OMX_ERRORTYPE OnEvent(
node_id node,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
OMX_ERRORTYPE OnEmptyBufferDone(
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
OMX_ERRORTYPE OnFillBufferDone(
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
void invalidateNodeID(node_id node);
private:
Mutex mLock;
struct CallbackDispatcher;
sp<CallbackDispatcher> mDispatcher;
static OMX_ERRORTYPE OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
int32_t mNodeCounter;
static OMX_ERRORTYPE OnEmptyBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
KeyedVector<node_id, OMXNodeInstance *> mNodeIDToInstance;
static OMX_ERRORTYPE OnFillBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
node_id makeNodeID(OMXNodeInstance *instance);
OMXNodeInstance *findInstance(node_id node);
OMX_ERRORTYPE OnEvent(
NodeMeta *meta,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
OMX_ERRORTYPE OnEmptyBufferDone(
NodeMeta *meta, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
OMX_ERRORTYPE OnFillBufferDone(
NodeMeta *meta, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
void invalidateNodeID_l(node_id node);
OMX(const OMX &);
OMX &operator=(const OMX &);

View File

@@ -0,0 +1,125 @@
/*
* 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_NODE_INSTANCE_H_
#define OMX_NODE_INSTANCE_H_
#include "OMX.h"
#include <utils/RefBase.h>
#include <utils/threads.h>
namespace android {
class IOMXObserver;
struct OMXNodeInstance {
OMXNodeInstance(
OMX *owner, const sp<IOMXObserver> &observer);
void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle);
OMX *owner();
sp<IOMXObserver> observer();
OMX::node_id nodeID();
status_t freeNode();
status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
status_t getParameter(OMX_INDEXTYPE index, void *params, size_t size);
status_t setParameter(
OMX_INDEXTYPE index, const void *params, size_t size);
status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size);
status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
status_t useBuffer(
OMX_U32 portIndex, const sp<IMemory> &params,
OMX::buffer_id *buffer);
status_t allocateBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer);
status_t allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> &params,
OMX::buffer_id *buffer);
status_t freeBuffer(OMX_U32 portIndex, OMX::buffer_id buffer);
status_t fillBuffer(OMX::buffer_id buffer);
status_t emptyBuffer(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
OMX_U32 flags, OMX_TICKS timestamp);
status_t getExtensionIndex(
const char *parameterName, OMX_INDEXTYPE *index);
void onMessage(const omx_message &msg);
void onObserverDied();
void onGetHandleFailed();
static OMX_CALLBACKTYPE kCallbacks;
private:
Mutex mLock;
OMX *mOwner;
OMX::node_id mNodeID;
OMX_HANDLETYPE mHandle;
sp<IOMXObserver> mObserver;
struct ActiveBuffer {
OMX_U32 mPortIndex;
OMX::buffer_id mID;
};
Vector<ActiveBuffer> mActiveBuffers;
~OMXNodeInstance();
void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void removeActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void freeActiveBuffers();
static OMX_ERRORTYPE OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData);
static OMX_ERRORTYPE OnEmptyBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
static OMX_ERRORTYPE OnFillBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
OMXNodeInstance(const OMXNodeInstance &);
OMXNodeInstance &operator=(const OMXNodeInstance &);
};
} // namespace android
#endif // OMX_NODE_INSTANCE_H_

View File

@@ -11,6 +11,7 @@ LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
LOCAL_SRC_FILES:= \
OMX.cpp \
OMXNodeInstance.cpp \
QComHardwareRenderer.cpp \
SoftwareRenderer.cpp \
TIHardwareRenderer.cpp

View File

@@ -18,13 +18,13 @@
#define LOG_TAG "OMX"
#include <utils/Log.h>
#include <sys/socket.h>
#include "OMX.h"
#include "../include/OMX.h"
#include "OMXRenderer.h"
#include "pv_omxcore.h"
#include "../include/OMXNodeInstance.h"
#include <binder/IMemory.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/QComHardwareRenderer.h>
@@ -36,47 +36,10 @@
namespace android {
class NodeMeta {
public:
NodeMeta(OMX *owner)
: mOwner(owner),
mHandle(NULL) {
}
OMX *owner() const {
return mOwner;
}
void setHandle(OMX_HANDLETYPE handle) {
CHECK_EQ(mHandle, NULL);
mHandle = handle;
}
OMX_HANDLETYPE handle() const {
return mHandle;
}
void setObserver(const sp<IOMXObserver> &observer) {
mObserver = observer;
}
sp<IOMXObserver> observer() {
return mObserver;
}
private:
OMX *mOwner;
OMX_HANDLETYPE mHandle;
sp<IOMXObserver> mObserver;
NodeMeta(const NodeMeta &);
NodeMeta &operator=(const NodeMeta &);
};
////////////////////////////////////////////////////////////////////////////////
struct OMX::CallbackDispatcher : public RefBase {
CallbackDispatcher();
CallbackDispatcher(OMX *owner);
void post(const omx_message &msg);
@@ -85,6 +48,8 @@ protected:
private:
Mutex mLock;
OMX *mOwner;
bool mDone;
Condition mQueueChanged;
List<omx_message> mQueue;
@@ -100,8 +65,9 @@ private:
CallbackDispatcher &operator=(const CallbackDispatcher &);
};
OMX::CallbackDispatcher::CallbackDispatcher()
: mDone(false) {
OMX::CallbackDispatcher::CallbackDispatcher(OMX *owner)
: mOwner(owner),
mDone(false) {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
@@ -130,12 +96,12 @@ void OMX::CallbackDispatcher::post(const omx_message &msg) {
}
void OMX::CallbackDispatcher::dispatch(const omx_message &msg) {
NodeMeta *meta = static_cast<NodeMeta *>(msg.node);
sp<IOMXObserver> observer = meta->observer();
if (observer.get() != NULL) {
observer->on_message(msg);
OMXNodeInstance *instance = mOwner->findInstance(msg.node);
if (instance == NULL) {
LOGV("Would have dispatched a message to a node that's already gone.");
return;
}
instance->onMessage(msg);
}
// static
@@ -213,46 +179,30 @@ private:
BufferMeta &operator=(const BufferMeta &);
};
// static
OMX_CALLBACKTYPE OMX::kCallbacks = {
&OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
};
// static
OMX_ERRORTYPE OMX::OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData) {
NodeMeta *meta = static_cast<NodeMeta *>(pAppData);
return meta->owner()->OnEvent(meta, eEvent, nData1, nData2, pEventData);
}
// static
OMX_ERRORTYPE OMX::OnEmptyBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
NodeMeta *meta = static_cast<NodeMeta *>(pAppData);
return meta->owner()->OnEmptyBufferDone(meta, pBuffer);
}
// static
OMX_ERRORTYPE OMX::OnFillBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
NodeMeta *meta = static_cast<NodeMeta *>(pAppData);
return meta->owner()->OnFillBufferDone(meta, pBuffer);
}
OMX::OMX()
: mDispatcher(new CallbackDispatcher) {
: mDispatcher(new CallbackDispatcher(this)),
mNodeCounter(0) {
}
status_t OMX::list_nodes(List<String8> *list) {
void OMX::binderDied(const wp<IBinder> &the_late_who) {
OMXNodeInstance *instance;
{
Mutex::Autolock autoLock(mLock);
ssize_t index = mLiveNodes.indexOfKey(the_late_who);
CHECK(index >= 0);
instance = mLiveNodes.editValueAt(index);
mLiveNodes.removeItemsAt(index);
invalidateNodeID_l(instance->nodeID());
}
instance->onObserverDied();
}
status_t OMX::listNodes(List<String8> *list) {
OMX_MasterInit(); // XXX Put this somewhere else.
list->clear();
@@ -269,204 +219,132 @@ status_t OMX::list_nodes(List<String8> *list) {
return OK;
}
status_t OMX::allocate_node(const char *name, node_id *node) {
status_t OMX::allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node) {
Mutex::Autolock autoLock(mLock);
*node = 0;
OMX_MasterInit(); // XXX Put this somewhere else.
NodeMeta *meta = new NodeMeta(this);
OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
OMX_HANDLETYPE handle;
OMX_ERRORTYPE err = OMX_MasterGetHandle(
&handle, const_cast<char *>(name), meta, &kCallbacks);
&handle, const_cast<char *>(name), instance,
&OMXNodeInstance::kCallbacks);
if (err != OMX_ErrorNone) {
LOGE("FAILED to allocate omx component '%s'", name);
delete meta;
meta = NULL;
instance->onGetHandleFailed();
return UNKNOWN_ERROR;
}
meta->setHandle(handle);
*node = makeNodeID(instance);
*node = meta;
instance->setHandle(*node, handle);
mLiveNodes.add(observer->asBinder(), instance);
observer->asBinder()->linkToDeath(this);
return OK;
}
status_t OMX::free_node(node_id node) {
Mutex::Autolock autoLock(mLock);
status_t OMX::freeNode(node_id node) {
OMXNodeInstance *instance = findInstance(node);
NodeMeta *meta = static_cast<NodeMeta *>(node);
ssize_t index = mLiveNodes.indexOfKey(instance->observer()->asBinder());
CHECK(index >= 0);
mLiveNodes.removeItemsAt(index);
instance->observer()->asBinder()->unlinkToDeath(this);
OMX_ERRORTYPE err = OMX_MasterFreeHandle(meta->handle());
delete meta;
meta = NULL;
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return instance->freeNode();
}
status_t OMX::send_command(
status_t OMX::sendCommand(
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
Mutex::Autolock autoLock(mLock);
NodeMeta *meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err = OMX_SendCommand(meta->handle(), cmd, param, NULL);
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return findInstance(node)->sendCommand(cmd, param);
}
status_t OMX::get_parameter(
status_t OMX::getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
NodeMeta *meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err = OMX_GetParameter(meta->handle(), index, params);
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return findInstance(node)->getParameter(
index, params, size);
}
status_t OMX::set_parameter(
status_t OMX::setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
NodeMeta *meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_SetParameter(meta->handle(), index, const_cast<void *>(params));
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return findInstance(node)->setParameter(
index, params, size);
}
status_t OMX::get_config(
status_t OMX::getConfig(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
NodeMeta *meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err = OMX_GetConfig(meta->handle(), index, params);
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return findInstance(node)->getConfig(
index, params, size);
}
status_t OMX::set_config(
status_t OMX::setConfig(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
NodeMeta *meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_SetConfig(meta->handle(), index, const_cast<void *>(params));
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
return findInstance(node)->setConfig(
index, params, size);
}
status_t OMX::use_buffer(
status_t OMX::useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(this, params);
OMX_BUFFERHEADERTYPE *header;
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_UseBuffer(node_meta->handle(), &header, port_index, buffer_meta,
params->size(), static_cast<OMX_U8 *>(params->pointer()));
if (err != OMX_ErrorNone) {
LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
return OK;
return findInstance(node)->useBuffer(
port_index, params, buffer);
}
status_t OMX::allocate_buffer(
status_t OMX::allocateBuffer(
node_id node, OMX_U32 port_index, size_t size,
buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(this, size);
OMX_BUFFERHEADERTYPE *header;
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_AllocateBuffer(node_meta->handle(), &header, port_index,
buffer_meta, size);
if (err != OMX_ErrorNone) {
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
return OK;
return findInstance(node)->allocateBuffer(
port_index, size, buffer);
}
status_t OMX::allocate_buffer_with_backup(
status_t OMX::allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(this, params, true);
OMX_BUFFERHEADERTYPE *header;
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_AllocateBuffer(
node_meta->handle(), &header, port_index, buffer_meta,
params->size());
if (err != OMX_ErrorNone) {
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
return OK;
return findInstance(node)->allocateBufferWithBackup(
port_index, params, buffer);
}
status_t OMX::free_buffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
return findInstance(node)->freeBuffer(
port_index, buffer);
}
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_FreeBuffer(node_meta->handle(), port_index, header);
status_t OMX::fillBuffer(node_id node, buffer_id buffer) {
return findInstance(node)->fillBuffer(buffer);
}
delete buffer_meta;
buffer_meta = NULL;
status_t OMX::emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp) {
return findInstance(node)->emptyBuffer(
buffer, range_offset, range_length, flags, timestamp);
}
return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK;
status_t OMX::getExtensionIndex(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index) {
return findInstance(node)->getExtensionIndex(
parameter_name, index);
}
OMX_ERRORTYPE OMX::OnEvent(
NodeMeta *meta,
node_id node,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
@@ -475,7 +353,7 @@ OMX_ERRORTYPE OMX::OnEvent(
omx_message msg;
msg.type = omx_message::EVENT;
msg.node = meta;
msg.node = node;
msg.u.event_data.event = eEvent;
msg.u.event_data.data1 = nData1;
msg.u.event_data.data2 = nData2;
@@ -484,14 +362,14 @@ OMX_ERRORTYPE OMX::OnEvent(
return OMX_ErrorNone;
}
OMX_ERRORTYPE OMX::OnEmptyBufferDone(
NodeMeta *meta, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
LOGV("OnEmptyBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::EMPTY_BUFFER_DONE;
msg.node = meta;
msg.node = node;
msg.u.buffer_data.buffer = pBuffer;
mDispatcher->post(msg);
@@ -500,14 +378,12 @@ OMX_ERRORTYPE OMX::OnEmptyBufferDone(
}
OMX_ERRORTYPE OMX::OnFillBufferDone(
NodeMeta *meta, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
LOGV("OnFillBufferDone buffer=%p", pBuffer);
BufferMeta *buffer_meta = static_cast<BufferMeta *>(pBuffer->pAppPrivate);
buffer_meta->CopyFromOMX(pBuffer);
omx_message msg;
msg.type = omx_message::FILL_BUFFER_DONE;
msg.node = meta;
msg.node = node;
msg.u.extended_buffer_data.buffer = pBuffer;
msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
@@ -520,62 +396,31 @@ OMX_ERRORTYPE OMX::OnFillBufferDone(
return OMX_ErrorNone;
}
status_t OMX::observe_node(
node_id node, const sp<IOMXObserver> &observer) {
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX::node_id OMX::makeNodeID(OMXNodeInstance *instance) {
// mLock is already held.
node_meta->setObserver(observer);
node_id node = (node_id)++mNodeCounter;
mNodeIDToInstance.add(node, instance);
return OK;
return node;
}
void OMX::fill_buffer(node_id node, buffer_id buffer) {
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
header->nFilledLen = 0;
header->nOffset = 0;
header->nFlags = 0;
OMXNodeInstance *OMX::findInstance(node_id node) {
Mutex::Autolock autoLock(mLock);
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
ssize_t index = mNodeIDToInstance.indexOfKey(node);
OMX_ERRORTYPE err =
OMX_FillThisBuffer(node_meta->handle(), header);
CHECK_EQ(err, OMX_ErrorNone);
return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);
}
void OMX::empty_buffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp) {
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
header->nFilledLen = range_length;
header->nOffset = range_offset;
header->nFlags = flags;
header->nTimeStamp = timestamp;
BufferMeta *buffer_meta =
static_cast<BufferMeta *>(header->pAppPrivate);
buffer_meta->CopyToOMX(header);
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_EmptyThisBuffer(node_meta->handle(), header);
CHECK_EQ(err, OMX_ErrorNone);
void OMX::invalidateNodeID(node_id node) {
Mutex::Autolock autoLock(mLock);
invalidateNodeID_l(node);
}
status_t OMX::get_extension_index(
node_id node,
const char *parameter_name,
OMX_INDEXTYPE *index) {
NodeMeta *node_meta = static_cast<NodeMeta *>(node);
OMX_ERRORTYPE err =
OMX_GetExtensionIndex(
node_meta->handle(),
const_cast<char *>(parameter_name), index);
return err == OMX_ErrorNone ? OK : UNKNOWN_ERROR;
void OMX::invalidateNodeID_l(node_id node) {
// mLock is held.
mNodeIDToInstance.removeItem(node);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,461 @@
/*
* 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.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXNodeInstance"
#include <utils/Log.h>
#include "../include/OMXNodeInstance.h"
#include "pv_omxcore.h"
#include <binder/IMemory.h>
#include <media/stagefright/MediaDebug.h>
namespace android {
struct BufferMeta {
BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
: mMem(mem),
mIsBackup(is_backup) {
}
BufferMeta(size_t size)
: mSize(size),
mIsBackup(false) {
}
void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
if (!mIsBackup) {
return;
}
memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
header->pBuffer + header->nOffset,
header->nFilledLen);
}
void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
if (!mIsBackup) {
return;
}
memcpy(header->pBuffer + header->nOffset,
(const OMX_U8 *)mMem->pointer() + header->nOffset,
header->nFilledLen);
}
private:
sp<IMemory> mMem;
size_t mSize;
bool mIsBackup;
BufferMeta(const BufferMeta &);
BufferMeta &operator=(const BufferMeta &);
};
// static
OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
&OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
};
OMXNodeInstance::OMXNodeInstance(
OMX *owner, const sp<IOMXObserver> &observer)
: mOwner(owner),
mNodeID(NULL),
mHandle(NULL),
mObserver(observer) {
}
OMXNodeInstance::~OMXNodeInstance() {
CHECK_EQ(mHandle, NULL);
}
void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
CHECK_EQ(mHandle, NULL);
mNodeID = node_id;
mHandle = handle;
}
OMX *OMXNodeInstance::owner() {
return mOwner;
}
sp<IOMXObserver> OMXNodeInstance::observer() {
return mObserver;
}
OMX::node_id OMXNodeInstance::nodeID() {
return mNodeID;
}
static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
return (err == OMX_ErrorNone) ? OK : UNKNOWN_ERROR;
}
status_t OMXNodeInstance::freeNode() {
// Transition the node from its current state all the way down
// to "Loaded".
// This ensures that all active buffers are properly freed even
// for components that don't do this themselves on a call to
// "FreeHandle".
OMX_STATETYPE state;
CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
switch (state) {
case OMX_StateExecuting:
{
LOGV("forcing Executing->Idle");
sendCommand(OMX_CommandStateSet, OMX_StateIdle);
OMX_ERRORTYPE err;
while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
&& state != OMX_StateIdle) {
usleep(100000);
}
CHECK_EQ(err, OMX_ErrorNone);
// fall through
}
case OMX_StateIdle:
{
LOGV("forcing Idle->Loaded");
sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
freeActiveBuffers();
OMX_ERRORTYPE err;
while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
&& state != OMX_StateLoaded) {
LOGV("waiting for Loaded state...");
usleep(100000);
}
CHECK_EQ(err, OMX_ErrorNone);
// fall through
}
case OMX_StateLoaded:
case OMX_StateInvalid:
break;
default:
CHECK(!"should not be here, unknown state.");
break;
}
OMX_ERRORTYPE err = OMX_MasterFreeHandle(mHandle);
mHandle = NULL;
if (err != OMX_ErrorNone) {
LOGE("FreeHandle FAILED with error 0x%08x.", err);
}
mOwner->invalidateNodeID(mNodeID);
mNodeID = NULL;
LOGV("OMXNodeInstance going away.");
delete this;
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::sendCommand(
OMX_COMMANDTYPE cmd, OMX_S32 param) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::getParameter(
OMX_INDEXTYPE index, void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::setParameter(
OMX_INDEXTYPE index, const void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetParameter(
mHandle, index, const_cast<void *>(params));
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::getConfig(
OMX_INDEXTYPE index, void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::setConfig(
OMX_INDEXTYPE index, const void *params, size_t size) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetConfig(
mHandle, index, const_cast<void *>(params));
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::useBuffer(
OMX_U32 portIndex, const sp<IMemory> &params,
OMX::buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(params);
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_UseBuffer(
mHandle, &header, portIndex, buffer_meta,
params->size(), static_cast<OMX_U8 *>(params->pointer()));
if (err != OMX_ErrorNone) {
LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
addActiveBuffer(portIndex, *buffer);
return OK;
}
status_t OMXNodeInstance::allocateBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(size);
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_AllocateBuffer(
mHandle, &header, portIndex, buffer_meta, size);
if (err != OMX_ErrorNone) {
LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
addActiveBuffer(portIndex, *buffer);
return OK;
}
status_t OMXNodeInstance::allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> &params,
OMX::buffer_id *buffer) {
Mutex::Autolock autoLock(mLock);
BufferMeta *buffer_meta = new BufferMeta(params, true);
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_AllocateBuffer(
mHandle, &header, portIndex, buffer_meta, params->size());
if (err != OMX_ErrorNone) {
LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
delete buffer_meta;
buffer_meta = NULL;
*buffer = 0;
return UNKNOWN_ERROR;
}
*buffer = header;
addActiveBuffer(portIndex, *buffer);
return OK;
}
status_t OMXNodeInstance::freeBuffer(
OMX_U32 portIndex, OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
removeActiveBuffer(portIndex, buffer);
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
delete buffer_meta;
buffer_meta = NULL;
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
header->nFilledLen = 0;
header->nOffset = 0;
header->nFlags = 0;
OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::emptyBuffer(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
OMX_U32 flags, OMX_TICKS timestamp) {
Mutex::Autolock autoLock(mLock);
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
header->nFilledLen = rangeLength;
header->nOffset = rangeOffset;
header->nFlags = flags;
header->nTimeStamp = timestamp;
BufferMeta *buffer_meta =
static_cast<BufferMeta *>(header->pAppPrivate);
buffer_meta->CopyToOMX(header);
OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::getExtensionIndex(
const char *parameterName, OMX_INDEXTYPE *index) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetExtensionIndex(
mHandle, const_cast<char *>(parameterName), index);
return StatusFromOMXError(err);
}
void OMXNodeInstance::onMessage(const omx_message &msg) {
if (msg.type == omx_message::FILL_BUFFER_DONE) {
OMX_BUFFERHEADERTYPE *buffer =
static_cast<OMX_BUFFERHEADERTYPE *>(
msg.u.extended_buffer_data.buffer);
BufferMeta *buffer_meta =
static_cast<BufferMeta *>(buffer->pAppPrivate);
buffer_meta->CopyFromOMX(buffer);
}
mObserver->onMessage(msg);
}
void OMXNodeInstance::onObserverDied() {
LOGE("!!! Observer died. Quickly, do something, ... anything...");
// Try to force shutdown of the node and hope for the best.
freeNode();
}
void OMXNodeInstance::onGetHandleFailed() {
delete this;
}
// static
OMX_ERRORTYPE OMXNodeInstance::OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
return instance->owner()->OnEvent(
instance->nodeID(), eEvent, nData1, nData2, pEventData);
}
// static
OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
}
// static
OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
}
void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
ActiveBuffer active;
active.mPortIndex = portIndex;
active.mID = id;
mActiveBuffers.push(active);
}
void OMXNodeInstance::removeActiveBuffer(
OMX_U32 portIndex, OMX::buffer_id id) {
bool found = false;
for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
if (mActiveBuffers[i].mPortIndex == portIndex
&& mActiveBuffers[i].mID == id) {
found = true;
mActiveBuffers.removeItemsAt(i);
break;
}
}
if (!found) {
LOGW("Attempt to remove an active buffer we know nothing about...");
}
}
void OMXNodeInstance::freeActiveBuffers() {
// Make sure to count down here, as freeBuffer will in turn remove
// the active buffer from the vector...
for (size_t i = mActiveBuffers.size(); i--;) {
freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
}
}
} // namespace android

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include <media/stagefright/string.h>
#include <media/stagefright/stagefright_string.h>
namespace android {