/** Send a buffer header to a port */ static MMAL_STATUS_T splitter_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_COMPONENT_T *component = port->component; MMAL_COMPONENT_MODULE_T *module = component->priv->module; MMAL_PORT_T *in_port, *out_port; MMAL_BUFFER_HEADER_T *in; MMAL_STATUS_T status; unsigned int i; mmal_queue_put(port->priv->module->queue, buffer); if (module->error) return MMAL_SUCCESS; /* Just do nothing */ /* Get input buffer header */ in_port = component->input[0]; in = mmal_queue_get(in_port->priv->module->queue); if (!in) return MMAL_SUCCESS; /* Nothing to do */ for (i = 0; i < component->output_num; i++) { out_port = component->output[i]; status = splitter_send_output(in, out_port); if (status != MMAL_SUCCESS && status != MMAL_EAGAIN) goto error; if (status == MMAL_SUCCESS) module->sent_flags |= (1<<i); } /* Check if we're done with the input buffer */ if ((module->sent_flags & module->enabled_flags) == module->enabled_flags) { in->length = 0; /* Consume the input buffer */ mmal_port_buffer_header_callback(in_port, in); module->sent_flags = 0; return MMAL_SUCCESS; } /* We're not done yet so put the buffer back in the queue */ mmal_queue_put(in_port->priv->module->queue, in); return MMAL_SUCCESS; error: mmal_queue_put(in_port->priv->module->queue, in); status = mmal_event_error_send(port->component, status); if (status != MMAL_SUCCESS) { LOG_ERROR("unable to send an error event buffer (%i)", (int)status); return MMAL_SUCCESS; } module->error = 1; return MMAL_SUCCESS; }
static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { AVCodecContext *avctx = (AVCodecContext*)port->userdata; MMALDecodeContext *ctx = avctx->priv_data; mmal_queue_put(ctx->queue_decoded_frames, buffer); }
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); } }
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)); }
/** 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); }
CMMALRenderer::~CMMALRenderer() { CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); // shutdown thread mmal_queue_put(m_release_queue, &m_quit_packet); m_sync.Wait(); mmal_queue_destroy(m_release_queue); UnInit(); }
/** Callback from the output port. * Buffer has been produced by the port and is available for processing. */ static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata; /* Queue the decoded video frame */ mmal_queue_put(ctx->queue, buffer); /* Kick the processing thread */ vcos_semaphore_post(&ctx->semaphore); }
/** Buffer sending */ static MMAL_STATUS_T sdl_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_COMPONENT_T *component = port->component; MMAL_COMPONENT_MODULE_T *module = component->priv->module; mmal_queue_put(module->queue, buffer); mmal_component_action_trigger(port->component); return MMAL_SUCCESS; }
/** Callback from an output port. Buffer is queued for the next component. */ static void mmal_connection_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)port->userdata; MMAL_PARAM_UNUSED(port); LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); /* Queue the buffer produced by the output port */ mmal_queue_put(connection->queue, buffer); if (connection->callback) connection->callback(connection); }
static MMAL_STATUS_T mmal_port_clock_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PORT_MODULE_T *module = port->priv->module; if (buffer->length) return mmal_port_clock_process_buffer(port, buffer); /* Queue empty buffers to be used later when forwarding clock updates */ mmal_queue_put(module->queue, buffer); return MMAL_SUCCESS; }
/** Callback from the pool. Buffer is available. */ static MMAL_BOOL_T mmal_connection_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata) { MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)userdata; MMAL_PARAM_UNUSED(pool); mmal_queue_put(pool->queue, buffer); if (connection->callback) connection->callback(connection); return 0; }
/** * 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 ); } }
void CMMALRenderer::vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data; #if defined(MMAL_DEBUG_VERBOSE) CLog::Log(LOGDEBUG, "%s::%s port:%p buffer %p (%p), len %d cmd:%x", CLASSNAME, __func__, port, buffer, omvb, buffer->length, buffer->cmd); #endif if (m_format == RENDER_FMT_MMAL) { mmal_queue_put(m_release_queue, buffer); } else if (m_format == RENDER_FMT_YUV420P) { mmal_buffer_header_release(buffer); } else assert(0); }
static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { decoder_t *dec = (decoder_t *)port->userdata; decoder_sys_t *sys = dec->p_sys; picture_t *picture; MMAL_EVENT_FORMAT_CHANGED_T *fmt; MMAL_ES_FORMAT_T *format; if (buffer->cmd == 0) { if (buffer->length > 0) { mmal_queue_put(sys->decoded_pictures, buffer); } else { picture = (picture_t *)buffer->user_data; picture_Release(picture); if (sys->output_pool) { buffer->user_data = NULL; buffer->alloc_size = 0; buffer->data = NULL; mmal_buffer_header_release(buffer); } } atomic_fetch_sub(&sys->output_in_transit, 1); vlc_sem_post(&sys->sem); } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { fmt = mmal_event_format_changed_get(buffer); format = mmal_format_alloc(); mmal_format_full_copy(format, fmt->format); if (sys->opaque) format->encoding = MMAL_ENCODING_OPAQUE; sys->output_format = format; mmal_buffer_header_release(buffer); } else { mmal_buffer_header_release(buffer); } }
/** * 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); } }
void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha) { CSingleLock lock(m_sharedSection); int source = m_iYV12RenderBuffer; CMMALBuffer *omvb = nullptr; if (!m_bConfigured) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - not configured: clear:%d flags:%x alpha:%d source:%d", CLASSNAME, __func__, clear, flags, alpha, source); goto exit; } if (m_format == RENDER_FMT_MMAL) omvb = m_buffers[source]; // we only want to upload frames once if (omvb && omvb->mmal_buffer && omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER1) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x skipping", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb->mmal_buffer, omvb->mmal_buffer->flags); goto exit; } ManageRenderArea(); if (m_format != RENDER_FMT_MMAL) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - bypass: clear:%d flags:%x alpha:%d source:%d format:%d", CLASSNAME, __func__, clear, flags, alpha, source, m_format); goto exit; } SetVideoRect(m_sourceRect, m_destRect); if (omvb && omvb->mmal_buffer) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb->mmal_buffer, omvb->mmal_buffer->flags); // check for changes in aligned sizes if (omvb->m_width != (uint32_t)m_vout_input->format->es->video.crop.width || omvb->m_height != (uint32_t)m_vout_input->format->es->video.crop.height || omvb->m_aligned_width != m_vout_input->format->es->video.width || omvb->m_aligned_height != m_vout_input->format->es->video.height) { CLog::Log(LOGDEBUG, "%s::%s Changing dimensions from %dx%d (%dx%d) to %dx%d (%dx%d)", CLASSNAME, __func__, m_vout_input->format->es->video.crop.width, m_vout_input->format->es->video.crop.height, omvb->m_width, omvb->m_height, m_vout_input->format->es->video.width, m_vout_input->format->es->video.height, omvb->m_aligned_width, omvb->m_aligned_height); m_vout_input->format->es->video.width = omvb->m_aligned_width; m_vout_input->format->es->video.height = omvb->m_aligned_height; m_vout_input->format->es->video.crop.width = omvb->m_width; m_vout_input->format->es->video.crop.height = omvb->m_height; MMAL_STATUS_T status = mmal_port_format_commit(m_vout_input); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to commit vout input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); goto exit; } } m_inflight++; assert(omvb->mmal_buffer && omvb->mmal_buffer->data && omvb->mmal_buffer->length); omvb->Acquire(); omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_USER1 | MMAL_BUFFER_HEADER_FLAG_USER2; omvb->mmal_buffer->user_data = omvb; if (m_queue && m_fps > 0.0f) mmal_queue_put(m_queue, omvb->mmal_buffer); else mmal_port_send_buffer(m_vout_input, omvb->mmal_buffer); } else CLog::Log(LOGDEBUG, "%s::%s - MMAL: No buffer to update clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb ? omvb->mmal_buffer : nullptr); exit: lock.Leave(); g_RBP.WaitVsync(); }