static rpi_pixmap_decoder_t * pixmap_decoder_create(int cfmt) { rpi_pixmap_decoder_t *rpd = calloc(1, sizeof(rpi_pixmap_decoder_t)); hts_mutex_init(&rpd->rpd_mtx); hts_cond_init(&rpd->rpd_cond, &rpd->rpd_mtx); rpd->rpd_decoder = omx_component_create("OMX.broadcom.image_decode", &rpd->rpd_mtx, &rpd->rpd_cond); rpd->rpd_decoder->oc_port_settings_changed_cb = decoder_port_settings_changed; rpd->rpd_decoder->oc_opaque = rpd; rpd->rpd_resizer = omx_component_create("OMX.broadcom.resize", &rpd->rpd_mtx, &rpd->rpd_cond); omx_set_state(rpd->rpd_decoder, OMX_StateIdle); OMX_IMAGE_PARAM_PORTFORMATTYPE fmt; OMX_INIT_STRUCTURE(fmt); fmt.nPortIndex = rpd->rpd_decoder->oc_inport; fmt.eCompressionFormat = cfmt; omxchk(OMX_SetParameter(rpd->rpd_decoder->oc_handle, OMX_IndexParamImagePortFormat, &fmt)); #ifndef NOCOPY omx_alloc_buffers(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport); omx_set_state(rpd->rpd_decoder, OMX_StateExecuting); #endif return rpd; }
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 void omx_mp_init(media_pipe_t *mp) { if(!(mp->mp_flags & MP_VIDEO)) return; mp->mp_seek_initiate = omx_mp_begin_seek; mp->mp_seek_audio_done = omx_mp_seek_audio_done; mp->mp_seek_video_done = omx_mp_seek_video_done; mp->mp_hold_changed = omx_mp_hold_changed; mp->mp_clock_setup = omx_mp_clock_setup; omx_clk_t *clk = calloc(1, sizeof(omx_clk_t)); TAILQ_INIT(&clk->q); clk->mp = mp; clk->c = omx_component_create("OMX.broadcom.clock", &mp->mp_mutex, NULL); hts_cond_init(&clk->cond, &mp->mp_mutex); mp->mp_extra = clk; omx_set_state(clk->c, OMX_StateIdle); omx_clk_do(clk, OMX_CLK_INIT, 1); hts_thread_create_joinable("omxclkctrl", &clk->tid, omx_clk_thread, clk, THREAD_PRIO_DEMUXER); }
static void omx_mp_init(media_pipe_t *mp) { if(!(mp->mp_flags & MP_VIDEO)) return; omx_component_t *c; c = omx_component_create("OMX.broadcom.clock", &mp->mp_mutex, NULL); mp->mp_extra = c; omx_set_state(c, OMX_StateIdle); OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCTURE(cstate); cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; omxchk(OMX_SetParameter(c->oc_handle, OMX_IndexConfigTimeClockState, &cstate)); OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); refClock.eClock = OMX_TIME_RefClockAudio; // refClock.eClock = OMX_TIME_RefClockVideo; // refClock.eClock = OMX_TIME_RefClockNone; omxchk(OMX_SetConfig(c->oc_handle, OMX_IndexConfigTimeActiveRefClock, &refClock)); omx_set_state(c, OMX_StateExecuting); }
static void omx_mp_init(media_pipe_t *mp) { if(!(mp->mp_flags & MP_VIDEO)) return; #if 0 if(0) { mp->mp_seek_initiate = omx_mp_begin_seek; mp->mp_seek_audio_done = omx_mp_seek_audio_done; mp->mp_seek_video_done = omx_mp_seek_video_done; } #endif mp->mp_hold_changed = omx_mp_hold_changed; omx_clk_t *clk = calloc(1, sizeof(omx_clk_t)); TAILQ_INIT(&clk->q); clk->mp = mp; clk->c = omx_component_create("OMX.broadcom.clock", &mp->mp_mutex, NULL); hts_cond_init(&clk->cond, &mp->mp_mutex); mp->mp_extra = clk; omx_set_state(clk->c, OMX_StateIdle); #if 0 OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCTURE(cstate); cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; omxchk(OMX_SetParameter(c->oc_handle, OMX_IndexConfigTimeClockState, &cstate)); OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); refClock.eClock = OMX_TIME_RefClockAudio; // refClock.eClock = OMX_TIME_RefClockVideo; // refClock.eClock = OMX_TIME_RefClockNone; #else OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCTURE(cstate); cstate.eState = OMX_TIME_ClockStateRunning; omxchk(OMX_SetParameter(clk->c->oc_handle, OMX_IndexConfigTimeClockState, &cstate)); OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); refClock.eClock = OMX_TIME_RefClockAudio; #endif omxchk(OMX_SetConfig(clk->c->oc_handle, OMX_IndexConfigTimeActiveRefClock, &refClock)); omx_set_state(clk->c, OMX_StateExecuting); hts_thread_create_joinable("omxclkctrl", &clk->tid, omx_clk_thread, clk, THREAD_PRIO_DEMUXER); }
static int rpi_codec_create(media_codec_t *mc, const media_codec_params_t *mcp, media_pipe_t *mp) { int fmt; switch(mc->codec_id) { case CODEC_ID_H264: fmt = OMX_VIDEO_CodingAVC; break; case CODEC_ID_MPEG2VIDEO: if(!omx_enable_mpg2) return 1; fmt = OMX_VIDEO_CodingMPEG2; break; #if 0 case CODEC_ID_VC1: case CODEC_ID_WMV3: if(mcp->extradata_size == 0) return 1; mc->decode = vc1_pt_decode; return 0; #endif default: return 1; } rpi_video_codec_t *rvc = calloc(1, sizeof(rpi_video_codec_t)); hts_cond_init(&rvc->rvc_avail_cond, &mp->mp_mutex); omx_component_t *d = omx_component_create("OMX.broadcom.video_decode", &mp->mp_mutex, &rvc->rvc_avail_cond); if(d == NULL) { hts_cond_destroy(&rvc->rvc_avail_cond); free(rvc); return 1; } rvc->rvc_decoder = d; omx_set_state(d, OMX_StateIdle); OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_INIT_STRUCTURE(format); format.nPortIndex = 130; format.eCompressionFormat = fmt; omxchk(OMX_SetParameter(d->oc_handle, OMX_IndexParamVideoPortFormat, &format)); OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE ec; OMX_INIT_STRUCTURE(ec); ec.bStartWithValidFrame = OMX_FALSE; omxchk(OMX_SetParameter(d->oc_handle, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &ec)); OMX_CONFIG_BOOLEANTYPE bt; OMX_INIT_STRUCTURE(bt); bt.bEnabled = 1; omxchk(OMX_SetConfig(d->oc_handle, OMX_IndexParamBrcmInterpolateMissingTimestamps, &bt)); omx_alloc_buffers(d, 130); omx_set_state(d, OMX_StateExecuting); if(mcp->extradata_size) { hts_mutex_lock(&mp->mp_mutex); OMX_BUFFERHEADERTYPE *buf = omx_get_buffer_locked(rvc->rvc_decoder); hts_mutex_unlock(&mp->mp_mutex); buf->nOffset = 0; buf->nFilledLen = mcp->extradata_size; memcpy(buf->pBuffer, mcp->extradata, buf->nFilledLen); buf->nFlags = OMX_BUFFERFLAG_CODECCONFIG; omxchk(OMX_EmptyThisBuffer(rvc->rvc_decoder->oc_handle, buf)); } mc->opaque = rvc; mc->close = rpi_codec_close; mc->decode = rpi_codec_decode; mc->flush = rpi_codec_flush; return 0; }