Пример #1
0
static av_cold void cleanup(OMXCodecContext *s)
{
    int i, executing;

    pthread_mutex_lock(&s->state_mutex);
    executing = s->state == OMX_StateExecuting;
    pthread_mutex_unlock(&s->state_mutex);

    if (executing) {
        OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        wait_for_state(s, OMX_StateIdle);
        OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
        for (i = 0; i < s->num_in_buffers; i++) {
            OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->input_mutex, &s->input_cond,
                                                      &s->num_free_in_buffers, s->free_in_buffers, 1);
            if (s->input_zerocopy)
                buffer->pBuffer = NULL;
            OMX_FreeBuffer(s->handle, s->in_port, buffer);
        }
        for (i = 0; i < s->num_out_buffers; i++) {
            OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->output_mutex, &s->output_cond,
                                                      &s->num_done_out_buffers, s->done_out_buffers, 1);
            OMX_FreeBuffer(s->handle, s->out_port, buffer);
        }
        wait_for_state(s, OMX_StateLoaded);
    }
    if (s->handle) {
        s->omx_context->ptr_FreeHandle(s->handle);
        s->handle = NULL;
    }

    omx_deinit(s->omx_context);
    s->omx_context = NULL;
    if (s->mutex_cond_inited) {
        pthread_cond_destroy(&s->state_cond);
        pthread_mutex_destroy(&s->state_mutex);
        pthread_cond_destroy(&s->input_cond);
        pthread_mutex_destroy(&s->input_mutex);
        pthread_cond_destroy(&s->output_cond);
        pthread_mutex_destroy(&s->output_mutex);
        s->mutex_cond_inited = 0;
    }
    av_freep(&s->in_buffer_headers);
    av_freep(&s->out_buffer_headers);
    av_freep(&s->free_in_buffers);
    av_freep(&s->done_out_buffers);
    av_freep(&s->output_buf);
}
Пример #2
0
void
g_omx_core_start (GOmxCore *core)
{
    change_state (core, OMX_StateExecuting);

    wait_for_state (core, OMX_StateExecuting);

    {
        guint index;
        guint i;

        for (index = 0; index < core->ports->len; index++)
        {
            GOmxPort *port;

            port = g_omx_core_get_port (core, index);

            for (i = 0; i < port->num_buffers; i++)
            {
                OMX_BUFFERHEADERTYPE *omx_buffer;

                omx_buffer = port->buffers[i];

                got_buffer (core, port, omx_buffer);
            }
        }
    }
}
Пример #3
0
void
g_omx_core_pause (GOmxCore *core)
{
    change_state (core, OMX_StatePause);

    wait_for_state (core, OMX_StatePause);
}
Пример #4
0
void
g_omx_core_pause (GOmxCore *core)
{
    GST_DEBUG_OBJECT (core->object, "begin");
    change_state (core, OMX_StatePause);
    wait_for_state (core, OMX_StatePause);
    GST_DEBUG_OBJECT (core->object, "end");
}
Пример #5
0
void
g_omx_core_finish (GOmxCore *core)
{
    change_state (core, OMX_StateIdle);

    wait_for_state (core, OMX_StateIdle);

    change_state (core, OMX_StateLoaded);

    {
        guint index;
        guint i;

        for (index = 0; index < core->ports->len; index++)
        {
            GOmxPort *port;

            port = g_omx_core_get_port (core, index);

            for (i = 0; i < port->num_buffers; i++)
            {
                OMX_BUFFERHEADERTYPE *omx_buffer;

                omx_buffer = port->buffers[i];

                g_free (omx_buffer->pBuffer);

                OMX_FreeBuffer (core->omx_handle, index, omx_buffer);
            }
        }
    }

    wait_for_state (core, OMX_StateLoaded);

    {
        gint index;
        for (index = 0; index < core->ports->len; index++)
        {
            GOmxPort *port;
            port = g_omx_core_get_port (core, index);
            g_omx_port_free (port);
        }
        g_ptr_array_clear (core->ports);
    }
}
Пример #6
0
void
g_omx_core_start (GOmxCore *core)
{
    change_state (core, OMX_StateExecuting);
    wait_for_state (core, OMX_StateExecuting);

    if (core->omx_state == OMX_StateExecuting)
        core_for_each_port (core, port_start_buffers);
}
Пример #7
0
void
g_omx_core_stop (GOmxCore *core)
{
    if (core->omx_state == OMX_StateExecuting ||
        core->omx_state == OMX_StatePause)
    {
        change_state (core, OMX_StateIdle);
        wait_for_state (core, OMX_StateIdle);
    }
}
Пример #8
0
void
g_omx_core_prepare (GOmxCore *core)
{
    change_state (core, OMX_StateIdle);

    /* Allocate buffers. */
    core_for_each_port (core, port_allocate_buffers);

    wait_for_state (core, OMX_StateIdle);
}
Пример #9
0
static void test(void)
{
    test_context *ctx = &ctx_instance;
    rtems_status_code sc;
    rtems_mode mode;

    ctx->consumer = rtems_task_self();
    ctx->consumer_processor = rtems_get_current_processor();

    sc = rtems_signal_catch(signal_handler, RTEMS_DEFAULT_MODES);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    sc = rtems_task_create(
             rtems_build_name('P', 'R', 'O', 'D'),
             RTEMS_MINIMUM_PRIORITY,
             RTEMS_MINIMUM_STACK_SIZE,
             RTEMS_DEFAULT_MODES,
             RTEMS_DEFAULT_ATTRIBUTES,
             &ctx->producer
         );
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    sc = rtems_task_start(ctx->producer, producer, (rtems_task_argument) ctx);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    check_consumer_processor(ctx);

    wait_for_state(ctx, SIG_0_SENT);
    change_state(ctx, SIG_0_ENABLE);

    sc = rtems_task_mode(RTEMS_ASR, RTEMS_ASR_MASK, &mode);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    wait_for_state(ctx, SIG_0_PROCESSED);

    check_consumer_processor(ctx);

    change_state(ctx, SIG_1_READY);
    wait_for_state(ctx, SIG_1_PROCESSED);

    check_consumer_processor(ctx);
}
Пример #10
0
void
g_omx_core_start (GOmxCore *core)
{
    GST_DEBUG_OBJECT (core->object, "begin");
    change_state (core, OMX_StateExecuting);
    wait_for_state (core, OMX_StateExecuting);

    if (core->omx_state == OMX_StateExecuting)
        core_for_each_port (core, g_omx_port_start_buffers);
    GST_DEBUG_OBJECT (core->object, "end");
}
Пример #11
0
static void producer(rtems_task_argument arg)
{
    test_context *ctx = (test_context *) arg;

    ctx->producer_processor = rtems_get_current_processor();

    rtems_test_assert(ctx->consumer_processor != ctx->producer_processor);

    wait_for_state(ctx, SIG_0_READY);
    signal_send(ctx, SIG_0_SENT);

    check_producer_processor(ctx);

    wait_for_state(ctx, SIG_1_READY);
    signal_send(ctx, SIG_1_SENT);

    check_producer_processor(ctx);

    rtems_task_suspend(RTEMS_SELF);
    rtems_test_assert(0);
}
Пример #12
0
void
g_omx_core_stop (GOmxCore *core)
{
    GST_DEBUG_OBJECT (core->object, "begin");
    if (core->omx_state == OMX_StateExecuting ||
        core->omx_state == OMX_StatePause)
    {
        change_state (core, OMX_StateIdle);
        wait_for_state (core, OMX_StateIdle);
    }
    GST_DEBUG_OBJECT (core->object, "end");
}
Пример #13
0
END_TEST

