/** * prop_mutex can be held here, so we need to avoid locking it */ void mp_release(media_pipe_t *mp) { if(atomic_dec(&mp->mp_refcount)) return; event_t *e; /* Make sure a clean shutdown has been made */ assert(mp->mp_audio_decoder == NULL); assert(mp != media_primary); if(media_pipe_fini_extra != NULL) media_pipe_fini_extra(mp); while((e = TAILQ_FIRST(&mp->mp_eq)) != NULL) { TAILQ_REMOVE(&mp->mp_eq, e, e_link); event_release(e); } mq_flush(mp, &mp->mp_audio, 1); mq_flush(mp, &mp->mp_video, 1); mq_destroy(&mp->mp_audio); mq_destroy(&mp->mp_video); video_overlay_flush_locked(mp, 0); dvdspu_destroy_all(mp); hts_cond_destroy(&mp->mp_backpressure); hts_mutex_destroy(&mp->mp_mutex); hts_mutex_destroy(&mp->mp_clock_mutex); hts_mutex_destroy(&mp->mp_overlay_mutex); pool_destroy(mp->mp_mb_pool); if(mp->mp_satisfied == 0) atomic_dec(&media_buffer_hungry); cancellable_release(mp->mp_cancellable); /** * We need to destroy mp_prop_root but there is a risk that prop_mutex * is held here, so we need to dispatch */ task_run(mp_final_release, mp); }
void video_decoder_destroy(video_decoder_t *vd) { dvdspu_t *d; while((d = TAILQ_FIRST(&vd->vd_spu_queue)) != NULL) dvdspu_destroy(vd, d); hts_mutex_destroy(&vd->vd_spu_mutex); video_overlay_flush(vd, 0); hts_mutex_destroy(&vd->vd_overlay_mutex); free(vd); }
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); }
int lockmgr_release(lockmgr_t *lm) { if(atomic_dec(&lm->lm_refcount)) return 1; hts_mutex_destroy(&lm->lm_mutex); return 0; }
void video_subtitles_deinit(video_decoder_t *vd) { subtitle_t *s; while((s = TAILQ_FIRST(&vd->vd_sub_queue)) != NULL) video_subtitle_destroy(vd, s); hts_mutex_destroy(&vd->vd_sub_mutex); }
void video_decoder_destroy(video_decoder_t *vd) { #ifdef CONFIG_DVD dvdspu_decoder_deinit(vd); #endif video_overlay_flush(vd, 0); hts_mutex_destroy(&vd->vd_overlay_mutex); free(vd); }
void glw_fini(glw_root_t *gr) { glw_text_bitmap_fini(gr); rstr_release(gr->gr_default_font); glw_tex_fini(gr); free(gr->gr_skin); glw_fini_settings(gr); pool_destroy(gr->gr_token_pool); pool_destroy(gr->gr_clone_pool); prop_courier_destroy(gr->gr_courier); hts_mutex_destroy(&gr->gr_mutex); }
void glw_fini(glw_root_t *gr) { if(gr->gr_osk_widget != NULL) { glw_unref(gr->gr_osk_widget); prop_unsubscribe(gr->gr_osk_text_sub); prop_unsubscribe(gr->gr_osk_ev_sub); } glw_text_bitmap_fini(gr); rstr_release(gr->gr_default_font); glw_tex_fini(gr); free(gr->gr_skin); prop_unsubscribe(gr->gr_evsub); pool_destroy(gr->gr_token_pool); pool_destroy(gr->gr_clone_pool); prop_courier_destroy(gr->gr_courier); hts_mutex_destroy(&gr->gr_mutex); }
static void decoder_close(struct media_codec *mc) { vdec_decoder_t *vdd = mc->opaque; TRACE(TRACE_DEBUG, "VDEC", "Freeing picture list"); free_picture_list(&vdd->pictures); vdec_close(vdd->handle); Lv2Syscall1(349, (uint64_t)vdd->mem); hts_cond_destroy(&vdd->audone); hts_cond_destroy(&vdd->seqdone); hts_mutex_destroy(&vdd->mtx); prop_ref_dec(vdd->metainfo); h264_to_annexb_cleanup(&vdd->annexb); free(vdd); TRACE(TRACE_DEBUG, "VDEC", "Cell decoder closed"); }
static int fflockmgr(void **_mtx, enum AVLockOp op) { hts_mutex_t **mtx = (hts_mutex_t **)_mtx; switch(op) { case AV_LOCK_CREATE: *mtx = malloc(sizeof(hts_mutex_t)); hts_mutex_init(*mtx); break; case AV_LOCK_OBTAIN: hts_mutex_lock(*mtx); break; case AV_LOCK_RELEASE: hts_mutex_unlock(*mtx); break; case AV_LOCK_DESTROY: hts_mutex_destroy(*mtx); break; } return 0; }
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; }