Merge change 9372
* changes: The IOMX interface now instantiates IOMXRenderers to hide the details of hardware accelerated blitting.
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <OMX_Core.h>
|
||||
#include <OMX_Video.h>
|
||||
|
||||
#define IOMX_USES_SOCKETS 0
|
||||
|
||||
@ -30,6 +31,8 @@ namespace android {
|
||||
|
||||
class IMemory;
|
||||
class IOMXObserver;
|
||||
class IOMXRenderer;
|
||||
class ISurface;
|
||||
|
||||
class IOMX : public IInterface {
|
||||
public:
|
||||
@ -87,6 +90,13 @@ public:
|
||||
OMX_U32 range_offset, OMX_U32 range_length,
|
||||
OMX_U32 flags, OMX_TICKS timestamp) = 0;
|
||||
#endif
|
||||
|
||||
virtual sp<IOMXRenderer> createRenderer(
|
||||
const sp<ISurface> &surface,
|
||||
const char *componentName,
|
||||
OMX_COLOR_FORMATTYPE colorFormat,
|
||||
size_t encodedWidth, size_t encodedHeight,
|
||||
size_t displayWidth, size_t displayHeight) = 0;
|
||||
};
|
||||
|
||||
struct omx_message {
|
||||
@ -155,6 +165,13 @@ public:
|
||||
virtual void on_message(const omx_message &msg) = 0;
|
||||
};
|
||||
|
||||
class IOMXRenderer : public IInterface {
|
||||
public:
|
||||
DECLARE_META_INTERFACE(OMXRenderer);
|
||||
|
||||
virtual void render(IOMX::buffer_id buffer) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BnOMX : public BnInterface<IOMX> {
|
||||
@ -171,6 +188,13 @@ public:
|
||||
uint32_t flags = 0);
|
||||
};
|
||||
|
||||
class BnOMXRenderer : public BnInterface<IOMXRenderer> {
|
||||
public:
|
||||
virtual status_t onTransact(
|
||||
uint32_t code, const Parcel &data, Parcel *reply,
|
||||
uint32_t flags = 0);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_IOMX_H_
|
||||
|
@ -28,6 +28,7 @@
|
||||
namespace android {
|
||||
|
||||
class AudioPlayer;
|
||||
class IOMXRenderer;
|
||||
class ISurface;
|
||||
class MediaExtractor;
|
||||
class MediaBuffer;
|
||||
@ -37,7 +38,6 @@ class MetaData;
|
||||
class OMXDecoder;
|
||||
class Surface;
|
||||
class TimeSource;
|
||||
class VideoRenderer;
|
||||
|
||||
class MediaPlayerImpl {
|
||||
public:
|
||||
@ -93,7 +93,7 @@ private:
|
||||
|
||||
sp<Surface> mSurface;
|
||||
sp<ISurface> mISurface;
|
||||
VideoRenderer *mRenderer;
|
||||
sp<IOMXRenderer> mVideoRenderer;
|
||||
|
||||
sp<MediaPlayerBase::AudioSink> mAudioSink;
|
||||
|
||||
|
@ -44,6 +44,7 @@ enum {
|
||||
kKeyColorFormat = 'colf',
|
||||
kKeyPlatformPrivate = 'priv',
|
||||
kKeyDecoderComponent = 'decC',
|
||||
kKeyBufferID = 'bfID',
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SURFACE_RENDERER_H_
|
||||
|
||||
#define SURFACE_RENDERER_H_
|
||||
|
||||
#include <media/stagefright/VideoRenderer.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Surface;
|
||||
|
||||
class SurfaceRenderer : public VideoRenderer {
|
||||
public:
|
||||
SurfaceRenderer(
|
||||
const sp<Surface> &surface,
|
||||
size_t displayWidth, size_t displayHeight,
|
||||
size_t decodedWidth, size_t decodedHeight);
|
||||
|
||||
virtual ~SurfaceRenderer();
|
||||
|
||||
virtual void render(
|
||||
const void *data, size_t size, void *platformPrivate);
|
||||
|
||||
private:
|
||||
sp<Surface> mSurface;
|
||||
size_t mDisplayWidth, mDisplayHeight;
|
||||
size_t mDecodedWidth, mDecodedHeight;
|
||||
|
||||
SurfaceRenderer(const SurfaceRenderer &);
|
||||
SurfaceRenderer &operator=(const SurfaceRenderer &);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // SURFACE_RENDERER_H_
|
@ -36,6 +36,7 @@ namespace android {
|
||||
|
||||
class BufferMapper;
|
||||
class Rect;
|
||||
class MediaPlayerImpl;
|
||||
class Surface;
|
||||
class SurfaceComposerClient;
|
||||
struct per_client_cblk_t;
|
||||
@ -180,6 +181,7 @@ private:
|
||||
// mediaplayer needs access to ISurface for display
|
||||
friend class MediaPlayer;
|
||||
friend class Test;
|
||||
friend class MediaPlayerImpl;
|
||||
const sp<ISurface>& getISurface() const { return mSurface; }
|
||||
|
||||
status_t getBufferLocked(int index);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <binder/IMemory.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <media/IOMX.h>
|
||||
#include <ui/ISurface.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@ -23,7 +24,9 @@ enum {
|
||||
OBSERVE_NODE,
|
||||
FILL_BUFFER,
|
||||
EMPTY_BUFFER,
|
||||
CREATE_RENDERER,
|
||||
OBSERVER_ON_MSG,
|
||||
RENDERER_RENDER,
|
||||
};
|
||||
|
||||
static void *readVoidStar(const Parcel *parcel) {
|
||||
@ -262,6 +265,28 @@ public:
|
||||
remote()->transact(EMPTY_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual sp<IOMXRenderer> createRenderer(
|
||||
const sp<ISurface> &surface,
|
||||
const char *componentName,
|
||||
OMX_COLOR_FORMATTYPE colorFormat,
|
||||
size_t encodedWidth, size_t encodedHeight,
|
||||
size_t displayWidth, size_t displayHeight) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
|
||||
|
||||
data.writeStrongBinder(surface->asBinder());
|
||||
data.writeCString(componentName);
|
||||
data.writeInt32(colorFormat);
|
||||
data.writeInt32(encodedWidth);
|
||||
data.writeInt32(encodedHeight);
|
||||
data.writeInt32(displayWidth);
|
||||
data.writeInt32(displayHeight);
|
||||
|
||||
remote()->transact(CREATE_RENDERER, data, &reply);
|
||||
|
||||
return interface_cast<IOMXRenderer>(reply.readStrongBinder());
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
|
||||
@ -513,6 +538,33 @@ status_t BnOMX::onTransact(
|
||||
}
|
||||
#endif
|
||||
|
||||
case CREATE_RENDERER:
|
||||
{
|
||||
CHECK_INTERFACE(IOMX, data, reply);
|
||||
|
||||
sp<ISurface> isurface =
|
||||
interface_cast<ISurface>(data.readStrongBinder());
|
||||
|
||||
const char *componentName = data.readCString();
|
||||
|
||||
OMX_COLOR_FORMATTYPE colorFormat =
|
||||
static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32());
|
||||
|
||||
size_t encodedWidth = (size_t)data.readInt32();
|
||||
size_t encodedHeight = (size_t)data.readInt32();
|
||||
size_t displayWidth = (size_t)data.readInt32();
|
||||
size_t displayHeight = (size_t)data.readInt32();
|
||||
|
||||
sp<IOMXRenderer> renderer =
|
||||
createRenderer(isurface, componentName, colorFormat,
|
||||
encodedWidth, encodedHeight,
|
||||
displayWidth, displayHeight);
|
||||
|
||||
reply->writeStrongBinder(renderer->asBinder());
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
default:
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
@ -558,4 +610,44 @@ status_t BnOMXObserver::onTransact(
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BpOMXRenderer : public BpInterface<IOMXRenderer> {
|
||||
public:
|
||||
BpOMXRenderer(const sp<IBinder> &impl)
|
||||
: BpInterface<IOMXRenderer>(impl) {
|
||||
}
|
||||
|
||||
virtual void render(IOMX::buffer_id buffer) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
|
||||
writeVoidStar(buffer, &data);
|
||||
|
||||
// NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
|
||||
// so that the caller knows when to recycle the buffer.
|
||||
remote()->transact(RENDERER_RENDER, data, &reply);
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer");
|
||||
|
||||
status_t BnOMXRenderer::onTransact(
|
||||
uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
|
||||
switch (code) {
|
||||
case RENDERER_RENDER:
|
||||
{
|
||||
CHECK_INTERFACE(IOMXRenderer, data, reply);
|
||||
|
||||
IOMX::buffer_id buffer = readVoidStar(&data);
|
||||
|
||||
render(buffer);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
default:
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
@ -19,14 +19,10 @@ LOCAL_SRC_FILES:= \
|
||||
MediaSource.cpp \
|
||||
MetaData.cpp \
|
||||
MmapSource.cpp \
|
||||
QComHardwareRenderer.cpp \
|
||||
SampleTable.cpp \
|
||||
ShoutcastSource.cpp \
|
||||
SoftwareRenderer.cpp \
|
||||
SurfaceRenderer.cpp \
|
||||
TimeSource.cpp \
|
||||
TimedEventQueue.cpp \
|
||||
TIHardwareRenderer.cpp \
|
||||
Utils.cpp \
|
||||
AudioPlayer.cpp \
|
||||
ESDS.cpp \
|
||||
|
@ -35,12 +35,8 @@
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/MmapSource.h>
|
||||
#include <media/stagefright/OMXDecoder.h>
|
||||
#include <media/stagefright/QComHardwareRenderer.h>
|
||||
#include <media/stagefright/ShoutcastSource.h>
|
||||
#include <media/stagefright/SoftwareRenderer.h>
|
||||
#include <media/stagefright/SurfaceRenderer.h>
|
||||
#include <media/stagefright/TimeSource.h>
|
||||
#include <media/stagefright/TIHardwareRenderer.h>
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <ui/Surface.h>
|
||||
|
||||
@ -61,7 +57,6 @@ MediaPlayerImpl::MediaPlayerImpl(const char *uri)
|
||||
mDuration(0),
|
||||
mPlaying(false),
|
||||
mPaused(false),
|
||||
mRenderer(NULL),
|
||||
mSeeking(false),
|
||||
mFrameSize(0),
|
||||
mUseSoftwareColorConversion(false) {
|
||||
@ -121,7 +116,6 @@ MediaPlayerImpl::MediaPlayerImpl(int fd, int64_t offset, int64_t length)
|
||||
mDuration(0),
|
||||
mPlaying(false),
|
||||
mPaused(false),
|
||||
mRenderer(NULL),
|
||||
mSeeking(false),
|
||||
mFrameSize(0),
|
||||
mUseSoftwareColorConversion(false) {
|
||||
@ -379,7 +373,7 @@ void MediaPlayerImpl::displayOrDiscardFrame(
|
||||
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
if (mRenderer != NULL) {
|
||||
if (mVideoRenderer.get() != NULL) {
|
||||
sendFrameToISurface(buffer);
|
||||
}
|
||||
}
|
||||
@ -652,52 +646,26 @@ void MediaPlayerImpl::populateISurface() {
|
||||
success = success && meta->findInt32(kKeyHeight, &decodedHeight);
|
||||
assert(success);
|
||||
|
||||
static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
|
||||
const sp<ISurface> &isurface =
|
||||
mSurface.get() != NULL ? mSurface->getISurface() : mISurface;
|
||||
|
||||
if (mSurface.get() != NULL) {
|
||||
LOGW("Using SurfaceRenderer.");
|
||||
mRenderer =
|
||||
new SurfaceRenderer(
|
||||
mSurface, mVideoWidth, mVideoHeight,
|
||||
decodedWidth, decodedHeight);
|
||||
} else if (format == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
|
||||
&& !strncmp(component, "OMX.qcom.video.decoder.", 23)) {
|
||||
LOGW("Using QComHardwareRenderer.");
|
||||
mRenderer =
|
||||
new QComHardwareRenderer(
|
||||
mISurface, mVideoWidth, mVideoHeight,
|
||||
decodedWidth, decodedHeight);
|
||||
} else if (format == OMX_COLOR_FormatCbYCrY
|
||||
&& !strcmp(component, "OMX.TI.Video.Decoder")) {
|
||||
LOGW("Using TIHardwareRenderer.");
|
||||
mRenderer =
|
||||
new TIHardwareRenderer(
|
||||
mISurface, mVideoWidth, mVideoHeight,
|
||||
decodedWidth, decodedHeight);
|
||||
} else {
|
||||
LOGW("Using software renderer.");
|
||||
mRenderer = new SoftwareRenderer(
|
||||
mISurface, mVideoWidth, mVideoHeight,
|
||||
decodedWidth, decodedHeight);
|
||||
}
|
||||
mVideoRenderer =
|
||||
mClient.interface()->createRenderer(
|
||||
isurface, component,
|
||||
(OMX_COLOR_FORMATTYPE)format,
|
||||
decodedWidth, decodedHeight,
|
||||
mVideoWidth, mVideoHeight);
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::depopulateISurface() {
|
||||
delete mRenderer;
|
||||
mRenderer = NULL;
|
||||
mVideoRenderer.clear();
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::sendFrameToISurface(MediaBuffer *buffer) {
|
||||
void *platformPrivate;
|
||||
if (!buffer->meta_data()->findPointer(
|
||||
kKeyPlatformPrivate, &platformPrivate)) {
|
||||
platformPrivate = NULL;
|
||||
void *id;
|
||||
if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) {
|
||||
mVideoRenderer->render((IOMX::buffer_id)id);
|
||||
}
|
||||
|
||||
mRenderer->render(
|
||||
(const uint8_t *)buffer->data() + buffer->range_offset(),
|
||||
buffer->range_length(),
|
||||
platformPrivate);
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::setAudioSink(
|
||||
|
@ -154,8 +154,7 @@ OMXDecoder *OMXDecoder::Create(
|
||||
if (!strncmp(codec, "OMX.qcom.video.", 15)) {
|
||||
quirks |= kRequiresLoadedToIdleAfterAllocation;
|
||||
}
|
||||
if (!strcmp(codec, "OMX.TI.AAC.decode")
|
||||
|| !strcmp(codec, "OMX.TI.MP3.decode")) {
|
||||
if (!strcmp(codec, "OMX.TI.MP3.decode")) {
|
||||
quirks |= kMeasuresTimeInMilliseconds;
|
||||
}
|
||||
|
||||
@ -1551,6 +1550,10 @@ void OMXDecoder::onRealFillBufferDone(const omx_message &msg) {
|
||||
kKeyPlatformPrivate,
|
||||
msg.u.extended_buffer_data.platform_private);
|
||||
|
||||
media_buffer->meta_data()->setPointer(
|
||||
kKeyBufferID,
|
||||
msg.u.extended_buffer_data.buffer);
|
||||
|
||||
if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
|
||||
mErrorCondition = ERROR_END_OF_STREAM;
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "SurfaceRenderer"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#include <media/stagefright/SurfaceRenderer.h>
|
||||
#include <ui/Surface.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
SurfaceRenderer::SurfaceRenderer(
|
||||
const sp<Surface> &surface,
|
||||
size_t displayWidth, size_t displayHeight,
|
||||
size_t decodedWidth, size_t decodedHeight)
|
||||
: mSurface(surface),
|
||||
mDisplayWidth(displayWidth),
|
||||
mDisplayHeight(displayHeight),
|
||||
mDecodedWidth(decodedWidth),
|
||||
mDecodedHeight(decodedHeight) {
|
||||
}
|
||||
|
||||
SurfaceRenderer::~SurfaceRenderer() {
|
||||
}
|
||||
|
||||
void SurfaceRenderer::render(
|
||||
const void *data, size_t size, void *platformPrivate) {
|
||||
Surface::SurfaceInfo info;
|
||||
status_t err = mSurface->lock(&info);
|
||||
if (err != OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t *src = (const uint8_t *)data;
|
||||
uint8_t *dst = (uint8_t *)info.bits;
|
||||
|
||||
for (size_t i = 0; i < mDisplayHeight; ++i) {
|
||||
memcpy(dst, src, mDisplayWidth);
|
||||
src += mDecodedWidth;
|
||||
dst += mDisplayWidth;
|
||||
}
|
||||
src += (mDecodedHeight - mDisplayHeight) * mDecodedWidth;
|
||||
|
||||
for (size_t i = 0; i < (mDisplayHeight + 1) / 2; ++i) {
|
||||
memcpy(dst, src, (mDisplayWidth + 1) & ~1);
|
||||
src += (mDecodedWidth + 1) & ~1;
|
||||
dst += (mDisplayWidth + 1) & ~1;
|
||||
}
|
||||
|
||||
mSurface->unlockAndPost();
|
||||
}
|
||||
|
||||
} // namespace android
|
@ -9,13 +9,17 @@ LOCAL_C_INCLUDES := $(PV_INCLUDES)
|
||||
LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
OMX.cpp
|
||||
OMX.cpp \
|
||||
QComHardwareRenderer.cpp \
|
||||
SoftwareRenderer.cpp \
|
||||
TIHardwareRenderer.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbinder \
|
||||
libmedia \
|
||||
libutils \
|
||||
libui \
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbinder \
|
||||
libmedia \
|
||||
libutils \
|
||||
libui \
|
||||
libcutils \
|
||||
libopencore_common
|
||||
|
||||
LOCAL_PRELINK_MODULE:= false
|
||||
|
@ -24,9 +24,15 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "OMX.h"
|
||||
#include "OMXRenderer.h"
|
||||
|
||||
#include "pv_omxcore.h"
|
||||
|
||||
#include <binder/IMemory.h>
|
||||
#include <media/stagefright/QComHardwareRenderer.h>
|
||||
#include <media/stagefright/SoftwareRenderer.h>
|
||||
#include <media/stagefright/TIHardwareRenderer.h>
|
||||
#include <media/stagefright/VideoRenderer.h>
|
||||
|
||||
#include <OMX_Component.h>
|
||||
|
||||
@ -619,5 +625,62 @@ void OMX::empty_buffer(
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sp<IOMXRenderer> OMX::createRenderer(
|
||||
const sp<ISurface> &surface,
|
||||
const char *componentName,
|
||||
OMX_COLOR_FORMATTYPE colorFormat,
|
||||
size_t encodedWidth, size_t encodedHeight,
|
||||
size_t displayWidth, size_t displayHeight) {
|
||||
VideoRenderer *impl = NULL;
|
||||
|
||||
static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
|
||||
|
||||
if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
|
||||
&& !strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
|
||||
LOGW("Using QComHardwareRenderer.");
|
||||
impl =
|
||||
new QComHardwareRenderer(
|
||||
surface,
|
||||
displayWidth, displayHeight,
|
||||
encodedWidth, encodedHeight);
|
||||
} else if (colorFormat == OMX_COLOR_FormatCbYCrY
|
||||
&& !strcmp(componentName, "OMX.TI.Video.Decoder")) {
|
||||
LOGW("Using TIHardwareRenderer.");
|
||||
impl =
|
||||
new TIHardwareRenderer(
|
||||
surface,
|
||||
displayWidth, displayHeight,
|
||||
encodedWidth, encodedHeight);
|
||||
} else {
|
||||
LOGW("Using software renderer.");
|
||||
impl = new SoftwareRenderer(
|
||||
surface,
|
||||
displayWidth, displayHeight,
|
||||
encodedWidth, encodedHeight);
|
||||
}
|
||||
|
||||
return new OMXRenderer(impl);
|
||||
}
|
||||
|
||||
OMXRenderer::OMXRenderer(VideoRenderer *impl)
|
||||
: mImpl(impl) {
|
||||
}
|
||||
|
||||
OMXRenderer::~OMXRenderer() {
|
||||
delete mImpl;
|
||||
mImpl = NULL;
|
||||
}
|
||||
|
||||
void OMXRenderer::render(IOMX::buffer_id buffer) {
|
||||
OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
|
||||
|
||||
mImpl->render(
|
||||
header->pBuffer + header->nOffset,
|
||||
header->nFilledLen,
|
||||
header->pPlatformPrivate);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
@ -79,6 +79,13 @@ public:
|
||||
OMX_U32 flags, OMX_TICKS timestamp);
|
||||
#endif
|
||||
|
||||
virtual sp<IOMXRenderer> createRenderer(
|
||||
const sp<ISurface> &surface,
|
||||
const char *componentName,
|
||||
OMX_COLOR_FORMATTYPE colorFormat,
|
||||
size_t encodedWidth, size_t encodedHeight,
|
||||
size_t displayWidth, size_t displayHeight);
|
||||
|
||||
private:
|
||||
static OMX_CALLBACKTYPE kCallbacks;
|
||||
|
||||
|
44
media/libstagefright/omx/OMXRenderer.h
Normal file
44
media/libstagefright/omx/OMXRenderer.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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_RENDERER_H_
|
||||
|
||||
#define OMX_RENDERER_H_
|
||||
|
||||
#include <media/IOMX.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class VideoRenderer;
|
||||
|
||||
class OMXRenderer : public BnOMXRenderer {
|
||||
public:
|
||||
// Assumes ownership of "impl".
|
||||
OMXRenderer(VideoRenderer *impl);
|
||||
virtual ~OMXRenderer();
|
||||
|
||||
virtual void render(IOMX::buffer_id buffer);
|
||||
|
||||
private:
|
||||
VideoRenderer *mImpl;
|
||||
|
||||
OMXRenderer(const OMXRenderer &);
|
||||
OMXRenderer &operator=(const OMXRenderer &);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // OMX_RENDERER_H_
|
@ -61,6 +61,10 @@ SoftwareRenderer::~SoftwareRenderer() {
|
||||
|
||||
void SoftwareRenderer::render(
|
||||
const void *data, size_t size, void *platformPrivate) {
|
||||
if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) {
|
||||
LOGE("size is %d, expected %d",
|
||||
size, (mDecodedHeight * mDecodedWidth * 3) / 2);
|
||||
}
|
||||
assert(size >= (mDecodedWidth * mDecodedHeight * 3) / 2);
|
||||
|
||||
static const signed kClipMin = -278;
|
Reference in New Issue
Block a user