From fa74be880c27b350615f62dd4a0d6a32be56c60e Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 11 Jul 2013 19:17:05 +0200 Subject: tv: add hack in preparation of demux_stream removal Currently, all demuxer fill_buffer functions have a demux_stream parameter. We want to remove that, but the TV code still depends on it. Add a hack to remove that dependency. The problem with the TV code is that reading video and audio frames blocks, so in order to avoid a deadlock, you should read either of them only if the decoder actually requests new data. --- demux/demux.c | 7 +++++++ demux/demux.h | 1 + stream/tv.c | 21 +++++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index 16adfeb795..df68d4ead7 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -559,6 +559,13 @@ bool demux_has_packet(struct sh_stream *sh) return ds && ds->head; } +// Same as demux_has_packet, but to be called internally by demuxers, as +// opposed to the user of the demuxer. +bool demuxer_stream_has_packets_queued(struct demuxer *d, struct sh_stream *stream) +{ + return demux_has_packet(stream); +} + // ==================================================================== void demuxer_help(void) diff --git a/demux/demux.h b/demux/demux.h index fade7533e9..4d4d861b7d 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -317,6 +317,7 @@ struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d, enum stream_type t, int id); bool demuxer_stream_is_selected(struct demuxer *d, struct sh_stream *stream); +bool demuxer_stream_has_packets_queued(struct demuxer *d, struct sh_stream *stream); void demux_packet_list_sort(struct demux_packet **pkts, int num_pkts); void demux_packet_list_seek(struct demux_packet **pkts, int num_pkts, diff --git a/stream/tv.c b/stream/tv.c index 72b67b7f9e..0f09bb3448 100644 --- a/stream/tv.c +++ b/stream/tv.c @@ -215,10 +215,23 @@ static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds) tvi_handle_t *tvh=(tvi_handle_t*)(demux->priv); demux_packet_t* dp; unsigned int len=0; + struct sh_stream *want_audio = NULL, *want_video = NULL; + + for (int n = 0; n < demux->num_streams; n++) { + struct sh_stream *sh = demux->streams[n]; + if (!demuxer_stream_has_packets_queued(demux, sh) && + demuxer_stream_is_selected(demux, sh)) + { + if (sh->type == STREAM_AUDIO) + want_audio = sh; + if (sh->type == STREAM_VIDEO) + want_video = sh; + } + } /* ================== ADD AUDIO PACKET =================== */ - if (ds==demux->audio && tvh->tv_param->noaudio == 0 && + if (want_audio && tvh->tv_param->noaudio == 0 && tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) { @@ -227,19 +240,19 @@ static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds) dp=new_demux_packet(len); dp->keyframe = true; dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len); - ds_add_packet(demux->audio,dp); + demuxer_add_packet(demux, want_audio, dp); } /* ================== ADD VIDEO PACKET =================== */ - if (ds==demux->video && tvh->functions->control(tvh->priv, + if (want_video && tvh->functions->control(tvh->priv, TVI_CONTROL_IS_VIDEO, 0) == TVI_CONTROL_TRUE) { len = tvh->functions->get_video_framesize(tvh->priv); dp=new_demux_packet(len); dp->keyframe = true; dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len); - ds_add_packet(demux->video,dp); + demuxer_add_packet(demux, want_video, dp); } if (tvh->tv_param->scan) tv_scan(tvh); -- cgit v1.2.3