Reputation: 89
I am trying to decode a VP8 encoded stream with OMX.SEC.vp8.dec and OMX.google.vpx.decoder in Samsung Galaxy Y Duos. I am configuring MediaCodec with surface and it shows the following error in the log. I am not sure if there are any MediaCodec or MediaFormat settings required prior to configuring MediaCodec which are specific to VP8/VP9 codec. The mimeType I am using is 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)
Edit (after fadden's reply): Code
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();
}
}
Edit 2: I create the surface instance in a test code (as shown below) and I pass to the code where I implement the MediaCodec configure.
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
}
}
The edit 1 is a decoder implementation prior to which I pass the surface with this:
Surface surface = null; // Local surface class object.
public void set_decoder_surface(Surface surface)
{
// Set surface for decoded video.
this.surface = surface;
}
Upvotes: 1
Views: 2153
Reputation: 1473
I think you migth be missed some of the params. Color format is important here
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
Or if you want to use YUV output buffer you do not need to specify surface.
There are some others, not sure if they matters.
Also, code you shared does not have anything about surface creation, hope it is correct one
Upvotes: 0