#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
-#include "libavcodec/audioconvert.h"
#include "libavutil/opt.h"
#include "libavcodec/avfft.h"
#include "libswresample/swresample.h"
const int program_birth_year = 2003;
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
-#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
#define MIN_FRAMES 5
/* SDL audio buffer size, in samples. Should be small to have precise
AVInputFormat *iformat;
int no_background;
int abort_request;
+ int force_refresh;
int paused;
int last_paused;
int seek_req;
}
}
SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
- s->xpos++;
+ if (!s->paused)
+ s->xpos++;
if (s->xpos >= s->width)
s->xpos= s->xleft;
}
SDL_Event event;
event.type = FF_REFRESH_EVENT;
event.user.data1 = opaque;
- if (!is->refresh) {
+ if (!is->refresh && (!is->paused || is->force_refresh)) {
is->refresh = 1;
SDL_PushEvent(&event);
}
goto retry;
}
+ if (is->paused)
+ goto display;
+
/* compute nominal last_duration */
last_duration = vp->pts - is->frame_last_pts;
if (last_duration > 0 && last_duration < 10.0) {
}
}
+display:
/* display picture */
if (!display_disable)
video_display(is);
- pictq_next_picture(is);
+ if (!is->paused)
+ pictq_next_picture(is);
}
} else if (is->audio_st) {
/* draw the next audio frame */
if (!display_disable)
video_display(is);
}
+ is->force_refresh = 0;
if (show_status) {
static int64_t last_time;
int64_t cur_time;
/* if the frame is not skipped, then display it */
if (vp->bmp) {
- AVPicture pict;
+ AVPicture pict = { { 0 } };
#if CONFIG_AVFILTER
if (vp->picref)
avfilter_unref_buffer(vp->picref);
/* get a pointer on the bitmap */
SDL_LockYUVOverlay (vp->bmp);
- memset(&pict, 0, sizeof(AVPicture));
pict.data[0] = vp->bmp->pixels[0];
pict.data[1] = vp->bmp->pixels[2];
pict.data[2] = vp->bmp->pixels[1];
int ret = 1;
if (decoder_reorder_pts == -1) {
- *pts = *(int64_t*)av_opt_ptr(avcodec_get_frame_class(), frame, "best_effort_timestamp");
+ *pts = av_frame_get_best_effort_timestamp(frame);
} else if (decoder_reorder_pts) {
*pts = frame->pkt_pts;
} else {
pic->opaque = ref;
pic->type = FF_BUFFER_TYPE_USER;
pic->reordered_opaque = codec->reordered_opaque;
+ pic->width = codec->width;
+ pic->height = codec->height;
+ pic->format = codec->pix_fmt;
+ pic->sample_aspect_ratio = codec->sample_aspect_ratio;
if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
else pic->pkt_pts = AV_NOPTS_VALUE;
return 0;
static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
{
+ static const enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
char sws_flags_str[128];
int ret;
- enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
- AVFilterContext *filt_src = NULL, *filt_out = NULL;
+ AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format;;
snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
graph->scale_sws_opts = av_strdup(sws_flags_str);
return ret;
#if FF_API_OLD_VSINK_API
- ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
- NULL, pix_fmts, graph);
+ ret = avfilter_graph_create_filter(&filt_out,
+ avfilter_get_by_name("buffersink"),
+ "out", NULL, pix_fmts, graph);
#else
buffersink_params->pixel_fmts = pix_fmts;
- ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
- NULL, buffersink_params, graph);
+ ret = avfilter_graph_create_filter(&filt_out,
+ avfilter_get_by_name("buffersink"),
+ "out", NULL, buffersink_params, graph);
#endif
av_freep(&buffersink_params);
if (ret < 0)
return ret;
+ if ((ret = avfilter_graph_create_filter(&filt_format,
+ avfilter_get_by_name("format"),
+ "format", "yuv420p", NULL, graph)) < 0)
+ return ret;
+ if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)
+ return ret;
+
+
if (vfilters) {
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
outputs->next = NULL;
inputs->name = av_strdup("out");
- inputs->filter_ctx = filt_out;
+ inputs->filter_ctx = filt_format;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse(graph, vfilters, &inputs, &outputs, NULL)) < 0)
return ret;
} else {
- if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
+ if ((ret = avfilter_link(filt_src, 0, filt_format, 0)) < 0)
return ret;
}
if (picref) {
avfilter_fill_frame_from_video_buffer_ref(frame, picref);
pts_int = picref->pts;
+ tb = filt_out->inputs[0]->time_base;
pos = picref->pos;
frame->opaque = picref;
+
+ ret = 1;
}
- if (av_cmp_q(tb, is->video_st->time_base)) {
+ if (ret >= 0 && av_cmp_q(tb, is->video_st->time_base)) {
av_unused int64_t pts1 = pts_int;
pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
av_dlog(NULL, "video_thread(): "
}
the_end:
#if CONFIG_AVFILTER
+ av_freep(&vfilters);
avfilter_graph_free(&graph);
#endif
av_free(frame);
/* if no pts, then compute it */
pts = is->audio_clock;
*pts_ptr = pts;
- is->audio_clock += (double)data_size / (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));
+ is->audio_clock += (double)data_size /
+ (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));
#ifdef DEBUG
{
static double last_clock;
avctx->flags |= CODEC_FLAG_EMU_EDGE;
if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+ memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
env = SDL_getenv("SDL_AUDIO_CHANNELS");
if (env)
wanted_channel_layout = av_get_default_channel_layout(SDL_atoi(env));
SDL_CloseAudio();
packet_queue_end(&is->audioq);
+ av_free_packet(&is->audio_pkt);
if (is->swr_ctx)
swr_free(&is->swr_ctx);
- av_free_packet(&is->audio_pkt);
av_freep(&is->audio_buf1);
is->audio_buf = NULL;
av_freep(&is->frame);
/* 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 .size > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
+ || ( (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))) {
/* wait 10 ms */
break;
case SDLK_f:
toggle_full_screen(cur_stream);
+ cur_stream->force_refresh = 1;
break;
case SDLK_p:
case SDLK_SPACE:
break;
case SDLK_w:
toggle_audio_display(cur_stream);
+ cur_stream->force_refresh = 1;
break;
case SDLK_PAGEUP:
incr = 600.0;
break;
}
break;
+ case SDL_VIDEOEXPOSE:
+ cur_stream->force_refresh = 1;
+ break;
case SDL_MOUSEBUTTONDOWN:
if (exit_on_mousedown) {
do_exit(cur_stream);
SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
screen_width = cur_stream->width = event.resize.w;
screen_height = cur_stream->height = event.resize.h;
+ cur_stream->force_refresh = 1;
break;
case SDL_QUIT:
case FF_QUIT_EVENT: