static int rvd_set_codec(media_codec_t *mc, glw_video_t *gv, const frame_info_t *fi) { media_pipe_t *mp = gv->gv_mp; glw_video_configure(gv, &glw_video_rvd); gv->gv_width = fi->fi_width; gv->gv_height = fi->fi_height; rpi_video_display_t *rvd = gv->gv_aux; rpi_video_codec_t *rvc = mc->opaque; if(rvd->rvd_vrender == NULL) { rvd->rvd_vrender = omx_component_create("OMX.broadcom.video_render", &rvd->rvd_mutex, NULL); rvd->rvd_vsched = omx_component_create("OMX.broadcom.video_scheduler", &rvd->rvd_mutex, NULL); rvd->rvd_vsched->oc_opaque = rvd; rvd->rvd_vrender->oc_opaque = rvd; gv->gv_vd->vd_render_component = rvd->rvd_vrender; omx_enable_buffer_marks(rvd->rvd_vrender); rvd->rvd_tun_clock_vsched = omx_tunnel_create(omx_get_clock(mp), 81, rvd->rvd_vsched, 12, "clock -> vsched"); rvd->rvd_vsched->oc_port_settings_changed_cb = vsched_port_settings_changed; rvd->rvd_vrender->oc_event_mark_cb = buffer_mark; } omx_set_state(rvd->rvd_vrender, OMX_StateIdle); if(rvd->rvd_tun_vdecoder_vsched != NULL) omx_tunnel_destroy(rvd->rvd_tun_vdecoder_vsched); if(rvd->rvd_mc != NULL) media_codec_deref(rvd->rvd_mc); rvd->rvd_mc = media_codec_ref(mc); rvd->rvd_tun_vdecoder_vsched = omx_tunnel_create(rvc->rvc_decoder, 131, rvd->rvd_vsched, 10, "vdecoder -> vsched"); omx_set_state(rvd->rvd_vsched, OMX_StateExecuting); return 0; }
static int64_t rvd_newframe(glw_video_t *gv, video_decoder_t *vd, int flags) { rpi_video_display_t *rvd = gv->gv_aux; if(rvd->rvd_vsched && rvd->rvd_reconfigure) { rvd->rvd_reconfigure = 0; if(rvd->rvd_tun_vsched_vrender) omx_tunnel_destroy(rvd->rvd_tun_vsched_vrender); rvd->rvd_tun_vsched_vrender = omx_tunnel_create(rvd->rvd_vsched, 11, rvd->rvd_vrender, 90, "vsched -> vrender"); omx_set_state(rvd->rvd_vrender, OMX_StateExecuting); OMX_CONFIG_DISPLAYREGIONTYPE dr; OMX_INIT_STRUCTURE(dr); dr.nPortIndex = 90; dr.set = OMX_DISPLAY_SET_LAYER; dr.layer = 3; omxchk(OMX_SetConfig(rvd->rvd_vrender->oc_handle, OMX_IndexConfigDisplayRegion, &dr)); } return rvd->rvd_pts; }
static void setup_tunnel(rpi_pixmap_decoder_t *rpd) { int dst_width, dst_height; OMX_PARAM_PORTDEFINITIONTYPE portdef; if(rpd->rpd_tunnel != NULL) return; OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = rpd->rpd_decoder->oc_outport; omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle, OMX_IndexParamPortDefinition, &portdef)); pixmap_compute_rescale_dim(rpd->rpd_im, portdef.format.image.nFrameWidth, portdef.format.image.nFrameHeight, &dst_width, &dst_height); portdef.nPortIndex = rpd->rpd_resizer->oc_inport; omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); rpd->rpd_tunnel = omx_tunnel_create(rpd->rpd_decoder, rpd->rpd_decoder->oc_outport, rpd->rpd_resizer, rpd->rpd_resizer->oc_inport, "decoder -> resizer"); OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = rpd->rpd_resizer->oc_outport; omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); int stride = (dst_width * 4 + PIXMAP_ROW_ALIGN - 1) & ~(PIXMAP_ROW_ALIGN - 1); portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; portdef.format.image.eColorFormat = OMX_COLOR_Format32bitABGR8888; portdef.format.image.nFrameWidth = dst_width; portdef.format.image.nFrameHeight = dst_height; portdef.format.image.nStride = stride; portdef.format.image.nSliceHeight = 0; portdef.format.image.bFlagErrorConcealment = OMX_FALSE; omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omx_set_state(rpd->rpd_resizer, OMX_StateExecuting); omx_port_enable(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport); pixmap_t *pm = rpd->rpd_pm = calloc(1, sizeof(pixmap_t)); pm->pm_refcount = 1; pm->pm_width = portdef.format.image.nFrameWidth; pm->pm_height = portdef.format.image.nFrameHeight; pm->pm_linesize = portdef.format.image.nStride; pm->pm_type = PIXMAP_BGR32; pm->pm_data = mymemalign(portdef.nBufferAlignment, portdef.nBufferSize); pm->pm_aspect = (float)pm->pm_width / (float)pm->pm_height; omxchk(OMX_UseBuffer(rpd->rpd_resizer->oc_handle, &rpd->rpd_buf, rpd->rpd_resizer->oc_outport, NULL, portdef.nBufferSize, pm->pm_data)); omx_wait_command(rpd->rpd_resizer); omxchk(OMX_FillThisBuffer(rpd->rpd_resizer->oc_handle, rpd->rpd_buf)); }