static void CloseDecoder(decoder_t *dec) { decoder_sys_t *sys = dec->p_sys; MMAL_BUFFER_HEADER_T *buffer; if (!sys) return; if (sys->component && sys->component->control->is_enabled) mmal_port_disable(sys->component->control); if (sys->input && sys->input->is_enabled) mmal_port_disable(sys->input); if (sys->output && sys->output->is_enabled) mmal_port_disable(sys->output); if (sys->component && sys->component->is_enabled) mmal_component_disable(sys->component); if (sys->input_pool) mmal_pool_destroy(sys->input_pool); if (sys->output_format) mmal_format_free(sys->output_format); /* Free pictures which are decoded but have not yet been sent * out to the core */ while ((buffer = mmal_queue_get(sys->decoded_pictures))) { picture_t *pic = (picture_t *)buffer->user_data; picture_Release(pic); if (sys->output_pool) { buffer->user_data = NULL; buffer->alloc_size = 0; buffer->data = NULL; mmal_buffer_header_release(buffer); } } if (sys->decoded_pictures) mmal_queue_destroy(sys->decoded_pictures); if (sys->output_pool) mmal_pool_destroy(sys->output_pool); if (sys->component) mmal_component_release(sys->component); vlc_mutex_destroy(&sys->mutex); vlc_sem_destroy(&sys->sem); free(sys); bcm_host_deinit(); }
CMMALVideo::~CMMALVideo() { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, this); assert(m_finished); Reset(); pthread_mutex_destroy(&m_output_mutex); if (m_deint && m_deint->control && m_deint->control->is_enabled) mmal_port_disable(m_deint->control); if (m_dec && m_dec->control && m_dec->control->is_enabled) mmal_port_disable(m_dec->control); if (m_dec_input && m_dec_input->is_enabled) mmal_port_disable(m_dec_input); m_dec_input = NULL; if (m_dec_output && m_dec_output->is_enabled) mmal_port_disable(m_dec_output); m_dec_output = NULL; if (m_deint_connection) mmal_connection_destroy(m_deint_connection); m_deint_connection = NULL; if (m_deint && m_deint->is_enabled) mmal_component_disable(m_deint); if (m_dec && m_dec->is_enabled) mmal_component_disable(m_dec); if (m_dec_input_pool) mmal_pool_destroy(m_dec_input_pool); m_dec_input_pool = NULL; if (m_dec_output_pool) mmal_pool_destroy(m_dec_output_pool); m_dec_output_pool = NULL; if (m_deint) mmal_component_destroy(m_deint); m_deint = NULL; if (m_dec) mmal_component_destroy(m_dec); m_dec = NULL; mmal_format_free(m_es_format); m_es_format = NULL; }
static void ffmmal_poolref_unref(FFPoolRef *ref) { if (ref && avpriv_atomic_int_add_and_fetch(&ref->refcount, -1) == 0) { mmal_pool_destroy(ref->pool); av_free(ref); } }
static MMAL_STATUS_T mmal_connection_destroy_internal(MMAL_CONNECTION_T *connection) { MMAL_STATUS_T status; if (connection->is_enabled) { status = mmal_connection_disable(connection); if (status != MMAL_SUCCESS) return status; } /* Special case for tunnelling */ if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING) { status = mmal_port_disconnect(connection->out); if (status != MMAL_SUCCESS) LOG_ERROR("connection %s could not be cleared", connection->name); } /* Cleanup resources */ if (connection->pool) mmal_pool_destroy(connection->pool); if (connection->queue) mmal_queue_destroy(connection->queue); vcos_free(connection); return MMAL_SUCCESS; }
/* Destroy SVP instance. svp may be NULL. */ void svp_destroy(SVP_T *svp) { if (svp) { MMAL_COMPONENT_T *components[] = { svp->reader, svp->video_decode, svp->camera }; MMAL_COMPONENT_T **comp; /* Stop thread, disable connection and components */ svp_stop(svp); for (comp = components; comp < components + vcos_countof(components); comp++) { mmal_component_disable(*comp); } /* Destroy connection + components */ if (svp->connection) { mmal_connection_destroy(svp->connection); } for (comp = components; comp < components + vcos_countof(components); comp++) { mmal_component_destroy(*comp); } /* Free remaining resources */ if (svp->out_pool) { mmal_pool_destroy(svp->out_pool); } if (svp->queue) { mmal_queue_destroy(svp->queue); } if (svp->created & SVP_CREATED_WD_TIMER) { vcos_timer_delete(&svp->wd_timer); } if (svp->created & SVP_CREATED_TIMER) { vcos_timer_delete(&svp->timer); } if (svp->created & SVP_CREATED_MUTEX) { vcos_mutex_delete(&svp->mutex); } if (svp->created & SVP_CREATED_SEM) { vcos_semaphore_delete(&svp->sema); } vcos_free(svp); } }
/** Disable processing on a port */ MMAL_STATUS_T mmal_port_disable(MMAL_PORT_T *port) { MMAL_POOL_T* pool = NULL; MMAL_STATUS_T status; if (!port || !port->priv) return MMAL_EINVAL; LOG_TRACE("%s(%i:%i) port %p", port->component->name, (int)port->type, (int)port->index, port); if (!port->priv->pf_disable) return MMAL_ENOSYS; LOCK_PORT(port); status = mmal_port_disable_locked(port); if (status == MMAL_SUCCESS) pool = port->priv->core->pool_for_connection; port->priv->core->pool_for_connection = NULL; UNLOCK_PORT(port); if (status == MMAL_SUCCESS && pool) mmal_pool_destroy(pool); return status; }
static void ffmmal_poolref_unref(FFPoolRef *ref) { if (ref && atomic_fetch_add_explicit(&ref->refcount, -1, memory_order_acq_rel) == 1) { mmal_pool_destroy(ref->pool); av_free(ref); } }
/** Disconnect a connected port. */ MMAL_STATUS_T mmal_port_disconnect(MMAL_PORT_T *port) { MMAL_PORT_PRIVATE_CORE_T* core; MMAL_PORT_T* other_port; MMAL_STATUS_T status = MMAL_SUCCESS; if (!port || !port->priv) { LOG_ERROR("invalid port"); return MMAL_EINVAL; } LOG_TRACE("%s(%p)", port->name, port); LOCK_PORT(port); core = port->priv->core; if (!core->connected_port) { UNLOCK_PORT(port); LOG_DEBUG("%s(%p) is not connected", port->name, port); return MMAL_ENOTCONN; } other_port = core->connected_port; if (port->is_enabled) { status = mmal_port_disable_locked(port); if (status != MMAL_SUCCESS) { LOG_ERROR("could not disable %s(%p) (%i)", port->name, port, status); goto finish; } if (port->priv->core->pool_for_connection) mmal_pool_destroy(port->priv->core->pool_for_connection); port->priv->core->pool_for_connection = NULL; } if (!core->core_owns_connection) { status = port->priv->pf_connect(port, NULL); if (status != MMAL_SUCCESS) { LOG_ERROR("disconnection of %s(%p) failed (%i)", port->name, port, status); goto finish; } } core->connected_port = NULL; other_port->priv->core->connected_port = NULL; finish: UNLOCK_PORT(port); return status; }
static MMAL_STATUS_T mmal_port_connection_disable(MMAL_PORT_T *port, MMAL_PORT_T *connected_port) { MMAL_POOL_T *pool = port->priv->core->pool_for_connection ? port->priv->core->pool_for_connection : connected_port->priv->core->pool_for_connection; mmal_pool_destroy(pool); port->priv->core->pool_for_connection = connected_port->priv->core->pool_for_connection = NULL; return MMAL_SUCCESS; }
static void Close(vlc_object_t *object) { vout_display_t *vd = (vout_display_t *)object; vout_display_sys_t *sys = vd->sys; char response[20]; /* answer is hvs_update_fields=%1d */ unsigned i; vc_tv_unregister_callback_full(tvservice_cb, vd); if (sys->dmx_handle) close_dmx(vd); if (sys->component && sys->component->control->is_enabled) mmal_port_disable(sys->component->control); if (sys->input && sys->input->is_enabled) mmal_port_disable(sys->input); if (sys->component && sys->component->is_enabled) mmal_component_disable(sys->component); if (sys->pool) mmal_pool_destroy(sys->pool); if (sys->component) mmal_component_release(sys->component); if (sys->picture_pool) picture_pool_Release(sys->picture_pool); else for (i = 0; i < sys->num_buffers; ++i) if (sys->pictures[i]) picture_Release(sys->pictures[i]); vlc_mutex_destroy(&sys->buffer_mutex); vlc_cond_destroy(&sys->buffer_cond); vlc_mutex_destroy(&sys->manage_mutex); if (sys->native_interlaced) { if (vc_gencmd(response, sizeof(response), "hvs_update_fields 0") < 0 || response[18] != '0') msg_Warn(vd, "Could not reset hvs field mode"); } free(sys->pictures); free(sys); bcm_host_deinit(); }
/** Destroy a pool of MMAL_BUFFER_HEADER_T */ void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool) { if (!port || !port->priv || !pool) return; LOG_TRACE("%s(%i:%i) port %p, pool %p", port->component->name, (int)port->type, (int)port->index, port, pool); if (!vcos_verify(!port->is_enabled)) { LOG_ERROR("port %p, pool %p destroyed while port enabled", port, pool); mmal_port_disable(port); } mmal_pool_destroy(pool); }
static av_cold int ffmmal_close_decoder(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; if (ctx->decoder) ffmmal_stop_decoder(avctx); mmal_component_destroy(ctx->decoder); ctx->decoder = NULL; mmal_queue_destroy(ctx->queue_decoded_frames); mmal_pool_destroy(ctx->pool_in); ffmmal_poolref_unref(ctx->pool_out); mmal_vc_deinit(); return 0; }
static void disable_renderer(struct gl_hwdec *hw) { struct priv *p = hw->priv; if (p->renderer_enabled) { mmal_port_disable(p->renderer->control); mmal_port_disable(p->renderer->input[0]); mmal_port_flush(p->renderer->control); mmal_port_flush(p->renderer->input[0]); mmal_component_disable(p->renderer); } mmal_pool_destroy(p->swpool); p->swpool = NULL; p->renderer_enabled = false; }
/* Destroys the pools of buffers used by the GL renderer. * @param state Pointer to the GL preview state. */ void raspitex_destroy(RASPITEX_STATE *state) { vcos_log_trace("%s", VCOS_FUNCTION); if (state->preview_pool) { mmal_pool_destroy(state->preview_pool); state->preview_pool = NULL; } if (state->preview_queue) { mmal_queue_destroy(state->preview_queue); state->preview_queue = NULL; } if (state->ops.destroy_native_window) state->ops.destroy_native_window(state); if (state->ops.close) state->ops.close(state); vcos_semaphore_delete(&state->capture.start_sem); vcos_semaphore_delete(&state->capture.completed_sem); }
int main(int argc, char **argv) { MMAL_STATUS_T status = MMAL_EINVAL; MMAL_COMPONENT_T *decoder = 0; MMAL_POOL_T *pool_in = 0, *pool_out = 0; unsigned int count; if (argc < 2) { fprintf(stderr, "invalid arguments\n"); return -1; } #ifndef WIN32 // TODO verify that we dont really need to call bcm_host_init bcm_host_init(); #endif vcos_semaphore_create(&context.semaphore, "example", 1); SOURCE_OPEN(argv[1]); /* Create the decoder component. * This specific component exposes 2 ports (1 input and 1 output). Like most components * its expects the format of its input port to be set by the client in order for it to * know what kind of data it will be fed. */ status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &decoder); CHECK_STATUS(status, "failed to create decoder"); /* Set format of video decoder input port */ MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; format_in->type = MMAL_ES_TYPE_VIDEO; format_in->encoding = MMAL_ENCODING_H264; format_in->es->video.width = 1280; format_in->es->video.height = 720; format_in->es->video.frame_rate.num = 30; format_in->es->video.frame_rate.den = 1; format_in->es->video.par.num = 1; format_in->es->video.par.den = 1; /* If the data is known to be framed then the following flag should be set: * format_in->flags |= MMAL_ES_FORMAT_FLAG_FRAMED; */ SOURCE_READ_CODEC_CONFIG_DATA(codec_header_bytes, codec_header_bytes_size); status = mmal_format_extradata_alloc(format_in, codec_header_bytes_size); CHECK_STATUS(status, "failed to allocate extradata"); format_in->extradata_size = codec_header_bytes_size; if (format_in->extradata_size) memcpy(format_in->extradata, codec_header_bytes, format_in->extradata_size); status = mmal_port_format_commit(decoder->input[0]); CHECK_STATUS(status, "failed to commit format"); /* Display the output port format */ MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format; fprintf(stderr, "%s\n", decoder->output[0]->name); fprintf(stderr, " type: %i, fourcc: %4.4s\n", format_out->type, (char *)&format_out->encoding); fprintf(stderr, " bitrate: %i, framed: %i\n", format_out->bitrate, !!(format_out->flags & MMAL_ES_FORMAT_FLAG_FRAMED)); fprintf(stderr, " extra data: %i, %p\n", format_out->extradata_size, format_out->extradata); fprintf(stderr, " width: %i, height: %i, (%i,%i,%i,%i)\n", format_out->es->video.width, format_out->es->video.height, format_out->es->video.crop.x, format_out->es->video.crop.y, format_out->es->video.crop.width, format_out->es->video.crop.height); /* The format of both ports is now set so we can get their buffer requirements and create * our buffer headers. We use the buffer pool API to create these. */ decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; pool_in = mmal_pool_create(decoder->input[0]->buffer_num, decoder->input[0]->buffer_size); pool_out = mmal_pool_create(decoder->output[0]->buffer_num, decoder->output[0]->buffer_size); /* Create a queue to store our decoded video frames. The callback we will get when * a frame has been decoded will put the frame into this queue. */ context.queue = mmal_queue_create(); /* Store a reference to our context in each port (will be used during callbacks) */ decoder->input[0]->userdata = (void *)&context; decoder->output[0]->userdata = (void *)&context; /* Enable all the input port and the output port. * The callback specified here is the function which will be called when the buffer header * we sent to the component has been processed. */ status = mmal_port_enable(decoder->input[0], input_callback); CHECK_STATUS(status, "failed to enable input port"); status = mmal_port_enable(decoder->output[0], output_callback); CHECK_STATUS(status, "failed to enable output port"); /* Component won't start processing data until it is enabled. */ status = mmal_component_enable(decoder); CHECK_STATUS(status, "failed to enable component"); /* Start decoding */ fprintf(stderr, "start decoding\n"); /* This is the main processing loop */ for (count = 0; count < 500; count++) { MMAL_BUFFER_HEADER_T *buffer; /* Wait for buffer headers to be available on either of the decoder ports */ vcos_semaphore_wait(&context.semaphore); /* Send data to decode to the input port of the video decoder */ if ((buffer = mmal_queue_get(pool_in->queue)) != NULL) { SOURCE_READ_DATA_INTO_BUFFER(buffer); if (!buffer->length) break; fprintf(stderr, "sending %i bytes\n", (int)buffer->length); status = mmal_port_send_buffer(decoder->input[0], buffer); CHECK_STATUS(status, "failed to send buffer"); } /* Get our decoded frames */ while ((buffer = mmal_queue_get(context.queue)) != NULL) { /* We have a frame, do something with it (why not display it for instance?). * Once we're done with it, we release it. It will automatically go back * to its original pool so it can be reused for a new video frame. */ fprintf(stderr, "decoded frame\n"); mmal_buffer_header_release(buffer); } /* Send empty buffers to the output port of the decoder */ while ((buffer = mmal_queue_get(pool_out->queue)) != NULL) { status = mmal_port_send_buffer(decoder->output[0], buffer); CHECK_STATUS(status, "failed to send buffer"); } } /* Stop decoding */ fprintf(stderr, "stop decoding\n"); /* Stop everything. Not strictly necessary since mmal_component_destroy() * will do that anyway */ mmal_port_disable(decoder->input[0]); mmal_port_disable(decoder->output[0]); mmal_component_disable(decoder); error: /* Cleanup everything */ if (decoder) mmal_component_destroy(decoder); if (pool_in) mmal_pool_destroy(pool_in); if (pool_out) mmal_pool_destroy(pool_out); if (context.queue) mmal_queue_destroy(context.queue); SOURCE_CLOSE(); vcos_semaphore_delete(&context.semaphore); return status == MMAL_SUCCESS ? 0 : -1; }