Merge remote-tracking branch 'cus/stable'

* cus/stable:
  ffplay: force exit when filter configuration fails
  ffplay: fix stream cycling if audio decoding fails
  ffplay: flush codec buffers before freeing filters
  ffplay: dont destroy packet queues on stream change

Merged-by: Michael Niedermayer <michaelni@gmx.at>
pull/59/head
Michael Niedermayer 13 years ago
commit 9c27f29a01
  1. 111
      ffplay.c

@ -232,6 +232,7 @@ typedef struct VideoState {
#endif
int refresh;
int last_video_stream, last_audio_stream, last_subtitle_stream;
} VideoState;
typedef struct AllocEventProps {
@ -303,12 +304,11 @@ void av_noreturn exit_program(int ret)
exit(ret);
}
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{
AVPacketList *pkt1;
/* duplicate the packet */
if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
if (q->abort_request)
return -1;
pkt1 = av_malloc(sizeof(AVPacketList));
@ -317,11 +317,7 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
pkt1->pkt = *pkt;
pkt1->next = NULL;
SDL_LockMutex(q->mutex);
if (!q->last_pkt)
q->first_pkt = pkt1;
else
q->last_pkt->next = pkt1;
@ -330,9 +326,25 @@ static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
q->size += pkt1->pkt.size + sizeof(*pkt1);
/* XXX: should duplicate packet data in DV case */
SDL_CondSignal(q->cond);
return 0;
}
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
int ret;
/* duplicate the packet */
if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
return -1;
SDL_LockMutex(q->mutex);
ret = packet_queue_put_private(q, pkt);
SDL_UnlockMutex(q->mutex);
return 0;
if (pkt != &flush_pkt && ret < 0)
av_free_packet(pkt);
return ret;
}
/* packet queue handling */
@ -341,7 +353,7 @@ static void packet_queue_init(PacketQueue *q)
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
q->cond = SDL_CreateCond();
packet_queue_put(q, &flush_pkt);
q->abort_request = 1;
}
static void packet_queue_flush(PacketQueue *q)
@ -361,7 +373,7 @@ static void packet_queue_flush(PacketQueue *q)
SDL_UnlockMutex(q->mutex);
}
static void packet_queue_end(PacketQueue *q)
static void packet_queue_destroy(PacketQueue *q)
{
packet_queue_flush(q);
SDL_DestroyMutex(q->mutex);
@ -379,6 +391,14 @@ static void packet_queue_abort(PacketQueue *q)
SDL_UnlockMutex(q->mutex);
}
static void packet_queue_start(PacketQueue *q)
{
SDL_LockMutex(q->mutex);
q->abort_request = 0;
packet_queue_put_private(q, &flush_pkt);
SDL_UnlockMutex(q->mutex);
}
/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
{
@ -877,6 +897,9 @@ static void stream_close(VideoState *is)
is->abort_request = 1;
SDL_WaitThread(is->read_tid, NULL);
SDL_WaitThread(is->refresh_tid, NULL);
packet_queue_destroy(&is->videoq);
packet_queue_destroy(&is->audioq);
packet_queue_destroy(&is->subtitleq);
/* free all pictures */
for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
@ -1816,8 +1839,13 @@ static int video_thread(void *arg)
int last_w = is->video_st->codec->width;
int last_h = is->video_st->codec->height;
if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
if ((ret = configure_video_filters(graph, is, vfilters)) < 0) {
SDL_Event event;
event.type = FF_QUIT_EVENT;
event.user.data1 = is;
SDL_PushEvent(&event);
goto the_end;
}
filt_out = is->out_video_filter;
#endif
@ -1893,6 +1921,7 @@ static int video_thread(void *arg)
stream_toggle_pause(is);
}
the_end:
avcodec_flush_buffers(is->video_st->codec);
#if CONFIG_AVFILTER
av_freep(&vfilters);
avfilter_graph_free(&graph);
@ -2240,9 +2269,9 @@ static int stream_component_open(VideoState *is, int stream_index)
opts = filter_codec_opts(codec_opts, codec, ic, ic->streams[stream_index]);
switch(avctx->codec_type){
case AVMEDIA_TYPE_AUDIO : if(audio_codec_name ) codec= avcodec_find_decoder_by_name( audio_codec_name); break;
case AVMEDIA_TYPE_SUBTITLE: if(subtitle_codec_name) codec= avcodec_find_decoder_by_name(subtitle_codec_name); break;
case AVMEDIA_TYPE_VIDEO : if(video_codec_name ) codec= avcodec_find_decoder_by_name( video_codec_name); break;
case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; if(audio_codec_name ) codec= avcodec_find_decoder_by_name( audio_codec_name); break;
case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; if(subtitle_codec_name) codec= avcodec_find_decoder_by_name(subtitle_codec_name); break;
case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; if(video_codec_name ) codec= avcodec_find_decoder_by_name( video_codec_name); break;
}
if (!codec)
return -1;
@ -2343,20 +2372,20 @@ static int stream_component_open(VideoState *is, int stream_index)
is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / wanted_spec.freq;
memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
packet_queue_init(&is->audioq);
packet_queue_start(&is->audioq);
SDL_PauseAudio(0);
break;
case AVMEDIA_TYPE_VIDEO:
is->video_stream = stream_index;
is->video_st = ic->streams[stream_index];
packet_queue_init(&is->videoq);
packet_queue_start(&is->videoq);
is->video_tid = SDL_CreateThread(video_thread, is);
break;
case AVMEDIA_TYPE_SUBTITLE:
is->subtitle_stream = stream_index;
is->subtitle_st = ic->streams[stream_index];
packet_queue_init(&is->subtitleq);
packet_queue_start(&is->subtitleq);
is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
break;
@ -2381,7 +2410,7 @@ static void stream_component_close(VideoState *is, int stream_index)
SDL_CloseAudio();
packet_queue_end(&is->audioq);
packet_queue_flush(&is->audioq);
av_free_packet(&is->audio_pkt);
if (is->swr_ctx)
swr_free(&is->swr_ctx);
@ -2407,7 +2436,7 @@ static void stream_component_close(VideoState *is, int stream_index)
SDL_WaitThread(is->video_tid, NULL);
packet_queue_end(&is->videoq);
packet_queue_flush(&is->videoq);
break;
case AVMEDIA_TYPE_SUBTITLE:
packet_queue_abort(&is->subtitleq);
@ -2422,7 +2451,7 @@ static void stream_component_close(VideoState *is, int stream_index)
SDL_WaitThread(is->subtitle_tid, NULL);
packet_queue_end(&is->subtitleq);
packet_queue_flush(&is->subtitleq);
break;
default:
break;
@ -2469,9 +2498,9 @@ static int read_thread(void *arg)
int orig_nb_streams;
memset(st_index, -1, sizeof(st_index));
is->video_stream = -1;
is->audio_stream = -1;
is->subtitle_stream = -1;
is->last_video_stream = is->video_stream = -1;
is->last_audio_stream = is->audio_stream = -1;
is->last_subtitle_stream = is->subtitle_stream = -1;
ic = avformat_alloc_context();
ic->interrupt_callback.callback = decode_interrupt_cb;
@ -2625,9 +2654,9 @@ static int read_thread(void *arg)
/* if the queue are full, no need to read more */
if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
|| ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0)
&& (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0)
&& (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
|| ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
&& (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request)
&& (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request))) {
/* wait 10 ms */
SDL_Delay(10);
continue;
@ -2732,6 +2761,10 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
is->subpq_mutex = SDL_CreateMutex();
is->subpq_cond = SDL_CreateCond();
packet_queue_init(&is->videoq);
packet_queue_init(&is->audioq);
packet_queue_init(&is->subtitleq);
is->av_sync_type = av_sync_type;
is->read_tid = SDL_CreateThread(read_thread, is);
if (!is->read_tid) {
@ -2745,16 +2778,19 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
{
AVFormatContext *ic = is->ic;
int start_index, stream_index;
int old_index;
AVStream *st;
if (codec_type == AVMEDIA_TYPE_VIDEO)
start_index = is->video_stream;
else if (codec_type == AVMEDIA_TYPE_AUDIO)
start_index = is->audio_stream;
else
start_index = is->subtitle_stream;
if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
return;
if (codec_type == AVMEDIA_TYPE_VIDEO) {
start_index = is->last_video_stream;
old_index = is->video_stream;
} else if (codec_type == AVMEDIA_TYPE_AUDIO) {
start_index = is->last_audio_stream;
old_index = is->audio_stream;
} else {
start_index = is->last_subtitle_stream;
old_index = is->subtitle_stream;
}
stream_index = start_index;
for (;;) {
if (++stream_index >= is->ic->nb_streams)
@ -2762,8 +2798,11 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
if (codec_type == AVMEDIA_TYPE_SUBTITLE)
{
stream_index = -1;
is->last_subtitle_stream = -1;
goto the_end;
} else
}
if (start_index == -1)
return;
stream_index = 0;
}
if (stream_index == start_index)
@ -2786,7 +2825,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
}
}
the_end:
stream_component_close(is, start_index);
stream_component_close(is, old_index);
stream_component_open(is, stream_index);
}

Loading…
Cancel
Save