diff --git a/ffplay.c b/ffplay.c index 42522b8add..8c0c415b4f 100644 --- a/ffplay.c +++ b/ffplay.c @@ -407,6 +407,16 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt) return ret; } +static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index) +{ + AVPacket pkt1, *pkt = &pkt1; + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; + pkt->stream_index = stream_index; + return packet_queue_put(q, pkt); +} + /* packet queue handling */ static void packet_queue_init(PacketQueue *q) { @@ -2894,6 +2904,7 @@ static int read_thread(void *arg) if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0) goto fail; packet_queue_put(&is->videoq, ©); + packet_queue_put_nullpacket(&is->videoq, is->video_stream); } is->queue_attachments_req = 0; } @@ -2922,20 +2933,10 @@ static int read_thread(void *arg) } } if (eof) { - if (is->video_stream >= 0) { - av_init_packet(pkt); - pkt->data = NULL; - pkt->size = 0; - pkt->stream_index = is->video_stream; - packet_queue_put(&is->videoq, pkt); - } - if (is->audio_stream >= 0) { - av_init_packet(pkt); - pkt->data = NULL; - pkt->size = 0; - pkt->stream_index = is->audio_stream; - packet_queue_put(&is->audioq, pkt); - } + if (is->video_stream >= 0) + packet_queue_put_nullpacket(&is->videoq, is->video_stream); + if (is->audio_stream >= 0) + packet_queue_put_nullpacket(&is->audioq, is->audio_stream); SDL_Delay(10); eof=0; continue; @@ -3043,6 +3044,8 @@ static void stream_cycle_channel(VideoState *is, int codec_type) int start_index, stream_index; int old_index; AVStream *st; + AVProgram *p = NULL; + int nb_streams = is->ic->nb_streams; if (codec_type == AVMEDIA_TYPE_VIDEO) { start_index = is->last_video_stream; @@ -3055,8 +3058,22 @@ static void stream_cycle_channel(VideoState *is, int codec_type) old_index = is->subtitle_stream; } stream_index = start_index; + + if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) { + p = av_find_program_from_stream(ic, NULL, is->video_stream); + if (p) { + nb_streams = p->nb_stream_indexes; + for (start_index = 0; start_index < nb_streams; start_index++) + if (p->stream_index[start_index] == stream_index) + break; + if (start_index == nb_streams) + start_index = -1; + stream_index = start_index; + } + } + for (;;) { - if (++stream_index >= is->ic->nb_streams) + if (++stream_index >= nb_streams) { if (codec_type == AVMEDIA_TYPE_SUBTITLE) { @@ -3070,7 +3087,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type) } if (stream_index == start_index) return; - st = ic->streams[stream_index]; + st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index]; if (st->codec->codec_type == codec_type) { /* check that parameters are OK */ switch (codec_type) { @@ -3088,6 +3105,8 @@ static void stream_cycle_channel(VideoState *is, int codec_type) } } the_end: + if (p && stream_index != -1) + stream_index = p->stream_index[stream_index]; stream_component_close(is, old_index); stream_component_open(is, stream_index); } @@ -3175,6 +3194,11 @@ static void event_loop(VideoState *cur_stream) case SDLK_v: stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO); break; + case SDLK_c: + stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO); + stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO); + stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE); + break; case SDLK_t: stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE); break; @@ -3479,6 +3503,7 @@ void show_help_default(const char *opt, const char *arg) "a cycle audio channel\n" "v cycle video channel\n" "t cycle subtitle channel\n" + "c cycle program\n" "w show audio waves\n" "s activate frame-step mode\n" "left/right seek backward/forward 10 seconds\n"