static void rvd_reset(glw_video_t *gv) { rpi_video_display_t *rvd = gv->gv_aux; omx_tunnel_destroy(rvd->rvd_tun_clock_vsched); omx_flush_port(rvd->rvd_vsched, 10); omx_flush_port(rvd->rvd_vsched, 11); omx_flush_port(rvd->rvd_vrender, 90); if(rvd->rvd_tun_vsched_vrender != NULL) omx_tunnel_destroy(rvd->rvd_tun_vsched_vrender); if(rvd->rvd_tun_vdecoder_vsched != NULL) omx_tunnel_destroy(rvd->rvd_tun_vdecoder_vsched); omx_set_state(rvd->rvd_vrender, OMX_StateIdle); omx_set_state(rvd->rvd_vsched, OMX_StateIdle); omx_set_state(rvd->rvd_vrender, OMX_StateLoaded); omx_set_state(rvd->rvd_vsched, OMX_StateLoaded); omx_component_destroy(rvd->rvd_vrender); omx_component_destroy(rvd->rvd_vsched); if(rvd->rvd_mc != NULL) media_codec_deref(rvd->rvd_mc); hts_mutex_destroy(&rvd->rvd_mutex); free(rvd); }
static void omx_mp_fini(media_pipe_t *mp) { if(mp->mp_extra == NULL) return; omx_clk_t *clk = mp->mp_extra; hts_mutex_lock(&mp->mp_mutex); omx_clk_do(clk, OMX_CLK_QUIT, 0); hts_mutex_unlock(&mp->mp_mutex); hts_thread_join(&clk->tid); omx_component_destroy(clk->c); free(clk); }
static void rpi_codec_close(struct media_codec *mc) { rpi_video_codec_t *rvc = mc->opaque; omx_flush_port(rvc->rvc_decoder, 130); omx_flush_port(rvc->rvc_decoder, 131); omx_wait_buffers(rvc->rvc_decoder); omx_set_state(rvc->rvc_decoder, OMX_StateIdle); omx_release_buffers(rvc->rvc_decoder, 130); omx_set_state(rvc->rvc_decoder, OMX_StateLoaded); omx_component_destroy(rvc->rvc_decoder); hts_cond_destroy(&rvc->rvc_avail_cond); free(rvc); }
static pixmap_t * rpi_pixmap_decode(pixmap_t *pm, const image_meta_t *im, char *errbuf, size_t errlen) { if(pm->pm_type != PIXMAP_JPEG) return NULL; #ifdef TIMING int64_t ts = showtime_get_ts(), ts2; #endif rpi_pixmap_decoder_t *rpd = pixmap_decoder_create(OMX_IMAGE_CodingJPEG); if(rpd == NULL) return NULL; rpd->rpd_im = im; #ifdef NOCOPY #error check rpd->rpd_decoder->oc_stream_corrupt OMX_PARAM_PORTDEFINITIONTYPE portdef; memset(&portdef, 0, sizeof(portdef)); portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = rpd->rpd_decoder->oc_inport; omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omx_send_command(rpd->rpd_decoder, OMX_CommandPortEnable, rpd->rpd_decoder->oc_inport, NULL, 0); OMX_BUFFERHEADERTYPE *buf; for(int i = 0; i < portdef.nBufferCountActual; i++) { omxchk(OMX_UseBuffer(rpd->rpd_decoder->oc_handle, &buf, rpd->rpd_decoder->oc_inport, NULL, pm->pm_size, pm->pm_data)); } // Waits for the OMX_CommandPortEnable command omx_wait_command(rpd->rpd_decoder); omx_set_state(rpd->rpd_decoder, OMX_StateExecuting); CHECKPOINT("Initialized"); buf->nOffset = 0; buf->nFilledLen = pm->pm_size; buf->nFlags |= OMX_BUFFERFLAG_EOS; rpd->rpd_decoder->oc_inflight_buffers++; omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf)); hts_mutex_lock(&rpd->rpd_mtx); while(rpd->rpd_change == 0) hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); hts_mutex_unlock(&rpd->rpd_mtx); CHECKPOINT("Setup tunnel"); setup_tunnel(rpd); #else const void *data = pm->pm_data; size_t len = pm->pm_size; hts_mutex_lock(&rpd->rpd_mtx); while(len > 0) { OMX_BUFFERHEADERTYPE *buf; if(rpd->rpd_decoder->oc_stream_corrupt) break; if(rpd->rpd_change == 1) { rpd->rpd_change = 2; hts_mutex_unlock(&rpd->rpd_mtx); setup_tunnel(rpd); hts_mutex_lock(&rpd->rpd_mtx); continue; } if(rpd->rpd_decoder->oc_avail == NULL) { hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); continue; } buf = rpd->rpd_decoder->oc_avail; rpd->rpd_decoder->oc_avail = buf->pAppPrivate; rpd->rpd_decoder->oc_inflight_buffers++; hts_mutex_unlock(&rpd->rpd_mtx); buf->nOffset = 0; buf->nFilledLen = MIN(len, buf->nAllocLen); memcpy(buf->pBuffer, data, buf->nFilledLen); buf->nFlags = 0; if(len <= buf->nAllocLen) buf->nFlags |= OMX_BUFFERFLAG_EOS; data += buf->nFilledLen; len -= buf->nFilledLen; omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf)); hts_mutex_lock(&rpd->rpd_mtx); } if(rpd->rpd_decoder->oc_stream_corrupt) { hts_mutex_unlock(&rpd->rpd_mtx); goto err; } if(rpd->rpd_change != 2) { while(rpd->rpd_change == 0 && !rpd->rpd_decoder->oc_stream_corrupt) hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx); hts_mutex_unlock(&rpd->rpd_mtx); if(rpd->rpd_decoder->oc_stream_corrupt) goto err; setup_tunnel(rpd); } else { hts_mutex_unlock(&rpd->rpd_mtx); } #endif omx_wait_fill_buffer(rpd->rpd_resizer, rpd->rpd_buf); CHECKPOINT("Got buffer"); err: omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport); omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_outport); omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_inport); omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport); if(rpd->rpd_tunnel != NULL) { omx_tunnel_destroy(rpd->rpd_tunnel); rpd->rpd_tunnel = NULL; } omx_set_state(rpd->rpd_decoder, OMX_StateIdle); omx_set_state(rpd->rpd_resizer, OMX_StateIdle); if(rpd->rpd_buf != NULL) { omxchk(OMX_FreeBuffer(rpd->rpd_resizer->oc_handle, rpd->rpd_resizer->oc_outport, rpd->rpd_buf)); } omx_release_buffers(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport); omx_set_state(rpd->rpd_resizer, OMX_StateLoaded); omx_set_state(rpd->rpd_decoder, OMX_StateLoaded); omx_component_destroy(rpd->rpd_resizer); omx_component_destroy(rpd->rpd_decoder); hts_cond_destroy(&rpd->rpd_cond); hts_mutex_destroy(&rpd->rpd_mtx); pixmap_t *out = rpd->rpd_pm; if(out) { pixmap_release(pm); } else { snprintf(errbuf, errlen, "Load error"); } free(rpd); CHECKPOINT("All done"); return out; }
static void omx_mp_fini(media_pipe_t *mp) { if(mp->mp_extra != NULL) omx_component_destroy(mp->mp_extra); }