Medicodec dequeue out failing with ImagerReader


I'm adding imagereader support in VLC-Android decoder pipeline. VLC has OutThread for dequeuing output and another thread for queuing input. When buffers are used dequeue_out (wrapper for AMediaCodec_dequeueOutputBuffer) returns valid values but when using imagereader dequeue_out returns undefined negative value.

Why is it not working with imagereader? If there is a problem with input thread then it should also not work with buffers. But when I use imagereader it fails at dequeue_out (returns invalid index due to which OutThread aborts).

static void *OutThread(void *data)
{
    decoder_t *p_dec = data;
    decoder_sys_t *p_sys = p_dec->p_sys;

    vlc_thread_set_name("vlc-mediacodec");

    vlc_mutex_lock(&p_sys->lock);
    while (!p_sys->b_aborted)
    {
        int i_index;

        /* Wait for output ready */
        if (!p_sys->b_flush_out && !p_sys->b_output_ready) {
            vlc_cond_wait(&p_sys->cond, &p_sys->lock);
            continue;
        }

        if (p_sys->b_flush_out)
        {
            /* Acknowledge flushed state */
            p_sys->b_flush_out = false;
            vlc_cond_broadcast(&p_sys->dec_cond);
            continue;
        }

        vlc_mutex_unlock(&p_sys->lock);

        /* Wait for an output buffer. This function returns when a new output
         * is available or if output is flushed. */
        i_index = p_sys->api.dequeue_out(&p_sys->api, -1);

        vlc_mutex_lock(&p_sys->lock);

        /* Ignore dequeue_out errors caused by flush, or late picture being
         * dequeued after close. */
        if (p_sys->b_flush_out || p_sys->b_decoder_dead)
        {
            /* If i_index >= 0, Release it. There is no way to know if i_index
             * is owned by us, so don't check the error. */
            if (i_index >= 0)
                p_sys->api.release_out(&p_sys->api, i_index, false);

            /* Parse output format/buffers even when we are flushing */
            if (i_index != MC_API_INFO_OUTPUT_FORMAT_CHANGED
             && i_index != MC_API_INFO_OUTPUT_BUFFERS_CHANGED)
                continue;
        }

        if (i_index == MC_API_ERROR)
        {
            msg_Warn(p_dec, "Failure in MediaCodec.dequeueOutputBuffer");
            break;
        }

        /* Process output returned by dequeue_out */
        if (i_index >= 0 || i_index == MC_API_INFO_OUTPUT_FORMAT_CHANGED
         || i_index == MC_API_INFO_OUTPUT_BUFFERS_CHANGED)
        {
            struct mc_api_out out;
            int i_ret = -1;
            if (p_sys->api.b_support_imagereader)
            {
                if (i_index > 0)
                {
                    p_sys->api.release_out(&p_sys->api, i_index, true);
                    if (p_sys->api.b_support_imagereader && !p_sys->b_img_ready)
                    {
                        vlc_cond_wait(&p_sys->img_cond, &p_sys->lock);
                    }

                    p_sys->b_img_ready = false;
                    i_ret = p_sys->api.acquire_latest_image(&p_sys->api, i_index, &out);
                }
                else if (i_index == MC_API_INFO_OUTPUT_FORMAT_CHANGED)
                {
                    p_sys->api.update_format(&p_sys->api, i_index, &out);
                }
            }
            else
            {
                i_ret = p_sys->api.get_out(&p_sys->api, i_index, &out);
            }

            if (i_ret == 1)
            {
                picture_t *p_pic = NULL;
                block_t *p_block = NULL;

                if (p_sys->pf_process_output(p_dec, &out, &p_pic,
                                             &p_block) == -1 && !out.b_eos)
                {
                    msg_Err(p_dec, "pf_process_output failed");
                    break;
                }
                if (p_pic)
                    decoder_QueueVideo(p_dec, p_pic);
                else if (p_block)
                    decoder_QueueAudio(p_dec, p_block);

                if (out.b_eos)
                {
                    msg_Warn(p_dec, "EOS received");
                    p_sys->b_drained = true;
                    vlc_cond_signal(&p_sys->dec_cond);
                }
            } else if (i_ret != 0)
            {
                msg_Err(p_dec, "get_out failed");
                break;
            }
        }
        else
            break;
    }
    if (!p_sys->b_decoder_dead)
        msg_Warn(p_dec, "OutThread stopped");

    /* Signal DecoderFlush that the output thread aborted */
    p_sys->b_aborted = true;
    vlc_cond_signal(&p_sys->dec_cond);
    vlc_mutex_unlock(&p_sys->lock);

    return NULL;
}
2
Jul 14 at 1:27 PM
User AvatarMangal K
#android#c#android-ndk#android-mediacodec

No answer found for this question yet.