渲染到Android表面我想利用OMX HW渲染器如下所述: http://www.slideshare.net/RaghavanVenkateswaran/iomx-in-androidHW用的OpenMAX IL
OS:使用的Android 2.3.4
系統libaries: libmedia,libbinder ,libstagefright,libutils我的設備上
OMX組件:
組件名稱:OMX.ITTIAM.AAC.decode,componentRole:audio_decoder.aac
組件名稱:OMX.ITTIAM.AAC.encode,componentRole:audio_encoder.aac
組件名稱:OMX.TI.720P.Decoder, componentRole:video_decoder.mpeg4
組件名稱:OMX.TI.720P.Decoder,componentRole:video_decoder.avc
組件名稱:OMX.TI.720P.Encoder,componentRole:video_encoder.mpeg4
組件名稱:OMX.TI.720P.Encoder,componentRole:video_encoder.avc
組件名稱:OMX.TI.AAC.decode,componentRole:audio_decoder.aac
組件名稱:OMX.TI.AAC.encode,componentRole :audio_encoder.aac
組件名稱:OMX.TI.AMR.decode,componentRole:audio_decoder.amrnb
組件名稱:OMX.TI.AMR.encode,componentRole:audio_encoder.amrnb
組件名稱:OMX。 TI.Camera,componentRole :camera.yuv
組件名稱:OMX.TI.JPEG.decoder,componentRole:image_decoder.jpeg
組件名稱:OMX.TI.JPEG.encoder,componentRole:image_encoder.jpeg
組件名稱:OMX。 TI.MP3.decode,componentRole:audio_decoder.mp3
組件名稱:OMX.TI.VPP,componentRole:iv_renderer.yuv.overlay
組件名稱:OMX.TI.Video.Decoder,componentRole:video_decoder.h263
組件名稱:OMX.TI.Video.Decoder,componentRole:video_decoder.avc
組件名稱:OMX.TI.Video.Decoder,componentRole:video_decoder.mpeg2
組件名稱:OMX.TI.Video.Decoder ,componentRole:video_decoder.mpeg4
組件名稱:OMX.TI.Video.Decoder,componentRole:video_decoder.wmv
組件名稱:OMX.TI.Video.encoder,componentRole:video_encoder。MPEG4
組件名稱:OMX.TI.Video.encoder,componentRole:video_encoder.h263
組件名稱:OMX.TI.Video.encoder,componentRole:video_encoder.avc
組件名稱:OMX.TI.WBAMR .decode,componentRole:audio_decoder.amrwb
組件名稱:OMX.TI.WBAMR.encode,componentRole:audio_encoder.amrwb
組件名稱:OMX.TI.WMA.decode,componentRole:audio_decoder.wma
我已經做了下列步驟:
1,通過了的Android Surface物件通過JNI這種方式(完全是在天然的MediaPlayer):
JNI(C++):
static void com_mautilus_media_MMediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz)
{
__android_log_print(ANDROID_LOG_INFO, TAG, "setVideoSurface");
MMediaPlayer *mp = getMediaPlayer(env, thiz);
if (mp == NULL)
{
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
setVideoSurface(mp, env, thiz);
}
static void setVideoSurface(MMediaPlayer *mp, JNIEnv *env, jobject thiz)
{
__android_log_print(ANDROID_LOG_INFO, TAG, "setVideoSurface");
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL && mp != NULL)
{
const android::sp<android::Surface> native_surface = get_surface(env, surface);
mp->setVideoSurface(native_surface);
}
}
在MMediaPlayer表面變量聲明爲:
android::sp<android::Surface> surface;
爪哇:
private Surface mSurface; // accessed by native methods
private SurfaceHolder mSurfaceHolder;
public void setDisplay(SurfaceHolder sh)
{
mSurfaceHolder = sh;
if (sh != null)
{
mSurface = sh.getSurface();
}
else
{
mSurface = null;
}
setVideoSurface(); // Native function call
}
2,初始化IOMX節點:
注:硬編碼值有僅出於簡化和測試目的
android::sp<android::IServiceManager> serviceManager = android::defaultServiceManager();
android::sp<android::IBinder> binder = serviceManager>getService(android::String16("media.player"));
android::sp<android::IMediaPlayerService> mediaPlayerService = android::interface_cast<android::IMediaPlayerService>(binder);
android::sp<android::IOMX> iomx = mediaPlayerService->getOMX();
android::IOMX::node_id node;
// observer is instance of class derived from android::BnOMXObserver class
iomx->allocateNode("OMX.TI.VPP", observer, &mRendererNode->node);
OMX_PARAM_PORTDEFINITIONTYPE portDefn;
portDefn.nPortIndex = 1;
iomx->getParameter(node, OMX_IndexParamPortDefinition, &portDefn, sizeof(portDefn));
//portDefn.nBufferCountActual = mInBufCnt; // set some suitable value here or don’t update to
//use default value
portDefn.format.video.nFrameWidth = 256; // width of the video to be played
portDefn.format.video.nFrameHeight = 144; // height of video to be played
portDefn.format.video.nStride = 256;
portDefn.format.video.nSliceHeight = 144;
iomx->setParameter(node, OMX_IndexParamPortDefinition, &portDefn, sizeof(portDefn));
portDefn.nPortIndex = 2;
iomx->getParameter(node, OMX_IndexParamPortDefinition, &portDefn, sizeof(portDefn));
//portDefn.nBufferCountActual = iOutBufCnt; // set suitable value or leave to default.
portDefn.nBufferSize = (256 * 144 * 3)/2;
portDefn.format.video.nFrameWidth = 256;
portDefn.format.video.nFrameHeight = 144;
portDefn.format.video.nStride = 256;
portDefn.format.video.nSliceHeight = 144;
iomx->setParameter(node, OMX_IndexParamPortDefinition, &portDefn, sizeof(portDefn));
3,試創建OMX渲染器:
android::sp<android::IOMXRenderer> mOMXRenderer;
mOMXRenderer = omxContext->iomx->createRenderer(surface, "OMX.TI.VPP", OMX_COLOR_FormatYUV420Planar, 256, 144, displayWidth, displayHeight, 0);
總是返回NULL。
有沒有人知道這有什麼問題?我正在初始化錯誤的組件嗎?或者必須遵循一些特殊的呼叫順序?或者是其他東西?