2015-05-05 194 views
1

我试图将MediaCodec作为h264流的解码器。我甚至无法让MediaCodec将它的调用传递给start()而不会崩溃。MediaCodec在启动时崩溃()

以下是日志。基本上我的SurfaceView.Holder回调发生在表面被创建和改变时。在surfaceChanged上我启动了一个线程,它试图启动一个MediaCodec。

的_surface实例是surfaceChanged(SurfaceHolder.getSurface())

String key_mime = "video/avc"; 
int w = 480; 
int h = 360; 
MediaFormat mediaFormat = MediaFormat.createVideoFormat(key_mime, w, h); 

mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000); 
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25); 
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar); 
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10); 

try 
{ 
decoder = MediaCodec.createDecoderByType(key_mime); 
} 
catch (IOException e) 
{ 
e.printStackTrace(); 
return; 
} 

decoder.configure(mediaFormat, _surface, null, 0); 
decoder.start(); 

登录:

05-05 13:18:14.645 22393-22393/ca.example.app D/StreamActivity﹕ surfaceCreated() 
05-05 13:18:14.645 22393-22393/ca.example.app D/StreamActivity﹕ surfaceChanged([email protected], 4, 1368, 765 
05-05 13:18:14.655 22393-22586/ca.example.app I/ACodec﹕ [] Now uninitialized 
05-05 13:18:14.655 22393-22588/ca.example.app I/OMXClient﹕ Using client-side OMX mux. 
05-05 13:18:14.685 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] Now Loaded 
05-05 13:18:14.685 22393-22588/ca.example.app E/ACodec﹕ onConfigureComponent mime.c_str() = video/avc 
05-05 13:18:14.685 22393-22588/ca.example.app E/ACodec﹕ [OMX.qcom.video.decoder.avc] storeMetaDataInBuffers failed w/ err -2147483648 
05-05 13:18:14.685 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] DRC Mode: Port Reconfig Mode 
05-05 13:18:14.685 22393-22588/ca.example.app W/ACodec﹕ do not know color format 0x7fa30c03 = 2141391875 
05-05 13:18:14.735 22393-22588/ca.example.app I/ExtendedCodec﹕ Decoder will be in frame by frame mode 
05-05 13:18:14.735 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] OMX_QCOM_FramePacking_OnlyOneCompleteFrame is setting 
05-05 13:18:14.765 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] Now Loaded->Idle 
05-05 13:18:14.795 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] configureOutputBuffersFromNativeWindow setBufferCount : 22, minUndequeuedBuffers : 4 
05-05 13:18:14.795 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] Allocating 22 buffers from a native window of size 294912 on output port 
05-05 13:18:14.805 22393-22588/ca.example.app E/ACodec﹕ dequeueBuffer failed: Invalid argument (22) 
05-05 13:18:14.805 22393-22588/ca.example.app E/ACodec﹕ Failed to allocate buffers after transitioning to IDLE state (error 0xffffffea) 
05-05 13:18:14.805 22393-22588/ca.example.app E/ACodec﹕ signalError(omxError 0x80001001, internalError -22) 
05-05 13:18:14.805 22393-22588/ca.example.app I/ACodec﹕ [OMX.qcom.video.decoder.avc] Now Loaded 
05-05 13:18:14.805 22393-22587/ca.example.app E/MediaCodec﹕ Codec reported err 0xffffffea, actionCode 0, while in state 5 
05-05 13:18:14.805 22393-22586/ca.example.app E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-2272 
    Process: ca.example.app, PID: 22393 
    android.media.MediaCodec$CodecException: start failed 
      at android.media.MediaCodec.native_start(Native Method) 
      at android.media.MediaCodec.start(MediaCodec.java:612) 
      at ca.example.app.StreamActivity$StreamingVideoThread.run(StreamActivity.java:975) 
      at java.lang.Thread.run(Thread.java:818) 

我测试主要是对三星Galaxy S4是在安卓5.0.1。我有一种感觉这个设备不支持MediaCodec?

UPDATE

如果我删除所有的mediaFormat.setInteger调用,则媒体编解码器启动正常。由于我的h264流具有每隔'n'帧的SPS/PPS信息,所以媒体编解码器也开心地工作。定时信息关闭,它正在播放视频方式来快速,但这是一个不同的问题。

回答

0

的mediaFormat.setInteger要求您使用仅用于编码器,请参阅Android Developer's site

快速播放的视频可以通过使用presentationTimeUS控制。例如,对于具有25fps的影片的presentationTimeUS值应通过40000对于每帧即[(1 /帧速率)* 1000000](以微秒为一帧的持续时间)

decoder.queueInputBuffer(inIndex,0,buffer.length,presentationTimeUS,0); 
2

你的正确的三星递增S4不支持媒体编解码器。它确实有用,但它很迂腐,并且不能很好地支持回收。

三星S4和S6给了我无法抗拒的麻烦。三星A5完美的作品像HTC一样,SONT,LG的Nexus等所有其他设备

对于三星S4则需要进行以下配置:

mediaFormat.SetInteger(MediaFormat.KeyMaxWidth, SelectedPalette.Value.Width); 
mediaFormat.SetInteger(MediaFormat.KeyMaxHeight, SelectedPalette.Value.Height); 
mediaFormat.SetInteger(MediaFormat.KeyMaxInputSize, SelectedPalette.Value.Width * SelectedPalette.Value.Height); 

(这是Xamarin顺便说一句,但电话是与Java相同)。然后,您必须尝试捕获mediaCodec.doSomething()的所有用法。

如果你有足够高的API级别,你应该使用异步解码器回调android 21+。你也应该使用mediaCodec.Reset();在任何异常情况下,您都应尽最大努力将解码器尽可能重置为原始状态:

+0

上述配置如何适用于samsung s4?有没有关于三星的任何文件? – Ajit