0

I have been trying to use OMXCodec through Stagefright. I have implemented the code for ICS version of Android.I have two classes CustomDataSource which derives MediaSource and another is CustomOmxCodec which calls OMXCodec::Create method and execute read operation to decode h264 frames. I have tested this implementation on a device with omx.google.video.avc software decoder and it works fine. Now, when I try to run the same implementation on an android phone with hardware h264 decode, it returns error on read call. The error is as below:

[OMX.MTK.VIDEO.DECODER.AVC] ERROR (0x80001005, 0)

0x80001005 is for OMX_ErrorBadParameter. and I get the error code -1103 on read operation. I tried various parameters but no success.

The complete log is as below:

[OMX.MTK.VIDEO.DECODER.AVC] mVideoInputErrorRate (0.000000)

!@@!>>create tid (21087) O<XCodec mOMXLivesLocally=0, mIsVideoDecoder (1), mIsVideoEncoder (0), mime(video/avc)

[OMX.MTK.VIDEO.DECODER.AVC] video dimensions are 640X480

mSupportesPartialFrames 1 err 0

[OMX.MTK.VIDEO.DECODER.AVC] allocating 10 buffers of size 65536 on input port.

[OMX.MTK.VIDEO.DECODER.AVC] mMemHeapBase = 0x00E8C288,  mOutputBufferPoolMemBase=0x51F8E000, size  = 9578848

[OMX.MTK.VIDEO.DECODER.AVC] ERROR (0x80001005, 0)

OMXCodec::onEvent--OMX Bad Parameter!!

Read Error : -1103

I'd grateful for any direction on this.

nalply
  • 26,770
  • 15
  • 78
  • 101
sam18
  • 631
  • 1
  • 10
  • 24

3 Answers3

2

From the question, the hardware codec i.e. OMX.MTK.VIDEO.DECODER.AVC is not supporting one of the parameters being passed as part of the configuration steps.

From OMXCodec::create, configureCodec will be invoked which internally invokes a lot of other functions. Since the error is coming as part of OMXCodec::onEvent, one of the possible scenarios could be that the component encountered an error while decoding the first few bytes of the first frame.

Specifically, when the component encounters SPS and PPS (part of codec specific data), the component would typically trigger a portSettingsChanged. From your response, I feel that during this process, there is some error and hence, onEvent has been triggered.

Please share more logs to analyze further.

Anitha
  • 21
  • 1
  • Thanks for your response. I haven't set kKeyAVCC parameters. Is it necessary OR recommended to define kKeyAVCC? I am integrating stagefright to decode frame by frame. and I am parsing encoded frames from my frames collection, not from mp4 or any other media container. So in this case, is it possible to set sps and pps to kKeyAVCC? Will share more logs in sometime. – sam18 Mar 19 '13 at 10:13
  • @sam18 The android code should be the same for both Emulator and hardware. Hence, I presume kKeyAVCC is already being passed as the first buffer to the decoder. The issue seems to be stemming from something else. From your logs, the error seems to be occuring during the creation of output buffers. Can you please share the complete logs? – Ganesh Mar 19 '13 at 14:06
1

