int Private_Impl_Still::startCapture() { // If the parameters were changed and this function wasn't called, it will be called here // However if the parameters weren't changed, the function won't do anything - it will return right away commitParameters(); if ( encoder_output_port->is_enabled ) { cout << API_NAME << ": Could not enable encoder output port. Try waiting longer before attempting to take another picture.\n"; return -1; } if ( mmal_port_enable ( encoder_output_port, buffer_callback ) != MMAL_SUCCESS ) { cout << API_NAME << ": Could not enable encoder output port.\n"; return -1; } int num = mmal_queue_length ( encoder_pool->queue ); for ( int b = 0; b < num; b++ ) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( encoder_pool->queue ); if ( !buffer ) cout << API_NAME << ": Could not get buffer (#" << b << ") from pool queue.\n"; if ( mmal_port_send_buffer ( encoder_output_port, buffer ) != MMAL_SUCCESS ) cout << API_NAME << ": Could not send a buffer (#" << b << ") to encoder output port.\n"; } if ( mmal_port_parameter_set_boolean ( camera_still_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) { cout << API_NAME << ": Failed to start capture.\n"; return -1; } return 0; }
/**After setting parameters video port is initialized with empty buffers */ bool Private_Impl::startCapture() { if ( !_isOpened ) { cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << " not opened." << endl; return false; //already opened } // start capture if ( mmal_port_parameter_set_boolean ( camera_video_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) { release(); return false; } // Send all the buffers to the video port int num = mmal_queue_length ( State.video_pool->queue ); int q; for ( q = 0; q < num; q++ ) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( State.video_pool->queue ); if ( !buffer ) cerr << "Unable to get a required buffer" << q << " from pool queue" << endl; if ( mmal_port_send_buffer ( camera_video_port, buffer ) != MMAL_SUCCESS ) cerr << "Unable to send a buffer to encoder output port " << q << endl; } _isCapturing = true; return true; }
bool CMMALVideo::SendCodecConfigData() { MMAL_STATUS_T status; if (!m_dec_input_pool) return true; // send code config data MMAL_BUFFER_HEADER_T *buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500); if (!buffer) { CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__); return false; } mmal_buffer_header_reset(buffer); buffer->cmd = 0; buffer->length = std::min(m_hints.extrasize, buffer->alloc_size); memcpy(buffer->data, m_hints.extradata, buffer->length); buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_CONFIG; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d flags:%x", CLASSNAME, __func__, buffer, buffer->length, buffer->flags); status = mmal_port_send_buffer(m_dec_input, buffer); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } return true; }
void take_frame( char * dump_pointer ) { gCallback_data.data_dump = dump_pointer; int num = mmal_queue_length(gState.camera_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(gState.camera_pool->queue); if (!buffer) vcos_log_error("Unable to get a required buffer %d from pool queue", q); if (mmal_port_send_buffer(gCamera_still_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to camera output port (%d)", q); } if (mmal_port_parameter_set_boolean(gCamera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { vcos_log_error("%s: Failed to start capture", __func__); } else { vcos_semaphore_wait(&gCallback_data.complete_semaphore); } }
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)); }
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"); } } }
/** 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; }
int start_capture(RASPIVID_STATE *state) { if (!(state->isInit)) init_cam(state); //raspicamcontrol_set_flips(state->camera_component, state->camera_parameters.hflip, state->camera_parameters.vflip); raspicamcontrol_set_flips(state->camera_component, hflip, vflip); MMAL_PORT_T *camera_video_port = state->camera_component->output[MMAL_CAMERA_VIDEO_PORT]; //MMAL_PORT_T *encoder_output_port = state->encoder_component->output[0]; ROS_INFO("Starting video capture (%d, %d, %d, %d)\n", state->width, state->height, state->quality, state->framerate); if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { return 1; } // Send all the buffers to the video port { int num = mmal_queue_length(state->camera_pool->queue); int q; for (q=0; q < num; q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state->camera_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) if (mmal_port_send_buffer(camera_video_port, buffer)!= MMAL_SUCCESS) vcos_log_error("Unable to send a buffer to encoder output port (%d)", q); } } ROS_INFO("Video capture started\n"); return 0; }
/** * 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_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)); }
/* 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; }
/* This is a camera path endpoint callback setup for GPU encoder data | to the ARM. The callback should handle final disposition of encoder data. */ boolean out_port_callback(CameraObject *obj, int port_num, void callback()) { MMAL_PORT_T *port; MMAL_STATUS_T status; char *msg = "mmal_port_enable"; int i, n; if (!obj->component) return FALSE; port = obj->component->output[port_num]; /* Create an initial queue of buffers for the output port. | FIXME? Can't handle callbacks for more than one splitter port | because I only have one pool_out per component. */ if (!obj->pool_out) { if ((obj->pool_out = mmal_port_pool_create(port, port->buffer_num, port->buffer_size)) == NULL) { log_printf("out_port_callback %s: mmal_port_pool_create failed.\n", obj->name); return FALSE; } } /* Connect the callback and initialize buffer pool of data that will | be sent to the callback. */ if ((status = mmal_port_enable(port, callback)) == MMAL_SUCCESS) { obj->port_out = port; port->userdata = (struct MMAL_PORT_USERDATA_T *) obj; /* Send all buffers in the created queue to the GPU output port. | These buffers will then be delivered back to the ARM with filled | GPU data via the above callback where we can process the data | and then resend the buffer back to the port to be refilled. */ msg = "mmal_port_send_buffer"; n = mmal_queue_length(obj->pool_out->queue); for (i = 0; i < n; ++i) { status = mmal_port_send_buffer(port, mmal_queue_get(obj->pool_out->queue)); if (status != MMAL_SUCCESS) break; } } if (status != MMAL_SUCCESS) { log_printf("out_port_callback %s: %s failed. Status %s\n", obj->name, msg, mmal_status[status]); return FALSE; } return TRUE; }
static picture_t *deinterlace(filter_t *filter, picture_t *picture) { filter_sys_t *sys = filter->p_sys; MMAL_BUFFER_HEADER_T *buffer; picture_t *out_picture = NULL; picture_t *ret = NULL; MMAL_STATUS_T status; unsigned i = 0; fill_output_port(filter); buffer = picture->p_sys->buffer; buffer->user_data = picture; buffer->pts = picture->date; buffer->cmd = 0; if (!picture->p_sys->displayed) { vlc_mutex_lock(&sys->buffer_cond_mutex); status = mmal_port_send_buffer(sys->input, buffer); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to send buffer to input port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); picture_Release(picture); } else { picture->p_sys->displayed = true; atomic_fetch_add(&sys->input_in_transit, 1); vlc_cond_signal(&sys->buffer_cond); } vlc_mutex_unlock(&sys->buffer_cond_mutex); } else { picture_Release(picture); } /* * Send output buffers */ while(atomic_load(&sys->started) && i < 2) { if (buffer = mmal_queue_timedwait(sys->filtered_pictures, 2000)) { i++; if (!out_picture) { out_picture = (picture_t *)buffer->user_data; ret = out_picture; } else { out_picture->p_next = (picture_t *)buffer->user_data; out_picture = out_picture->p_next; } out_picture->date = buffer->pts; } else { msg_Dbg(filter, "Failed waiting for filtered picture"); break; } } if (out_picture) out_picture->p_next = NULL; return ret; }
/** * 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"); } }
/** * buffer header callback function for camera output port * * 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 camera_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) { if (buffer->length) { mmal_buffer_header_mem_lock(buffer); int i; for( i = 0; i < buffer->length; i++ ) pData->data_dump[i] = buffer->data[i]; mmal_buffer_header_mem_unlock(buffer); } // Check end of frame or error if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED)) complete = 1; } else { vcos_log_error("Received a camera still 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_BUFFER_HEADER_T *new_buffer = mmal_queue_get(pData->pstate->camera_pool->queue); // and back to the port from there. if (new_buffer) { status = mmal_port_send_buffer(port, new_buffer); } if (!new_buffer || status != MMAL_SUCCESS) vcos_log_error("Unable to return the buffer to the camera still port"); } if (complete) { vcos_semaphore_post(&(pData->complete_semaphore)); } }
MMAL_POOL_T* CCameraOutput::EnablePortCallbackAndCreateBufferPool(MMAL_PORT_T* port, MMAL_PORT_BH_CB_T cb, int buffer_count) { MMAL_STATUS_T status; MMAL_POOL_T* buffer_pool = 0; //setup video port buffer and a pool to hold them port->buffer_num = buffer_count; port->buffer_size = port->buffer_size_recommended; printf("Creating pool with %d buffers of size %d\n", port->buffer_num, port->buffer_size); buffer_pool = mmal_port_pool_create(port, port->buffer_num, port->buffer_size); if (!buffer_pool) { printf("Couldn't create video buffer pool\n"); goto error; } //enable the port and hand it the callback port->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(port, cb); if (status != MMAL_SUCCESS) { printf("Failed to set video buffer callback\n"); goto error; } //send all the buffers in our pool to the video port ready for use { int num = mmal_queue_length(buffer_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(buffer_pool->queue); if (!buffer) { printf("Unable to get a required buffer %d from pool queue\n", q); goto error; } else if (mmal_port_send_buffer(port, buffer)!= MMAL_SUCCESS) { printf("Unable to send a buffer to port (%d)\n", q); goto error; } } } return buffer_pool; error: if(buffer_pool) mmal_port_pool_destroy(port,buffer_pool); return NULL; }
void consume_queue_on_connection(MMAL_PORT_T *port, MMAL_QUEUE_T *queue) { MMAL_BUFFER_HEADER_T *buffer; while ((buffer = mmal_queue_get(queue)) != NULL) { if (mmal_port_send_buffer(port, buffer) != MMAL_SUCCESS) { mmal_queue_put_back(queue, buffer); break; } } }
/** * 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) { MMAL_BUFFER_HEADER_T *new_buffer; // 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; vcos_assert(pData->file_handle); if (buffer->length) { mmal_buffer_header_mem_lock(buffer); bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle); mmal_buffer_header_mem_unlock(buffer); } if (bytes_written != buffer->length) { vcos_log_error("Failed to write buffer data (%d from %d)- aborting", bytes_written, buffer->length); pData->abort = 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; 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"); } }
static void vd_display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; picture_sys_t *pic_sys = picture->p_sys; MMAL_BUFFER_HEADER_T *buffer = pic_sys->buffer; MMAL_STATUS_T status; if (picture->format.i_frame_rate != sys->i_frame_rate || picture->format.i_frame_rate_base != sys->i_frame_rate_base || picture->b_progressive != sys->b_progressive || picture->b_top_field_first != sys->b_top_field_first) { sys->b_top_field_first = picture->b_top_field_first; sys->b_progressive = picture->b_progressive; sys->i_frame_rate = picture->format.i_frame_rate; sys->i_frame_rate_base = picture->format.i_frame_rate_base; configure_display(vd, NULL, &picture->format); } if (!pic_sys->displayed || !sys->opaque) { buffer->cmd = 0; buffer->length = sys->input->buffer_size; vlc_mutex_lock(&sys->buffer_mutex); while (sys->buffers_in_transit >= MAX_BUFFERS_IN_TRANSIT) vlc_cond_wait(&sys->buffer_cond, &sys->buffer_mutex); status = mmal_port_send_buffer(sys->input, buffer); if (status == MMAL_SUCCESS) ++sys->buffers_in_transit; vlc_mutex_unlock(&sys->buffer_mutex); if (status != MMAL_SUCCESS) { msg_Err(vd, "Failed to send buffer to input port. Frame dropped"); picture_Release(picture); } pic_sys->displayed = true; } else { picture_Release(picture); } display_subpicture(vd, subpicture); if (subpicture) subpicture_Delete(subpicture); if (sys->next_phase_check == 0 && sys->adjust_refresh_rate) maintain_phase_sync(vd); sys->next_phase_check = (sys->next_phase_check + 1) % PHASE_CHECK_INTERVAL; }
static void jpegencoder_buffer_callback (MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { int bytes_written = buffer->length; char *filename_temp, *filename_temp2; if(mjpeg_cnt == 0) { if(!jpegoutput_file) { asprintf(&filename_temp, jpeg_filename, image_cnt); asprintf(&filename_temp2, "%s.part", filename_temp); jpegoutput_file = fopen(filename_temp2, "wb"); free(filename_temp); free(filename_temp2); if(!jpegoutput_file) error("Could not open mjpeg-destination"); } if(buffer->length) { mmal_buffer_header_mem_lock(buffer); bytes_written = fwrite(buffer->data, 1, buffer->length, jpegoutput_file); mmal_buffer_header_mem_unlock(buffer); } if(bytes_written != buffer->length) error("Could not write all bytes"); } if(buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) { mjpeg_cnt++; if(mjpeg_cnt == divider) { fclose(jpegoutput_file); jpegoutput_file = NULL; asprintf(&filename_temp, jpeg_filename, image_cnt); asprintf(&filename_temp2, "%s.part", filename_temp); rename(filename_temp2, filename_temp); free(filename_temp); free(filename_temp2); image_cnt++; mjpeg_cnt = 0; } } mmal_buffer_header_release(buffer); if (port->is_enabled) { MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_BUFFER_HEADER_T *new_buffer; new_buffer = mmal_queue_get(pool_jpegencoder->queue); if (new_buffer) status = mmal_port_send_buffer(port, new_buffer); if (!new_buffer || status != MMAL_SUCCESS) error("Could not send buffers to port"); } }
/** Populate clock ports from the given pool */ static MMAL_STATUS_T mmal_port_populate_clock_ports(MMAL_PORT_T* output, MMAL_PORT_T* input, MMAL_POOL_T* pool) { MMAL_STATUS_T status = MMAL_SUCCESS; MMAL_BUFFER_HEADER_T *buffer; if (!output->priv->pf_send || !input->priv->pf_send) return MMAL_ENOSYS; LOG_TRACE("output %s %p, input %s %p, pool: %p", output->name, output, input->name, input, pool); buffer = mmal_queue_get(pool->queue); while (buffer) { status = mmal_port_send_buffer(output, buffer); if (status != MMAL_SUCCESS) { LOG_ERROR("failed to send buffer to clock port %s", output->name); mmal_buffer_header_release(buffer); break; } buffer = mmal_queue_get(pool->queue); if (buffer) { status = mmal_port_send_buffer(input, buffer); if (status != MMAL_SUCCESS) { LOG_ERROR("failed to send buffer to clock port %s", output->name); mmal_buffer_header_release(buffer); break; } buffer = mmal_queue_get(pool->queue); } } return status; }
void Private_Impl::video_buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) { MMAL_BUFFER_HEADER_T *new_buffer; PORT_USERDATA *pData = ( PORT_USERDATA * ) port->userdata; bool hasGrabbed = false; //pData->_mutex.lock(); std::unique_lock<std::mutex> lck ( pData->_mutex ); if ( pData ) { if ( pData->wantToGrab && buffer->length ) { mmal_buffer_header_mem_lock ( buffer ); //printf("pdata buff length%d\n",pData->_buffData.size); pData->_buffData.resize ( buffer->length ); memcpy ( pData->_buffData.data, buffer->data, buffer->length ); pData->npts = buffer->pts; //tst=buffer->pts; pData->wantToGrab = false; hasGrabbed = true; mmal_buffer_header_mem_unlock ( buffer ); } } //pData->_mutex.unlock(); // if ( hasGrabbed ) pData->Thcond.BroadCast(); //wake up waiting client // 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 ) printf ( "Unable to return a buffer to the encoder port\n" ); } if ( pData->pstate->shutterSpeed != 0 ) mmal_port_parameter_set_uint32 ( pData->pstate->camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, pData->pstate->shutterSpeed ) ; if ( hasGrabbed ) pData->Thcond.BroadCast(); //wake up waiting client }
int fill_port_buffer(MMAL_PORT_T *port, MMAL_POOL_T *pool) { int q; int num = mmal_queue_length(pool->queue); for (q = 0; q < num; q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(pool->queue); if (!buffer) { fprintf(stderr, "Unable to get a required buffer %d from pool queue\n", q); } if (mmal_port_send_buffer(port, buffer) != MMAL_SUCCESS) { fprintf(stderr, "Unable to send a buffer to port (%d)\n", q); } } }
/** Callback for when a buffer from a connected input port is finally released */ static MMAL_BOOL_T mmal_port_connected_pool_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata) { MMAL_PORT_T* port = (MMAL_PORT_T*)userdata; MMAL_STATUS_T status; MMAL_PARAM_UNUSED(pool); LOG_TRACE("released buffer %p, data %p alloc_size %u length %u", buffer, buffer->data, buffer->alloc_size, buffer->length); /* Pipe the buffer back to the output port */ status = mmal_port_send_buffer(port, buffer); /* Put the buffer back in the pool if we were successful */ return status != MMAL_SUCCESS; }
/** Preview worker thread. * Ensures camera preview is supplied with buffers and sends preview frames to GL. * @param arg Pointer to state. * @return NULL always. */ static void *preview_worker(void *arg) { RASPITEX_STATE* state = arg; MMAL_PORT_T *preview_port = state->preview_port; MMAL_BUFFER_HEADER_T *buf; MMAL_STATUS_T st; int rc; vcos_log_trace("%s: port %p", VCOS_FUNCTION, preview_port); rc = state->ops.create_native_window(state); if (rc != 0) goto end; rc = state->ops.gl_init(state); if (rc != 0) goto end; while (state->preview_stop == 0) { /* Send empty buffers to camera preview port */ while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL) { st = mmal_port_send_buffer(preview_port, buf); if (st != MMAL_SUCCESS) { vcos_log_error("Failed to send buffer to %s", preview_port->name); } } /* Process returned buffers */ if (preview_process_returned_bufs(state) != 0) { vcos_log_error("Preview error. Exiting."); state->preview_stop = 1; } } end: /* Make sure all buffers are returned on exit */ while ((buf = mmal_queue_get(state->preview_queue)) != NULL) mmal_buffer_header_release(buf); /* Tear down GL */ state->ops.gl_term(state); vcos_log_trace("Exiting preview worker"); return NULL; }
// Move prepared/split packets from waiting_buffers to the MMAL decoder. static int ffmmal_fill_input_port(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; while (ctx->waiting_buffers) { MMAL_BUFFER_HEADER_T *mbuffer; FFBufferEntry *buffer; MMAL_STATUS_T status; mbuffer = mmal_queue_get(ctx->pool_in->queue); if (!mbuffer) return 0; buffer = ctx->waiting_buffers; mmal_buffer_header_reset(mbuffer); mbuffer->cmd = 0; mbuffer->pts = buffer->pts; mbuffer->dts = buffer->dts; mbuffer->flags = buffer->flags; mbuffer->data = buffer->data; mbuffer->length = buffer->length; mbuffer->user_data = buffer; mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size; // Remove from start of the list ctx->waiting_buffers = buffer->next; if (ctx->waiting_buffers_tail == buffer) ctx->waiting_buffers_tail = NULL; if ((status = mmal_port_send_buffer(ctx->decoder->input[0], mbuffer))) { mmal_buffer_header_release(mbuffer); av_buffer_unref(&buffer->ref); if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1); av_free(buffer); } if (status) { av_log(avctx, AV_LOG_ERROR, "MMAL error %d when sending input\n", (int)status); return AVERROR_UNKNOWN; } } return 0; }
void PiCam::start() { if (mmal_port_parameter_set_boolean(videoPort, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { throw std::runtime_error("Couldn't start video capture"); } vcos_semaphore_create(&frame_semaphore, "frame_semaphore", 0); int num = mmal_queue_length(videoPool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(videoPool->queue); // TODO: Add numbers to these error messages. if (!buffer) throw std::runtime_error("Unable to get a required buffer from pool queue"); if (mmal_port_send_buffer(videoPort, buffer)!= MMAL_SUCCESS) throw std::runtime_error("Unable to send a buffer to an encoder output port"); } std::chrono::time_point<std::chrono::system_clock> t1, t2; t1 = std::chrono::system_clock::now(); /* while(true) { if(vcos_semaphore_wait(&frame_semaphore) == VCOS_SUCCESS) { callback(frame); ++numFrames; if(numFrames >= 30) { t2 = std::chrono::system_clock::now(); std::chrono::duration<float> secs = t2-t1; t1 = t2; std::cout << (numFrames / secs.count()) << " FPS\n"; numFrames = 0; } cv::waitKey(1); } } */ }
static int send_output_buffer(filter_t *filter) { filter_sys_t *sys = filter->p_sys; MMAL_BUFFER_HEADER_T *buffer; MMAL_STATUS_T status; picture_t *picture; int ret = 0; if (!sys->output->is_enabled) { ret = VLC_EGENERIC; goto out; } picture = filter_NewPicture(filter); if (!picture) { msg_Warn(filter, "Failed to get new picture"); ret = -1; goto out; } picture->format.i_frame_rate = filter->fmt_out.video.i_frame_rate; picture->format.i_frame_rate_base = filter->fmt_out.video.i_frame_rate_base; buffer = picture->p_sys->buffer; buffer->user_data = picture; buffer->cmd = 0; mmal_picture_lock(picture); vlc_mutex_lock(&sys->buffer_cond_mutex); status = mmal_port_send_buffer(sys->output, buffer); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to send buffer to output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); mmal_buffer_header_release(buffer); picture_Release(picture); ret = -1; } else { atomic_fetch_add(&sys->output_in_transit, 1); vlc_cond_signal(&sys->buffer_cond); } vlc_mutex_unlock(&sys->buffer_cond_mutex); out: return ret; }
/** * buffer header callback function for camera output port * * 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 camera_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_STATUS_T status; // We pass our file handle and other stuff in via the userdata field. PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata; if (pData) { if (buffer->length) { mmal_buffer_header_mem_lock(buffer); fwrite(buffer->data, 1, buffer->length, pData->file_handle); mmal_buffer_header_mem_unlock(buffer); } // What about error conditions? if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_EOS | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED)) { vcos_semaphore_post(&(pData->complete_semaphore)); } } else { vcos_log_error("Received a camera still 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_BUFFER_HEADER_T *new_buffer = mmal_queue_get(pData->pstate->camera_pool->queue); // and back to the port from there. status = mmal_port_send_buffer(port, new_buffer); if (status != MMAL_SUCCESS) vcos_log_error("Unable to return the buffer to the camera still port"); } }
void CMMALVideo::Recycle(MMAL_BUFFER_HEADER_T *buffer) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, buffer); MMAL_STATUS_T status; mmal_buffer_header_reset(buffer); buffer->cmd = 0; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s Send buffer %p from pool to decoder output port %p dts_queue(%d) ready_queue(%d) busy_queue(%d)", CLASSNAME, __func__, buffer, m_dec_output, m_dts_queue.size(), m_output_ready.size(), m_output_busy); status = mmal_port_send_buffer(m_dec_output, buffer); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s - Failed send buffer to decoder output port (status=0%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return; } }
/** Connected input port buffer callback */ static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { 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); /* Clock ports are bi-directional and a buffer coming from an "input" * clock port can potentially have valid payload data, in which case * it should be sent directly to the connected port. */ if (port->type == MMAL_PORT_TYPE_CLOCK && buffer->length) { MMAL_PORT_T* connected_port = port->priv->core->connected_port; mmal_port_send_buffer(connected_port, buffer); return; } /* Simply release buffer back into pool for re-use */ mmal_buffer_header_release(buffer); }