static void ffmmal_stop_decoder(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; MMAL_COMPONENT_T *decoder = ctx->decoder; MMAL_BUFFER_HEADER_T *buffer; mmal_port_disable(decoder->input[0]); mmal_port_disable(decoder->output[0]); mmal_port_disable(decoder->control); mmal_port_flush(decoder->input[0]); mmal_port_flush(decoder->output[0]); mmal_port_flush(decoder->control); while ((buffer = mmal_queue_get(ctx->queue_decoded_frames))) mmal_buffer_header_release(buffer); while (ctx->waiting_buffers) { FFBufferEntry *buffer = ctx->waiting_buffers; ctx->waiting_buffers = buffer->next; av_buffer_unref(&buffer->ref); av_free(buffer); } ctx->waiting_buffers_tail = NULL; ctx->frames_output = ctx->eos_received = ctx->eos_sent = ctx->packets_sent = 0; }
void camera_object_destroy(CameraObject *obj) { if (!obj || !obj->component) return; if (obj->input_connection) mmal_connection_destroy(obj->input_connection); if (obj->port_out && obj->port_out->is_enabled) mmal_port_disable(obj->port_out); if (obj->pool_out) mmal_port_pool_destroy(obj->port_out, obj->pool_out); mmal_component_disable(obj->component); /* If this object created a buffer pool for sending data to another | camera object input via a callback. Eg resizer. */ if (obj->callback_port_in && obj->callback_port_in->is_enabled) mmal_port_disable(obj->callback_port_in); if (obj->callback_pool_in) mmal_port_pool_destroy(obj->callback_port_in, obj->callback_pool_in); mmal_component_destroy(obj->component); memset(obj, 0, sizeof(CameraObject)); }
static void ffmmal_stop_decoder(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; MMAL_COMPONENT_T *decoder = ctx->decoder; MMAL_BUFFER_HEADER_T *buffer; mmal_port_disable(decoder->input[0]); mmal_port_disable(decoder->output[0]); mmal_port_disable(decoder->control); mmal_port_flush(decoder->input[0]); mmal_port_flush(decoder->output[0]); mmal_port_flush(decoder->control); while ((buffer = mmal_queue_get(ctx->queue_decoded_frames))) mmal_buffer_header_release(buffer); while (ctx->waiting_buffers) { FFBufferEntry *buffer = ctx->waiting_buffers; ctx->waiting_buffers = buffer->next; if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1); av_buffer_unref(&buffer->ref); av_free(buffer); } ctx->waiting_buffers_tail = NULL; av_assert0(avpriv_atomic_int_get(&ctx->packets_buffered) == 0); ctx->frames_output = ctx->eos_received = ctx->eos_sent = ctx->packets_sent = ctx->extradata_sent = 0; }
static int flush_decoder(decoder_t *dec) { decoder_sys_t *sys = dec->p_sys; MMAL_BUFFER_HEADER_T *buffer; MMAL_STATUS_T status; int ret = 0; msg_Dbg(dec, "Flushing decoder ports..."); mmal_port_disable(sys->output); mmal_port_disable(sys->input); mmal_port_flush(sys->output); mmal_port_flush(sys->input); /* Reload extradata if available */ if (dec->fmt_in.i_codec == VLC_CODEC_H264) { if (dec->fmt_in.i_extra > 0) { status = mmal_format_extradata_alloc(sys->input->format, dec->fmt_in.i_extra); if (status == MMAL_SUCCESS) { memcpy(sys->input->format->extradata, dec->fmt_in.p_extra, dec->fmt_in.i_extra); sys->input->format->extradata_size = dec->fmt_in.i_extra; } else { msg_Err(dec, "Failed to allocate extra format data on input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); } } } status = mmal_port_format_commit(sys->input); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to commit format for input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); } mmal_port_enable(sys->output, output_port_cb); mmal_port_enable(sys->input, input_port_cb); while (atomic_load(&sys->output_in_transit)) vlc_sem_wait(&sys->sem); /* 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); } } msg_Dbg(dec, "Ports flushed, returning to normal operation"); return ret; }
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 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(); }
int close_cam(RASPIVID_STATE *state) { if (state->isInit) { state -> isInit = 0; MMAL_COMPONENT_T *camera = state->camera_component; MMAL_PORT_T *camera_video_port = camera->output[MMAL_CAMERA_VIDEO_PORT]; //MMAL_COMPONENT_T *encoder = state->encoder_component; //MMAL_PORT_T *encoder_output_port = state->encoder_component->output[0]; MMAL_PORT_T *camera_still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT]; PORT_USERDATA * pData = (PORT_USERDATA *)camera_video_port->userdata; if (camera_still_port && camera_still_port->is_enabled) mmal_port_disable(camera_still_port); if (camera_video_port && camera_video_port->is_enabled) mmal_port_disable(camera_video_port); //mmal_connection_destroy(state->encoder_connection); // Disable components /*if (encoder) mmal_component_disable(encoder); */ if (camera) mmal_component_disable(camera); //Destroy encoder component // Get rid of any port buffers first if (state->camera_pool) { mmal_port_pool_destroy(camera_video_port, state->camera_pool); } free(pData->buffer[0]); free(pData->buffer[1]); /*if (encoder) { mmal_component_destroy(encoder); encoder = NULL; }*/ //destroy camera component if (camera) { mmal_component_destroy(camera); camera = NULL; } return 0; } else { return 1; } }
MmalVideoCamera::~MmalVideoCamera() { // Disable the video port if (m_videoPort != NULL && m_videoPort->is_enabled) { if (mmal_port_disable(m_videoPort) != MMAL_SUCCESS) { std::cerr << "Error disabling the video port" << std::endl; } else { std::cout << "Disabled the video port" << std::endl; } } if (m_camera != NULL) { mmal_component_disable(m_camera); } if (m_pool != NULL) { mmal_port_pool_destroy(m_videoPort, m_pool); } if (m_camera != NULL) { mmal_component_destroy(m_camera); } delete m_callbackData; m_callbackData = NULL; }
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; }
void CMMALVideo::Reset(void) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); if (m_dec_input && m_dec_input->is_enabled) mmal_port_disable(m_dec_input); if (m_deint_connection && m_deint_connection->is_enabled) mmal_connection_disable(m_deint_connection); if (m_dec_output && m_dec_output->is_enabled) mmal_port_disable(m_dec_output); if (!m_finished) { if (m_dec_input) mmal_port_enable(m_dec_input, dec_input_port_cb); if (m_deint_connection) mmal_connection_enable(m_deint_connection); if (m_dec_output) mmal_port_enable(m_dec_output, dec_output_port_cb_static); } // blow all ready video frames bool old_drop_state = m_drop_state; SetDropState(true); pthread_mutex_lock(&m_output_mutex); while(!m_dts_queue.empty()) m_dts_queue.pop(); while (!m_demux_queue.empty()) m_demux_queue.pop(); m_demux_queue_length = 0; pthread_mutex_unlock(&m_output_mutex); if (!old_drop_state) SetDropState(false); if (!m_finished) SendCodecConfigData(); m_startframe = false; m_decoderPts = DVD_NOPTS_VALUE; m_droppedPics = 0; m_decode_frame_number = 1; m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE); }
bool CMMALVideo::DestroyDeinterlace() { MMAL_STATUS_T status; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); assert(m_deint); assert(m_dec_output == m_deint->output[0]); status = mmal_port_disable(m_dec_output); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to disable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } status = mmal_connection_destroy(m_deint_connection); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to destroy deinterlace connection (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_deint_connection = NULL; status = mmal_component_disable(m_deint); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to disable deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } status = mmal_component_destroy(m_deint); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to destroy deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_deint = NULL; m_dec->output[0]->buffer_size = m_dec->output[0]->buffer_size_min; m_dec->output[0]->buffer_num = m_dec->output[0]->buffer_num_recommended; m_dec->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(m_dec->output[0], dec_output_port_cb_static); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_dec_output = m_dec->output[0]; m_interlace_method = VS_INTERLACEMETHOD_NONE; return true; }
void stop_all (void) { mmal_port_disable(jpegencoder->output[0]); mmal_connection_destroy(con_cam_res); mmal_connection_destroy(con_res_jpeg); mmal_port_pool_destroy(jpegencoder->output[0], pool_jpegencoder); mmal_component_disable(jpegencoder); mmal_component_disable(camera); mmal_component_destroy(jpegencoder); mmal_component_destroy(h264encoder); mmal_component_destroy(camera); }
static void Close(filter_t *filter) { filter_sys_t *sys = filter->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); while ((buffer = mmal_queue_get(sys->filtered_pictures))) { picture_t *pic = (picture_t *)buffer->user_data; picture_Release(pic); } if (sys->filtered_pictures) mmal_queue_destroy(sys->filtered_pictures); if (sys->component) mmal_component_release(sys->component); vlc_mutex_destroy(&sys->mutex); vlc_mutex_destroy(&sys->buffer_cond_mutex); vlc_cond_destroy(&sys->buffer_cond); 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); }
void CMMALRenderer::UnInitMMAL() { CSingleLock lock(m_sharedSection); CLog::Log(LOGDEBUG, "%s::%s pool(%p)", CLASSNAME, __func__, m_vout_input_pool); if (m_queue) { StopThread(true); mmal_queue_destroy(m_queue); m_queue = nullptr; } if (m_vout) { mmal_component_disable(m_vout); } if (m_vout_input) { mmal_port_flush(m_vout_input); mmal_port_disable(m_vout_input); } ReleaseBuffers(); if (m_vout_input_pool) { mmal_port_pool_destroy(m_vout_input, m_vout_input_pool); m_vout_input_pool = NULL; } m_vout_input = NULL; if (m_vout) { mmal_component_release(m_vout); m_vout = NULL; } m_src_rect.SetRect(0, 0, 0, 0); m_dst_rect.SetRect(0, 0, 0, 0); m_video_stereo_mode = RENDER_STEREO_MODE_OFF; m_display_stereo_mode = RENDER_STEREO_MODE_OFF; m_StereoInvert = false; m_format = RENDER_FMT_NONE; m_bConfigured = false; m_bMMALConfigured = false; }
static MMAL_STATUS_T mmal_port_disable_locked(MMAL_PORT_T *port) { MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core; MMAL_STATUS_T status; if (!port->is_enabled) { LOG_ERROR("port %p is not enabled", port); return MMAL_EINVAL; } LOCK_SENDING(port); port->is_enabled = 0; UNLOCK_SENDING(port); mmal_component_action_lock(port->component); if (core->pool_for_connection) mmal_pool_callback_set(core->pool_for_connection, NULL, NULL); status = port->priv->pf_disable(port); mmal_component_action_unlock(port->component); if (status != MMAL_SUCCESS) { LOG_ERROR("port %p could not be disabled (%s)", port->name, mmal_status_to_string(status)); LOCK_SENDING(port); port->is_enabled = 1; UNLOCK_SENDING(port); return status; } /* Wait for all the buffers to have come back from the component */ LOG_DEBUG("%s waiting for %i buffers left in transit", port->name, (int)IN_TRANSIT_COUNT(port)); IN_TRANSIT_WAIT(port); LOG_DEBUG("%s has no buffers left in transit", port->name); port->priv->core->buffer_header_callback = NULL; if (core->connected_port && port->type == MMAL_PORT_TYPE_OUTPUT) mmal_port_disable(core->connected_port); return status; }
void Private_Impl::release() { if ( !_isOpened ) return; // Disable camera_video_port if ( camera_video_port && camera_video_port->is_enabled ) { mmal_port_disable ( camera_video_port ); camera_video_port = NULL; } // Disable all our ports that are not handled by connections if ( State.camera_component ) mmal_component_disable ( State.camera_component ); destroy_camera_component ( &State ); _isOpened = false; _isCapturing = false; }
/* Stop SVP. Stops worker thread + disables MMAL connection. */ void svp_stop(SVP_T *svp) { vcos_timer_cancel(&svp->wd_timer); vcos_timer_cancel(&svp->timer); /* Stop worker thread */ if (svp->created & SVP_CREATED_THREAD) { svp_set_stop(svp, SVP_STOP_USER); vcos_semaphore_post(&svp->sema); vcos_thread_join(&svp->thread, NULL); svp->created &= ~SVP_CREATED_THREAD; } if (svp->connection) { mmal_connection_disable(svp->connection); } mmal_port_disable(svp->video_output); }
MmalStillCamera::~MmalStillCamera() { // Disable the process if (m_targetPort != NULL && m_targetPort->is_enabled) { if (mmal_port_disable(m_targetPort) != MMAL_SUCCESS) { std::cerr << "Error disabling the encoder port" << std::endl; } } if (m_camera != NULL) { mmal_component_disable(m_camera); } if (m_pool != NULL) { mmal_port_pool_destroy(m_targetPort, m_pool); } if (m_preview != NULL) { mmal_component_destroy(m_preview); } if (m_encoder != NULL) { mmal_component_destroy(m_encoder); } if (m_camera != NULL) { mmal_component_destroy(m_camera); } delete m_callbackData; }
// Fetch a decoded buffer and place it into the frame parameter. static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame) { MMALDecodeContext *ctx = avctx->priv_data; MMAL_BUFFER_HEADER_T *buffer = NULL; MMAL_STATUS_T status = 0; int ret = 0; if (ctx->eos_received) goto done; while (1) { // To ensure decoding in lockstep with a constant delay between fed packets // and output frames, we always wait until an output buffer is available. // Except during start we don't know after how many input packets the decoder // is going to return the first buffer, and we can't distinguish decoder // being busy from decoder waiting for input. So just poll at the start and // keep feeding new data to the buffer. // We are pretty sure the decoder will produce output if we sent more input // frames than what a H.264 decoder could logically delay. This avoids too // excessive buffering. // We also wait if we sent eos, but didn't receive it yet (think of decoding // stream with a very low number of frames). if (avpriv_atomic_int_get(&ctx->packets_buffered) > MAX_DELAYED_FRAMES || (ctx->packets_sent && ctx->eos_sent)) { // MMAL will ignore broken input packets, which means the frame we // expect here may never arrive. Dealing with this correctly is // complicated, so here's a hack to avoid that it freezes forever // in this unlikely situation. buffer = mmal_queue_timedwait(ctx->queue_decoded_frames, 100); if (!buffer) { av_log(avctx, AV_LOG_ERROR, "Did not get output frame from MMAL.\n"); ret = AVERROR_UNKNOWN; goto done; } } else { buffer = mmal_queue_get(ctx->queue_decoded_frames); if (!buffer) goto done; } ctx->eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS); if (ctx->eos_received) goto done; if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { MMAL_COMPONENT_T *decoder = ctx->decoder; MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer); MMAL_BUFFER_HEADER_T *stale_buffer; av_log(avctx, AV_LOG_INFO, "Changing output format.\n"); if ((status = mmal_port_disable(decoder->output[0]))) goto done; while ((stale_buffer = mmal_queue_get(ctx->queue_decoded_frames))) mmal_buffer_header_release(stale_buffer); mmal_format_copy(decoder->output[0]->format, ev->format); if ((ret = ffmal_update_format(avctx)) < 0) goto done; if ((status = mmal_port_enable(decoder->output[0], output_callback))) goto done; if ((ret = ffmmal_fill_output_port(avctx)) < 0) goto done; if ((ret = ffmmal_fill_input_port(avctx)) < 0) goto done; mmal_buffer_header_release(buffer); continue; } else if (buffer->cmd) { char s[20]; av_get_codec_tag_string(s, sizeof(s), buffer->cmd); av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on output port\n", s); goto done; } else if (buffer->length == 0) { // Unused output buffer that got drained after format change. mmal_buffer_header_release(buffer); continue; } ctx->frames_output++; if ((ret = ffmal_copy_frame(avctx, frame, buffer)) < 0) goto done; *got_frame = 1; break; } done: if (buffer) mmal_buffer_header_release(buffer); if (status && ret >= 0) ret = AVERROR_UNKNOWN; return ret; }
void internelVideoWithDetails(char *filename, int width, int height, int duration) { RASPISTILL_STATE state; MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_PORT_T *camera_video_port = NULL; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; FILE *output_file = NULL; if (width > 1920) { width = 1920; } else if (width < 20) { width = 20; } if (height > 1080) { height = 1080; } else if (height < 20) { height = 20; } bcm_host_init(); default_status(&state); state.width = width; state.height = height; state.quality = 0; state.videoEncode = 1; state.filename = filename; if ((status = create_video_camera_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create camera component", __func__); } else if ((status = create_video_encoder_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create encode component", __func__); destroy_camera_component(&state); } else { PORT_USERDATA callback_data; camera_video_port = state.camera_component->output[MMAL_CAMERA_VIDEO_PORT]; encoder_input_port = state.encoder_component->input[0]; encoder_output_port = state.encoder_component->output[0]; // Now connect the camera to the encoder status = connect_ports(camera_video_port, encoder_input_port, &state.encoder_connection); if (status != MMAL_SUCCESS) { vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__); goto error; } // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename callback_data.pstate = &state; if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup encoder output"); goto error; } if (state.filename) { output_file = fopen(state.filename, "wb"); callback_data.file_handle = output_file; callback_data.pstate = &state; callback_data.abort = 0; } encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; int wait; // Enable the encoder output port and tell it its callback function status = mmal_port_enable(encoder_output_port, encoder_buffer_callback); if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { goto error; } // Send all the buffers to the encoder output port { int num = mmal_queue_length(state.encoder_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } } for (wait = 0; wait < duration; wait+= ABORT_INTERVAL) { vcos_sleep(ABORT_INTERVAL); if (callback_data.abort) break; } // Disable encoder output port status = mmal_port_disable(encoder_output_port); vcos_semaphore_delete(&callback_data.complete_semaphore); } error: mmal_status_to_int(status); // Disable all our ports that are not handled by connections check_disable_port(encoder_output_port); if (output_file && output_file != stdout) fclose(output_file); mmal_connection_destroy(state.encoder_connection); if (state.encoder_component) mmal_component_disable(state.encoder_component); if (state.camera_component) mmal_component_disable(state.camera_component); destroy_encoder_component(&state); destroy_camera_component(&state); if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); }
void Private_Impl_Still::stopCapture() { if ( !encoder_output_port->is_enabled ) return; if ( mmal_port_disable ( encoder_output_port ) ) delete ( RASPICAM_USERDATA* ) encoder_output_port->userdata; }
/** * Checks if specified port is valid and enabled, then disables it * * @param port Pointer the port * */ static void check_disable_port(MMAL_PORT_T *port) { if (port && port->is_enabled) mmal_port_disable(port); }
int main (int argc, char* argv[]) { MMAL_STATUS_T status; int i, max, fd, length, cam_setting; unsigned long int cam_setting_long; char readbuf[20]; char *filename_temp, *filename_temp2, *cmd_temp; bcm_host_init(); // // read arguments // unsigned char of_set = 0; for(i=1; i<argc; i++) { if(strcmp(argv[i], "--version") == 0) { printf("RaspiMJPEG Version "); printf(VERSION); printf("\n"); exit(0); } else if(strcmp(argv[i], "-w") == 0) { i++; width = atoi(argv[i]); } else if(strcmp(argv[i], "-h") == 0) { i++; height = atoi(argv[i]); } else if(strcmp(argv[i], "-wp") == 0) { i++; width_pic = atoi(argv[i]); } else if(strcmp(argv[i], "-hp") == 0) { i++; height_pic = atoi(argv[i]); } else if(strcmp(argv[i], "-q") == 0) { i++; quality = atoi(argv[i]); } else if(strcmp(argv[i], "-d") == 0) { i++; divider = atoi(argv[i]); } else if(strcmp(argv[i], "-p") == 0) { mp4box = 1; } else if(strcmp(argv[i], "-ic") == 0) { i++; image2_cnt = atoi(argv[i]); } else if(strcmp(argv[i], "-vc") == 0) { i++; video_cnt = atoi(argv[i]); } else if(strcmp(argv[i], "-of") == 0) { i++; jpeg_filename = argv[i]; of_set = 1; } else if(strcmp(argv[i], "-if") == 0) { i++; jpeg2_filename = argv[i]; of_set = 1; } else if(strcmp(argv[i], "-cf") == 0) { i++; pipe_filename = argv[i]; } else if(strcmp(argv[i], "-vf") == 0) { i++; h264_filename = argv[i]; } else if(strcmp(argv[i], "-sf") == 0) { i++; status_filename = argv[i]; } else if(strcmp(argv[i], "-pa") == 0) { autostart = 0; idle = 1; } else if(strcmp(argv[i], "-md") == 0) { motion_detection = 1; } else if(strcmp(argv[i], "-fp") == 0) { preview_mode = RES_4_3; } else if(strcmp(argv[i], "-audio") == 0) { audio_mode = 1; } else error("Invalid arguments"); } if(!of_set) error("Output file not specified"); // // init // if(autostart) start_all(); if(motion_detection) { if(system("motion") == -1) error("Could not start Motion"); } // // run // if(autostart) { if(pipe_filename != 0) printf("MJPEG streaming, ready to receive commands\n"); else printf("MJPEG streaming\n"); } else { if(pipe_filename != 0) printf("MJPEG idle, ready to receive commands\n"); else printf("MJPEG idle\n"); } struct sigaction action; memset(&action, 0, sizeof(struct sigaction)); action.sa_handler = term; sigaction(SIGTERM, &action, NULL); sigaction(SIGINT, &action, NULL); if(status_filename != 0) { status_file = fopen(status_filename, "w"); if(!status_file) error("Could not open/create status-file"); if(autostart) { if(!motion_detection) { fprintf(status_file, "ready"); } else fprintf(status_file, "md_ready"); } else fprintf(status_file, "halted"); fclose(status_file); } while(running) { if(pipe_filename != 0) { fd = open(pipe_filename, O_RDONLY | O_NONBLOCK); if(fd < 0) error("Could not open PIPE"); fcntl(fd, F_SETFL, 0); length = read(fd, readbuf, 20); close(fd); if(length) { if((readbuf[0]=='p') && (readbuf[1]=='m')) { stop_all(); readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; if(strcmp(readbuf, " 4_3") == 0) preview_mode = RES_4_3; else if(strcmp(readbuf, " 16_9_STD") == 0) preview_mode = RES_16_9_STD; else if(strcmp(readbuf, " 16_9_WIDE") == 0) preview_mode = RES_16_9_WIDE; start_all(); printf("Changed preview mode\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "ready"); fclose(status_file); } } else if((readbuf[0]=='c') && (readbuf[1]=='a')) { if(readbuf[3]=='1') { if(!capturing) { status = mmal_component_enable(h264encoder); if(status != MMAL_SUCCESS) error("Could not enable h264encoder"); pool_h264encoder = mmal_port_pool_create(h264encoder->output[0], h264encoder->output[0]->buffer_num, h264encoder->output[0]->buffer_size); if(!pool_h264encoder) error("Could not create pool"); status = mmal_connection_create(&con_cam_h264, camera->output[1], h264encoder->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT); if(status != MMAL_SUCCESS) error("Could not create connecton camera -> video converter"); status = mmal_connection_enable(con_cam_h264); if(status != MMAL_SUCCESS) error("Could not enable connection camera -> video converter"); currTime = time(NULL); localTime = localtime (&currTime); if(mp4box) { asprintf(&filename_temp, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec); asprintf(&filename_temp2, "%s.h264", filename_temp); } else { asprintf(&filename_temp2, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec); } h264output_file = fopen(filename_temp2, "wb"); free(filename_temp2); if(mp4box) { if(audio_mode) { asprintf(&cmd_temp, "/usr/bin/arecord -q -D hw:1,0 -f S16_LE -t wav | /usr/bin/lame - %s.mp3 -S &", filename_temp); printf("Audio recording with \"%s\\n", cmd_temp); if(system(cmd_temp) == -1) error("Could not start audio recording"); } free(filename_temp); } if(!h264output_file) error("Could not open/create video-file"); status = mmal_port_enable(h264encoder->output[0], h264encoder_buffer_callback); if(status != MMAL_SUCCESS) error("Could not enable video port"); max = mmal_queue_length(pool_h264encoder->queue); for(i=0;i<max;i++) { MMAL_BUFFER_HEADER_T *h264buffer = mmal_queue_get(pool_h264encoder->queue); if(!h264buffer) error("Could not create video pool header"); status = mmal_port_send_buffer(h264encoder->output[0], h264buffer); if(status != MMAL_SUCCESS) error("Could not send buffers to video port"); } mmal_port_parameter_set_boolean(camera->output[1], MMAL_PARAMETER_CAPTURE, 1); if(status != MMAL_SUCCESS) error("Could not start capture"); printf("Capturing started\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); if(!motion_detection) fprintf(status_file, "video"); else fprintf(status_file, "md_video"); fclose(status_file); } capturing = 1; } } else { if(capturing) { mmal_port_parameter_set_boolean(camera->output[1], MMAL_PARAMETER_CAPTURE, 0); if(status != MMAL_SUCCESS) error("Could not stop capture"); status = mmal_port_disable(h264encoder->output[0]); if(status != MMAL_SUCCESS) error("Could not disable video port"); status = mmal_connection_destroy(con_cam_h264); if(status != MMAL_SUCCESS) error("Could not destroy connection camera -> video encoder"); mmal_port_pool_destroy(h264encoder->output[0], pool_h264encoder); if(status != MMAL_SUCCESS) error("Could not destroy video buffer pool"); status = mmal_component_disable(h264encoder); if(status != MMAL_SUCCESS) error("Could not disable video converter"); fclose(h264output_file); h264output_file = NULL; printf("Capturing stopped\n"); if(mp4box) { printf("Boxing started\n"); status_file = fopen(status_filename, "w"); if(!motion_detection) fprintf(status_file, "boxing"); else fprintf(status_file, "md_boxing"); fclose(status_file); asprintf(&filename_temp, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec); if(audio_mode) { asprintf(&cmd_temp, "/usr/bin/killall arecord > /dev/null"); if(system(cmd_temp) == -1) error("Could not stop audio recording"); free(cmd_temp); asprintf(&cmd_temp, "MP4Box -fps 25 -add %s.h264 -add %s.mp3 %s > /dev/null", filename_temp, filename_temp, filename_temp); } else { asprintf(&cmd_temp, "MP4Box -fps 25 -add %s.h264 %s > /dev/null", filename_temp, filename_temp); } if(system(cmd_temp) == -1) error("Could not start MP4Box"); asprintf(&filename_temp2, "%s.h264", filename_temp); remove(filename_temp2); free(filename_temp2); if (audio_mode) { asprintf(&filename_temp2, "%s.mp3", filename_temp); remove(filename_temp2); free(filename_temp2); } free(filename_temp); free(cmd_temp); printf("Boxing stopped\n"); } video_cnt++; if(status_filename != 0) { status_file = fopen(status_filename, "w"); if(!motion_detection) fprintf(status_file, "ready"); else fprintf(status_file, "md_ready"); fclose(status_file); } capturing = 0; } } } else if((readbuf[0]=='i') && (readbuf[1]=='m')) { capt_img(); } else if((readbuf[0]=='t') && (readbuf[1]=='l')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; time_between_pic = atoi(readbuf); if(time_between_pic) { if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "timelapse"); fclose(status_file); } timelapse = 1; printf("Timelapse started\n"); } else { if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "ready"); fclose(status_file); } timelapse = 0; printf("Timelapse stopped\n"); } } else if((readbuf[0]=='s') && (readbuf[1]=='h')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); MMAL_RATIONAL_T value = {cam_setting, 100}; status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_SHARPNESS, value); if(status != MMAL_SUCCESS) error("Could not set sharpness"); printf("Sharpness: %d\n", cam_setting); } else if((readbuf[0]=='c') && (readbuf[1]=='o')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); MMAL_RATIONAL_T value = {cam_setting, 100}; status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_CONTRAST, value); if(status != MMAL_SUCCESS) error("Could not set contrast"); printf("Contrast: %d\n", cam_setting); } else if((readbuf[0]=='b') && (readbuf[1]=='r')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); MMAL_RATIONAL_T value = {cam_setting, 100}; status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_BRIGHTNESS, value); if(status != MMAL_SUCCESS) error("Could not set brightness"); printf("Brightness: %d\n", cam_setting); } else if((readbuf[0]=='s') && (readbuf[1]=='a')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); MMAL_RATIONAL_T value = {cam_setting, 100}; status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_SATURATION, value); if(status != MMAL_SUCCESS) error("Could not set saturation"); printf("Saturation: %d\n", cam_setting); } else if((readbuf[0]=='i') && (readbuf[1]=='s')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); status = mmal_port_parameter_set_uint32(camera->control, MMAL_PARAMETER_ISO, cam_setting); if(status != MMAL_SUCCESS) error("Could not set ISO"); printf("ISO: %d\n", cam_setting); } else if((readbuf[0]=='v') && (readbuf[1]=='s')) { if(readbuf[3]=='1') { status = mmal_port_parameter_set_boolean(camera->control, MMAL_PARAMETER_VIDEO_STABILISATION, 1); printf("Video Stabilisation ON\n"); } else { status = mmal_port_parameter_set_boolean(camera->control, MMAL_PARAMETER_VIDEO_STABILISATION, 0); printf("Video Stabilisation OFF\n"); } if(status != MMAL_SUCCESS) error("Could not set video stabilisation"); } else if((readbuf[0]=='e') && (readbuf[1]=='c')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); status = mmal_port_parameter_set_int32(camera->control, MMAL_PARAMETER_EXPOSURE_COMP, cam_setting); if(status != MMAL_SUCCESS) error("Could not set exposure compensation"); printf("Exposure Compensation: %d\n", cam_setting); } else if((readbuf[0]=='e') && (readbuf[1]=='m')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; MMAL_PARAM_EXPOSUREMODE_T mode = MMAL_PARAM_EXPOSUREMODE_OFF; if(strcmp(readbuf, " auto") == 0) mode = MMAL_PARAM_EXPOSUREMODE_AUTO; else if(strcmp(readbuf, " night") == 0) mode = MMAL_PARAM_EXPOSUREMODE_NIGHT; else if(strcmp(readbuf, " nightpreview") == 0) mode = MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW; else if(strcmp(readbuf, " backlight") == 0) mode = MMAL_PARAM_EXPOSUREMODE_BACKLIGHT; else if(strcmp(readbuf, " spotlight") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT; else if(strcmp(readbuf, " sports") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SPORTS; else if(strcmp(readbuf, " snow") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SNOW; else if(strcmp(readbuf, " beach") == 0) mode = MMAL_PARAM_EXPOSUREMODE_BEACH; else if(strcmp(readbuf, " verylong") == 0) mode = MMAL_PARAM_EXPOSUREMODE_VERYLONG; else if(strcmp(readbuf, " fixedfps") == 0) mode = MMAL_PARAM_EXPOSUREMODE_FIXEDFPS; else if(strcmp(readbuf, " antishake") == 0) mode = MMAL_PARAM_EXPOSUREMODE_ANTISHAKE; else if(strcmp(readbuf, " fireworks") == 0) mode = MMAL_PARAM_EXPOSUREMODE_FIREWORKS; MMAL_PARAMETER_EXPOSUREMODE_T exp_mode = {{MMAL_PARAMETER_EXPOSURE_MODE,sizeof(exp_mode)}, mode}; status = mmal_port_parameter_set(camera->control, &exp_mode.hdr); if(status != MMAL_SUCCESS) error("Could not set exposure mode"); printf("Exposure mode changed\n"); } else if((readbuf[0]=='w') && (readbuf[1]=='b')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; MMAL_PARAM_AWBMODE_T awb_mode = MMAL_PARAM_AWBMODE_OFF; if(strcmp(readbuf, " auto") == 0) awb_mode = MMAL_PARAM_AWBMODE_AUTO; else if(strcmp(readbuf, " auto") == 0) awb_mode = MMAL_PARAM_AWBMODE_AUTO; else if(strcmp(readbuf, " sun") == 0) awb_mode = MMAL_PARAM_AWBMODE_SUNLIGHT; else if(strcmp(readbuf, " cloudy") == 0) awb_mode = MMAL_PARAM_AWBMODE_CLOUDY; else if(strcmp(readbuf, " shade") == 0) awb_mode = MMAL_PARAM_AWBMODE_SHADE; else if(strcmp(readbuf, " tungsten") == 0) awb_mode = MMAL_PARAM_AWBMODE_TUNGSTEN; else if(strcmp(readbuf, " fluorescent") == 0) awb_mode = MMAL_PARAM_AWBMODE_FLUORESCENT; else if(strcmp(readbuf, " incandescent") == 0) awb_mode = MMAL_PARAM_AWBMODE_INCANDESCENT; else if(strcmp(readbuf, " flash") == 0) awb_mode = MMAL_PARAM_AWBMODE_FLASH; else if(strcmp(readbuf, " horizon") == 0) awb_mode = MMAL_PARAM_AWBMODE_HORIZON; MMAL_PARAMETER_AWBMODE_T param = {{MMAL_PARAMETER_AWB_MODE,sizeof(param)}, awb_mode}; status = mmal_port_parameter_set(camera->control, ¶m.hdr); if(status != MMAL_SUCCESS) error("Could not set white balance"); printf("White balance changed\n"); } else if((readbuf[0]=='r') && (readbuf[1]=='o')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); status = mmal_port_parameter_set_int32(camera->output[0], MMAL_PARAMETER_ROTATION, cam_setting); if(status != MMAL_SUCCESS) error("Could not set rotation (0)"); status = mmal_port_parameter_set_int32(camera->output[1], MMAL_PARAMETER_ROTATION, cam_setting); if(status != MMAL_SUCCESS) error("Could not set rotation (1)"); status = mmal_port_parameter_set_int32(camera->output[2], MMAL_PARAMETER_ROTATION, cam_setting); if(status != MMAL_SUCCESS) error("Could not set rotation (2)"); printf("Rotation: %d\n", cam_setting); } else if((readbuf[0]=='q') && (readbuf[1]=='u')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting = atoi(readbuf); status = mmal_port_parameter_set_uint32(jpegencoder2->output[0], MMAL_PARAMETER_JPEG_Q_FACTOR, cam_setting); if(status != MMAL_SUCCESS) error("Could not set quality"); printf("Quality: %d\n", cam_setting); } else if((readbuf[0]=='b') && (readbuf[1]=='i')) { readbuf[0] = ' '; readbuf[1] = ' '; readbuf[length] = 0; cam_setting_long = strtoull(readbuf, NULL, 0); h264encoder->output[0]->format->bitrate = cam_setting_long; status = mmal_port_format_commit(h264encoder->output[0]); if(status != MMAL_SUCCESS) error("Could not set bitrate"); printf("Bitrate: %lu\n", cam_setting_long); } else if((readbuf[0]=='r') && (readbuf[1]=='u')) { if(readbuf[3]=='0') { stop_all(); idle = 1; printf("Stream halted\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "halted"); fclose(status_file); } } else { start_all(); idle = 0; printf("Stream continued\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "ready"); fclose(status_file); } } } else if((readbuf[0]=='m') && (readbuf[1]=='d')) { if(readbuf[3]=='0') { motion_detection = 0; if(system("killall motion") == -1) error("Could not stop Motion"); printf("Motion detection stopped\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "ready"); fclose(status_file); } } else { motion_detection = 1; if(system("motion") == -1) error("Could not start Motion"); printf("Motion detection started\n"); if(status_filename != 0) { status_file = fopen(status_filename, "w"); fprintf(status_file, "md_ready"); fclose(status_file); } } } } } if(timelapse) { tl_cnt++; if(tl_cnt >= time_between_pic) { if(capturing == 0) { capt_img(); tl_cnt = 0; } } } usleep(100000); } printf("SIGINT/SIGTERM received, stopping\n"); // // tidy up // if(!idle) stop_all(); return 0; }
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; }
static int change_output_format(decoder_t *dec) { MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type; decoder_sys_t *sys = dec->p_sys; MMAL_STATUS_T status; int pool_size; int ret = 0; if (atomic_load(&sys->started)) { mmal_format_full_copy(sys->output->format, sys->output_format); status = mmal_port_format_commit(sys->output); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to commit output format (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = -1; goto port_reset; } goto apply_fmt; } port_reset: msg_Dbg(dec, "%s: Do full port reset", __func__); status = mmal_port_disable(sys->output); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to disable output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = -1; goto out; } mmal_format_full_copy(sys->output->format, sys->output_format); status = mmal_port_format_commit(sys->output); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to commit output format (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = -1; goto out; } if (sys->opaque) { sys->output->buffer_num = NUM_ACTUAL_OPAQUE_BUFFERS; pool_size = NUM_DECODER_BUFFER_HEADERS; } else { sys->output->buffer_num = __MAX(sys->output->buffer_num_recommended, MIN_NUM_BUFFERS_IN_TRANSIT); pool_size = sys->output->buffer_num; } sys->output->buffer_size = sys->output->buffer_size_recommended; status = mmal_port_enable(sys->output, output_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = -1; goto out; } if (!atomic_load(&sys->started)) { if (!sys->opaque) { sys->output_pool = mmal_port_pool_create(sys->output, pool_size, 0); msg_Dbg(dec, "Created output pool with %d pictures", sys->output_pool->headers_num); } atomic_store(&sys->started, true); /* we need one picture from vout for each buffer header on the output * port */ dec->i_extra_picture_buffers = pool_size; /* remove what VLC core reserves as it is part of the pool_size * already */ if (dec->fmt_in.i_codec == VLC_CODEC_H264) dec->i_extra_picture_buffers -= 19; else dec->i_extra_picture_buffers -= 3; msg_Dbg(dec, "Request %d extra pictures", dec->i_extra_picture_buffers); } apply_fmt: dec->fmt_out.video.i_width = sys->output->format->es->video.width; dec->fmt_out.video.i_height = sys->output->format->es->video.height; dec->fmt_out.video.i_x_offset = sys->output->format->es->video.crop.x; dec->fmt_out.video.i_y_offset = sys->output->format->es->video.crop.y; dec->fmt_out.video.i_visible_width = sys->output->format->es->video.crop.width; dec->fmt_out.video.i_visible_height = sys->output->format->es->video.crop.height; dec->fmt_out.video.i_sar_num = sys->output->format->es->video.par.num; dec->fmt_out.video.i_sar_den = sys->output->format->es->video.par.den; dec->fmt_out.video.i_frame_rate = sys->output->format->es->video.frame_rate.num; dec->fmt_out.video.i_frame_rate_base = sys->output->format->es->video.frame_rate.den; /* Query interlaced type */ interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE; interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T); status = mmal_port_parameter_get(sys->output, &interlace_type.hdr); if (status != MMAL_SUCCESS) { msg_Warn(dec, "Failed to query interlace type from decoder output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); } else { sys->b_progressive = (interlace_type.eMode == MMAL_InterlaceProgressive); sys->b_top_field_first = sys->b_progressive ? true : (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst); msg_Dbg(dec, "Detected %s%s video (%d)", sys->b_progressive ? "progressive" : "interlaced", sys->b_progressive ? "" : (sys->b_top_field_first ? " tff" : " bff"), interlace_type.eMode); } out: mmal_format_free(sys->output_format); sys->output_format = NULL; return ret; }
uint8_t *internelPhotoWithDetails(int width, int height, int quality,MMAL_FOURCC_T encoding, PicamParams *parms, long *sizeread) { RASPISTILL_STATE state; MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_PORT_T *preview_input_port = NULL; MMAL_PORT_T *camera_preview_port = NULL; MMAL_PORT_T *camera_still_port = NULL; MMAL_PORT_T *encoder_input_port = NULL; MMAL_PORT_T *encoder_output_port = NULL; if (width > 2592) { width = 2592; } else if (width < 20) { width = 20; } if (height > 1944) { height = 1944; } else if (height < 20) { height = 20; } if (quality > 100) { quality = 100; } else if (quality < 0) { quality = 85; } bcm_host_init(); default_status(&state); state.width = width; state.height = height; state.quality = quality; state.encoding = encoding; state.videoEncode = 0; state.camera_parameters.exposureMode = parms->exposure; state.camera_parameters.exposureMeterMode = parms->meterMode; state.camera_parameters.awbMode = parms->awbMode; state.camera_parameters.imageEffect = parms->imageFX; state.camera_parameters.ISO = parms->ISO; state.camera_parameters.sharpness = parms->sharpness; state.camera_parameters.contrast = parms->contrast; state.camera_parameters.brightness= parms->brightness; state.camera_parameters.saturation = parms->saturation; state.camera_parameters.videoStabilisation = parms->videoStabilisation; /// 0 or 1 (false or true) state.camera_parameters.exposureCompensation = parms->exposureCompensation; state.camera_parameters.rotation = parms->rotation; state.camera_parameters.hflip = parms->hflip; state.camera_parameters.vflip = parms->vflip; MMAL_COMPONENT_T *preview = 0; if ((status = create_video_camera_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create camera component", __func__); } else if ((status = mmal_component_create("vc.null_sink", &preview)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create preview component", __func__); destroy_camera_component(&state); } else if ((status = create_encoder_component(&state)) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to create encode component", __func__); destroy_camera_component(&state); } else { status = mmal_component_enable(preview); state.preview_component = preview; PORT_USERDATA callback_data; camera_preview_port = state.camera_component->output[MMAL_CAMERA_PREVIEW_PORT]; camera_still_port = state.camera_component->output[MMAL_CAMERA_CAPTURE_PORT]; encoder_input_port = state.encoder_component->input[0]; encoder_output_port = state.encoder_component->output[0]; preview_input_port = state.preview_component->input[0]; status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection); VCOS_STATUS_T vcos_status; // Now connect the camera to the encoder status = connect_ports(camera_still_port, encoder_input_port, &state.encoder_connection); if (status != MMAL_SUCCESS) { vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__); goto error; } // Set up our userdata - this is passed though to the callback where we need the information. // Null until we open our filename callback_data.pstate = &state; vcos_status = vcos_semaphore_create(&callback_data.complete_semaphore, "picam-sem", 0); vcos_assert(vcos_status == VCOS_SUCCESS); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to setup encoder output"); goto error; } int num, q; // Enable the encoder output port encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data; // Enable the encoder output port and tell it its callback function status = mmal_port_enable(encoder_output_port, encoder_buffer_callback); // Send all the buffers to the encoder output port num = mmal_queue_length(state.encoder_pool->queue); for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } if (mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to start capture", __func__); } else { // Wait for capture to complete // For some reason using vcos_semaphore_wait_timeout sometimes returns immediately with bad parameter error // even though it appears to be all correct, so reverting to untimed one until figure out why its erratic vcos_semaphore_wait(&callback_data.complete_semaphore); } // Disable encoder output port status = mmal_port_disable(encoder_output_port); *sizeread = state.bytesStored; vcos_semaphore_delete(&callback_data.complete_semaphore); } error: mmal_status_to_int(status); // Disable all our ports that are not handled by connections check_disable_port(encoder_output_port); mmal_connection_destroy(state.encoder_connection); if (state.encoder_component) mmal_component_disable(state.encoder_component); if (state.preview_component) { mmal_component_disable(state.preview_component); mmal_component_destroy(state.preview_component); state.preview_component = NULL; } if (state.camera_component) mmal_component_disable(state.camera_component); destroy_encoder_component(&state); destroy_camera_component(&state); if (status != MMAL_SUCCESS) raspicamcontrol_check_configuration(128); return state.filedata; }
bool CMMALVideo::CreateDeinterlace(EINTERLACEMETHOD interlace_method) { MMAL_STATUS_T status; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s method:%d", CLASSNAME, __func__, interlace_method); assert(!m_deint); assert(m_dec_output == m_dec->output[0]); status = mmal_port_disable(m_dec_output); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to disable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } /* Create deinterlace filter */ status = mmal_component_create("vc.ril.image_fx", &m_deint); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to create deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)}, interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED || interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF ? MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST, 3, {3, 0, interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF || interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF }}; status = mmal_port_parameter_set(m_deint->output[0], &imfx_param.hdr); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } MMAL_PORT_T *m_deint_input = m_deint->input[0]; m_deint_input->userdata = (struct MMAL_PORT_USERDATA_T *)this; // Now connect the decoder output port to deinterlace input port status = mmal_connection_create(&m_deint_connection, m_dec->output[0], m_deint->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to connect deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status)); return false; } status = mmal_connection_enable(m_deint_connection); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable connection %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status)); return false; } mmal_format_copy(m_deint->output[0]->format, m_es_format); status = mmal_port_format_commit(m_deint->output[0]); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to commit deint output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } status = mmal_component_enable(m_deint); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status)); return false; } m_deint->output[0]->buffer_size = m_deint->output[0]->buffer_size_min; m_deint->output[0]->buffer_num = m_deint->output[0]->buffer_num_recommended; m_deint->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(m_deint->output[0], dec_output_port_cb_static); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_dec_output = m_deint->output[0]; m_interlace_method = interlace_method; return true; }