/** * 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 epoll_loop(engine_t n) { assert(n); struct epoll_event events[MAX_SOCKET]; memset(events,0,sizeof(events)); uint32_t tick = GetSystemMs(); uint32_t last_sync = tick; while(n->status) { int nfds = TEMP_FAILURE_RETRY(epoll_wait(n->poller_fd,events,MAX_SOCKET,10)); if(nfds < 0) { printf("error:%d\n",errno); break; } int i; for(i = 0 ; i < nfds ; ++i) { socket_t sock = (socket_t)events[i].data.ptr; if(sock) { if(events[i].events & EPOLLIN) on_read_active(sock); if(events[i].events & EPOLLOUT) on_write_active(sock); if(events[i].events & EPOLLERR) { } } } mq_flush(n->event_queue); uint32_t now = GetSystemMs(); if(now - tick > 1000) { printf("recv:%dmb\n",total_bytes_recv/1024/1024); tick = now; total_bytes_recv = 0; } } close(n->poller_fd); }
void audio_decoder_destroy(struct audio_decoder *ad) { mp_send_cmd(ad->ad_mp, &ad->ad_mp->mp_audio, MB_CTRL_EXIT); hts_thread_join(&ad->ad_tid); mq_flush(ad->ad_mp, &ad->ad_mp->mp_audio, 1); av_frame_free(&ad->ad_frame); if(ad->ad_avr != NULL) { avresample_close(ad->ad_avr); avresample_free(&ad->ad_avr); } audio_cleanup_spdif_muxer(ad); free(ad); }