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 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); }
/** * Video decoder thread */ static void * vd_thread(void *aux) { video_decoder_t *vd = aux; media_pipe_t *mp = vd->vd_mp; media_queue_t *mq = &mp->mp_video; media_buf_t *mb; media_codec_t *mc; int run = 1; int reqsize = -1; int reinit = 0; int size; vd->vd_frame = avcodec_alloc_frame(); hts_mutex_lock(&mp->mp_mutex); while(run) { if((mb = TAILQ_FIRST(&mq->mq_q)) == NULL) { hts_cond_wait(&mq->mq_avail, &mp->mp_mutex); continue; } if(mb->mb_data_type == MB_VIDEO && vd->vd_hold && vd->vd_skip == 0 && mb->mb_skip == 0) { hts_cond_wait(&mq->mq_avail, &mp->mp_mutex); continue; } TAILQ_REMOVE(&mq->mq_q, mb, mb_link); mq->mq_packets_current--; mp->mp_buffer_current -= mb->mb_size; mq_update_stats(mp, mq); hts_cond_signal(&mp->mp_backpressure); hts_mutex_unlock(&mp->mp_mutex); mc = mb->mb_cw; switch(mb->mb_data_type) { case MB_CTRL_EXIT: run = 0; break; case MB_CTRL_PAUSE: vd->vd_hold = 1; break; case MB_CTRL_PLAY: vd->vd_hold = 0; break; case MB_FLUSH: vd_init_timings(vd); vd->vd_do_flush = 1; vd->vd_interlaced = 0; video_overlay_flush(vd, 1); break; case MB_VIDEO: if(reinit) { reinit = 0; if(mc->reinit != NULL) mc->reinit(mc); } if(mb->mb_skip == 2) vd->vd_skip = 1; size = mb->mb_size; if(mc->decode) mc->decode(mc, vd, mq, mb, reqsize); else vd_decode_video(vd, mq, mb); update_vbitrate(mp, mq, size, vd); reqsize = -1; break; case MB_REQ_OUTPUT_SIZE: reqsize = mb->mb_data32; break; case MB_REINITIALIZE: reinit = 1; break; #ifdef CONFIG_DVD case MB_DVD_HILITE: case MB_DVD_RESET_SPU: case MB_DVD_CLUT: case MB_DVD_PCI: case MB_DVD_SPU: dvdspu_decoder_dispatch(vd, mb, mp); break; #endif case MB_SUBTITLE: if(vd->vd_ext_subtitles == NULL && mb->mb_stream == mq->mq_stream2) video_overlay_decode(vd, mb); break; case MB_END: break; case MB_BLACKOUT: vd->vd_frame_deliver(FRAME_BUFFER_TYPE_BLACKOUT, NULL, NULL, vd->vd_opaque); break; case MB_FLUSH_SUBTITLES: video_overlay_flush(vd, 1); break; case MB_EXT_SUBTITLE: if(vd->vd_ext_subtitles != NULL) subtitles_destroy(vd->vd_ext_subtitles); // Steal subtitle from the media_buf vd->vd_ext_subtitles = mb->mb_data; mb->mb_data = NULL; video_overlay_flush(vd, 1); break; default: abort(); } hts_mutex_lock(&mp->mp_mutex); media_buf_free_locked(mp, mb); } hts_mutex_unlock(&mp->mp_mutex); if(vd->vd_ext_subtitles != NULL) subtitles_destroy(vd->vd_ext_subtitles); /* Free ffmpeg frame */ av_free(vd->vd_frame); return NULL; }