START_TEST (test_idle)
{
    CustomData *custom_data;
    OMX_ERRORTYPE omx_error;
    OMX_HANDLETYPE omx_handle;

    custom_data = custom_data_new ();

    omx_error = init ();
    fail_if (omx_error != OMX_ErrorNone);

    omx_error = get_handle (&omx_handle, "OMX.check.dummy", custom_data, &callbacks);
    fail_if (omx_error != OMX_ErrorNone);

    custom_data->omx_handle = omx_handle;

    change_state (custom_data, OMX_StateIdle);

    /* allocate_buffers */

    wait_for_state (custom_data, OMX_StateIdle);

    change_state (custom_data, OMX_StateLoaded);

    /* free_buffers */

    wait_for_state (custom_data, OMX_StateLoaded);

    omx_error = free_handle (omx_handle);
    fail_if (omx_error != OMX_ErrorNone);

    omx_error = deinit ();
    fail_if (omx_error != OMX_ErrorNone);

    custom_data_free (custom_data);
}
Пример #14
0
void
g_omx_core_prepare (GOmxCore *core)
{
    GST_DEBUG_OBJECT (core->object, "begin");

    /* Prepare port */
    core_for_each_port (core, port_prepare);

    change_state (core, OMX_StateIdle);

    /* Allocate buffers. */
    core_for_each_port (core, port_allocate_buffers);

    wait_for_state (core, OMX_StateIdle);
    GST_DEBUG_OBJECT (core->object, "end");
}
Пример #15
0
void
g_omx_core_unload (GOmxCore *core)
{
    GST_DEBUG_OBJECT (core->object, "begin");
    if (core->omx_state == OMX_StateIdle ||
        core->omx_state == OMX_StateWaitForResources ||
        core->omx_state == OMX_StateInvalid)
    {
        if (core->omx_state != OMX_StateInvalid)
            change_state (core, OMX_StateLoaded);

        core_for_each_port (core, g_omx_port_free_buffers);

        if (core->omx_state != OMX_StateInvalid)
            wait_for_state (core, OMX_StateLoaded);
    }
    GST_DEBUG_OBJECT (core->object, "end");
}
Пример #16
0
void
g_omx_core_unload (GOmxCore *core)
{
    if (core->omx_state == OMX_StateIdle ||
        core->omx_state == OMX_StateWaitForResources ||
        core->omx_state == OMX_StateInvalid)
    {
        if (core->omx_state != OMX_StateInvalid)
            change_state (core, OMX_StateLoaded);

        core_for_each_port (core, port_free_buffers);

        if (core->omx_state != OMX_StateInvalid)
            wait_for_state (core, OMX_StateLoaded);
    }

    core_for_each_port (core, g_omx_port_free);
    g_ptr_array_clear (core->ports);
}
Пример #17
0
void
g_omx_core_prepare (GOmxCore *core)
{
    change_state (core, OMX_StateIdle);

    /* Allocate buffers. */
    {
        gint index;
        gint i;

        for (index = 0; index < core->ports->len; index++)
        {
            GOmxPort *port;

            port = g_omx_core_get_port (core, index);

            if (port)
            {
                for (i = 0; i < port->num_buffers; i++)
                {
                    gpointer buffer_data;
                    guint size;

                    size = port->buffer_size;
                    buffer_data = g_malloc (size);

                    OMX_UseBuffer (core->omx_handle,
                                   &port->buffers[i],
                                   index,
                                   NULL,
                                   size,
                                   buffer_data);
                }
            }
        }
    }

    wait_for_state (core, OMX_StateIdle);
}
Пример #18
0
void 
g_omx_core_change_state (GOmxCore *core, OMX_STATETYPE state)
{
    change_state (core, state);
    wait_for_state (core, state);
}
Пример #19
0
static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
{
    OMXCodecContext *s = avctx->priv_data;
    OMX_PARAM_COMPONENTROLETYPE role_params = { 0 };
    OMX_PORT_PARAM_TYPE video_port_params = { 0 };
    OMX_PARAM_PORTDEFINITIONTYPE in_port_params = { 0 }, out_port_params = { 0 };
    OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = { 0 };
    OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 };
    OMX_ERRORTYPE err;
    int i;

    s->version.s.nVersionMajor = 1;
    s->version.s.nVersionMinor = 1;
    s->version.s.nRevision     = 2;

    err = s->omx_context->ptr_GetHandle(&s->handle, s->component_name, s, (OMX_CALLBACKTYPE*) &callbacks);
    if (err != OMX_ErrorNone) {
        av_log(avctx, AV_LOG_ERROR, "OMX_GetHandle(%s) failed: %x\n", s->component_name, err);
        return AVERROR_UNKNOWN;
    }

    // This one crashes the mediaserver on qcom, if used over IOMX
    INIT_STRUCT(role_params);
    av_strlcpy(role_params.cRole, role, sizeof(role_params.cRole));
    // Intentionally ignore errors on this one
    OMX_SetParameter(s->handle, OMX_IndexParamStandardComponentRole, &role_params);

    INIT_STRUCT(video_port_params);
    err = OMX_GetParameter(s->handle, OMX_IndexParamVideoInit, &video_port_params);
    CHECK(err);

    s->in_port = s->out_port = -1;
    for (i = 0; i < video_port_params.nPorts; i++) {
        int port = video_port_params.nStartPortNumber + i;
        OMX_PARAM_PORTDEFINITIONTYPE port_params = { 0 };
        INIT_STRUCT(port_params);
        port_params.nPortIndex = port;
        err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &port_params);
        if (err != OMX_ErrorNone) {
            av_log(avctx, AV_LOG_WARNING, "port %d error %x\n", port, err);
            break;
        }
        if (port_params.eDir == OMX_DirInput && s->in_port < 0) {
            in_port_params = port_params;
            s->in_port = port;
        } else if (port_params.eDir == OMX_DirOutput && s->out_port < 0) {
            out_port_params = port_params;
            s->out_port = port;
        }
    }
    if (s->in_port < 0 || s->out_port < 0) {
        av_log(avctx, AV_LOG_ERROR, "No in or out port found (in %d out %d)\n", s->in_port, s->out_port);
        return AVERROR_UNKNOWN;
    }

    s->color_format = 0;
    for (i = 0; ; i++) {
        INIT_STRUCT(video_port_format);
        video_port_format.nIndex = i;
        video_port_format.nPortIndex = s->in_port;
        if (OMX_GetParameter(s->handle, OMX_IndexParamVideoPortFormat, &video_port_format) != OMX_ErrorNone)
            break;
        if (video_port_format.eColorFormat == OMX_COLOR_FormatYUV420Planar ||
            video_port_format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar) {
            s->color_format = video_port_format.eColorFormat;
            break;
        }
    }
    if (s->color_format == 0) {
        av_log(avctx, AV_LOG_ERROR, "No supported pixel formats (%d formats available)\n", i);
        return AVERROR_UNKNOWN;
    }

    in_port_params.bEnabled   = OMX_TRUE;
    in_port_params.bPopulated = OMX_FALSE;
    in_port_params.eDomain    = OMX_PortDomainVideo;

    in_port_params.format.video.pNativeRender         = NULL;
    in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
    in_port_params.format.video.eColorFormat          = s->color_format;
    s->stride     = avctx->width;
    s->plane_size = avctx->height;
    // If specific codecs need to manually override the stride/plane_size,
    // that can be done here.
    in_port_params.format.video.nStride      = s->stride;
    in_port_params.format.video.nSliceHeight = s->plane_size;
    in_port_params.format.video.nFrameWidth  = avctx->width;
    in_port_params.format.video.nFrameHeight = avctx->height;
    if (avctx->framerate.den > 0 && avctx->framerate.num > 0)
        in_port_params.format.video.xFramerate = (1 << 16) * avctx->framerate.num / avctx->framerate.den;
    else
        in_port_params.format.video.xFramerate = (1 << 16) * avctx->time_base.den / avctx->time_base.num;

    err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
    CHECK(err);
    err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
    CHECK(err);
    s->stride         = in_port_params.format.video.nStride;
    s->plane_size     = in_port_params.format.video.nSliceHeight;
    s->num_in_buffers = in_port_params.nBufferCountActual;

    err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
    out_port_params.bEnabled   = OMX_TRUE;
    out_port_params.bPopulated = OMX_FALSE;
    out_port_params.eDomain    = OMX_PortDomainVideo;
    out_port_params.format.video.pNativeRender = NULL;
    out_port_params.format.video.nFrameWidth   = avctx->width;
    out_port_params.format.video.nFrameHeight  = avctx->height;
    out_port_params.format.video.nStride       = 0;
    out_port_params.format.video.nSliceHeight  = 0;
    out_port_params.format.video.nBitrate      = avctx->bit_rate;
    out_port_params.format.video.xFramerate    = in_port_params.format.video.xFramerate;
    out_port_params.format.video.bFlagErrorConcealment  = OMX_FALSE;
    if (avctx->codec->id == AV_CODEC_ID_MPEG4)
        out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
    else if (avctx->codec->id == AV_CODEC_ID_H264)
        out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;

    err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
    CHECK(err);
    err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
    CHECK(err);
    s->num_out_buffers = out_port_params.nBufferCountActual;

    INIT_STRUCT(vid_param_bitrate);
    vid_param_bitrate.nPortIndex     = s->out_port;
    vid_param_bitrate.eControlRate   = OMX_Video_ControlRateVariable;
    vid_param_bitrate.nTargetBitrate = avctx->bit_rate;
    err = OMX_SetParameter(s->handle, OMX_IndexParamVideoBitrate, &vid_param_bitrate);
    if (err != OMX_ErrorNone)
        av_log(avctx, AV_LOG_WARNING, "Unable to set video bitrate parameter\n");

    if (avctx->codec->id == AV_CODEC_ID_H264) {
        OMX_VIDEO_PARAM_AVCTYPE avc = { 0 };
        INIT_STRUCT(avc);
        avc.nPortIndex = s->out_port;
        err = OMX_GetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
        CHECK(err);
        avc.nBFrames = 0;
        avc.nPFrames = avctx->gop_size - 1;
        switch (s->profile == FF_PROFILE_UNKNOWN ? avctx->profile : s->profile) {
        case FF_PROFILE_H264_BASELINE:
            avc.eProfile = OMX_VIDEO_AVCProfileBaseline;
            break;
        case FF_PROFILE_H264_MAIN:
            avc.eProfile = OMX_VIDEO_AVCProfileMain;
            break;
        case FF_PROFILE_H264_HIGH:
            avc.eProfile = OMX_VIDEO_AVCProfileHigh;
            break;
        default:
            break;
        }
        err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
        CHECK(err);
    }

    err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    CHECK(err);

    s->in_buffer_headers  = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
    s->free_in_buffers    = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
    s->out_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
    s->done_out_buffers   = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
    if (!s->in_buffer_headers || !s->free_in_buffers || !s->out_buffer_headers || !s->done_out_buffers)
        return AVERROR(ENOMEM);
    for (i = 0; i < s->num_in_buffers && err == OMX_ErrorNone; i++) {
        if (s->input_zerocopy)
            err = OMX_UseBuffer(s->handle, &s->in_buffer_headers[i], s->in_port, s, in_port_params.nBufferSize, NULL);
        else
            err = OMX_AllocateBuffer(s->handle, &s->in_buffer_headers[i],  s->in_port,  s, in_port_params.nBufferSize);
        if (err == OMX_ErrorNone)
            s->in_buffer_headers[i]->pAppPrivate = s->in_buffer_headers[i]->pOutputPortPrivate = NULL;
    }
    CHECK(err);
    s->num_in_buffers = i;
    for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
        err = OMX_AllocateBuffer(s->handle, &s->out_buffer_headers[i], s->out_port, s, out_port_params.nBufferSize);
    CHECK(err);
    s->num_out_buffers = i;

    if (wait_for_state(s, OMX_StateIdle) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateIdle\n");
        return AVERROR_UNKNOWN;
    }
    err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    CHECK(err);
    if (wait_for_state(s, OMX_StateExecuting) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateExecuting\n");
        return AVERROR_UNKNOWN;
    }

    for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
        err = OMX_FillThisBuffer(s->handle, s->out_buffer_headers[i]);
    if (err != OMX_ErrorNone) {
        for (; i < s->num_out_buffers; i++)
            s->done_out_buffers[s->num_done_out_buffers++] = s->out_buffer_headers[i];
    }
    for (i = 0; i < s->num_in_buffers; i++)
        s->free_in_buffers[s->num_free_in_buffers++] = s->in_buffer_headers[i];
    return err != OMX_ErrorNone ? AVERROR_UNKNOWN : 0;
}