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); }
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); } } } }
void g_omx_core_pause (GOmxCore *core) { change_state (core, OMX_StatePause); wait_for_state (core, OMX_StatePause); }
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"); }
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); } }
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); }
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); } }
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); }
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); }
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"); }
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); }
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"); }
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); }
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"); }
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"); }
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); }
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); }
void g_omx_core_change_state (GOmxCore *core, OMX_STATETYPE state) { change_state (core, state); wait_for_state (core, state); }
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; }