Commit 73bd473e authored by Thomas Guillem's avatar Thomas Guillem

codec: remove iomx support (android)

The API is private and we are not allowed to use it on recent devices (and
MediaCodec support is far more advanced).
parent eaefcb7d
......@@ -12,6 +12,7 @@ Platform support changes:
Codecs:
* Support for experimental AV1 video encoding
* WebVTT encoder
* Remove iomx support for Android
Video ouput:
* Remove aa plugin
......
......@@ -204,7 +204,6 @@ $Id$
* inflate: zlib decompression stream_filter module
* integer_mixer: Integer audio mixer
* invert: inverse video filter
* iomx: IPC/OpenMaxIL for Android
* jack: jack server audio output
* jpeg: JPEG image decoder
* kai: OS/2 audio output
......
......@@ -478,10 +478,6 @@ libomxil_plugin_la_SOURCES = \
packetizer/hevc_nal.c packetizer/hevc_nal.h \
codec/omxil/qcom.c codec/omxil/qcom.h \
codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h
if HAVE_ANDROID
libomxil_plugin_la_SOURCES += video_output/android/utils.c video_output/android/utils.h \
video_output/android/display.h
endif
libomxil_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil)
libomxil_plugin_la_LIBADD = libchroma_copy.la $(LIBDL)
libomxil_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
......@@ -491,10 +487,6 @@ libomxil_vout_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLA
libomxil_vout_plugin_la_LIBADD = libchroma_copy.la $(LIBDL)
libomxil_vout_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
libiomx_plugin_la_SOURCES = $(libomxil_plugin_la_SOURCES)
libiomx_plugin_la_CPPFLAGS = $(libomxil_plugin_la_CPPFLAGS) -DUSE_IOMX
libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil
libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacodec.h \
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c \
......@@ -508,7 +500,7 @@ libmediacodec_plugin_la_LIBADD = libchroma_copy.la
codec_LTLIBRARIES += $(LTLIBomxil) $(LTLIBomxil_vout)
EXTRA_LTLIBRARIES += libomxil_plugin.la libomxil_vout_plugin.la
if HAVE_ANDROID
codec_LTLIBRARIES += libiomx_plugin.la libmediacodec_plugin.la
codec_LTLIBRARIES += libmediacodec_plugin.la
endif
......
/*****************************************************************************
* iomx.cpp: OpenMAX interface implementation based on IOMX
*****************************************************************************
* Copyright (C) 2011 VLC authors and VideoLAN
*
* Authors: Martin Storsjo <martin@martin.st>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <media/stagefright/OMXClient.h>
#include <media/IOMX.h>
#include <binder/MemoryDealer.h>
#include <OMX_Component.h>
#define PREFIX(x) I ## x
#if ANDROID_API >= 11
#define HAS_USE_BUFFER
#endif
using namespace android;
class IOMXContext {
public:
IOMXContext() {
}
sp<IOMX> iomx;
List<IOMX::ComponentInfo> components;
};
static IOMXContext *ctx;
class OMXNode;
class OMXCodecObserver : public BnOMXObserver {
public:
OMXCodecObserver() {
node = NULL;
}
void setNode(OMXNode* n) {
node = n;
}
void onMessage(const omx_message &msg);
void registerBuffers(const sp<IMemoryHeap> &) {
}
private:
OMXNode *node;
};
class OMXNode {
public:
IOMX::node_id node;
sp<OMXCodecObserver> observer;
OMX_CALLBACKTYPE callbacks;
OMX_PTR app_data;
OMX_STATETYPE state;
List<OMX_BUFFERHEADERTYPE*> buffers;
OMX_HANDLETYPE handle;
String8 component_name;
};
class OMXBuffer {
public:
sp<MemoryDealer> dealer;
#ifdef HAS_USE_BUFFER
sp<GraphicBuffer> graphicBuffer;
#endif
IOMX::buffer_id id;
};
void OMXCodecObserver::onMessage(const omx_message &msg)
{
if (!node)
return;
switch (msg.type) {
case omx_message::EVENT:
// TODO: Needs locking
if (msg.u.event_data.event == OMX_EventCmdComplete && msg.u.event_data.data1 == OMX_CommandStateSet)
node->state = (OMX_STATETYPE) msg.u.event_data.data2;
node->callbacks.EventHandler(node->handle, node->app_data, msg.u.event_data.event, msg.u.event_data.data1, msg.u.event_data.data2, NULL);
break;
case omx_message::EMPTY_BUFFER_DONE:
for( List<OMX_BUFFERHEADERTYPE*>::iterator it = node->buffers.begin(); it != node->buffers.end(); ++it ) {
OMXBuffer* info = (OMXBuffer*) (*it)->pPlatformPrivate;
if (msg.u.buffer_data.buffer == info->id) {
node->callbacks.EmptyBufferDone(node->handle, node->app_data, *it);
break;
}
}
break;
case omx_message::FILL_BUFFER_DONE:
for( List<OMX_BUFFERHEADERTYPE*>::iterator it = node->buffers.begin(); it != node->buffers.end(); ++it ) {
OMXBuffer* info = (OMXBuffer*) (*it)->pPlatformPrivate;
if (msg.u.extended_buffer_data.buffer == info->id) {
OMX_BUFFERHEADERTYPE *buffer = *it;
buffer->nOffset = msg.u.extended_buffer_data.range_offset;
buffer->nFilledLen = msg.u.extended_buffer_data.range_length;
buffer->nFlags = msg.u.extended_buffer_data.flags;
buffer->nTimeStamp = msg.u.extended_buffer_data.timestamp;
node->callbacks.FillBufferDone(node->handle, node->app_data, buffer);
break;
}
}
break;
default:
break;
}
}
static OMX_ERRORTYPE get_error(status_t err)
{
if (err == OK)
return OMX_ErrorNone;
return OMX_ErrorUndefined;
}
static OMX_ERRORTYPE iomx_send_command(OMX_HANDLETYPE component, OMX_COMMANDTYPE command, OMX_U32 param1, OMX_PTR)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
return get_error(ctx->iomx->sendCommand(node->node, command, param1));
}
static OMX_ERRORTYPE iomx_get_parameter(OMX_HANDLETYPE component, OMX_INDEXTYPE param_index, OMX_PTR param)
{
/*
* Some QCOM OMX_getParameter implementations override the nSize element to
* a bad value. So, save the initial nSize in order to restore it after.
*/
OMX_U32 nSize = *(OMX_U32*)param;
OMX_ERRORTYPE error;
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
error = get_error(ctx->iomx->getParameter(node->node, param_index, param, nSize));
*(OMX_U32*)param = nSize;
return error;
}
static OMX_ERRORTYPE iomx_set_parameter(OMX_HANDLETYPE component, OMX_INDEXTYPE param_index, OMX_PTR param)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
return get_error(ctx->iomx->setParameter(node->node, param_index, param, *(OMX_U32*)param));
}
static OMX_ERRORTYPE iomx_get_state(OMX_HANDLETYPE component, OMX_STATETYPE *ptr) {
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
*ptr = node->state;
return OMX_ErrorNone;
}
static OMX_ERRORTYPE iomx_allocate_buffer(OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE **bufferptr, OMX_U32 port_index, OMX_PTR app_private, OMX_U32 size)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
OMXBuffer* info = new OMXBuffer;
#ifdef HAS_USE_BUFFER
info->graphicBuffer = NULL;
#endif
info->dealer = new MemoryDealer(size + 4096); // Do we need to keep this around, or is it kept alive via the IMemory that references it?
sp<IMemory> mem = info->dealer->allocate(size);
int ret = ctx->iomx->allocateBufferWithBackup(node->node, port_index, mem, &info->id);
if (ret != OK)
return OMX_ErrorUndefined;
OMX_BUFFERHEADERTYPE *buffer = (OMX_BUFFERHEADERTYPE*) calloc(1, sizeof(OMX_BUFFERHEADERTYPE));
*bufferptr = buffer;
buffer->pPlatformPrivate = info;
buffer->pAppPrivate = app_private;
buffer->nAllocLen = size;
buffer->pBuffer = (OMX_U8*) mem->pointer();
node->buffers.push_back(buffer);
return OMX_ErrorNone;
}
#ifdef HAS_USE_BUFFER
static OMX_ERRORTYPE iomx_use_buffer(OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE **bufferptr, OMX_U32 port_index, OMX_PTR app_private, OMX_U32 size, OMX_U8* data)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
OMXBuffer* info = new OMXBuffer;
info->dealer = NULL;
#if ANDROID_API <= 13
info->graphicBuffer = new GraphicBuffer((android_native_buffer_t*) data, false);
#else
info->graphicBuffer = new GraphicBuffer((ANativeWindowBuffer*) data, false);
#endif
int ret = ctx->iomx->useGraphicBuffer(node->node, port_index, info->graphicBuffer, &info->id);
if (ret != OK)
return OMX_ErrorUndefined;
OMX_BUFFERHEADERTYPE *buffer = (OMX_BUFFERHEADERTYPE*) calloc(1, sizeof(OMX_BUFFERHEADERTYPE));
*bufferptr = buffer;
buffer->pPlatformPrivate = info;
buffer->pAppPrivate = app_private;
buffer->nAllocLen = size;
buffer->pBuffer = data;
node->buffers.push_back(buffer);
return OMX_ErrorNone;
}
#endif
static OMX_ERRORTYPE iomx_free_buffer(OMX_HANDLETYPE component, OMX_U32 port, OMX_BUFFERHEADERTYPE *buffer)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
OMXBuffer* info = (OMXBuffer*) buffer->pPlatformPrivate;
status_t ret = ctx->iomx->freeBuffer(node->node, port, info->id);
for( List<OMX_BUFFERHEADERTYPE*>::iterator it = node->buffers.begin(); it != node->buffers.end(); ++it ) {
if (buffer == *it) {
node->buffers.erase(it);
break;
}
}
free(buffer);
delete info;
return get_error(ret);
}
static OMX_ERRORTYPE iomx_empty_this_buffer(OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE *buffer)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
OMXBuffer* info = (OMXBuffer*) buffer->pPlatformPrivate;
return get_error(ctx->iomx->emptyBuffer(node->node, info->id, buffer->nOffset, buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp));
}
static OMX_ERRORTYPE iomx_fill_this_buffer(OMX_HANDLETYPE component, OMX_BUFFERHEADERTYPE *buffer)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
OMXBuffer* info = (OMXBuffer*) buffer->pPlatformPrivate;
return get_error(ctx->iomx->fillBuffer(node->node, info->id));
}
static OMX_ERRORTYPE iomx_component_role_enum(OMX_HANDLETYPE component, OMX_U8 *role, OMX_U32 index)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
for( List<IOMX::ComponentInfo>::iterator it = ctx->components.begin(); it != ctx->components.end(); ++it ) {
if (node->component_name == it->mName) {
if (index >= it->mRoles.size())
return OMX_ErrorNoMore;
List<String8>::iterator it2 = it->mRoles.begin();
for( OMX_U32 i = 0; it2 != it->mRoles.end() && i < index; i++, ++it2 ) ;
strncpy((char*)role, it2->string(), OMX_MAX_STRINGNAME_SIZE);
if (it2->length() >= OMX_MAX_STRINGNAME_SIZE)
role[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
return OMX_ErrorNone;
}
}
return OMX_ErrorInvalidComponentName;
}
static OMX_ERRORTYPE iomx_get_extension_index(OMX_HANDLETYPE component, OMX_STRING parameter, OMX_INDEXTYPE *index)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
return get_error(ctx->iomx->getExtensionIndex(node->node, parameter, index));
}
static OMX_ERRORTYPE iomx_set_config(OMX_HANDLETYPE component, OMX_INDEXTYPE index, OMX_PTR param)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
return get_error(ctx->iomx->setConfig(node->node, index, param, *(OMX_U32*)param));
}
static OMX_ERRORTYPE iomx_get_config(OMX_HANDLETYPE component, OMX_INDEXTYPE index, OMX_PTR param)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
return get_error(ctx->iomx->getConfig(node->node, index, param, *(OMX_U32*)param));
}
extern "C" {
OMX_ERRORTYPE PREFIX(OMX_GetHandle)(OMX_HANDLETYPE *handle_ptr, OMX_STRING component_name, OMX_PTR app_data, OMX_CALLBACKTYPE *callbacks)
{
OMXNode* node = new OMXNode();
node->app_data = app_data;
node->callbacks = *callbacks;
node->observer = new OMXCodecObserver();
node->observer->setNode(node);
node->state = OMX_StateLoaded;
node->component_name = component_name;
OMX_COMPONENTTYPE* component = (OMX_COMPONENTTYPE*) malloc(sizeof(OMX_COMPONENTTYPE));
memset(component, 0, sizeof(OMX_COMPONENTTYPE));
component->nSize = sizeof(OMX_COMPONENTTYPE);
component->nVersion.s.nVersionMajor = 1;
component->nVersion.s.nVersionMinor = 1;
component->nVersion.s.nRevision = 0;
component->nVersion.s.nStep = 0;
component->pComponentPrivate = node;
component->SendCommand = iomx_send_command;
component->GetParameter = iomx_get_parameter;
component->SetParameter = iomx_set_parameter;
component->FreeBuffer = iomx_free_buffer;
component->EmptyThisBuffer = iomx_empty_this_buffer;
component->FillThisBuffer = iomx_fill_this_buffer;
component->GetState = iomx_get_state;
component->AllocateBuffer = iomx_allocate_buffer;
#ifdef HAS_USE_BUFFER
component->UseBuffer = iomx_use_buffer;
#else
component->UseBuffer = NULL;
#endif
component->ComponentRoleEnum = iomx_component_role_enum;
component->GetExtensionIndex = iomx_get_extension_index;
component->SetConfig = iomx_set_config;
component->GetConfig = iomx_get_config;
*handle_ptr = component;
node->handle = component;
status_t ret;
if ((ret = ctx->iomx->allocateNode( component_name, node->observer, &node->node )) != OK)
return OMX_ErrorUndefined;
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMX_FreeHandle)(OMX_HANDLETYPE handle)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)handle)->pComponentPrivate;
ctx->iomx->freeNode( node->node );
node->observer->setNode(NULL);
delete node;
free(handle);
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMX_Init)(void)
{
OMXClient client;
if (client.connect() != OK)
return OMX_ErrorUndefined;
if (!ctx)
ctx = new IOMXContext();
ctx->iomx = client.interface();
ctx->iomx->listNodes(&ctx->components);
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMX_Deinit)(void)
{
ctx->iomx = NULL;
delete ctx;
ctx = NULL;
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMX_ComponentNameEnum)(OMX_STRING component_name, OMX_U32 name_length, OMX_U32 index)
{
if (index >= ctx->components.size())
return OMX_ErrorNoMore;
List<IOMX::ComponentInfo>::iterator it = ctx->components.begin();
for( OMX_U32 i = 0; i < index; i++ )
++it;
strncpy(component_name, it->mName.string(), name_length);
component_name[name_length - 1] = '\0';
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMX_GetRolesOfComponent)(OMX_STRING component_name, OMX_U32 *num_roles, OMX_U8 **roles)
{
for( List<IOMX::ComponentInfo>::iterator it = ctx->components.begin(); it != ctx->components.end(); ++it ) {
if (!strcmp(component_name, it->mName.string())) {
if (!roles) {
*num_roles = it->mRoles.size();
return OMX_ErrorNone;
}
if (*num_roles < it->mRoles.size())
return OMX_ErrorInsufficientResources;
*num_roles = it->mRoles.size();
OMX_U32 i = 0;
for( List<String8>::iterator it2 = it->mRoles.begin(); it2 != it->mRoles.end(); i++, ++it2 ) {
strncpy((char*)roles[i], it2->string(), OMX_MAX_STRINGNAME_SIZE);
roles[i][OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
}
return OMX_ErrorNone;
}
}
return OMX_ErrorInvalidComponentName;
}
OMX_ERRORTYPE PREFIX(OMX_GetComponentsOfRole)(OMX_STRING role, OMX_U32 *num_comps, OMX_U8 **comp_names)
{
OMX_U32 i = 0;
for( List<IOMX::ComponentInfo>::iterator it = ctx->components.begin(); it != ctx->components.end(); ++it ) {
for( List<String8>::iterator it2 = it->mRoles.begin(); it2 != it->mRoles.end(); ++it2 ) {
if (!strcmp(it2->string(), role)) {
if (comp_names) {
if (*num_comps < i)
return OMX_ErrorInsufficientResources;
strncpy((char*)comp_names[i], it->mName.string(), OMX_MAX_STRINGNAME_SIZE);
comp_names[i][OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
}
i++;
break;
}
}
}
*num_comps = i;
return OMX_ErrorNone;
}
#ifdef HAS_USE_BUFFER
OMX_ERRORTYPE PREFIX(OMXAndroid_EnableGraphicBuffers)(OMX_HANDLETYPE component, OMX_U32 port_index, OMX_BOOL enable)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
int ret = ctx->iomx->enableGraphicBuffers(node->node, port_index, enable);
if (ret != OK)
return OMX_ErrorUndefined;
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMXAndroid_GetGraphicBufferUsage)(OMX_HANDLETYPE component, OMX_U32 port_index, OMX_U32* usage)
{
OMXNode* node = (OMXNode*) ((OMX_COMPONENTTYPE*)component)->pComponentPrivate;
int ret = ctx->iomx->getGraphicBufferUsage(node->node, port_index, usage);
if (ret != OK)
return OMX_ErrorUndefined;
return OMX_ErrorNone;
}
OMX_ERRORTYPE PREFIX(OMXAndroid_GetHalFormat)( const char *comp_name, int* hal_format )
{
if( !strncmp( comp_name, "OMX.SEC.", 8 ) ) {
switch( *hal_format ) {
case OMX_COLOR_FormatYUV420SemiPlanar:
*hal_format = 0x105; // HAL_PIXEL_FORMAT_YCbCr_420_SP
break;
case OMX_COLOR_FormatYUV420Planar:
*hal_format = 0x101; // HAL_PIXEL_FORMAT_YCbCr_420_P
break;
}
}
else if( !strcmp( comp_name, "OMX.TI.720P.Decoder" ) ||
!strcmp( comp_name, "OMX.TI.Video.Decoder" ) )
*hal_format = 0x14; // HAL_PIXEL_FORMAT_YCbCr_422_I
#if ANDROID_API <= 13 // Required on msm8660 on 3.2, not required on 4.1
else if( !strcmp( comp_name, "OMX.qcom.video.decoder.avc" ))
*hal_format = 0x108;
#endif
return OMX_ErrorNone;
}
#endif
}
......@@ -42,12 +42,6 @@
#include "omxil_core.h"
#include "OMX_Broadcom.h"
#if defined(USE_IOMX)
#include <dlfcn.h>
#include <jni.h>
#include "../../video_output/android/display.h"
#endif
#ifndef NDEBUG
# define OMX_DBG(...) msg_Dbg( p_dec, __VA_ARGS__ )
#else
......@@ -64,11 +58,6 @@
/* Defined in the broadcom version of OMX_Core.h */
#define OMX_EventParamOrConfigChanged 0x7F000001
#if defined(USE_IOMX)
/* JNI functions to get/set an Android Surface object. */
#define THREAD_NAME "omxil"
#endif
/*****************************************************************************
* Local prototypes
*****************************************************************************/
......@@ -89,50 +78,6 @@ static OMX_ERRORTYPE OmxEmptyBufferDone( OMX_HANDLETYPE, OMX_PTR,
static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE, OMX_PTR,
OMX_BUFFERHEADERTYPE * );
#if defined(USE_IOMX)
static void *DequeueThread( void *data );
static void ReleasePicture( decoder_t *p_dec, unsigned int i_index, bool b_render );
static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port );
static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_FreeBuffers( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_Join( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port,
picture_t **pp_pic );
static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
OMX_CONFIG_RECTTYPE *p_rect );
static void HwBuffer_ChangeState( decoder_t *p_dec, OmxPort *p_port,
int i_index, int i_state );
#define HWBUFFER_LOCK(p_port) vlc_mutex_lock( &(p_port)->p_hwbuf->lock )
#define HWBUFFER_UNLOCK(p_port) vlc_mutex_unlock( &(p_port)->p_hwbuf->lock )
#define HWBUFFER_WAIT(p_port) vlc_cond_wait( &(p_port)->p_hwbuf->wait, \
&(p_port)->p_hwbuf->lock )
#define HWBUFFER_BROADCAST(p_port) vlc_cond_broadcast( &(p_port)->p_hwbuf->wait )
#else
static inline int HwBuffer_dummy( )
{
return 0;
}
#define HwBuffer_Init(p_dec, p_port) do { } while (0)
#define HwBuffer_Destroy(p_dec, p_port) do { } while (0)
#define HwBuffer_AllocateBuffers(p_dec, p_port) HwBuffer_dummy()
#define HwBuffer_FreeBuffers(p_dec, p_port) HwBuffer_dummy()
#define HwBuffer_Start(p_dec, p_port) HwBuffer_dummy()
#define HwBuffer_Stop(p_dec, p_port) HwBuffer_dummy()
#define HwBuffer_Join(p_dec, p_port) HwBuffer_dummy()
#define HwBuffer_GetPic(p_dec, p_port, pp_pic) HwBuffer_dummy()
#define HwBuffer_SetCrop(p_dec, p_port, p_rect) do { } while (0)
#define HWBUFFER_LOCK(p_port) do { } while (0)
#define HWBUFFER_UNLOCK(p_port) do { } while (0)
#define HWBUFFER_WAIT(p_port) do { } while (0)
#define HWBUFFER_BROADCAST(p_port) do { } while (0)
#endif
/*****************************************************************************
* Module descriptor
*****************************************************************************/
......@@ -146,24 +91,11 @@ vlc_module_begin ()
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_VCODEC )
set_section( N_("Decoding") , NULL )
#if defined(USE_IOMX)
/* For IOMX, don't enable it automatically via priorities,
* enable it only via the --codec iomx command line parameter when
* wanted. */
set_capability( "video decoder", 0 )
add_bool(CFG_PREFIX "dr", true,
DIRECTRENDERING_TEXT, DIRECTRENDERING_LONGTEXT, true)
#else
set_capability( "video decoder", 80 )
#endif
set_callbacks( OpenDecoder, CloseGeneric )
#ifndef __ANDROID__
add_submodule()
# if defined(USE_IOMX)
set_capability("audio decoder", 0)
# else
set_capability("audio decoder", 80)
# endif
set_callbacks(OpenDecoder, CloseGeneric)
#endif
......@@ -304,12 +236,6 @@ static OMX_ERRORTYPE SetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
}
else
{
if( p_port->p_hwbuf )
{
p_fmt->i_codec = VLC_CODEC_ANDROID_OPAQUE;
break;
}
if( !GetVlcChromaFormat( def->format.video.eColorFormat,
&p_fmt->i_codec, 0 ) )
{
......@@ -395,7 +321,7 @@ static OMX_ERRORTYPE SetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
}
}
if (!strcmp(p_dec->p_sys->psz_component, "OMX.TI.DUCATI1.VIDEO.DECODER") &&
def->eDir == OMX_DirOutput && !p_port->p_hwbuf)
def->eDir == OMX_DirOutput)
{
/* When setting the output buffer size above, the decoder actually
* sets the buffer size to a lower value than what was chosen. If
......@@ -466,18 +392,7 @@ static OMX_ERRORTYPE AllocateBuffers(decoder_t *p_dec, OmxPort *p_port)
p_port->pp_buffers[i] = (void *)ALIGN((uintptr_t)p_buf, p_port->definition.nBufferAlignment);
#endif
if( p_port->p_hwbuf )
{
omx_error =
OMX_UseBuffer( p_sys->omx_handle, &p_port->pp_buffers[i],
p_port->i_port_index, 0,
p_port->definition.nBufferSize,
p_port->p_hwbuf->pp_handles[i] );
OMX_DBG( "OMX_UseBuffer(%d) %p, %p", def->eDir,
(void *)p_port->pp_buffers[i],
p_port->p_hwbuf->pp_handles[i] );
}
else if( p_port->b_direct )
if( p_port->b_direct )
{
omx_error =
OMX_UseBuffer( p_sys->omx_handle, &p_port->pp_buffers[i],
......@@ -503,8 +418,7 @@ static OMX_ERRORTYPE AllocateBuffers(decoder_t *p_dec, OmxPort *p_port)
p_port->i_buffers = i;
break;
}
if( !p_port->p_hwbuf )
OMX_FIFO_PUT(&p_port->fifo, p_port->pp_buffers[i]);
OMX_FIFO_PUT(&p_port->fifo, p_port->pp_buffers[i]);
}
CHECK_ERROR(omx_error, "AllocateBuffers failed (%x, %i)",
......@@ -526,17 +440,7 @@ static OMX_ERRORTYPE FreeBuffers(decoder_t *p_dec, OmxPort *p_port)
OMX_BUFFERHEADERTYPE *p_buffer;
unsigned int i, i_wait_buffers;
/* Normally, all buffers are in the port fifo, or given to the codec that
* will return them when disabling the port or changing state, therefore we
* normally wait for all buffers. For IOMX direct rendering (HwBuffer),
* only a few buffers are given to the codec at a time, thus we can only
* wait for that many buffers. And after that, we can still free all OMX
* buffers since we either got some of them returned via OMX_FIFO_GET, or
* never passed them to the codec at all. */
if( p_port->p_hwbuf )
i_wait_buffers = p_port->p_hwbuf->i_owned;
else
i_wait_buffers = p_port->i_buffers;
i_wait_buffers = p_port->i_buffers;
OMX_DBG( "FreeBuffers(%d), waiting for %u buffers", def->eDir,
i_wait_buffers);
......@@ -622,9 +526,6 @@ static OMX_ERRORTYPE GetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
p_fmt->video.i_visible_height = crop_rect.nHeight;
if (def->format.video.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
def->format.video.nSliceHeight -= crop_rect.nTop/2;
if( p_port->p_hwbuf )
HwBuffer_SetCrop( p_dec, p_port, &crop_rect );
}
else
{
......@@ -632,11 +533,6 @@ static OMX_ERRORTYPE GetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
omx_error = OMX_ErrorNone;
}
if( p_port->p_hwbuf )
{
UpdatePixelAspect(p_dec);
break;
}
/* Hack: Nexus One (stock firmware with binary OMX driver blob)
* claims to output 420Planar even though it in in practice is
* NV21. */
......@@ -748,9 +644,6 @@ static OMX_ERRORTYPE DeinitialiseComponent(decoder_t *p_dec,
omx_error = OMX_GetState(omx_handle, &state);
CHECK_ERROR(omx_error, "OMX_GetState failed (%x)", omx_error );
if( p_sys->out.p_hwbuf && HwBuffer_Stop( p_dec, &p_sys->out ) != 0 )
msg_Warn( p_dec, "HwBuffer_Stop failed" );
if(state == OMX_StateExecuting)
{
omx_error = OMX_SendCommand( omx_handle, OMX_CommandStateSet,
......@@ -783,11 +676,6 @@ static OMX_ERRORTYPE DeinitialiseComponent(decoder_t *p_dec,
omx_error = FreeBuffers( p_dec, p_port );
CHECK_ERROR(omx_error, "FreeBuffers failed (%x, %i)",
omx_error, (int)p_port->i_port_index );
if( p_port->p_hwbuf )
{
HwBuffer_FreeBuffers( p_dec, p_port );
HwBuffer_Join( p_dec, p_port );
}
}
omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
......@@ -813,7 +701,6 @@ static OMX_ERRORTYPE DeinitialiseComponent(decoder_t *p_dec,
msg_Warn( p_dec, "Stray buffer left in fifo, %p",
(void *)p_buffer );
}
HwBuffer_Destroy( p_dec, p_port );
}
omx_error = pf_free_handle( omx_handle );