/** Create an instance of a component */ static MMAL_STATUS_T mmal_component_create_splitter(const char *name, MMAL_COMPONENT_T *component) { MMAL_COMPONENT_MODULE_T *module; MMAL_STATUS_T status = MMAL_ENOMEM; unsigned int i; MMAL_PARAM_UNUSED(name); /* Allocate the context for our module */ component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); if (!module) return MMAL_ENOMEM; memset(module, 0, sizeof(*module)); component->priv->pf_destroy = splitter_component_destroy; /* Allocate and initialise all the ports for this component */ component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); if(!component->input) goto error; component->input_num = 1; component->input[0]->priv->pf_enable = splitter_port_enable; component->input[0]->priv->pf_disable = splitter_port_disable; component->input[0]->priv->pf_flush = splitter_port_flush; component->input[0]->priv->pf_send = splitter_port_send; component->input[0]->priv->pf_set_format = splitter_port_format_commit; component->input[0]->priv->pf_parameter_set = splitter_port_parameter_set; component->input[0]->buffer_num_min = 1; component->input[0]->buffer_num_recommended = 0; component->input[0]->priv->module->queue = mmal_queue_create(); if(!component->input[0]->priv->module->queue) goto error; component->output = mmal_ports_alloc(component, SPLITTER_OUTPUT_PORTS_NUM, MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); if(!component->output) goto error; component->output_num = SPLITTER_OUTPUT_PORTS_NUM; for(i = 0; i < component->output_num; i++) { component->output[i]->priv->pf_enable = splitter_port_enable; component->output[i]->priv->pf_disable = splitter_port_disable; component->output[i]->priv->pf_flush = splitter_port_flush; component->output[i]->priv->pf_send = splitter_port_send; component->output[i]->priv->pf_set_format = splitter_port_format_commit; component->output[i]->priv->pf_parameter_set = splitter_port_parameter_set; component->output[i]->buffer_num_min = 1; component->output[i]->buffer_num_recommended = 0; component->output[i]->capabilities = MMAL_PORT_CAPABILITY_PASSTHROUGH; component->output[i]->priv->module->queue = mmal_queue_create(); if(!component->output[i]->priv->module->queue) goto error; } return MMAL_SUCCESS; error: splitter_component_destroy(component); return status; }
CMMALRenderer::CMMALRenderer() : CThread("CMMALRenderer") { CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); m_vout = NULL; m_vout_input = NULL; m_vout_input_pool = NULL; memset(m_buffers, 0, sizeof m_buffers); m_release_queue = mmal_queue_create(); Create(); }
/** Create an instance of a component */ static MMAL_STATUS_T mmal_component_create_sdl(const char *name, MMAL_COMPONENT_T *component) { MMAL_COMPONENT_MODULE_T *module; MMAL_STATUS_T status = MMAL_ENOMEM; /* Check we're the requested component */ if(strcmp(name, "sdl." MMAL_VIDEO_RENDER)) return MMAL_ENOENT; if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTTHREAD|SDL_INIT_NOPARACHUTE) < 0) return MMAL_ENXIO; /* Allocate our module context */ component->priv->module = module = vcos_calloc(1, sizeof(*module), "mmal module"); if(!module) return MMAL_ENOMEM; module->queue = mmal_queue_create(); if(!module->queue) goto error; /* Allocate the ports for this component */ component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, 0); if(!component->input) goto error; component->input_num = 1; module->display_region.width = SDL_WIDTH; module->display_region.height = SDL_HEIGHT; /************/ component->input[0]->priv->pf_set_format = sdl_port_set_format; component->input[0]->priv->pf_enable = sdl_port_enable; component->input[0]->priv->pf_disable = sdl_port_disable; component->input[0]->priv->pf_flush = sdl_port_flush; component->input[0]->priv->pf_send = sdl_port_send; component->input[0]->priv->pf_parameter_set = sdl_port_parameter_set; component->input[0]->buffer_num_min = INPUT_MIN_BUFFER_NUM; component->input[0]->buffer_num_recommended = INPUT_RECOMMENDED_BUFFER_NUM; component->priv->pf_destroy = sdl_component_destroy; /* Create a thread to monitor SDL events */ module->thread = SDL_CreateThread(sdl_event_thread, component); status = mmal_component_action_register(component, sdl_do_processing_loop); if (status != MMAL_SUCCESS) goto error; return MMAL_SUCCESS; error: sdl_component_destroy(component); return status; }
/* Initialise all callbacks and setup internal resources */ static MMAL_STATUS_T mmal_port_clock_setup(MMAL_PORT_T *port, MMAL_PORT_CLOCK_EVENT_CB event_cb) { MMAL_STATUS_T status; status = mmal_clock_create(&port->priv->module->clock); if (status != MMAL_SUCCESS) { LOG_ERROR("failed to create clock module on port %s (%s)", port->name, mmal_status_to_string(status)); return status; } port->priv->module->clock->user_data = port; port->buffer_size = sizeof(MMAL_CLOCK_PAYLOAD_T); port->buffer_size_min = sizeof(MMAL_CLOCK_PAYLOAD_T); port->buffer_num_min = MMAL_PORT_CLOCK_BUFFERS_MIN; port->buffer_num_recommended = MMAL_PORT_CLOCK_BUFFERS_MIN; port->priv->module->event_cb = event_cb; port->priv->module->queue = mmal_queue_create(); if (!port->priv->module->queue) { mmal_clock_destroy(port->priv->module->clock); return MMAL_ENOMEM; } port->priv->pf_set_format = mmal_port_clock_set_format; port->priv->pf_enable = mmal_port_clock_enable; port->priv->pf_disable = mmal_port_clock_disable; port->priv->pf_send = mmal_port_clock_send; port->priv->pf_flush = mmal_port_clock_flush; port->priv->pf_parameter_set = mmal_port_clock_parameter_set; port->priv->pf_parameter_get = mmal_port_clock_parameter_get; port->priv->pf_connect = mmal_port_clock_connect; #ifdef __VIDEOCORE__ port->priv->pf_payload_alloc = mmal_port_clock_payload_alloc; port->priv->pf_payload_free = mmal_port_clock_payload_free; port->capabilities = MMAL_PORT_CAPABILITY_ALLOCATION; #endif return status; }
static av_cold int ffmmal_init_decoder(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; MMAL_STATUS_T status; MMAL_ES_FORMAT_T *format_in; MMAL_COMPONENT_T *decoder; char tmp[32]; int ret = 0; bcm_host_init(); if (mmal_vc_init()) { av_log(avctx, AV_LOG_ERROR, "Cannot initialize MMAL VC driver!\n"); return AVERROR(ENOSYS); } if ((ret = ff_get_format(avctx, avctx->codec->pix_fmts)) < 0) return ret; avctx->pix_fmt = ret; if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->decoder))) goto fail; decoder = ctx->decoder; format_in = decoder->input[0]->format; format_in->type = MMAL_ES_TYPE_VIDEO; switch (avctx->codec_id) { case AV_CODEC_ID_MPEG2VIDEO: format_in->encoding = MMAL_ENCODING_MP2V; break; case AV_CODEC_ID_MPEG4: format_in->encoding = MMAL_ENCODING_MP4V; break; case AV_CODEC_ID_VC1: format_in->encoding = MMAL_ENCODING_WVC1; break; case AV_CODEC_ID_H264: default: format_in->encoding = MMAL_ENCODING_H264; break; } format_in->es->video.width = FFALIGN(avctx->width, 32); format_in->es->video.height = FFALIGN(avctx->height, 16); format_in->es->video.crop.width = avctx->width; format_in->es->video.crop.height = avctx->height; format_in->es->video.frame_rate.num = 24000; format_in->es->video.frame_rate.den = 1001; format_in->es->video.par.num = avctx->sample_aspect_ratio.num; format_in->es->video.par.den = avctx->sample_aspect_ratio.den; format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED; av_get_codec_tag_string(tmp, sizeof(tmp), format_in->encoding); av_log(avctx, AV_LOG_DEBUG, "Using MMAL %s encoding.\n", tmp); #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS, -1 - ctx->extra_decoder_buffers)) { av_log(avctx, AV_LOG_WARNING, "Could not set input buffering limit.\n"); } #endif if ((status = mmal_port_format_commit(decoder->input[0]))) goto fail; decoder->input[0]->buffer_num = FFMAX(decoder->input[0]->buffer_num_min, 20); decoder->input[0]->buffer_size = FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024); ctx->pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0); if (!ctx->pool_in) { ret = AVERROR(ENOMEM); goto fail; } if ((ret = ffmal_update_format(avctx)) < 0) goto fail; ctx->queue_decoded_frames = mmal_queue_create(); if (!ctx->queue_decoded_frames) goto fail; decoder->input[0]->userdata = (void*)avctx; decoder->output[0]->userdata = (void*)avctx; decoder->control->userdata = (void*)avctx; if ((status = mmal_port_enable(decoder->control, control_port_cb))) goto fail; if ((status = mmal_port_enable(decoder->input[0], input_callback))) goto fail; if ((status = mmal_port_enable(decoder->output[0], output_callback))) goto fail; if ((status = mmal_component_enable(decoder))) goto fail; return 0; fail: ffmmal_close_decoder(avctx); return ret < 0 ? ret : AVERROR_UNKNOWN; }
static int Open(filter_t *filter) { int32_t frame_duration = filter->fmt_in.video.i_frame_rate != 0 ? (int64_t)1000000 * filter->fmt_in.video.i_frame_rate_base / filter->fmt_in.video.i_frame_rate : 0; MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = { { MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param) }, MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV, 2, { 3, frame_duration } }; int ret = VLC_SUCCESS; MMAL_STATUS_T status; filter_sys_t *sys; msg_Dbg(filter, "Try to open mmal_deinterlace filter. frame_duration: %d!", frame_duration); if (filter->fmt_in.video.i_chroma != VLC_CODEC_MMAL_OPAQUE) return VLC_EGENERIC; if (filter->fmt_out.video.i_chroma != VLC_CODEC_MMAL_OPAQUE) return VLC_EGENERIC; sys = calloc(1, sizeof(filter_sys_t)); if (!sys) return VLC_ENOMEM; filter->p_sys = sys; bcm_host_init(); status = mmal_component_create(MMAL_COMPONENT_DEFAULT_DEINTERLACE, &sys->component); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to create MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_port_parameter_set(sys->component->output[0], &imfx_param.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to configure MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)filter; status = mmal_port_enable(sys->component->control, control_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable control port %s (status=%"PRIx32" %s)", sys->component->control->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input = sys->component->input[0]; sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)filter; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) sys->input->format->encoding = MMAL_ENCODING_OPAQUE; sys->input->format->es->video.width = filter->fmt_in.video.i_width; sys->input->format->es->video.height = filter->fmt_in.video.i_height; sys->input->format->es->video.crop.x = 0; sys->input->format->es->video.crop.y = 0; sys->input->format->es->video.crop.width = filter->fmt_in.video.i_width; sys->input->format->es->video.crop.height = filter->fmt_in.video.i_height; sys->input->format->es->video.par.num = filter->fmt_in.video.i_sar_num; sys->input->format->es->video.par.den = filter->fmt_in.video.i_sar_den; es_format_Copy(&filter->fmt_out, &filter->fmt_in); filter->fmt_out.video.i_frame_rate *= 2; status = mmal_port_format_commit(sys->input); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to commit format for input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input->buffer_size = sys->input->buffer_size_recommended; sys->input->buffer_num = sys->input->buffer_num_recommended; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) { MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->input, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->input, input_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output = sys->component->output[0]; sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)filter; mmal_format_full_copy(sys->output->format, sys->input->format); status = mmal_port_format_commit(sys->output); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to commit format for output port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output->buffer_num = 3; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) { MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->output, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->output, output_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable output port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_component_enable(sys->component); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable component %s (status=%"PRIx32" %s)", sys->component->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->filtered_pictures = mmal_queue_create(); filter->pf_video_filter = deinterlace; filter->pf_video_flush = flush; vlc_mutex_init_recursive(&sys->mutex); vlc_mutex_init(&sys->buffer_cond_mutex); vlc_cond_init(&sys->buffer_cond); out: if (ret != VLC_SUCCESS) Close(filter); return ret; }
bool CCameraOutput::Init(int width, int height, MMAL_COMPONENT_T* input_component, int input_port_idx, bool do_argb_conversion) { printf("Init camera output with %d/%d\n",width,height); Width = width; Height = height; MMAL_COMPONENT_T *resizer = 0; MMAL_CONNECTION_T* connection = 0; MMAL_STATUS_T status; MMAL_POOL_T* video_buffer_pool = 0; MMAL_QUEUE_T* output_queue = 0; //got the port we're receiving from MMAL_PORT_T* input_port = input_component->output[input_port_idx]; //check if user wants conversion to argb or the width or height is different to the input if(do_argb_conversion || width != input_port->format->es->video.width || height != input_port->format->es->video.height) { //create the resizing component, reading from the splitter output resizer = CreateResizeComponentAndSetupPorts(input_port,do_argb_conversion); if(!resizer) goto error; //create and enable a connection between the video output and the resizer input status = mmal_connection_create(&connection, input_port, resizer->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT); if (status != MMAL_SUCCESS) { printf("Failed to create connection\n"); goto error; } status = mmal_connection_enable(connection); if (status != MMAL_SUCCESS) { printf("Failed to enable connection\n"); goto error; } //set the buffer pool port to be the resizer output BufferPort = resizer->output[0]; } else { //no convert/resize needed so just set the buffer pool port to be the input port BufferPort = input_port; } //setup the video buffer callback video_buffer_pool = EnablePortCallbackAndCreateBufferPool(BufferPort,VideoBufferCallback,3); if(!video_buffer_pool) goto error; //create the output queue output_queue = mmal_queue_create(); if(!output_queue) { printf("Failed to create output queue\n"); goto error; } ResizerComponent = resizer; BufferPool = video_buffer_pool; OutputQueue = output_queue; Connection = connection; return true; error: if(output_queue) mmal_queue_destroy(output_queue); if(video_buffer_pool) mmal_port_pool_destroy(resizer->output[0],video_buffer_pool); if(connection) mmal_connection_destroy(connection); if(resizer) mmal_component_destroy(resizer); return false; }
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 OpenDecoder(decoder_t *dec) { int ret = VLC_SUCCESS; decoder_sys_t *sys; MMAL_PARAMETER_UINT32_T extra_buffers; MMAL_STATUS_T status; if (dec->fmt_in.i_cat != VIDEO_ES) return VLC_EGENERIC; if (dec->fmt_in.i_codec != VLC_CODEC_MPGV && dec->fmt_in.i_codec != VLC_CODEC_H264) return VLC_EGENERIC; sys = calloc(1, sizeof(decoder_sys_t)); if (!sys) { ret = VLC_ENOMEM; goto out; } dec->p_sys = sys; dec->b_need_packetized = true; sys->opaque = var_InheritBool(dec, MMAL_OPAQUE_NAME); bcm_host_init(); status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &sys->component); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to create MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)dec; status = mmal_port_enable(sys->component->control, control_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable control port %s (status=%"PRIx32" %s)", sys->component->control->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input = sys->component->input[0]; sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)dec; if (dec->fmt_in.i_codec == VLC_CODEC_MPGV) sys->input->format->encoding = MMAL_ENCODING_MP2V; else sys->input->format->encoding = MMAL_ENCODING_H264; 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)); ret = VLC_EGENERIC; goto out; } sys->input->buffer_size = sys->input->buffer_size_recommended; sys->input->buffer_num = sys->input->buffer_num_recommended; status = mmal_port_enable(sys->input, input_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output = sys->component->output[0]; sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)dec; if (sys->opaque) { extra_buffers.hdr.id = MMAL_PARAMETER_EXTRA_BUFFERS; extra_buffers.hdr.size = sizeof(MMAL_PARAMETER_UINT32_T); extra_buffers.value = NUM_EXTRA_BUFFERS; status = mmal_port_parameter_set(sys->output, &extra_buffers.hdr); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to set MMAL_PARAMETER_EXTRA_BUFFERS on output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } msg_Dbg(dec, "Activate zero-copy for output port"); MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->output, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->output, output_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable output port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_component_enable(sys->component); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable component %s (status=%"PRIx32" %s)", sys->component->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input_pool = mmal_pool_create(sys->input->buffer_num, 0); sys->decoded_pictures = mmal_queue_create(); if (sys->opaque) { dec->fmt_out.i_codec = VLC_CODEC_MMAL_OPAQUE; dec->fmt_out.video.i_chroma = VLC_CODEC_MMAL_OPAQUE; } else { dec->fmt_out.i_codec = VLC_CODEC_I420; dec->fmt_out.video.i_chroma = VLC_CODEC_I420; } dec->fmt_out.i_cat = VIDEO_ES; dec->pf_decode_video = decode; vlc_mutex_init_recursive(&sys->mutex); vlc_sem_init(&sys->sem, 0); out: if (ret != VLC_SUCCESS) CloseDecoder(dec); return ret; }
static av_cold int ffmmal_init_decoder(AVCodecContext *avctx) { MMALDecodeContext *ctx = avctx->priv_data; MMAL_STATUS_T status; MMAL_ES_FORMAT_T *format_in; MMAL_COMPONENT_T *decoder; int ret = 0; bcm_host_init(); if (mmal_vc_init()) { av_log(avctx, AV_LOG_ERROR, "Cannot initialize MMAL VC driver!\n"); return AVERROR(ENOSYS); } if ((ret = ff_get_format(avctx, avctx->codec->pix_fmts)) < 0) return ret; avctx->pix_fmt = ret; if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->decoder))) goto fail; decoder = ctx->decoder; format_in = decoder->input[0]->format; format_in->type = MMAL_ES_TYPE_VIDEO; format_in->encoding = MMAL_ENCODING_H264; format_in->es->video.width = FFALIGN(avctx->width, 32); format_in->es->video.height = FFALIGN(avctx->height, 16); format_in->es->video.crop.width = avctx->width; format_in->es->video.crop.height = avctx->height; format_in->es->video.frame_rate.num = 24000; format_in->es->video.frame_rate.den = 1001; format_in->es->video.par.num = avctx->sample_aspect_ratio.num; format_in->es->video.par.den = avctx->sample_aspect_ratio.den; format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED; if (avctx->codec->id == AV_CODEC_ID_H264 && avctx->extradata && avctx->extradata[0] == 1) { uint8_t *dummy_p; int dummy_int; ctx->bsfc = av_bitstream_filter_init("h264_mp4toannexb"); if (!ctx->bsfc) { av_log(avctx, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n"); ret = AVERROR(ENOSYS); goto fail; } av_bitstream_filter_filter(ctx->bsfc, avctx, NULL, &dummy_p, &dummy_int, NULL, 0, 0); } if (avctx->extradata_size) { if ((status = mmal_format_extradata_alloc(format_in, avctx->extradata_size))) goto fail; format_in->extradata_size = avctx->extradata_size; memcpy(format_in->extradata, avctx->extradata, format_in->extradata_size); } if ((status = mmal_port_format_commit(decoder->input[0]))) goto fail; decoder->input[0]->buffer_num = FFMAX(decoder->input[0]->buffer_num_min, 20); decoder->input[0]->buffer_size = FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024); ctx->pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0); if (!ctx->pool_in) { ret = AVERROR(ENOMEM); goto fail; } if ((ret = ffmal_update_format(avctx)) < 0) goto fail; ctx->queue_decoded_frames = mmal_queue_create(); if (!ctx->queue_decoded_frames) goto fail; decoder->input[0]->userdata = (void*)avctx; decoder->output[0]->userdata = (void*)avctx; decoder->control->userdata = (void*)avctx; if ((status = mmal_port_enable(decoder->control, control_port_cb))) goto fail; if ((status = mmal_port_enable(decoder->input[0], input_callback))) goto fail; if ((status = mmal_port_enable(decoder->output[0], output_callback))) goto fail; if ((status = mmal_component_enable(decoder))) goto fail; return 0; fail: ffmmal_close_decoder(avctx); return ret < 0 ? ret : AVERROR_UNKNOWN; }
/* Create Simple Video Player instance. */ SVP_T *svp_create(const char *uri, SVP_CALLBACKS_T *callbacks, const SVP_OPTS_T *opts) { SVP_T *svp; MMAL_STATUS_T st; VCOS_STATUS_T vst; MMAL_PORT_T *reader_output = NULL; MMAL_COMPONENT_T *video_decode = NULL; MMAL_PORT_T *video_output = NULL; LOG_TRACE("Creating player for %s", (uri ? uri : "camera preview")); vcos_assert(callbacks->video_frame_cb); vcos_assert(callbacks->stop_cb); svp = vcos_calloc(1, sizeof(*svp), "svp"); CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to allocate context"); svp->opts = *opts; svp->callbacks = *callbacks; /* Semaphore used for synchronising buffer handling for decoded frames */ vst = vcos_semaphore_create(&svp->sema, "svp-sem", 0); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create semaphore"); svp->created |= SVP_CREATED_SEM; vst = vcos_mutex_create(&svp->mutex, "svp-mutex"); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create mutex"); svp->created |= SVP_CREATED_MUTEX; vst = vcos_timer_create(&svp->timer, "svp-timer", svp_timer_cb, svp); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer"); svp->created |= SVP_CREATED_TIMER; vst = vcos_timer_create(&svp->wd_timer, "svp-wd-timer", svp_watchdog_cb, svp); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer"); svp->created |= SVP_CREATED_WD_TIMER; /* Create components */ svp->reader = NULL; svp->video_decode = NULL; svp->camera = NULL; svp->connection = NULL; if (uri) { /* Video from URI: setup container_reader -> video_decode */ /* Create and set up container reader */ st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CONTAINER_READER, &svp->reader); CHECK_STATUS(st, "Failed to create container reader"); st = svp_setup_reader(svp->reader, uri, &reader_output); if (st != MMAL_SUCCESS) goto error; st = mmal_component_enable(svp->reader); CHECK_STATUS(st, "Failed to enable container reader"); st = svp_port_enable(svp, svp->reader->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable container reader control port"); /* Create and set up video decoder */ st = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &svp->video_decode); CHECK_STATUS(st, "Failed to create video decoder"); video_decode = svp->video_decode; video_output = video_decode->output[0]; st = mmal_component_enable(video_decode); CHECK_STATUS(st, "Failed to enable video decoder"); st = svp_port_enable(svp, video_decode->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable video decoder control port"); } else { /* Camera preview */ MMAL_PARAMETER_CAMERA_CONFIG_T config; st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &svp->camera); CHECK_STATUS(st, "Failed to create camera"); st = mmal_component_enable(svp->camera); CHECK_STATUS(st, "Failed to enable camera"); st = svp_port_enable(svp, svp->camera->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable camera control port"); video_output = svp->camera->output[0]; /* Preview port */ } st = mmal_port_parameter_set_boolean(video_output, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); CHECK_STATUS((st == MMAL_ENOSYS ? MMAL_SUCCESS : st), "Failed to enable zero copy"); if (uri) { /* Create connection: container_reader -> video_decoder */ st = mmal_connection_create(&svp->connection, reader_output, video_decode->input[0], MMAL_CONNECTION_FLAG_TUNNELLING); CHECK_STATUS(st, "Failed to create connection"); } /* Set video output port format. * Opaque encoding ensures we get buffer data as handles to relocatable heap. */ video_output->format->encoding = MMAL_ENCODING_OPAQUE; if (!uri) { /* Set video format for camera preview */ MMAL_VIDEO_FORMAT_T *vfmt = &video_output->format->es->video; CHECK_STATUS((video_output->format->type == MMAL_ES_TYPE_VIDEO) ? MMAL_SUCCESS : MMAL_EINVAL, "Output port isn't video format"); vfmt->width = SVP_CAMERA_WIDTH; vfmt->height = SVP_CAMERA_HEIGHT; vfmt->crop.x = 0; vfmt->crop.y = 0; vfmt->crop.width = vfmt->width; vfmt->crop.height = vfmt->height; vfmt->frame_rate.num = SVP_CAMERA_FRAMERATE; vfmt->frame_rate.den = 1; } st = mmal_port_format_commit(video_output); CHECK_STATUS(st, "Failed to set output port format"); /* Finally, set buffer num/size. N.B. For container_reader/video_decode, must be after * connection created, in order for port format to propagate. * Don't enable video output port until want to produce frames. */ video_output->buffer_num = video_output->buffer_num_recommended; video_output->buffer_size = video_output->buffer_size_recommended; /* Pool + queue to hold decoded video frames */ svp->out_pool = mmal_port_pool_create(video_output, video_output->buffer_num, video_output->buffer_size); CHECK_STATUS((svp->out_pool ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating pool"); svp->queue = mmal_queue_create(); CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating queue"); svp->video_output = video_output; return svp; error: svp_destroy(svp); return NULL; }
bool CMMALRenderer::init_vout(ERenderFormat format, bool opaque) { CSingleLock lock(m_sharedSection); bool formatChanged = m_format != format || m_opaque != opaque; MMAL_STATUS_T status; CLog::Log(LOGDEBUG, "%s::%s configured:%d format %d->%d opaque %d->%d", CLASSNAME, __func__, m_bConfigured, m_format, format, m_opaque, opaque); if (m_bMMALConfigured && formatChanged) UnInitMMAL(); if (m_bMMALConfigured || format != RENDER_FMT_MMAL) return true; m_format = format; m_opaque = opaque; /* Create video renderer */ status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &m_vout); if(status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to create vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_vout_input = m_vout->input[0]; m_vout_input->userdata = (struct MMAL_PORT_USERDATA_T *)this; MMAL_ES_FORMAT_T *es_format = m_vout_input->format; es_format->type = MMAL_ES_TYPE_VIDEO; if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709) es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709; else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601) es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601; else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M) es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M; es_format->es->video.crop.width = m_sourceWidth; es_format->es->video.crop.height = m_sourceHeight; es_format->es->video.width = m_sourceWidth; es_format->es->video.height = m_sourceHeight; es_format->encoding = m_opaque ? MMAL_ENCODING_OPAQUE : MMAL_ENCODING_I420; status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); if (status != MMAL_SUCCESS) CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_vout_input->name, status, mmal_status_to_string(status)); 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)); return false; } m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers+(m_opaque?0:32)); m_vout_input->buffer_size = m_vout_input->buffer_size_recommended; status = mmal_port_enable(m_vout_input, vout_input_port_cb_static); if(status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to vout enable input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } status = mmal_component_enable(m_vout); if(status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } CLog::Log(LOGDEBUG, "%s::%s Created pool of size %d x %d", CLASSNAME, __func__, m_vout_input->buffer_num, m_vout_input->buffer_size); m_vout_input_pool = mmal_port_pool_create(m_vout_input , m_vout_input->buffer_num, m_opaque ? m_vout_input->buffer_size:0); if (!m_vout_input_pool) { CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } if (!CSettings::GetInstance().GetBool("videoplayer.usedisplayasclock")) { m_queue = mmal_queue_create(); Create(); } return true; }
/* Registers a callback on the camera preview port to receive * notifications of new frames. * This must be called before rapitex_start and may not be called again * without calling raspitex_destroy first. * * @param state Pointer to the GL preview state. * @param port Pointer to the camera preview port * @return Zero if successful. */ int raspitex_configure_preview_port(RASPITEX_STATE *state, MMAL_PORT_T *preview_port) { MMAL_STATUS_T status; vcos_log_trace("%s port %p", VCOS_FUNCTION, preview_port); /* Enable ZERO_COPY mode on the preview port which instructs MMAL to only * pass the 4-byte opaque buffer handle instead of the contents of the opaque * buffer. * The opaque handle is resolved on VideoCore by the GL driver when the EGL * image is created. */ status = mmal_port_parameter_set_boolean(preview_port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to enable zero copy on camera preview port"); goto end; } status = mmal_port_format_commit(preview_port); if (status != MMAL_SUCCESS) { vcos_log_error("camera viewfinder format couldn't be set"); goto end; } /* For GL a pool of opaque buffer handles must be allocated in the client. * These buffers are used to create the EGL images. */ state->preview_port = preview_port; preview_port->buffer_num = preview_port->buffer_num_recommended; preview_port->buffer_size = preview_port->buffer_size_recommended; vcos_log_trace("Creating buffer pool for GL renderer num %d size %d", preview_port->buffer_num, preview_port->buffer_size); /* Pool + queue to hold preview frames */ state->preview_pool = mmal_port_pool_create(preview_port, preview_port->buffer_num, preview_port->buffer_size); if (! state->preview_pool) { vcos_log_error("Error allocating pool"); status = MMAL_ENOMEM; goto end; } /* Place filled buffers from the preview port in a queue to render */ state->preview_queue = mmal_queue_create(); if (! state->preview_queue) { vcos_log_error("Error allocating queue"); status = MMAL_ENOMEM; goto end; } /* Enable preview port callback */ preview_port->userdata = (struct MMAL_PORT_USERDATA_T*) state; status = mmal_port_enable(preview_port, preview_output_cb); if (status != MMAL_SUCCESS) { vcos_log_error("Failed to camera preview port"); goto end; } end: return (status == MMAL_SUCCESS ? 0 : -1); }
void create_camera_component(int Width, int Height, int FrameRate){ MMAL_COMPONENT_T *camera = 0; MMAL_ES_FORMAT_T *format; MMAL_STATUS_T status; /* Create the component */ status = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &camera); if (status != MMAL_SUCCESS) { printf("Failed to create camera component : error %d\n", status); exit(1); } if (!camera->output_num) { status = MMAL_ENOSYS; printf("Camera doesn't have output ports\n"); exit(1); } preview_port = camera->output[MMAL_CAMERA_PREVIEW_PORT]; video_port = camera->output[MMAL_CAMERA_VIDEO_PORT]; still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT]; // Enable the camera, and tell it its control callback function status = mmal_port_enable(camera->control, camera_control_callback); if (status != MMAL_SUCCESS) { printf("Unable to enable control port : error %d\n", status); mmal_component_destroy(camera); exit(1); } //set camera parameters. MMAL_PARAMETER_CAMERA_CONFIG_T cam_config; cam_config.hdr = MMAL_PARAMETER_CAMERA_CONFIG; cam_config.hdr.size = sizeof(cam_config); cam_config.max_stills_w = Width; cam_config.max_stills_h = Height; cam_config.stills_yuv422 = 0; cam_config.one_shot_stills = 0; cam_config.max_preview_video_w = Width; cam_config.max_preview_video_h = Height; cam_config.num_preview_video_frames = 3; cam_config.stills_capture_circular_buffer_height = 0; cam_config.fast_preview_resume = 0; cam_config.use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC; status = mmal_port_parameter_set(camera->control, &cam_config.hdr); if (status != MMAL_SUCCESS) { printf("Unable to set camera parameters : error %d\n", status); mmal_component_destroy(camera); exit(1); } // setup preview port format - QUESTION: Needed if we aren't using preview? format = preview_port->format; format->encoding = MMAL_ENCODING_OPAQUE; format->encoding_variant = MMAL_ENCODING_I420; format->es->video.width = Width; format->es->video.height = Height; format->es->video.crop.x = 0; format->es->video.crop.y = 0; format->es->video.crop.width = Width; format->es->video.crop.height = Height; format->es->video.frame_rate.num = FrameRate; format->es->video.frame_rate.den = 1; status = mmal_port_format_commit(preview_port); if (status != MMAL_SUCCESS) { printf("Couldn't set preview port format : error %d\n", status); mmal_component_destroy(camera); exit(1); } //setup video port format format = video_port->format; format->encoding = MMAL_ENCODING_I420; format->encoding_variant = MMAL_ENCODING_I420; format->es->video.width = Width; format->es->video.height = Height; format->es->video.crop.x = 0; format->es->video.crop.y = 0; format->es->video.crop.width = Width; format->es->video.crop.height = Height; format->es->video.frame_rate.num = FrameRate; format->es->video.frame_rate.den = 1; status = mmal_port_format_commit(video_port); if (status != MMAL_SUCCESS) { printf("Couldn't set video port format : error %d\n", status); mmal_component_destroy(camera); exit(1); } //setup still port format format = still_port->format; format->encoding = MMAL_ENCODING_OPAQUE; format->encoding_variant = MMAL_ENCODING_I420; format->es->video.width = Width; format->es->video.height = Height; format->es->video.crop.x = 0; format->es->video.crop.y = 0; format->es->video.crop.width = Width; format->es->video.crop.height = Height; format->es->video.frame_rate.num = 1; format->es->video.frame_rate.den = 1; status = mmal_port_format_commit(still_port); if (status != MMAL_SUCCESS) { printf("Couldn't set still port format : error %d\n", status); mmal_component_destroy(camera); exit(1); } status = mmal_port_parameter_set_boolean(preview_port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); if (status != MMAL_SUCCESS) { printf("Failed to enable zero copy on camera video port\n"); exit(1); } status = mmal_port_format_commit(preview_port); if (status != MMAL_SUCCESS) { printf("camera format couldn't be set\n"); exit(1); } /* For GL a pool of opaque buffer handles must be allocated in the client. * These buffers are used to create the EGL images. */ preview_port->buffer_num = 3; preview_port->buffer_size = preview_port->buffer_size_recommended; /* Pool + queue to hold preview frames */ video_pool = mmal_port_pool_create(preview_port,preview_port->buffer_num,preview_port->buffer_size); if (!video_pool) { printf("Error allocating camera video pool. Buffer num: %d Buffer size: %d\n", preview_port->buffer_num, preview_port->buffer_size); status = MMAL_ENOMEM; exit(1); } printf("Allocated %d MMAL buffers of size %d.\n", preview_port->buffer_num, preview_port->buffer_size); /* Place filled buffers from the preview port in a queue to render */ video_queue = mmal_queue_create(); if (!video_queue) { printf("Error allocating video buffer queue\n"); status = MMAL_ENOMEM; exit(1); } /* Enable video port callback */ //port->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(preview_port, video_output_callback); if (status != MMAL_SUCCESS) { printf("Failed to enable video port\n"); exit(1); } // Set up the camera_parameters to default raspicamcontrol_set_defaults(&cameraParameters); //apply all camera parameters raspicamcontrol_set_all_parameters(camera, &cameraParameters); //enable the camera status = mmal_component_enable(camera); if (status != MMAL_SUCCESS) { printf("Couldn't enable camera\n\n"); mmal_component_destroy(camera); exit(1); } //send all the buffers in our pool to the video port ready for use { int num = mmal_queue_length(video_pool->queue); int q; for (q=0;q<num;q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(video_pool->queue); if (!buffer) { printf("Unable to get a required buffer %d from pool queue\n\n", q); exit(1); } else if (mmal_port_send_buffer(preview_port, buffer)!= MMAL_SUCCESS) { printf("Unable to send a buffer to port (%d)\n\n", q); exit(1); } } } /* //begin capture if (mmal_port_parameter_set_boolean(preview_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) { printf("Failed to start capture\n\n"); exit(1); } */ printf("Camera initialized.\n"); //Setup the camera's textures and EGL images. glGenTextures(1, &cam_ytex); glGenTextures(1, &cam_utex); glGenTextures(1, &cam_vtex); return; }