/** Callback from video decode output port. */ static void svp_bh_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf) { SVP_T *svp = (SVP_T *)port->userdata; if (buf->length == 0) { LOG_TRACE("%s: zero-length buffer => EOS", port->name); svp_set_stop(svp, SVP_STOP_EOS); // This shouldn't be necessary, but it is ... mmal_buffer_header_release(buf); } else if (buf->data == NULL) { LOG_ERROR("%s: zero buffer handle", port->name); mmal_buffer_header_release(buf); } else { /* Reset watchdog timer */ vcos_timer_set(&svp->wd_timer, SVP_WATCHDOG_TIMEOUT_MS); /* Enqueue the decoded frame so we can return quickly to MMAL core */ mmal_queue_put(svp->queue, buf); } /* Notify worker */ vcos_semaphore_post(&svp->sema); }
static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { filter_t *filter = (filter_t *)port->userdata; filter_sys_t *sys = filter->p_sys; picture_t *picture; if (buffer->cmd == 0) { vlc_mutex_lock(&sys->buffer_cond_mutex); if (buffer->length > 0) { atomic_store(&sys->started, true); mmal_queue_put(sys->filtered_pictures, buffer); picture = (picture_t *)buffer->user_data; } else { picture = (picture_t *)buffer->user_data; picture_Release(picture); } atomic_fetch_sub(&sys->output_in_transit, 1); vlc_cond_signal(&sys->buffer_cond); vlc_mutex_unlock(&sys->buffer_cond_mutex); } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { msg_Warn(filter, "MMAL_EVENT_FORMAT_CHANGED seen but not handled"); mmal_buffer_header_release(buffer); } else { mmal_buffer_header_release(buffer); } }
/** Connected output port buffer callback */ static void mmal_port_connected_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PORT_T* connected_port = port->priv->core->connected_port; MMAL_STATUS_T status; LOG_TRACE("buffer %p from connected output port %p: data %p, alloc_size %u, length %u", buffer, port, buffer->data, buffer->alloc_size, buffer->length); if (buffer->cmd) { MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); /* Handle format changed events */ if (event) { /* Apply the change */ status = mmal_format_full_copy(port->format, event->format); if (status == MMAL_SUCCESS) status = mmal_port_format_commit(port); if (status != MMAL_SUCCESS) LOG_ERROR("format commit failed on port %s (%i)", port->name, status); /* Forward to the connected port */ if (status == MMAL_SUCCESS) status = mmal_port_send_buffer(connected_port, buffer); if (status != MMAL_SUCCESS) { mmal_event_error_send(port->component, status); mmal_buffer_header_release(buffer); } return; /* Event handled */ } /* FIXME Release other event buffers for now, until we can deal with shared memory issues */ mmal_buffer_header_release(buffer); } else { if (port->is_enabled) { /* Forward data buffers to the connected input port */ status = mmal_port_send_buffer(connected_port, buffer); if (status != MMAL_SUCCESS) { LOG_ERROR("%s could not send buffer on port %s (%s)", port->name, connected_port->name, mmal_status_to_string(status)); mmal_buffer_header_release(buffer); } } else { /* This port is disabled. Buffer will be a flushed buffer, so * return to the pool rather than delivering it. */ mmal_buffer_header_release(buffer); } } }
/** * buffer header callback function for camera control * * Callback will dump buffer data to the specific file * * @param port Pointer to port from which callback originated * @param buffer mmal buffer header pointer */ void camera_control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { if (buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED) { MMAL_EVENT_PARAMETER_CHANGED_T *param = (MMAL_EVENT_PARAMETER_CHANGED_T *)buffer->data; switch (param->hdr.id) { case MMAL_PARAMETER_CAMERA_SETTINGS: { MMAL_PARAMETER_CAMERA_SETTINGS_T *settings = (MMAL_PARAMETER_CAMERA_SETTINGS_T*)param; mmal_encoder_copy_camera_settings(settings); } break; default: DLOG_FORMAT("Unprocessed Camera Event: %d", (param->hdr.id)); break; } } else if (buffer->cmd == MMAL_EVENT_ERROR) { vcos_log_error("No data received from sensor. Check all connections, including the Sunny one on the camera board"); } else { vcos_log_error("Received unexpected camera control callback event, 0x%08x", buffer->cmd); } mmal_buffer_header_release(buffer); }
/** Callback from a control port. */ static void svp_bh_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf) { SVP_T *svp = (SVP_T *)port->userdata; switch (buf->cmd) { case MMAL_EVENT_EOS: LOG_TRACE("%s: EOS", port->name); svp_set_stop(svp, SVP_STOP_EOS); break; case MMAL_EVENT_ERROR: LOG_ERROR("%s: MMAL error: %s", port->name, mmal_status_to_string(*(MMAL_STATUS_T *)buf->data)); svp_set_stop(svp, SVP_STOP_ERROR); break; default: LOG_TRACE("%s: buf %p, event %4.4s", port->name, buf, (char *)&buf->cmd); break; } mmal_buffer_header_release(buf); vcos_semaphore_post(&svp->sema); }
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; }
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; }
void PiCam::video_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { PiCam* cam = (PiCam*) port->userdata; if (buffer->length) { mmal_buffer_header_mem_lock(buffer); memcpy(cam->frame.data, buffer->data, 3*cam->width*cam->height); //memcpy(cam->frame.data, buffer->data, cam->width*cam->height); mmal_buffer_header_mem_unlock(buffer); cam->callback(cam->frame); //cv::waitKey(1); } // release buffer back to the pool mmal_buffer_header_release(buffer); /* if (vcos_semaphore_trywait(&(cam->frame_semaphore)) != VCOS_SUCCESS) { vcos_semaphore_post(&(cam->frame_semaphore)); } */ // and send one back to the port (if still open) if (port->is_enabled) { MMAL_STATUS_T status; MMAL_BUFFER_HEADER_T* new_buffer = mmal_queue_get(cam->videoPool->queue); if (new_buffer) status = mmal_port_send_buffer(port, new_buffer); if (!new_buffer || status != MMAL_SUCCESS) vcos_log_error("Unable to return a buffer to the encoder port"); } }
/** Callback from an input port. Buffer is released. */ static void mmal_connection_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PARAM_UNUSED(port); LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); /* We're done with the buffer, just recycle it */ mmal_buffer_header_release(buffer); }
static void encoder_output_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_BUFFER_HEADER_T *new_buffer; PORT_USERDATA *userdata = (PORT_USERDATA *) port->userdata; MMAL_POOL_T *pool = userdata->encoder_output_pool; //fprintf(stderr, "INFO:%s\n", __func__); mmal_buffer_header_mem_lock(buffer); fwrite(buffer->data, 1, buffer->length, stdout); mmal_buffer_header_mem_unlock(buffer); mmal_buffer_header_release(buffer); if (port->is_enabled) { MMAL_STATUS_T status; new_buffer = mmal_queue_get(pool->queue); if (new_buffer) { status = mmal_port_send_buffer(port, new_buffer); } if (!new_buffer || status != MMAL_SUCCESS) { fprintf(stderr, "Unable to return a buffer to the video port\n"); } } }
static void encoder_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { USERDATA_T *data; vcos_assert((data = (USERDATA_T *)port->userdata) != NULL && "No data associated with this buffer"); vcos_assert((buffer && buffer->length > 0) && "buffer == NULL or buffer has size 0"); mmal_buffer_header_mem_lock(buffer); vcos_assert((fwrite(buffer->data, 1, buffer->length, data->file_handle) == buffer->length) && "Failed writing buffer to file (different size returned)"); mmal_buffer_header_mem_unlock(buffer); mmal_buffer_header_release(buffer); // send one buffer back if (port->is_enabled) { MMAL_BUFFER_HEADER_T *new_buffer; if ((new_buffer = mmal_queue_get(data->pool->queue)) != NULL ) vcos_assert((mmal_port_send_buffer(port, new_buffer) == MMAL_SUCCESS) && "Unable to return buffer to encoder port"); } }
void CMMALVideo::ReturnBuffer(CMMALVideoBuffer *buffer) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s %p (%d)", CLASSNAME, __func__, buffer, m_output_busy); mmal_buffer_header_release(buffer->mmal_buffer); }
static MMAL_STATUS_T mmalplay_event_handle(MMAL_CONNECTION_T *connection, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_STATUS_T status = MMAL_SUCCESS; LOG_INFO("%s(%p) received event %4.4s (%i bytes)", port->name, port, (char *)&buffer->cmd, (int)buffer->length); if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED && port->type == MMAL_PORT_TYPE_OUTPUT) { MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer); if (event) { LOG_INFO("----------Port format changed----------"); log_format(port->format, port); LOG_INFO("-----------------to---------------------"); log_format(event->format, 0); LOG_INFO(" buffers num (opt %i, min %i), size (opt %i, min: %i)", event->buffer_num_recommended, event->buffer_num_min, event->buffer_size_recommended, event->buffer_size_min); LOG_INFO("----------------------------------------"); } status = mmal_connection_event_format_changed(connection, buffer); } mmal_buffer_header_release(buffer); return status; }
/** * buffer header callback function for encoder * * Callback will dump buffer data to the specific file * * @param port Pointer to port from which callback originated * @param buffer mmal buffer header pointer */ static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { int complete = 0; // We pass our file handle and other stuff in via the userdata field. PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata; if (pData) { int bytes_written = buffer->length; if (buffer->length && pData->file_handle) { mmal_buffer_header_mem_lock(buffer); bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle); mmal_buffer_header_mem_unlock(buffer); } // We need to check we wrote what we wanted - it's possible we have run out of storage. if (bytes_written != buffer->length) { vcos_log_error("Unable to write buffer to file - aborting"); complete = 1; } // Now flag if we have completed if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED)) complete = 1; } else { vcos_log_error("Received a encoder buffer callback with no state"); } // release buffer back to the pool mmal_buffer_header_release(buffer); // and send one back to the port (if still open) if (port->is_enabled) { MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_BUFFER_HEADER_T *new_buffer; new_buffer = mmal_queue_get(pData->pstate->encoder_pool->queue); if (new_buffer) { status = mmal_port_send_buffer(port, new_buffer); } if (!new_buffer || status != MMAL_SUCCESS) vcos_log_error("Unable to return a buffer to the encoder port"); } if (complete) vcos_semaphore_post(&(pData->complete_semaphore)); }
/** * buffer header callback function for camera control * * @param port Pointer to port from which callback originated * @param buffer mmal buffer header pointer */ static void camera_control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { fprintf(stderr, "Camera control callback cmd=0x%08x", buffer->cmd); if (buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED) { MMAL_EVENT_PARAMETER_CHANGED_T *param = (MMAL_EVENT_PARAMETER_CHANGED_T *)buffer->data; switch (param->hdr.id) { case MMAL_PARAMETER_CAMERA_SETTINGS: { MMAL_PARAMETER_CAMERA_SETTINGS_T *settings = (MMAL_PARAMETER_CAMERA_SETTINGS_T*)param; vcos_log_error("Exposure now %u, analog gain %u/%u, digital gain %u/%u", settings->exposure, settings->analog_gain.num, settings->analog_gain.den, settings->digital_gain.num, settings->digital_gain.den); vcos_log_error("AWB R=%u/%u, B=%u/%u", settings->awb_red_gain.num, settings->awb_red_gain.den, settings->awb_blue_gain.num, settings->awb_blue_gain.den ); } break; } } else if (buffer->cmd == MMAL_EVENT_ERROR) { vcos_log_error("No data received from sensor. Check all connections, including the Sunny one on the camera board"); } else { vcos_log_error("Received unexpected camera control callback event, 0x%08x", buffer->cmd); } mmal_buffer_header_release(buffer); }
/** Populate an output port with a pool of buffers */ static MMAL_STATUS_T mmal_port_populate_from_pool(MMAL_PORT_T* port, MMAL_POOL_T* pool) { MMAL_STATUS_T status = MMAL_SUCCESS; uint32_t buffer_idx; MMAL_BUFFER_HEADER_T *buffer; if (!port->priv->pf_send) return MMAL_ENOSYS; LOG_TRACE("%s port %p, pool: %p", port->name, port, pool); /* Populate port from pool */ for (buffer_idx = 0; buffer_idx < port->buffer_num; buffer_idx++) { buffer = mmal_queue_get(pool->queue); if (!buffer) { LOG_ERROR("too few buffers in the pool"); status = MMAL_ENOMEM; break; } status = mmal_port_send_buffer(port, buffer); if (status != MMAL_SUCCESS) { LOG_ERROR("failed to send buffer to port"); mmal_buffer_header_release(buffer); break; } } return status; }
static void control_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) { if ( buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED ) { } else { // Unexpected control callback event! } mmal_buffer_header_release ( buffer ); }
void gst_mmal_opaque_mem_set_mmal_header (GstMemory * mem, MMAL_BUFFER_HEADER_T * mmal_buffer_header) { if (mem == NULL || !gst_is_mmal_opaque_memory (mem)) { return; } { GstMMALOpaqueMemory *mmem = GST_MMAL_OPAQUE_MEMORY (mem); /* This function is also used by gst_mmal_opaque_buffer_pool_reset_buffer(), so we should take care to unref any header we're already pointing at. */ if (mmem->mmal_buffer_header != NULL) { mmal_buffer_header_release (mmem->mmal_buffer_header); } if (mmal_buffer_header != NULL) { mmal_buffer_header_acquire (mmal_buffer_header); } /* N.B. Setting to NULL is fine. */ mmem->mmal_buffer_header = mmal_buffer_header; } }
void CCameraOutput::OnVideoBufferCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { //to handle the user not reading frames, remove and return any pre-existing ones if(mmal_queue_length(OutputQueue)>=2) { if(MMAL_BUFFER_HEADER_T* existing_buffer = mmal_queue_get(OutputQueue)) { mmal_buffer_header_release(existing_buffer); if (port->is_enabled) { MMAL_STATUS_T status; MMAL_BUFFER_HEADER_T *new_buffer; new_buffer = mmal_queue_get(BufferPool->queue); if (new_buffer) status = mmal_port_send_buffer(port, new_buffer); if (!new_buffer || status != MMAL_SUCCESS) printf("Unable to return a buffer to the video port\n"); } } } //add the buffer to the output queue mmal_queue_put(OutputQueue,buffer); //printf("Video buffer callback, output queue len=%d\n", mmal_queue_length(OutputQueue)); }
void CMMALVideo::dec_output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { if (!(buffer->cmd == 0 && buffer->length > 0)) if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s port:%p buffer %p, len %d cmd:%x", CLASSNAME, __func__, port, buffer, buffer->length, buffer->cmd); bool kept = false; if (buffer->cmd == 0) { if (buffer->length > 0) { assert(!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_DECODEONLY)); double dts = DVD_NOPTS_VALUE; if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER0) { pthread_mutex_lock(&m_output_mutex); if (!m_dts_queue.empty()) { dts = m_dts_queue.front(); m_dts_queue.pop(); } else assert(0); pthread_mutex_unlock(&m_output_mutex); } if (m_drop_state) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - dropping %p (drop:%d)", CLASSNAME, __func__, buffer, m_drop_state); } else { CMMALVideoBuffer *omvb = new CMMALVideoBuffer(this); m_output_busy++; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - %p (%p) buffer_size(%u) dts:%.3f pts:%.3f flags:%x:%x frame:%d", CLASSNAME, __func__, buffer, omvb, buffer->length, dts*1e-6, buffer->pts*1e-6, buffer->flags, buffer->type->video.flags, omvb->m_changed_count); omvb->mmal_buffer = buffer; buffer->user_data = (void *)omvb; omvb->m_changed_count = m_changed_count; omvb->dts = dts; omvb->width = m_decoded_width; omvb->height = m_decoded_height; omvb->m_aspect_ratio = m_aspect_ratio; pthread_mutex_lock(&m_output_mutex); m_output_ready.push(omvb); pthread_mutex_unlock(&m_output_mutex); kept = true; } } } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { PortSettingsChanged(port, buffer); } if (!kept) mmal_buffer_header_release(buffer); }
/* This will output a frame that can be used for OpenCV */ IplImage* cvQueryRPiFrame(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_BUFFER_HEADER_T *new_buffer; PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata; if (pData) { if (buffer->length) { /*Convert buffer to RGB IplImage*/ mmal_buffer_header_mem_lock(buffer); int w=pData->pstate->width; // get image size int h=pData->pstate->height; int h4=h/4; memcpy(yCSI_CAM->imageData,buffer->data,w*h); memcpy(uCSI_CAM->imageData,buffer->data+w*h,w*h4); memcpy(vCSI_CAM->imageData,buffer->data+w*h+w*h4,w*h4); cvResize(uCSI_CAM, uCSI_CAM_BIG, CV_INTER_NN); cvResize(vCSI_CAM, vCSI_CAM_BIG, CV_INTER_NN); //CV_INTER_LINEAR looks better but it's slower cvMerge(yCSI_CAM, uCSI_CAM_BIG, vCSI_CAM_BIG, NULL, CSI_CAM_IMAGE); cvCvtColor(CSI_CAM_IMAGE,CSI_CAM_DSTIMAGE,CV_YCrCb2RGB); // convert in RGB color space (slow) mmal_buffer_header_mem_unlock(buffer); } else { vcos_log_error("buffer null"); } } else { vcos_log_error("Received a encoder buffer callback with no state"); } // release buffer back to the pool mmal_buffer_header_release(buffer); // and send one back to the port (if still open) if (port->is_enabled) { MMAL_STATUS_T status; new_buffer = mmal_queue_get(pData->pstate->video_pool->queue); if (new_buffer) status = mmal_port_send_buffer(port, new_buffer); if (!new_buffer || status != MMAL_SUCCESS) vcos_log_error("Unable to return a buffer to the encoder port"); } return CSI_CAM_DSTIMAGE; }
static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { if (!buffer->cmd) { AVBufferRef *buf = buffer->user_data; av_buffer_unref(&buf); } mmal_buffer_header_release(buffer); }
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; }
/** * MMAL Callback from camera preview output port. * @param port The camera preview port. * @param buf The new preview buffer. **/ static void preview_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf) { RASPITEX_STATE *state = (RASPITEX_STATE*) port->userdata; if (buf->length == 0) { vcos_log_trace("%s: zero-length buffer => EOS", port->name); state->preview_stop = 1; mmal_buffer_header_release(buf); } else if (buf->data == NULL) { vcos_log_trace("%s: zero buffer handle", port->name); mmal_buffer_header_release(buf); } else { /* Enqueue the preview frame for rendering and return to * avoid blocking MMAL core. */ //mmal_queue_put(state->preview_queue, buf); //to handle the user not reading frames, remove and return any pre-existing ones if(mmal_queue_length( state->preview_queue ) >= 2) { //fprintf(stderr, "mmal_queue_length too long\n" ); MMAL_BUFFER_HEADER_T *existing_buffer = mmal_queue_get( state->preview_queue ); if(existing_buffer) { mmal_buffer_header_release(existing_buffer); if (port->is_enabled) { fill_port_buffer_simple( port, state->preview_pool, "preview_output_cb" ); } // if (port->is_enabled) } // if(existing_buffer) } //add the buffer to the output queue mmal_queue_put(state->preview_queue, buf ); } }
static void ffmmal_release_frame(void *opaque, uint8_t *data) { FFBufferRef *ref = (void *)data; mmal_buffer_header_release(ref->buffer); ffmmal_poolref_unref(ref->pool); av_free(ref); }
static void CameraControlCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { if (buffer->cmd != MMAL_EVENT_PARAMETER_CHANGED) { std::cerr << "Received unexpected camera control callback event" << std::endl; } mmal_buffer_header_release(buffer); }
/** * buffer header callback function for camera control * * No actions taken in current version * * @param port Pointer to port from which callback originated * @param buffer mmal buffer header pointer */ static void camera_control_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { if (buffer->cmd == MMAL_EVENT_PARAMETER_CHANGED) { } else { vcos_log_error("Received unexpected camera control callback event, 0x%08x", buffer->cmd); } mmal_buffer_header_release(buffer); }
/** * buffer header callback function for video * * @param port Pointer to port from which callback originated * @param buffer mmal buffer header pointer */ static void video_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_BUFFER_HEADER_T *new_buffer; RASPIVID_STATE * state = (RASPIVID_STATE *)port->userdata; if (state) { if (state->finished) { vcos_semaphore_post(&state->capture_done_sem); return; } if (buffer->length) { mmal_buffer_header_mem_lock(buffer); // // *** PR : OPEN CV Stuff here ! // int w=state->width; // get image size int h=state->height; int pixelSize = state->monochrome ? 1 : 3; memcpy(state->dstImage->imageData,buffer->data,w*h*pixelSize); vcos_semaphore_post(&state->capture_done_sem); vcos_semaphore_wait(&state->capture_sem); mmal_buffer_header_mem_unlock(buffer); } else { vcos_log_error("buffer null"); } } else { vcos_log_error("Received a encoder buffer callback with no state"); } // release buffer back to the pool mmal_buffer_header_release(buffer); // and send one back to the port (if still open) if (port->is_enabled) { MMAL_STATUS_T status; new_buffer = mmal_queue_get(state->video_pool->queue); if (new_buffer) status = mmal_port_send_buffer(port, new_buffer); if (!new_buffer || status != MMAL_SUCCESS) vcos_log_error("Unable to return a buffer to the encoder port"); } }
/** Connected input port buffer callback */ static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PARAM_UNUSED(port); LOG_TRACE("buffer %p from connected input port %p: data %p, alloc_size %u, length %u", buffer, port, buffer->data, buffer->alloc_size, buffer->length); /* Simply release buffer back into pool for re-use */ mmal_buffer_header_release(buffer); }
/** Callback from the input port. * Buffer has been consumed and is available to be used again. */ static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; /* The decoder is done with the data, just recycle the buffer header into its pool */ mmal_buffer_header_release(buffer); /* Kick the processing thread */ vcos_semaphore_post(&ctx->semaphore); }