2

渲染到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。

有沒有人知道這有什麼問題?我正在初始化錯誤的組件嗎?或者必須遵循一些特殊的呼叫順序?或者是其他東西?

回答

1

使用IOMX.h中定義的createRendererFromJavaSurface