使用Samsung Galaxy Y Duos中的OMX.SEC.vp8.dec和OMX.google.vpx.decoder进行解码

时间:2014-03-05 12:14:40

标签: android mediacodec

我正在尝试使用 OMX.SEC.vp8.dec OMX.google.vpx.decoder 解码 VP8编码流三星Galaxy Y Duos。我正在使用surface配置MediaCodec,它在日志中显示以下错误。我不确定在配置MediaCodec之前是否需要任何MediaCodec或MediaFormat设置,这些设置是特定于VP8 / VP9编解码器的。我使用的mimeType是video / x-vnd.on2.vp8

03-05 16:55:45.231: A/ACodec(3468): frameworks/av/media/libstagefright/ACodec.cpp:3333 CHECK_EQ( (status_t)OK,mCodec->initNativeWindow()) failed: 0 vs. -2147483648
03-05 16:57:28.811: A/libc(4165): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 4187 (CodecLooper)

编辑(在fadden的回复之后):代码

int colorFormat = 0;
int frm_width  = 640;
int frm_height = 360;
int frm_format_choice = 0;
String mimeType = "video/x-vnd.on2.vp8";
String[] types = info.getSupportedTypes();
int numCodecs = MediaCodecList.getCodecCount();
MediaCodec mediaCodec = null;
MediaFormat mediaFormat = null;

public int  decode_frame() {
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

    for (int i = 0; i < numCodecs && codecInfo == null; i++) {
        MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
        if (info.isEncoder()) {
            continue;
        }
        String[] types = info.getSupportedTypes();

        for (int j = 0; j < types.length && !found; j++) {  
            if (types[j].equals(mimeType)) {
                found = true;
                decoder_name = info.getName();
                dec_name.format("%s\n", decoder_name);
                dec_name.flush();
            }
        }
        System.out.println("decoder name " +info.getName());

        if (!found)
            continue;

        codecInfo = info;
    }

    if ( decoder_name.equals("OMX.SEC.vp8.dec") || decoder_name.equals("OMX.google.vpx.decoder") {

        MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);

        for (int i = 0; i < capabilities.colorFormats.length && colorFormat == 0; i++) {
            int format = capabilities.colorFormats[i];
            switch (format) {
                case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
                case COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced :
                    colorFormat= format;
                    frm_format_choice = format;
                    break;

                case COLOR_TI_Format :
                    colorFormat       = format;
                    frm_format_choice = format;
                    break;

                default:
                    break;
            }
        }
    }

    mediaCodec = MediaCodec.createDecoderByType(mimeType);
    mediaFormat = MediaFormat.createVideoFormat(mimeType, frm_width, frm_height);
    mediaCodec.configure(mediaFormat, surface, null, 0); // this is where it is crashing.

    if (mediaCodec != null) {
        mediaCodec.start();
        inputBuffers  = mediaCodec.getInputBuffers();
        outputBuffers = mediaCodec.getOutputBuffers();  
    }
}

编辑2:我在测试代码中创建了曲面实例(如下所示),然后传递给我实现MediaCodec配置的代码。

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

public class MyClass extends Activity implements SurfaceHolder.Callback {

    private PlayerThread mPlayer = null;

    //few other initializations

    @Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    SurfaceView sv = new SurfaceView(this);

    sv.getHolder().addCallback(this);

    setContentView(sv);
}

protected void onDestroy() {

    super.onDestroy();
}

@Override

public void surfaceCreated(SurfaceHolder holder) {
}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    if (mPlayer == null) {
        mPlayer = new PlayerThread(holder.getSurface());
        mPlayer.start();
    }
}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {
    if (mPlayer != null) {
        mPlayer.interrupt();
    }
}

private class PlayerThread extends Thread {

    private Surface surface;

    public PlayerThread(Surface surface) {

        this.surface = surface;
    }

@Override

public void run() {

    // my implementations

    //This is the method I call to pass the surface where  I am configuring MediaCodec with surface.
    obj_decoder.set_decoder_surface(surface);

    // my implementations

}

}

编辑1是一个解码器实现,在此之前我通过表面传递:

Surface surface = null; // Local surface class object.

public void set_decoder_surface(Surface surface)
{
    // Set surface for decoded video.

    this.surface = surface;     

}

1 个答案:

答案 0 :(得分:0)

我认为你会错过一些参数。 颜色格式在这里很重要

  format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); 

或者如果你想使用YUV输出缓冲区,你不需要指定表面。

还有其他人,不确定他们是否重要。

此外,您共享的代码没有关于曲面创建的任何内容,希望它是正确的