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); } }
CMMALVideo::CMMALVideo() { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, this); pthread_mutex_init(&m_output_mutex, NULL); m_drop_state = false; m_decoded_width = 0; m_decoded_height = 0; m_finished = false; m_pFormatName = "mmal-xxxx"; m_interlace_mode = MMAL_InterlaceProgressive; m_interlace_method = VS_INTERLACEMETHOD_NONE; m_startframe = false; m_decoderPts = DVD_NOPTS_VALUE; m_droppedPics = 0; m_decode_frame_number = 1; m_dec = NULL; m_dec_input = NULL; m_dec_output = NULL; m_dec_input_pool = NULL; m_dec_output_pool = NULL; m_deint = NULL; m_deint_connection = NULL; m_codingType = 0; m_changed_count = 0; m_changed_count_dec = 0; m_output_busy = 0; m_demux_queue_length = 0; m_es_format = mmal_format_alloc(); m_preroll = true; m_speed = DVD_PLAYSPEED_NORMAL; }
bool CMMALRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation) { ReleaseBuffers(); m_sourceWidth = width; m_sourceHeight = height; m_renderOrientation = orientation; m_fps = fps; m_iFlags = flags; m_format = format; CLog::Log(LOGDEBUG, "%s::%s - %dx%d->%dx%d@%.2f flags:%x format:%d ext:%x orient:%d", CLASSNAME, __func__, width, height, d_width, d_height, fps, flags, format, extended_format, orientation); m_RenderUpdateCallBackFn = NULL; m_RenderUpdateCallBackCtx = NULL; // calculate the input frame aspect ratio CalculateFrameAspectRatio(d_width, d_height); ChooseBestResolution(fps); m_destWidth = g_graphicsContext.GetResInfo(m_resolution).iWidth; m_destHeight = g_graphicsContext.GetResInfo(m_resolution).iHeight; SetViewMode(CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode); ManageDisplay(); if (m_format == RENDER_FMT_MMAL|| m_format == RENDER_FMT_YUV420P) { MMAL_ES_FORMAT_T *es_format = mmal_format_alloc(); es_format->type = MMAL_ES_TYPE_VIDEO; es_format->es->video.crop.width = m_sourceWidth; es_format->es->video.crop.height = m_sourceHeight; if (m_format == RENDER_FMT_MMAL) { es_format->encoding = MMAL_ENCODING_OPAQUE; es_format->es->video.width = m_sourceWidth; es_format->es->video.height = m_sourceHeight; } else if (m_format == RENDER_FMT_YUV420P) { const int pitch = ALIGN_UP(m_sourceWidth, 32); const int aligned_height = ALIGN_UP(m_sourceHeight, 16); es_format->encoding = MMAL_ENCODING_I420; es_format->es->video.width = pitch; es_format->es->video.height = aligned_height; 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; } if (m_bConfigured) UnInitMMAL(); m_bConfigured = init_vout(es_format); mmal_format_free(es_format); } else m_bConfigured = true; return m_bConfigured; }
/** Allocate a port structure */ MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size) { MMAL_PORT_T *port; MMAL_PORT_PRIVATE_CORE_T *core; unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT); unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) + sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size; MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0; MMAL_BOOL_T lock_stats = 0, lock_connection = 0; LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size); port = vcos_calloc(1, size, "mmal port"); if (!port) { LOG_ERROR("failed to allocate port, size %u", size); return 0; } port->type = type; port->priv = (MMAL_PORT_PRIVATE_T *)(port+1); port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1); if (extra_size) port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1); port->component = component; port->name = core->name = ((char *)(port->priv->core+1)) + extra_size; core->name_size = name_size; mmal_port_name_update(port); core->queue_last = &core->queue_first; port->priv->pf_connect = mmal_port_connect_default; lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS; lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS; lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS; sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS; lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS; lock_connection = vcos_mutex_create(&port->priv->core->connection_lock, "mmal connection lock") == VCOS_SUCCESS; if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats || !lock_connection) { LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u,%u)", port->name, lock, lock_send, lock_transit, sema_transit, lock_stats, lock_connection); goto error; } port->format = mmal_format_alloc(); if (!port->format) { LOG_ERROR("%s: failed to allocate format object", port->name); goto error; } port->priv->core->format_ptr_copy = port->format; LOG_TRACE("%s: created at %p", port->name, port); return port; error: if (lock) vcos_mutex_delete(&port->priv->core->lock); if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock); if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock); if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema); if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock); if (lock_connection) vcos_mutex_delete(&port->priv->core->connection_lock); if (port->format) mmal_format_free(port->format); vcos_free(port); return 0; }