The MTK H264 decoder need the parameter csd-0 and csd-1 to init the decoder(You can get some information at http://developer.android.com/reference/android/media/MediaCodec.html). csd-0 and csd-1 stands for SPS and PPS of H264.I have asked a MTK engineer and he said that we can use the code below to set these two parameters.

byte[] sps = {0,0,0,1,103,100,0,40,-84,52,-59,1,-32,17,31,120,11,80,16,16,31
              ,0,0,3,3,-23,0,0,-22,96,-108};
byte[] pps = {0,0,0,1,104,-18,60,-128};
MediaFormat mFormat = MediaFormat.createVideoFormat("video/avc", width, height);
mFormat.setByteBuffer("csd-0", ByteBuffer.wrap(sps));
mFormat.setByteBuffer("csd-1", ByteBuffer.wrap(pps));

Maybe that's whay we got the OMX Bad Parameter error message.

Austias
  • 19
  • 1
0

From the logs and mapping the same to the implemented code, I feel that the following is happening

[OMX.MTK.VIDEO.DECODER.AVC] allocating 10 buffers of size 65536 on input port.

This step allocates the buffers on the input port of the decoder

From the flow of code, after input port buffers are allocated, the buffers on output port are allocated from nativeWindow through allocateOutputBuffersFromNativeWindow.

One of the steps as part of this method implementation is to increase the number of buffers on the output port by 2 and set the same to the OMX component as shown here.

I feel your error might be stemming from this specific point as nBufferSize is a read-only parameter of OMX_IndexParamPortDefinition index. Please refer to the OMX Standard, section 3.1.3.12.1, page 83, which clearly shows that nBufferSize is a read-only parameter.

It appears that your OMX component may be strictly OMX compliant component, whereas in Android from ICS onwards, certain deviations are expected. This could be one of the potential causes of your error.

P.S: If you could share more information, we could help further.

Ganesh
  • 5,880
  • 2
  • 36
  • 54
  • thanks a lot for indepth information.i can dig deeper using your information. i have pasted all logs which i found in logcat. is there any onther way to generate omx specific logs? – sam18 Mar 19 '13 at 16:14
  • @sam18 you can add more logs in `OMXCodec` and enable logs in `OMXNodeInstance` also. Please use `Codec_LOGV` construct in `OMXCodec` to differentiate between the different codec prints. If you can contact the `OMX` component developer, please check if the `OMX` component supports the deviations mentioned in my post. – Ganesh Mar 19 '13 at 16:17
  • you said the problem is lying whithin output buffer creation process on first read opeation. This make me guess a cause of problem. While Creating videosource using OMXCodec::Create method, I am not passing pointer of sp as last parameter, instead I am passing null. because I wanted to render surface under my control. Can this be the reason of my issue? As there is no surface for which hardware decoder can allocate the output buffer so it fails with error code -1103 and throws (0x80001005, 0) for ERR Bad Parameter. – sam18 Mar 20 '13 at 07:02
  • @sam18 If you don't provide the `nativeWindow` and pass `NULL`, the component will either allocate the buffer on it's own through `OMX_AllocateBuffer` if `kRequiresAllocateBufferOnOutputPorts` is set for your component OR `OMXCodec` will itself create the buffer and invoke a `OMX_UseBuffer`. Your read will invoke a `OMXCodec::start` which will feed the buffers for input and output ports and start the processing. You would require more logs to narrow down the issue. Else, we are just guessing potential blocks. – Ganesh Mar 20 '13 at 13:54
  • @sam18 Could you localize the issue further? Any luck? – Ganesh Mar 22 '13 at 04:08
  • Hello Ganesh. As you asked, for more logs OR I should contact the vendor to discuss what you said about output buffer, I was trying for that. But the situation is I want to develope vendor independent appliaction, so I am linking against the phone's libstagefright.so. and hence I cannot access openMAX IL from stagefright layer. Which make me stuck. But...There are other informations I want to share with you. – sam18 Mar 22 '13 at 08:30
  • I am testing on Micromax Ninja A89, which has MTK6577 chipset which provides OMX.MTK.VIDEO.DECODER.AVC. I crosscheck the hardware decoder with MxPlayer for android which gives option to select SW/HW/HW+ decoders. And I found the same issue with MxPlayer also. Ya, It can initilize and even can decode first few frames also but it dies after that. Even VLC beta also hangup. So I guess the h264's bitstream structure cannot be handled by MediaTek. Then I tested On Samsung Galaxy S3, which has Exynos4412 chipset. It has OMX.SEC.avc.dev component. it can decode h264 frames successfully. – sam18 Mar 22 '13 at 08:41
  • I have other issues too, for software and harware decoding operations. But currently I am focusing for stable decoding operation. Once it get done, I will focus on other issues like multiple omx instance buffer issue and parallel omxcodec initilization etc. One more thing to ask you is can I forcefully initilize OMX.google.h264.decoder? I tried kSoftwareOnly flag for OMXCodec::Create method but not working. Do I need to use IOMX instance from Media Service, to access openMAX IL api? – sam18 Mar 22 '13 at 08:48
  • @sam18.. I think the flag is `kSoftwareCodecsOnly` which should be successful. Can you please try with this flag? From an application developer point of view, I think your strategy of working at `OMXCodec` level is correct. – Ganesh Mar 22 '13 at 08:55
  • OMXCodec level means using libstagefright.so right? Your last statement gives me relief. pardon me for the flag name. I was mentioning about kSoftwareCodecsOnly. In some other post you mentioend that according to HW decoder integration routine, the custome component is register at lower index no, compare to software component such that by default hardware decoder is accessed. Let me give some more try and will let you know. – sam18 Mar 22 '13 at 09:03
  • @sam18 .. ok Good luck.. in fact if you plan to move to `JellyBean`, I would recommend you to work at `MediaCodec` level. Good luck with decoders.. I am around in case you require any help from me – Ganesh Mar 22 '13 at 09:04
  • I want to try to support lower versions so I prefered stagefright. Let me see. Thanks a lot. If other applications can decode using HW decoder then I should also. – sam18 Mar 22 '13 at 09:07
  • @sam18.. What happened.. did your code work as expected? Can we also close this question? – Ganesh Mar 28 '13 at 06:38
  • The last status is, my problem is not solved yet. When listing components through IOMX instance through media service it retrives all hardware and software components but when I try to call OMXCodec::Create for OMX.google.h264.decoder component it fails. – sam18 Mar 29 '13 at 05:35
  • @sam18.. Do you have logs when it fails? Also, can you check by adding this component to `media_codecs.xml` in case it isn't already done? – Ganesh Mar 29 '13 at 13:47
  • I come to know that there are two types of bitstream structure for H264 compressed frame. One is annexb and another is avcc. Hardware decoder must be capable to handle both type of bitstream structure. Mp4 file follows avcc structure for h264 data. So, if a vendor's hardware decoder can play Mp4 file than it means it supports avcc structure. If you provide h264 data in annexb format to hardware decoder and it cannot decode than it may be the resone that vendor provided hardware decoder doesnot support annexb format. – sam18 Apr 06 '13 at 12:08
  • @sam18.. `Annex B` will encapsulate a small layer above `RBSP`. Reference: http://wiki.multimedia.cx/index.php?title=H.264 . The underlying decoder doesn't decode the `MP4` file-format but the `video frames` or `NAL` units. So, even in case of `Annex B` streams also, it will be standard `NAL` unit which should be decoded by the decoder. – Ganesh Apr 06 '13 at 13:08