This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

in ICS : OMX event OMX_TI_EventBufferRefCount is removed comparing with GB

Hello:

I am developing gst-openmax on ICS 4.0.3 blaze tablet, currently, found that decoded frame is not right (eg, 1st, 2nd, 3rd, 4th, 5th frame is right, 6th and 7th are exactly same hex, 10 th and 11th are same hex ), but gst-openmax works well on GB, btw, stagefright also works well on ICS.

some findings :

1. some buffers are flagged with OMX_TI_BUFFERFLAG_READONLY, in GB, after the event OMX_TI_EventBufferRefCount, the buf will be unref,  but in ICS, event OMX_TI_EventBufferRefCount is never coming.

2. event OMX_IndexConfigCommonOutputCrop, the crop information is not same with stagefright for same h264 file

  crop is [32, 24, 1280, 720] for gst-openmax on ics

  crop is [32, 24, 1408, 816] for stagefright on ics, which could play well.

Thanks in advance for your information.

  • About OMX_TI_EventBufferRefCount, be sure to be calling OMX_TI_IndexConfigBufferRefCountNotification with correct values, this structure is set onlt using OMX_GetConfig and OMX_SetConfig and check that it is called after port definitions are set. The definition is in next file

    ./mydroid/hardware/ti/domx/omx_core/inc/OMX_TI_Common.h

    typedef struct OMX_TI_CONFIG_BUFFERREFCOUNTNOTIFYTYPE
    {
        OMX_U32 nSize;
        OMX_VERSIONTYPE nVersion;
        OMX_U32 nPortIndex;
        OMX_BOOL bNotifyOnIncrease;
        OMX_BOOL bNotifyOnDecrease;
        OMX_U32 nCountForNotification;
    }OMX_TI_CONFIG_BUFFERREFCOUNTNOTIFYTYPE;

    ./mydroid/hardware/ti/domx/omx_core/inc/OMX_TI_Index.h

        OMX_TI_IndexConfigBufferRefCountNotification,       /**< 0x7F000056 reference: OMX_TI_CONFIG_BUFFERREFCOUNTNOTIFYTYPE */

    In GST_OpenMax after searching for it I can find it in

    ./gst/gst-openmax/omx/gstomx_port.c

    check that proper defines are ok, USE_OMXTICORE, by checking data for OMX_TI_IndexParamBufferPreAnnouncement this value needs to be set in OMX_StateLoaded of when ports are disabled.

    For Crop information, this value must not be affecting if the file is 720p, because padded values needs to be only for allocation, can you check what are the resolution values for regular port setting changed? the events that happens before this crop event, those must be padded values, and how many events are you receiving and how many are being handled?

  • Hello Manuel:

    thanks for information.

    1, I checked the code, OMX_TI_IndexConfigBufferRefCountNotification is really disable, after re-enable it, found, the data1 is not OMX_BUFFERHEADERTYPE, but remoteBufHdr; found function  PROXY_EventHandler in domx/omx_proxy_common/src/omx_proxy_common.c,

      switch (eEvent)
      {
    #if 0 // This feature is currently not supported, so kept in if(0) to be supported in the future ==>
      case OMX_TI_EventBufferRefCount:
        DOMX_DEBUG("Received Ref Count Event");
        /*nData1 will be pBufferHeader, nData2 will be present count. Need to find local
           buffer header for nData1 which is remote buffer header */
    after change the above event to correct, gstomx_core eventhandler could get correct OMX_BUFFERHEADERTYPE, it appears the same problem, so maybe this is not root reason for my chaos decoded frames.

    2. About the events received:

        1): OMX_EventCmdComplete  -  OMX_CommandPortDisable

                  OMX_EventCmdComplete  -  OMX_CommandPortEnable

       2):  OMX_EventPortSettingsChanged data_2 =0, received for 1st time,

                nFrameWidth = 1408  --> previously is 1280 allocated for port buf

                nFrameHeight = 816    --> previously is 720 allocated for port buf

                nBufferCountActual = 5 --> for stagefright , this is 7 when OMX_EventPortSettingsChanged received

                nBufferCountMin = 3     --> for stagefright , this is 5 when OMX_EventPortSettingsChanged received

                For this event processing

                Disable output port , and free its buf

                Enable output port , and allocate its buf (5* 1408 * 816)

       3):  OMX_EventPortSettingsChanged, data_2 =0,  received for 2st time,  ===> I do not know why we have the event twice (portSettingChanged, data2=0)
                nFrameWidth = 1408 

                nFrameHeight = 816  

                nBufferCountActual = 7 --> changed comparing with 1st OMX_EventPortSettingsChanged event received

                nBufferCountMin = 5     --> changed comparing with 1st OMX_EventPortSettingsChanged event received

                For this event processing

                Disable output port , and free its buf

                Enable output port , and allocate its buf (7* 1408 * 816)

        4) :  OMX_EventPortSettingsChanged, data_2 == OMX_IndexConfigCommonOutputCrop

               [32, 24, 1280, 720], comparing with stagefright [32, 24, 1408, 816];

    And for native window buffer count :

    change :

    native_window_set_buffer_count (def.nBufferCountActual+4) , this is to have enough buffer count allocation.

    And in my test, it seams, only the first 3 frame (0, 1, 2) yuv data are correct, frame 4, 5, 6, 7, 8 are same, frame 9  10 11 are same,  frame 12  13 14 are same,  frame 15 16 17 18 19 are same...

    Could you give some suggestion? thanks.

  • About #1,

    I missed that part of DOMX, basically you answered this questions.

    About #2,

    I was going to say that you could be using OMX_IndexConfigCommonOutputCrop for allocating Android native buffers, I need to check if this value is used only to configure Surface and buffers allocate with padded values, and the thing about you adding +4 buffers to the count that could not be ok if you are adding those to native buffers only and not to DOMX component, because those extra buffers are not going to be with DOMX OMX_UseBuffer function.

  • Hello Manuel:

    Thanks, I have 2 questions:

    Question 1:

    Currently we send 1st buffer to OMX is arranged as (SPS + PPS + encoded data) , do we have to send SPS, PPS and encoded data separately, I do not know whether it is related with event  OMX_EventPortSettingsChanged, data_2 =0,  received for twice.

    1) 1st OMX_EventPortSettingsChanged, nFrameWidth, nFrameHeight changed .

    2) 2nd OMX_EventPortSettingsChanged, nBufferCountActual = 5   -->  changed to 7

        nBufferCountMin = 3   --> changed to 5


    Question 2:

    And for Event OMX_EventPortSettingsChanged, data_2 == OMX_IndexConfigCommonOutputCrop,

    It seams once received this event, the buffer sent to OMX will have error decoded yuv . (OMX and native window have same buffer count)

    eg:  nBufferCountActual=7,  buffer 0, 1, 2, 3, 4, these 5 buffer will sent to OMX when OMX change state to OMX_StateExecuting;

    And the decoded yuv are correct for these 5 buffer.

    After OMX_EventPortSettingsChanged ,set native window to [32, 24, 1280+32, 720+24], I was wrong previouly.

    and after these,  OMX decoded yuv are error, buffer 5 is exactly with buffer 4, without error information from OMX or ducati.

    And in file, omx_proxy_component/omx_video_dec/src/omx_proxy_videodec.c, function PROXY_VIDDEC_FillBufferDone,

    pCompPrv->grallocModule->lock also failed to lock decoded data, once event OMX_EventPortSettingsChanged, and native window crop set.



    Thanks.

  • The duplicated calls are because what you say for SPS+PPS+iframe in first buffer, you need to send SPS+PPS in first buffer then Ducati is  going to get configured and then is going to be able to process first iframe.

  • Hello Manuel:

    With your suggestion, send SPS+PPS in first buffer, then IFrame in second buffer, my first question is fixed, OMX_EventPortSettingsChanged, data2=0, is received once with correct portDefinations. Thank you so much.

    And about gst-openmax decode output exactly same yuv buffer data issue, could you give some advice? Thanks in advance.

    After Event OMX_EventPortSettingsChanged, data_2 == OMX_IndexConfigCommonOutputCrop, OMX output buffer, the serials of yuv buffer contains same data.

    It seams once received this event, the buffer sent to OMX will have several exactly same decoded yuv .

    eg:  nBufferCountActual=7, Buffer 0, 1, 2, 3, 4, these 5 buffer are sent to OMX when OMX change state to OMX_StateExecuting; And the decoded yuv are correct for these 5 buffer.

    After event OMX_EventPortSettingsChanged ,OMX_IndexConfigCommonOutputCrop, set native window to [32, 24, 1280+32, 720+24]; 

    When every FillBufferDone received, dequeue native window and send buffer (id=5) to OMX by fillThisBuffer.

    I dump the raw yuv data in function PROXY_VIDDEC_FillBufferDone. Found:

    The output of buffer (id= 5) is exactly same with buffer 4, hence, the output buffer  5,6, 7, 8  are also exactly same with buffer 4;

    The output buffer 9 changed, but buffer 10 HEX is same with buffer 9;

    The output buffer 11 changed, but buffer 12, 13, 14 HEX are all same with buffer 11;

    The output buffer 15 changed, but buffer 16, 17, 18, 19, 20, 21, 22, 23, 24 are exactly same HEX value......

     

    So after receive event OMX_EventPortSettingsChanged(OMX_IndexConfigCommonOutputCrop), the output buffers sent to OMX, the decoded yuv are error, buffer 5 is exactly with buffer 4, without error information from OMX or ducati.

    Could you give me some advice for my check/debug.  Thanks you so much.

     

     

  • I have mainly 2 ideas;

    1. The input data is being the same all the time when it is repeated.

    2. the output buffers have some issue, do you remember the dup message that was appearing?

    Next are some suggestions,

    1. try to dump full input buffer with pBuffer address and buffer header information too, this is to check what the input is for decoder. Under the base that duplicated buffers can be at both ports, starting point is input port, and like I don't know what code is behind this point. You must check that data for each buffer is different and the pointer is not getting repeated, this is, it must exist a sequence of pointers, if you start buffer movement with sequence 1,2,3,4 then this must be the same all the time, even when you do a flush counting buffers at Client IL and inside the component must match in sequence. For error cases, in this case it happens in the first 10 buffers what is relatively easy to debug, sometimes this happens after a seek or at the middle of the file and following the sequence gets not that easy. If you see 3,1,4,2 or 1,4,2,2,4,1,1 after some time then something is getting wrong, 1,2,3,4 means symbolic numbers for buffer pointers.

    2. You need to check the same output, if buffers are correct at input but in output some buffers are duplicated then one buffer overwrite the other, what seems described behavior in your last post.

    3. Check that input file is correct, it could have some corrupted frames or it could be that the video sequence contains the same picture for many frames, but in this case you will need to compare the full buffer to check for some small difference in the picture between frames.

    4. Check if input files has bframes, this behavior is seen in some files with bframes, other times with unsupported levels where some frames gets an error and the information stored in those buffers is not erased or filledlen is not cleared before sending to output buffer to be fill, check decoding process with many files and try setting the nFilledLen to zero before sending the output buffer. Sometimes it happens to use the same file when developing and after some time we found that it was incorrect at some point or it doesn't contains some characteristic that we needed to test some feature, just a comment.

    5. Other thing to check is how buffers are written to a file, I mean it is very difficult that it fails, but for example if you wrote a complex code to optimize this process and in the middle some of the buffers is being returned to this write queue and it is duplicated then it matches the actual issue. This comment could not be that realistic, but it is a possibility, and like I am not aware of how you are measuring or testing the output, if it is by dumping buffers or at the final processed output file.

    For now this is what I can think about check/debugging the issue.

  • Hello Manuel:

    Thanks for detailed help information.

    After some investigation.it seams the reason is because the OMX header sent to OMX_BUFFERHEADERTYPE is not binded with the native buffer handle.

    That means:

    1) OMX_UseBuffer(hComponent, ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer) , ppBufferHdr and pBuffer sent to OMX at the beginning.

    2) But the later buffers sent to OMX is not such binded,

          eg : ppBufferHdr_1 and pBuffer=pBuffer_5 (native buffer handle) sent to OMX by OMX_FillThisBuffer; (KO)

                 ppBufferHdr_1 and pBuffer=pBuffer_1 (native buffer handle) sent to OMX by OMX_FillThisBuffer; (OK)      

    After bind/map the ppBufferHdr and pBuffer , OMX decoder works. DO you know above OMX premise is introduce since android 4.0?

  • That is great to know that is working now.

    I think I don't understand you last question, if you refer to the fact to send the specific buffer for each OMX_BUFFERHEADERTYPE, for what I know it is from OMX specification and under the logic that if you say the OMX component to use certain buffer for the buffer header then it must be used for it. I don't know for a specific change that checks this fact, but there must be some.

    For what I can imagine but not sure, the possible issue could be that following your error description the error could be caused when other buffer is assigned to a buffer header many times, and that causes the repetitive frames, this if there is no logic in the background to control this.