]> git.sesse.net Git - ffmpeg/blob - ffplay.c
ffplay: reset audio_pkt_temp when opening audio
[ffmpeg] / ffplay.c
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * simple media player based on the FFmpeg libraries
24  */
25
26 #include "config.h"
27 #include <inttypes.h>
28 #include <math.h>
29 #include <limits.h>
30 #include <signal.h>
31 #include "libavutil/avstring.h"
32 #include "libavutil/colorspace.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/dict.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/samplefmt.h"
39 #include "libavutil/avassert.h"
40 #include "libavformat/avformat.h"
41 #include "libavdevice/avdevice.h"
42 #include "libswscale/swscale.h"
43 #include "libavcodec/audioconvert.h"
44 #include "libavutil/opt.h"
45 #include "libavcodec/avfft.h"
46 #include "libswresample/swresample.h"
47
48 #if CONFIG_AVFILTER
49 # include "libavfilter/avcodec.h"
50 # include "libavfilter/avfilter.h"
51 # include "libavfilter/avfiltergraph.h"
52 # include "libavfilter/buffersink.h"
53 #endif
54
55 #include <SDL.h>
56 #include <SDL_thread.h>
57
58 #include "cmdutils.h"
59
60 #include <unistd.h>
61 #include <assert.h>
62
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
65
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
67 #define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
68 #define MIN_FRAMES 5
69
70 /* SDL audio buffer size, in samples. Should be small to have precise
71    A/V sync as SDL does not have hardware buffer fullness info. */
72 #define SDL_AUDIO_BUFFER_SIZE 1024
73
74 /* no AV sync correction is done if below the AV sync threshold */
75 #define AV_SYNC_THRESHOLD 0.01
76 /* no AV correction is done if too big error */
77 #define AV_NOSYNC_THRESHOLD 10.0
78
79 /* maximum audio speed change to get correct sync */
80 #define SAMPLE_CORRECTION_PERCENT_MAX 10
81
82 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
83 #define AUDIO_DIFF_AVG_NB   20
84
85 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
86 #define SAMPLE_ARRAY_SIZE (2 * 65536)
87
88 static int sws_flags = SWS_BICUBIC;
89
90 typedef struct PacketQueue {
91     AVPacketList *first_pkt, *last_pkt;
92     int nb_packets;
93     int size;
94     int abort_request;
95     SDL_mutex *mutex;
96     SDL_cond *cond;
97 } PacketQueue;
98
99 #define VIDEO_PICTURE_QUEUE_SIZE 2
100 #define SUBPICTURE_QUEUE_SIZE 4
101
102 typedef struct VideoPicture {
103     double pts;                                  ///< presentation time stamp for this picture
104     double duration;                             ///< expected duration of the frame
105     int64_t pos;                                 ///< byte position in file
106     int skip;
107     SDL_Overlay *bmp;
108     int width, height; /* source height & width */
109     int allocated;
110     int reallocate;
111     enum PixelFormat pix_fmt;
112
113 #if CONFIG_AVFILTER
114     AVFilterBufferRef *picref;
115 #endif
116 } VideoPicture;
117
118 typedef struct SubPicture {
119     double pts; /* presentation time stamp for this picture */
120     AVSubtitle sub;
121 } SubPicture;
122
123 enum {
124     AV_SYNC_AUDIO_MASTER, /* default choice */
125     AV_SYNC_VIDEO_MASTER,
126     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
127 };
128
129 typedef struct VideoState {
130     SDL_Thread *read_tid;
131     SDL_Thread *video_tid;
132     SDL_Thread *refresh_tid;
133     AVInputFormat *iformat;
134     int no_background;
135     int abort_request;
136     int force_refresh;
137     int paused;
138     int last_paused;
139     int seek_req;
140     int seek_flags;
141     int64_t seek_pos;
142     int64_t seek_rel;
143     int read_pause_return;
144     AVFormatContext *ic;
145
146     int audio_stream;
147
148     int av_sync_type;
149     double external_clock; /* external clock base */
150     int64_t external_clock_time;
151
152     double audio_clock;
153     double audio_diff_cum; /* used for AV difference average computation */
154     double audio_diff_avg_coef;
155     double audio_diff_threshold;
156     int audio_diff_avg_count;
157     AVStream *audio_st;
158     PacketQueue audioq;
159     int audio_hw_buf_size;
160     DECLARE_ALIGNED(16,uint8_t,audio_buf2)[AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];
161     uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
162     uint8_t *audio_buf;
163     uint8_t *audio_buf1;
164     unsigned int audio_buf_size; /* in bytes */
165     int audio_buf_index; /* in bytes */
166     int audio_write_buf_size;
167     AVPacket audio_pkt_temp;
168     AVPacket audio_pkt;
169     enum AVSampleFormat audio_src_fmt;
170     enum AVSampleFormat audio_tgt_fmt;
171     int audio_src_channels;
172     int audio_tgt_channels;
173     int64_t audio_src_channel_layout;
174     int64_t audio_tgt_channel_layout;
175     int audio_src_freq;
176     int audio_tgt_freq;
177     struct SwrContext *swr_ctx;
178     double audio_current_pts;
179     double audio_current_pts_drift;
180     int frame_drops_early;
181     int frame_drops_late;
182     AVFrame *frame;
183
184     enum ShowMode {
185         SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
186     } show_mode;
187     int16_t sample_array[SAMPLE_ARRAY_SIZE];
188     int sample_array_index;
189     int last_i_start;
190     RDFTContext *rdft;
191     int rdft_bits;
192     FFTSample *rdft_data;
193     int xpos;
194
195     SDL_Thread *subtitle_tid;
196     int subtitle_stream;
197     int subtitle_stream_changed;
198     AVStream *subtitle_st;
199     PacketQueue subtitleq;
200     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
201     int subpq_size, subpq_rindex, subpq_windex;
202     SDL_mutex *subpq_mutex;
203     SDL_cond *subpq_cond;
204
205     double frame_timer;
206     double frame_last_pts;
207     double frame_last_duration;
208     double frame_last_dropped_pts;
209     double frame_last_returned_time;
210     double frame_last_filter_delay;
211     int64_t frame_last_dropped_pos;
212     double video_clock;                          ///< pts of last decoded frame / predicted pts of next decoded frame
213     int video_stream;
214     AVStream *video_st;
215     PacketQueue videoq;
216     double video_current_pts;                    ///< current displayed pts (different from video_clock if frame fifos are used)
217     double video_current_pts_drift;              ///< video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
218     int64_t video_current_pos;                   ///< current displayed file pos
219     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
220     int pictq_size, pictq_rindex, pictq_windex;
221     SDL_mutex *pictq_mutex;
222     SDL_cond *pictq_cond;
223 #if !CONFIG_AVFILTER
224     struct SwsContext *img_convert_ctx;
225 #endif
226
227     char filename[1024];
228     int width, height, xleft, ytop;
229     int step;
230
231 #if CONFIG_AVFILTER
232     AVFilterContext *out_video_filter;          ///< the last filter in the video chain
233 #endif
234
235     int refresh;
236 } VideoState;
237
238 static int opt_help(const char *opt, const char *arg);
239
240 /* options specified by the user */
241 static AVInputFormat *file_iformat;
242 static const char *input_filename;
243 static const char *window_title;
244 static int fs_screen_width;
245 static int fs_screen_height;
246 static int screen_width  = 0;
247 static int screen_height = 0;
248 static int audio_disable;
249 static int video_disable;
250 static int wanted_stream[AVMEDIA_TYPE_NB] = {
251     [AVMEDIA_TYPE_AUDIO]    = -1,
252     [AVMEDIA_TYPE_VIDEO]    = -1,
253     [AVMEDIA_TYPE_SUBTITLE] = -1,
254 };
255 static int seek_by_bytes = -1;
256 static int display_disable;
257 static int show_status = 1;
258 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
259 static int64_t start_time = AV_NOPTS_VALUE;
260 static int64_t duration = AV_NOPTS_VALUE;
261 static int workaround_bugs = 1;
262 static int fast = 0;
263 static int genpts = 0;
264 static int lowres = 0;
265 static int idct = FF_IDCT_AUTO;
266 static enum AVDiscard skip_frame       = AVDISCARD_DEFAULT;
267 static enum AVDiscard skip_idct        = AVDISCARD_DEFAULT;
268 static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT;
269 static int error_concealment = 3;
270 static int decoder_reorder_pts = -1;
271 static int autoexit;
272 static int exit_on_keydown;
273 static int exit_on_mousedown;
274 static int loop = 1;
275 static int framedrop = -1;
276 static enum ShowMode show_mode = SHOW_MODE_NONE;
277 static const char *audio_codec_name;
278 static const char *subtitle_codec_name;
279 static const char *video_codec_name;
280 static int rdftspeed = 20;
281 #if CONFIG_AVFILTER
282 static char *vfilters = NULL;
283 #endif
284
285 /* current context */
286 static int is_full_screen;
287 static int64_t audio_callback_time;
288
289 static AVPacket flush_pkt;
290
291 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
292 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
293 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
294
295 static SDL_Surface *screen;
296
297 void av_noreturn exit_program(int ret)
298 {
299     exit(ret);
300 }
301
302 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
303 {
304     AVPacketList *pkt1;
305
306     /* duplicate the packet */
307     if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
308         return -1;
309
310     pkt1 = av_malloc(sizeof(AVPacketList));
311     if (!pkt1)
312         return -1;
313     pkt1->pkt = *pkt;
314     pkt1->next = NULL;
315
316
317     SDL_LockMutex(q->mutex);
318
319     if (!q->last_pkt)
320
321         q->first_pkt = pkt1;
322     else
323         q->last_pkt->next = pkt1;
324     q->last_pkt = pkt1;
325     q->nb_packets++;
326     q->size += pkt1->pkt.size + sizeof(*pkt1);
327     /* XXX: should duplicate packet data in DV case */
328     SDL_CondSignal(q->cond);
329
330     SDL_UnlockMutex(q->mutex);
331     return 0;
332 }
333
334 /* packet queue handling */
335 static void packet_queue_init(PacketQueue *q)
336 {
337     memset(q, 0, sizeof(PacketQueue));
338     q->mutex = SDL_CreateMutex();
339     q->cond = SDL_CreateCond();
340     packet_queue_put(q, &flush_pkt);
341 }
342
343 static void packet_queue_flush(PacketQueue *q)
344 {
345     AVPacketList *pkt, *pkt1;
346
347     SDL_LockMutex(q->mutex);
348     for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
349         pkt1 = pkt->next;
350         av_free_packet(&pkt->pkt);
351         av_freep(&pkt);
352     }
353     q->last_pkt = NULL;
354     q->first_pkt = NULL;
355     q->nb_packets = 0;
356     q->size = 0;
357     SDL_UnlockMutex(q->mutex);
358 }
359
360 static void packet_queue_end(PacketQueue *q)
361 {
362     packet_queue_flush(q);
363     SDL_DestroyMutex(q->mutex);
364     SDL_DestroyCond(q->cond);
365 }
366
367 static void packet_queue_abort(PacketQueue *q)
368 {
369     SDL_LockMutex(q->mutex);
370
371     q->abort_request = 1;
372
373     SDL_CondSignal(q->cond);
374
375     SDL_UnlockMutex(q->mutex);
376 }
377
378 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
379 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
380 {
381     AVPacketList *pkt1;
382     int ret;
383
384     SDL_LockMutex(q->mutex);
385
386     for (;;) {
387         if (q->abort_request) {
388             ret = -1;
389             break;
390         }
391
392         pkt1 = q->first_pkt;
393         if (pkt1) {
394             q->first_pkt = pkt1->next;
395             if (!q->first_pkt)
396                 q->last_pkt = NULL;
397             q->nb_packets--;
398             q->size -= pkt1->pkt.size + sizeof(*pkt1);
399             *pkt = pkt1->pkt;
400             av_free(pkt1);
401             ret = 1;
402             break;
403         } else if (!block) {
404             ret = 0;
405             break;
406         } else {
407             SDL_CondWait(q->cond, q->mutex);
408         }
409     }
410     SDL_UnlockMutex(q->mutex);
411     return ret;
412 }
413
414 static inline void fill_rectangle(SDL_Surface *screen,
415                                   int x, int y, int w, int h, int color)
416 {
417     SDL_Rect rect;
418     rect.x = x;
419     rect.y = y;
420     rect.w = w;
421     rect.h = h;
422     SDL_FillRect(screen, &rect, color);
423 }
424
425 #define ALPHA_BLEND(a, oldp, newp, s)\
426 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
427
428 #define RGBA_IN(r, g, b, a, s)\
429 {\
430     unsigned int v = ((const uint32_t *)(s))[0];\
431     a = (v >> 24) & 0xff;\
432     r = (v >> 16) & 0xff;\
433     g = (v >> 8) & 0xff;\
434     b = v & 0xff;\
435 }
436
437 #define YUVA_IN(y, u, v, a, s, pal)\
438 {\
439     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
440     a = (val >> 24) & 0xff;\
441     y = (val >> 16) & 0xff;\
442     u = (val >> 8) & 0xff;\
443     v = val & 0xff;\
444 }
445
446 #define YUVA_OUT(d, y, u, v, a)\
447 {\
448     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
449 }
450
451
452 #define BPP 1
453
454 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
455 {
456     int wrap, wrap3, width2, skip2;
457     int y, u, v, a, u1, v1, a1, w, h;
458     uint8_t *lum, *cb, *cr;
459     const uint8_t *p;
460     const uint32_t *pal;
461     int dstx, dsty, dstw, dsth;
462
463     dstw = av_clip(rect->w, 0, imgw);
464     dsth = av_clip(rect->h, 0, imgh);
465     dstx = av_clip(rect->x, 0, imgw - dstw);
466     dsty = av_clip(rect->y, 0, imgh - dsth);
467     lum = dst->data[0] + dsty * dst->linesize[0];
468     cb  = dst->data[1] + (dsty >> 1) * dst->linesize[1];
469     cr  = dst->data[2] + (dsty >> 1) * dst->linesize[2];
470
471     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
472     skip2 = dstx >> 1;
473     wrap = dst->linesize[0];
474     wrap3 = rect->pict.linesize[0];
475     p = rect->pict.data[0];
476     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
477
478     if (dsty & 1) {
479         lum += dstx;
480         cb += skip2;
481         cr += skip2;
482
483         if (dstx & 1) {
484             YUVA_IN(y, u, v, a, p, pal);
485             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
486             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
487             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
488             cb++;
489             cr++;
490             lum++;
491             p += BPP;
492         }
493         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
494             YUVA_IN(y, u, v, a, p, pal);
495             u1 = u;
496             v1 = v;
497             a1 = a;
498             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
499
500             YUVA_IN(y, u, v, a, p + BPP, pal);
501             u1 += u;
502             v1 += v;
503             a1 += a;
504             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
505             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
506             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
507             cb++;
508             cr++;
509             p += 2 * BPP;
510             lum += 2;
511         }
512         if (w) {
513             YUVA_IN(y, u, v, a, p, pal);
514             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
515             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
516             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
517             p++;
518             lum++;
519         }
520         p += wrap3 - dstw * BPP;
521         lum += wrap - dstw - dstx;
522         cb += dst->linesize[1] - width2 - skip2;
523         cr += dst->linesize[2] - width2 - skip2;
524     }
525     for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
526         lum += dstx;
527         cb += skip2;
528         cr += skip2;
529
530         if (dstx & 1) {
531             YUVA_IN(y, u, v, a, p, pal);
532             u1 = u;
533             v1 = v;
534             a1 = a;
535             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
536             p += wrap3;
537             lum += wrap;
538             YUVA_IN(y, u, v, a, p, pal);
539             u1 += u;
540             v1 += v;
541             a1 += a;
542             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
543             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
544             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
545             cb++;
546             cr++;
547             p += -wrap3 + BPP;
548             lum += -wrap + 1;
549         }
550         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
551             YUVA_IN(y, u, v, a, p, pal);
552             u1 = u;
553             v1 = v;
554             a1 = a;
555             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
556
557             YUVA_IN(y, u, v, a, p + BPP, pal);
558             u1 += u;
559             v1 += v;
560             a1 += a;
561             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
562             p += wrap3;
563             lum += wrap;
564
565             YUVA_IN(y, u, v, a, p, pal);
566             u1 += u;
567             v1 += v;
568             a1 += a;
569             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
570
571             YUVA_IN(y, u, v, a, p + BPP, pal);
572             u1 += u;
573             v1 += v;
574             a1 += a;
575             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
576
577             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
578             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
579
580             cb++;
581             cr++;
582             p += -wrap3 + 2 * BPP;
583             lum += -wrap + 2;
584         }
585         if (w) {
586             YUVA_IN(y, u, v, a, p, pal);
587             u1 = u;
588             v1 = v;
589             a1 = a;
590             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
591             p += wrap3;
592             lum += wrap;
593             YUVA_IN(y, u, v, a, p, pal);
594             u1 += u;
595             v1 += v;
596             a1 += a;
597             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
598             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
599             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
600             cb++;
601             cr++;
602             p += -wrap3 + BPP;
603             lum += -wrap + 1;
604         }
605         p += wrap3 + (wrap3 - dstw * BPP);
606         lum += wrap + (wrap - dstw - dstx);
607         cb += dst->linesize[1] - width2 - skip2;
608         cr += dst->linesize[2] - width2 - skip2;
609     }
610     /* handle odd height */
611     if (h) {
612         lum += dstx;
613         cb += skip2;
614         cr += skip2;
615
616         if (dstx & 1) {
617             YUVA_IN(y, u, v, a, p, pal);
618             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
619             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
620             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
621             cb++;
622             cr++;
623             lum++;
624             p += BPP;
625         }
626         for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
627             YUVA_IN(y, u, v, a, p, pal);
628             u1 = u;
629             v1 = v;
630             a1 = a;
631             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
632
633             YUVA_IN(y, u, v, a, p + BPP, pal);
634             u1 += u;
635             v1 += v;
636             a1 += a;
637             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
638             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
639             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
640             cb++;
641             cr++;
642             p += 2 * BPP;
643             lum += 2;
644         }
645         if (w) {
646             YUVA_IN(y, u, v, a, p, pal);
647             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
648             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
649             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
650         }
651     }
652 }
653
654 static void free_subpicture(SubPicture *sp)
655 {
656     avsubtitle_free(&sp->sub);
657 }
658
659 static void video_image_display(VideoState *is)
660 {
661     VideoPicture *vp;
662     SubPicture *sp;
663     AVPicture pict;
664     float aspect_ratio;
665     int width, height, x, y;
666     SDL_Rect rect;
667     int i;
668
669     vp = &is->pictq[is->pictq_rindex];
670     if (vp->bmp) {
671 #if CONFIG_AVFILTER
672          if (vp->picref->video->sample_aspect_ratio.num == 0)
673              aspect_ratio = 0;
674          else
675              aspect_ratio = av_q2d(vp->picref->video->sample_aspect_ratio);
676 #else
677
678         /* XXX: use variable in the frame */
679         if (is->video_st->sample_aspect_ratio.num)
680             aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
681         else if (is->video_st->codec->sample_aspect_ratio.num)
682             aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
683         else
684             aspect_ratio = 0;
685 #endif
686         if (aspect_ratio <= 0.0)
687             aspect_ratio = 1.0;
688         aspect_ratio *= (float)vp->width / (float)vp->height;
689
690         if (is->subtitle_st) {
691             if (is->subpq_size > 0) {
692                 sp = &is->subpq[is->subpq_rindex];
693
694                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
695                     SDL_LockYUVOverlay (vp->bmp);
696
697                     pict.data[0] = vp->bmp->pixels[0];
698                     pict.data[1] = vp->bmp->pixels[2];
699                     pict.data[2] = vp->bmp->pixels[1];
700
701                     pict.linesize[0] = vp->bmp->pitches[0];
702                     pict.linesize[1] = vp->bmp->pitches[2];
703                     pict.linesize[2] = vp->bmp->pitches[1];
704
705                     for (i = 0; i < sp->sub.num_rects; i++)
706                         blend_subrect(&pict, sp->sub.rects[i],
707                                       vp->bmp->w, vp->bmp->h);
708
709                     SDL_UnlockYUVOverlay (vp->bmp);
710                 }
711             }
712         }
713
714
715         /* XXX: we suppose the screen has a 1.0 pixel ratio */
716         height = is->height;
717         width = ((int)rint(height * aspect_ratio)) & ~1;
718         if (width > is->width) {
719             width = is->width;
720             height = ((int)rint(width / aspect_ratio)) & ~1;
721         }
722         x = (is->width - width) / 2;
723         y = (is->height - height) / 2;
724         is->no_background = 0;
725         rect.x = is->xleft + x;
726         rect.y = is->ytop  + y;
727         rect.w = FFMAX(width,  1);
728         rect.h = FFMAX(height, 1);
729         SDL_DisplayYUVOverlay(vp->bmp, &rect);
730     }
731 }
732
733 static inline int compute_mod(int a, int b)
734 {
735     return a < 0 ? a%b + b : a%b;
736 }
737
738 static void video_audio_display(VideoState *s)
739 {
740     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
741     int ch, channels, h, h2, bgcolor, fgcolor;
742     int16_t time_diff;
743     int rdft_bits, nb_freq;
744
745     for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
746         ;
747     nb_freq = 1 << (rdft_bits - 1);
748
749     /* compute display index : center on currently output samples */
750     channels = s->audio_tgt_channels;
751     nb_display_channels = channels;
752     if (!s->paused) {
753         int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
754         n = 2 * channels;
755         delay = s->audio_write_buf_size;
756         delay /= n;
757
758         /* to be more precise, we take into account the time spent since
759            the last buffer computation */
760         if (audio_callback_time) {
761             time_diff = av_gettime() - audio_callback_time;
762             delay -= (time_diff * s->audio_tgt_freq) / 1000000;
763         }
764
765         delay += 2 * data_used;
766         if (delay < data_used)
767             delay = data_used;
768
769         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
770         if (s->show_mode == SHOW_MODE_WAVES) {
771             h = INT_MIN;
772             for (i = 0; i < 1000; i += channels) {
773                 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
774                 int a = s->sample_array[idx];
775                 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
776                 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
777                 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
778                 int score = a - d;
779                 if (h < score && (b ^ c) < 0) {
780                     h = score;
781                     i_start = idx;
782                 }
783             }
784         }
785
786         s->last_i_start = i_start;
787     } else {
788         i_start = s->last_i_start;
789     }
790
791     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
792     if (s->show_mode == SHOW_MODE_WAVES) {
793         fill_rectangle(screen,
794                        s->xleft, s->ytop, s->width, s->height,
795                        bgcolor);
796
797         fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
798
799         /* total height for one channel */
800         h = s->height / nb_display_channels;
801         /* graph height / 2 */
802         h2 = (h * 9) / 20;
803         for (ch = 0; ch < nb_display_channels; ch++) {
804             i = i_start + ch;
805             y1 = s->ytop + ch * h + (h / 2); /* position of center line */
806             for (x = 0; x < s->width; x++) {
807                 y = (s->sample_array[i] * h2) >> 15;
808                 if (y < 0) {
809                     y = -y;
810                     ys = y1 - y;
811                 } else {
812                     ys = y1;
813                 }
814                 fill_rectangle(screen,
815                                s->xleft + x, ys, 1, y,
816                                fgcolor);
817                 i += channels;
818                 if (i >= SAMPLE_ARRAY_SIZE)
819                     i -= SAMPLE_ARRAY_SIZE;
820             }
821         }
822
823         fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
824
825         for (ch = 1; ch < nb_display_channels; ch++) {
826             y = s->ytop + ch * h;
827             fill_rectangle(screen,
828                            s->xleft, y, s->width, 1,
829                            fgcolor);
830         }
831         SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
832     } else {
833         nb_display_channels= FFMIN(nb_display_channels, 2);
834         if (rdft_bits != s->rdft_bits) {
835             av_rdft_end(s->rdft);
836             av_free(s->rdft_data);
837             s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
838             s->rdft_bits = rdft_bits;
839             s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
840         }
841         {
842             FFTSample *data[2];
843             for (ch = 0; ch < nb_display_channels; ch++) {
844                 data[ch] = s->rdft_data + 2 * nb_freq * ch;
845                 i = i_start + ch;
846                 for (x = 0; x < 2 * nb_freq; x++) {
847                     double w = (x-nb_freq) * (1.0 / nb_freq);
848                     data[ch][x] = s->sample_array[i] * (1.0 - w * w);
849                     i += channels;
850                     if (i >= SAMPLE_ARRAY_SIZE)
851                         i -= SAMPLE_ARRAY_SIZE;
852                 }
853                 av_rdft_calc(s->rdft, data[ch]);
854             }
855             // least efficient way to do this, we should of course directly access it but its more than fast enough
856             for (y = 0; y < s->height; y++) {
857                 double w = 1 / sqrt(nb_freq);
858                 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
859                 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
860                        + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
861                 a = FFMIN(a, 255);
862                 b = FFMIN(b, 255);
863                 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
864
865                 fill_rectangle(screen,
866                             s->xpos, s->height-y, 1, 1,
867                             fgcolor);
868             }
869         }
870         SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
871         s->xpos++;
872         if (s->xpos >= s->width)
873             s->xpos= s->xleft;
874     }
875 }
876
877 static void stream_close(VideoState *is)
878 {
879     VideoPicture *vp;
880     int i;
881     /* XXX: use a special url_shutdown call to abort parse cleanly */
882     is->abort_request = 1;
883     SDL_WaitThread(is->read_tid, NULL);
884     SDL_WaitThread(is->refresh_tid, NULL);
885
886     /* free all pictures */
887     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
888         vp = &is->pictq[i];
889 #if CONFIG_AVFILTER
890         if (vp->picref) {
891             avfilter_unref_buffer(vp->picref);
892             vp->picref = NULL;
893         }
894 #endif
895         if (vp->bmp) {
896             SDL_FreeYUVOverlay(vp->bmp);
897             vp->bmp = NULL;
898         }
899     }
900     SDL_DestroyMutex(is->pictq_mutex);
901     SDL_DestroyCond(is->pictq_cond);
902     SDL_DestroyMutex(is->subpq_mutex);
903     SDL_DestroyCond(is->subpq_cond);
904 #if !CONFIG_AVFILTER
905     if (is->img_convert_ctx)
906         sws_freeContext(is->img_convert_ctx);
907 #endif
908     av_free(is);
909 }
910
911 static void do_exit(VideoState *is)
912 {
913     if (is) {
914         stream_close(is);
915     }
916     av_lockmgr_register(NULL);
917     uninit_opts();
918 #if CONFIG_AVFILTER
919     avfilter_uninit();
920 #endif
921     avformat_network_deinit();
922     if (show_status)
923         printf("\n");
924     SDL_Quit();
925     av_log(NULL, AV_LOG_QUIET, "%s", "");
926     exit(0);
927 }
928
929 static void sigterm_handler(int sig)
930 {
931     exit(123);
932 }
933
934 static int video_open(VideoState *is, int force_set_video_mode)
935 {
936     int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
937     int w,h;
938
939     if (is_full_screen) flags |= SDL_FULLSCREEN;
940     else                flags |= SDL_RESIZABLE;
941
942     if (is_full_screen && fs_screen_width) {
943         w = fs_screen_width;
944         h = fs_screen_height;
945     } else if (!is_full_screen && screen_width) {
946         w = screen_width;
947         h = screen_height;
948 #if CONFIG_AVFILTER
949     } else if (is->out_video_filter && is->out_video_filter->inputs[0]) {
950         w = is->out_video_filter->inputs[0]->w;
951         h = is->out_video_filter->inputs[0]->h;
952 #else
953     } else if (is->video_st && is->video_st->codec->width) {
954         w = is->video_st->codec->width;
955         h = is->video_st->codec->height;
956 #endif
957     } else {
958         w = 640;
959         h = 480;
960     }
961     if (screen && is->width == screen->w && screen->w == w
962        && is->height== screen->h && screen->h == h && !force_set_video_mode)
963         return 0;
964     screen = SDL_SetVideoMode(w, h, 0, flags);
965     if (!screen) {
966         fprintf(stderr, "SDL: could not set video mode - exiting\n");
967         do_exit(is);
968     }
969     if (!window_title)
970         window_title = input_filename;
971     SDL_WM_SetCaption(window_title, window_title);
972
973     is->width  = screen->w;
974     is->height = screen->h;
975
976     return 0;
977 }
978
979 /* display the current picture, if any */
980 static void video_display(VideoState *is)
981 {
982     if (!screen)
983         video_open(is, 0);
984     if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
985         video_audio_display(is);
986     else if (is->video_st)
987         video_image_display(is);
988 }
989
990 static int refresh_thread(void *opaque)
991 {
992     VideoState *is= opaque;
993     while (!is->abort_request) {
994         SDL_Event event;
995         event.type = FF_REFRESH_EVENT;
996         event.user.data1 = opaque;
997         if (!is->refresh && (!is->paused || is->force_refresh)) {
998             is->refresh = 1;
999             SDL_PushEvent(&event);
1000         }
1001         //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
1002         usleep(is->audio_st && is->show_mode != SHOW_MODE_VIDEO ? rdftspeed*1000 : 5000);
1003     }
1004     return 0;
1005 }
1006
1007 /* get the current audio clock value */
1008 static double get_audio_clock(VideoState *is)
1009 {
1010     if (is->paused) {
1011         return is->audio_current_pts;
1012     } else {
1013         return is->audio_current_pts_drift + av_gettime() / 1000000.0;
1014     }
1015 }
1016
1017 /* get the current video clock value */
1018 static double get_video_clock(VideoState *is)
1019 {
1020     if (is->paused) {
1021         return is->video_current_pts;
1022     } else {
1023         return is->video_current_pts_drift + av_gettime() / 1000000.0;
1024     }
1025 }
1026
1027 /* get the current external clock value */
1028 static double get_external_clock(VideoState *is)
1029 {
1030     int64_t ti;
1031     ti = av_gettime();
1032     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
1033 }
1034
1035 /* get the current master clock value */
1036 static double get_master_clock(VideoState *is)
1037 {
1038     double val;
1039
1040     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1041         if (is->video_st)
1042             val = get_video_clock(is);
1043         else
1044             val = get_audio_clock(is);
1045     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1046         if (is->audio_st)
1047             val = get_audio_clock(is);
1048         else
1049             val = get_video_clock(is);
1050     } else {
1051         val = get_external_clock(is);
1052     }
1053     return val;
1054 }
1055
1056 /* seek in the stream */
1057 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1058 {
1059     if (!is->seek_req) {
1060         is->seek_pos = pos;
1061         is->seek_rel = rel;
1062         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1063         if (seek_by_bytes)
1064             is->seek_flags |= AVSEEK_FLAG_BYTE;
1065         is->seek_req = 1;
1066     }
1067 }
1068
1069 /* pause or resume the video */
1070 static void stream_toggle_pause(VideoState *is)
1071 {
1072     if (is->paused) {
1073         is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1074         if (is->read_pause_return != AVERROR(ENOSYS)) {
1075             is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1076         }
1077         is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1078     }
1079     is->paused = !is->paused;
1080 }
1081
1082 static double compute_target_delay(double delay, VideoState *is)
1083 {
1084     double sync_threshold, diff;
1085
1086     /* update delay to follow master synchronisation source */
1087     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1088          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1089         /* if video is slave, we try to correct big delays by
1090            duplicating or deleting a frame */
1091         diff = get_video_clock(is) - get_master_clock(is);
1092
1093         /* skip or repeat frame. We take into account the
1094            delay to compute the threshold. I still don't know
1095            if it is the best guess */
1096         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1097         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1098             if (diff <= -sync_threshold)
1099                 delay = 0;
1100             else if (diff >= sync_threshold)
1101                 delay = 2 * delay;
1102         }
1103     }
1104
1105     av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1106             delay, -diff);
1107
1108     return delay;
1109 }
1110
1111 static void pictq_next_picture(VideoState *is) {
1112     /* update queue size and signal for next picture */
1113     if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1114         is->pictq_rindex = 0;
1115
1116     SDL_LockMutex(is->pictq_mutex);
1117     is->pictq_size--;
1118     SDL_CondSignal(is->pictq_cond);
1119     SDL_UnlockMutex(is->pictq_mutex);
1120 }
1121
1122 static void update_video_pts(VideoState *is, double pts, int64_t pos) {
1123     double time = av_gettime() / 1000000.0;
1124     /* update current video pts */
1125     is->video_current_pts = pts;
1126     is->video_current_pts_drift = is->video_current_pts - time;
1127     is->video_current_pos = pos;
1128     is->frame_last_pts = pts;
1129 }
1130
1131 /* called to display each frame */
1132 static void video_refresh(void *opaque)
1133 {
1134     VideoState *is = opaque;
1135     VideoPicture *vp;
1136     double time;
1137
1138     SubPicture *sp, *sp2;
1139
1140     if (is->video_st) {
1141 retry:
1142         if (is->pictq_size == 0) {
1143             SDL_LockMutex(is->pictq_mutex);
1144             if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
1145                 update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos);
1146                 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1147             }
1148             SDL_UnlockMutex(is->pictq_mutex);
1149             // nothing to do, no picture to display in the que
1150         } else {
1151             double last_duration, duration, delay;
1152             /* dequeue the picture */
1153             vp = &is->pictq[is->pictq_rindex];
1154
1155             if (vp->skip) {
1156                 pictq_next_picture(is);
1157                 goto retry;
1158             }
1159
1160             if (is->paused)
1161                 goto display;
1162
1163             /* compute nominal last_duration */
1164             last_duration = vp->pts - is->frame_last_pts;
1165             if (last_duration > 0 && last_duration < 10.0) {
1166                 /* if duration of the last frame was sane, update last_duration in video state */
1167                 is->frame_last_duration = last_duration;
1168             }
1169             delay = compute_target_delay(is->frame_last_duration, is);
1170
1171             time= av_gettime()/1000000.0;
1172             if (time < is->frame_timer + delay)
1173                 return;
1174
1175             if (delay > 0)
1176                 is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
1177
1178             SDL_LockMutex(is->pictq_mutex);
1179             update_video_pts(is, vp->pts, vp->pos);
1180             SDL_UnlockMutex(is->pictq_mutex);
1181
1182             if (is->pictq_size > 1) {
1183                 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
1184                 duration = nextvp->pts - vp->pts; // More accurate this way, 1/time_base is often not reflecting FPS
1185             } else {
1186                 duration = vp->duration;
1187             }
1188
1189             if((framedrop>0 || (framedrop && is->audio_st)) && time > is->frame_timer + duration){
1190                 if(is->pictq_size > 1){
1191                     is->frame_drops_late++;
1192                     pictq_next_picture(is);
1193                     goto retry;
1194                 }
1195             }
1196
1197             if (is->subtitle_st) {
1198                 if (is->subtitle_stream_changed) {
1199                     SDL_LockMutex(is->subpq_mutex);
1200
1201                     while (is->subpq_size) {
1202                         free_subpicture(&is->subpq[is->subpq_rindex]);
1203
1204                         /* update queue size and signal for next picture */
1205                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1206                             is->subpq_rindex = 0;
1207
1208                         is->subpq_size--;
1209                     }
1210                     is->subtitle_stream_changed = 0;
1211
1212                     SDL_CondSignal(is->subpq_cond);
1213                     SDL_UnlockMutex(is->subpq_mutex);
1214                 } else {
1215                     if (is->subpq_size > 0) {
1216                         sp = &is->subpq[is->subpq_rindex];
1217
1218                         if (is->subpq_size > 1)
1219                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1220                         else
1221                             sp2 = NULL;
1222
1223                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1224                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1225                         {
1226                             free_subpicture(sp);
1227
1228                             /* update queue size and signal for next picture */
1229                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1230                                 is->subpq_rindex = 0;
1231
1232                             SDL_LockMutex(is->subpq_mutex);
1233                             is->subpq_size--;
1234                             SDL_CondSignal(is->subpq_cond);
1235                             SDL_UnlockMutex(is->subpq_mutex);
1236                         }
1237                     }
1238                 }
1239             }
1240
1241 display:
1242             /* display picture */
1243             if (!display_disable)
1244                 video_display(is);
1245
1246             if (!is->paused)
1247                 pictq_next_picture(is);
1248         }
1249     } else if (is->audio_st) {
1250         /* draw the next audio frame */
1251
1252         /* if only audio stream, then display the audio bars (better
1253            than nothing, just to test the implementation */
1254
1255         /* display picture */
1256         if (!display_disable)
1257             video_display(is);
1258     }
1259     is->force_refresh = 0;
1260     if (show_status) {
1261         static int64_t last_time;
1262         int64_t cur_time;
1263         int aqsize, vqsize, sqsize;
1264         double av_diff;
1265
1266         cur_time = av_gettime();
1267         if (!last_time || (cur_time - last_time) >= 30000) {
1268             aqsize = 0;
1269             vqsize = 0;
1270             sqsize = 0;
1271             if (is->audio_st)
1272                 aqsize = is->audioq.size;
1273             if (is->video_st)
1274                 vqsize = is->videoq.size;
1275             if (is->subtitle_st)
1276                 sqsize = is->subtitleq.size;
1277             av_diff = 0;
1278             if (is->audio_st && is->video_st)
1279                 av_diff = get_audio_clock(is) - get_video_clock(is);
1280             printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1281                    get_master_clock(is),
1282                    av_diff,
1283                    is->frame_drops_early + is->frame_drops_late,
1284                    aqsize / 1024,
1285                    vqsize / 1024,
1286                    sqsize,
1287                    is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1288                    is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1289             fflush(stdout);
1290             last_time = cur_time;
1291         }
1292     }
1293 }
1294
1295 /* allocate a picture (needs to do that in main thread to avoid
1296    potential locking problems */
1297 static void alloc_picture(void *opaque)
1298 {
1299     VideoState *is = opaque;
1300     VideoPicture *vp;
1301
1302     vp = &is->pictq[is->pictq_windex];
1303
1304     if (vp->bmp)
1305         SDL_FreeYUVOverlay(vp->bmp);
1306
1307 #if CONFIG_AVFILTER
1308     if (vp->picref)
1309         avfilter_unref_buffer(vp->picref);
1310     vp->picref = NULL;
1311
1312     vp->width   = is->out_video_filter->inputs[0]->w;
1313     vp->height  = is->out_video_filter->inputs[0]->h;
1314     vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1315 #else
1316     vp->width   = is->video_st->codec->width;
1317     vp->height  = is->video_st->codec->height;
1318     vp->pix_fmt = is->video_st->codec->pix_fmt;
1319 #endif
1320
1321     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1322                                    SDL_YV12_OVERLAY,
1323                                    screen);
1324     if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1325         /* SDL allocates a buffer smaller than requested if the video
1326          * overlay hardware is unable to support the requested size. */
1327         fprintf(stderr, "Error: the video system does not support an image\n"
1328                         "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1329                         "to reduce the image size.\n", vp->width, vp->height );
1330         do_exit(is);
1331     }
1332
1333     SDL_LockMutex(is->pictq_mutex);
1334     vp->allocated = 1;
1335     SDL_CondSignal(is->pictq_cond);
1336     SDL_UnlockMutex(is->pictq_mutex);
1337 }
1338
1339 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1340 {
1341     VideoPicture *vp;
1342     double frame_delay, pts = pts1;
1343
1344     /* compute the exact PTS for the picture if it is omitted in the stream
1345      * pts1 is the dts of the pkt / pts of the frame */
1346     if (pts != 0) {
1347         /* update video clock with pts, if present */
1348         is->video_clock = pts;
1349     } else {
1350         pts = is->video_clock;
1351     }
1352     /* update video clock for next frame */
1353     frame_delay = av_q2d(is->video_st->codec->time_base);
1354     /* for MPEG2, the frame can be repeated, so we update the
1355        clock accordingly */
1356     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1357     is->video_clock += frame_delay;
1358
1359 #if defined(DEBUG_SYNC) && 0
1360     printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1361            av_get_picture_type_char(src_frame->pict_type), pts, pts1);
1362 #endif
1363
1364     /* wait until we have space to put a new picture */
1365     SDL_LockMutex(is->pictq_mutex);
1366
1367     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1368            !is->videoq.abort_request) {
1369         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1370     }
1371     SDL_UnlockMutex(is->pictq_mutex);
1372
1373     if (is->videoq.abort_request)
1374         return -1;
1375
1376     vp = &is->pictq[is->pictq_windex];
1377
1378     vp->duration = frame_delay;
1379
1380     /* alloc or resize hardware picture buffer */
1381     if (!vp->bmp || vp->reallocate ||
1382 #if CONFIG_AVFILTER
1383         vp->width  != is->out_video_filter->inputs[0]->w ||
1384         vp->height != is->out_video_filter->inputs[0]->h) {
1385 #else
1386         vp->width != is->video_st->codec->width ||
1387         vp->height != is->video_st->codec->height) {
1388 #endif
1389         SDL_Event event;
1390
1391         vp->allocated  = 0;
1392         vp->reallocate = 0;
1393
1394         /* the allocation must be done in the main thread to avoid
1395            locking problems */
1396         event.type = FF_ALLOC_EVENT;
1397         event.user.data1 = is;
1398         SDL_PushEvent(&event);
1399
1400         /* wait until the picture is allocated */
1401         SDL_LockMutex(is->pictq_mutex);
1402         while (!vp->allocated && !is->videoq.abort_request) {
1403             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1404         }
1405         /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1406         if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1407             while (!vp->allocated) {
1408                 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1409             }
1410         }
1411         SDL_UnlockMutex(is->pictq_mutex);
1412
1413         if (is->videoq.abort_request)
1414             return -1;
1415     }
1416
1417     /* if the frame is not skipped, then display it */
1418     if (vp->bmp) {
1419         AVPicture pict;
1420 #if CONFIG_AVFILTER
1421         if (vp->picref)
1422             avfilter_unref_buffer(vp->picref);
1423         vp->picref = src_frame->opaque;
1424 #endif
1425
1426         /* get a pointer on the bitmap */
1427         SDL_LockYUVOverlay (vp->bmp);
1428
1429         memset(&pict, 0, sizeof(AVPicture));
1430         pict.data[0] = vp->bmp->pixels[0];
1431         pict.data[1] = vp->bmp->pixels[2];
1432         pict.data[2] = vp->bmp->pixels[1];
1433
1434         pict.linesize[0] = vp->bmp->pitches[0];
1435         pict.linesize[1] = vp->bmp->pitches[2];
1436         pict.linesize[2] = vp->bmp->pitches[1];
1437
1438 #if CONFIG_AVFILTER
1439         // FIXME use direct rendering
1440         av_picture_copy(&pict, (AVPicture *)src_frame,
1441                         vp->pix_fmt, vp->width, vp->height);
1442 #else
1443         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1444         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1445             vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
1446             PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1447         if (is->img_convert_ctx == NULL) {
1448             fprintf(stderr, "Cannot initialize the conversion context\n");
1449             exit(1);
1450         }
1451         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1452                   0, vp->height, pict.data, pict.linesize);
1453 #endif
1454         /* update the bitmap content */
1455         SDL_UnlockYUVOverlay(vp->bmp);
1456
1457         vp->pts = pts;
1458         vp->pos = pos;
1459         vp->skip = 0;
1460
1461         /* now we can update the picture count */
1462         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1463             is->pictq_windex = 0;
1464         SDL_LockMutex(is->pictq_mutex);
1465         is->pictq_size++;
1466         SDL_UnlockMutex(is->pictq_mutex);
1467     }
1468     return 0;
1469 }
1470
1471 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1472 {
1473     int got_picture, i;
1474
1475     if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1476         return -1;
1477
1478     if (pkt->data == flush_pkt.data) {
1479         avcodec_flush_buffers(is->video_st->codec);
1480
1481         SDL_LockMutex(is->pictq_mutex);
1482         // Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1483         for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1484             is->pictq[i].skip = 1;
1485         }
1486         while (is->pictq_size && !is->videoq.abort_request) {
1487             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1488         }
1489         is->video_current_pos = -1;
1490         is->frame_last_pts = AV_NOPTS_VALUE;
1491         is->frame_last_duration = 0;
1492         is->frame_timer = (double)av_gettime() / 1000000.0;
1493         is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1494         SDL_UnlockMutex(is->pictq_mutex);
1495
1496         return 0;
1497     }
1498
1499     avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt);
1500
1501     if (got_picture) {
1502         int ret = 1;
1503
1504         if (decoder_reorder_pts == -1) {
1505             *pts = *(int64_t*)av_opt_ptr(avcodec_get_frame_class(), frame, "best_effort_timestamp");
1506         } else if (decoder_reorder_pts) {
1507             *pts = frame->pkt_pts;
1508         } else {
1509             *pts = frame->pkt_dts;
1510         }
1511
1512         if (*pts == AV_NOPTS_VALUE) {
1513             *pts = 0;
1514         }
1515
1516         if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) || is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK) &&
1517              (framedrop>0 || (framedrop && is->audio_st))) {
1518             SDL_LockMutex(is->pictq_mutex);
1519             if (is->frame_last_pts != AV_NOPTS_VALUE && *pts) {
1520                 double clockdiff = get_video_clock(is) - get_master_clock(is);
1521                 double dpts = av_q2d(is->video_st->time_base) * *pts;
1522                 double ptsdiff = dpts - is->frame_last_pts;
1523                 if (fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
1524                      ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
1525                      clockdiff + ptsdiff - is->frame_last_filter_delay < 0) {
1526                     is->frame_last_dropped_pos = pkt->pos;
1527                     is->frame_last_dropped_pts = dpts;
1528                     is->frame_drops_early++;
1529                     ret = 0;
1530                 }
1531             }
1532             SDL_UnlockMutex(is->pictq_mutex);
1533         }
1534
1535         if (ret)
1536             is->frame_last_returned_time = av_gettime() / 1000000.0;
1537
1538         return ret;
1539     }
1540     return 0;
1541 }
1542
1543 #if CONFIG_AVFILTER
1544 typedef struct {
1545     VideoState *is;
1546     AVFrame *frame;
1547     int use_dr1;
1548 } FilterPriv;
1549
1550 static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
1551 {
1552     AVFilterContext *ctx = codec->opaque;
1553     AVFilterBufferRef  *ref;
1554     int perms = AV_PERM_WRITE;
1555     int i, w, h, stride[AV_NUM_DATA_POINTERS];
1556     unsigned edge;
1557     int pixel_size;
1558
1559     av_assert0(codec->flags & CODEC_FLAG_EMU_EDGE);
1560
1561     if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
1562         perms |= AV_PERM_NEG_LINESIZES;
1563
1564     if (pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
1565         if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
1566         if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
1567         if (pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
1568     }
1569     if (pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
1570
1571     w = codec->width;
1572     h = codec->height;
1573
1574     if(av_image_check_size(w, h, 0, codec) || codec->pix_fmt<0)
1575         return -1;
1576
1577     avcodec_align_dimensions2(codec, &w, &h, stride);
1578     edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
1579     w += edge << 1;
1580     h += edge << 1;
1581     if (codec->pix_fmt != ctx->outputs[0]->format) {
1582         av_log(codec, AV_LOG_ERROR, "Pixel format mismatches %d %d\n", codec->pix_fmt, ctx->outputs[0]->format);
1583         return -1;
1584     }
1585     if (!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
1586         return -1;
1587
1588     pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1 + 1;
1589     ref->video->w = codec->width;
1590     ref->video->h = codec->height;
1591     for (i = 0; i < 4; i ++) {
1592         unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
1593         unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
1594
1595         if (ref->data[i]) {
1596             ref->data[i]    += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
1597         }
1598         pic->data[i]     = ref->data[i];
1599         pic->linesize[i] = ref->linesize[i];
1600     }
1601     pic->opaque = ref;
1602     pic->type   = FF_BUFFER_TYPE_USER;
1603     pic->reordered_opaque = codec->reordered_opaque;
1604     if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1605     else            pic->pkt_pts = AV_NOPTS_VALUE;
1606     return 0;
1607 }
1608
1609 static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1610 {
1611     memset(pic->data, 0, sizeof(pic->data));
1612     avfilter_unref_buffer(pic->opaque);
1613 }
1614
1615 static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1616 {
1617     AVFilterBufferRef *ref = pic->opaque;
1618
1619     if (pic->data[0] == NULL) {
1620         pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1621         return codec->get_buffer(codec, pic);
1622     }
1623
1624     if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
1625         (codec->pix_fmt != ref->format)) {
1626         av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1627         return -1;
1628     }
1629
1630     pic->reordered_opaque = codec->reordered_opaque;
1631     if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1632     else            pic->pkt_pts = AV_NOPTS_VALUE;
1633     return 0;
1634 }
1635
1636 static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1637 {
1638     FilterPriv *priv = ctx->priv;
1639     AVCodecContext *codec;
1640     if (!opaque) return -1;
1641
1642     priv->is = opaque;
1643     codec    = priv->is->video_st->codec;
1644     codec->opaque = ctx;
1645     if (codec->codec->capabilities & CODEC_CAP_DR1) {
1646         av_assert0(codec->flags & CODEC_FLAG_EMU_EDGE);
1647         priv->use_dr1 = 1;
1648         codec->get_buffer     = input_get_buffer;
1649         codec->release_buffer = input_release_buffer;
1650         codec->reget_buffer   = input_reget_buffer;
1651         codec->thread_safe_callbacks = 1;
1652     }
1653
1654     priv->frame = avcodec_alloc_frame();
1655
1656     return 0;
1657 }
1658
1659 static void input_uninit(AVFilterContext *ctx)
1660 {
1661     FilterPriv *priv = ctx->priv;
1662     av_free(priv->frame);
1663 }
1664
1665 static int input_request_frame(AVFilterLink *link)
1666 {
1667     FilterPriv *priv = link->src->priv;
1668     AVFilterBufferRef *picref;
1669     int64_t pts = 0;
1670     AVPacket pkt;
1671     int ret;
1672
1673     while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1674         av_free_packet(&pkt);
1675     if (ret < 0)
1676         return -1;
1677
1678     if (priv->use_dr1 && priv->frame->opaque) {
1679         picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
1680     } else {
1681         picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1682         av_image_copy(picref->data, picref->linesize,
1683                       (const uint8_t **)(void **)priv->frame->data, priv->frame->linesize,
1684                       picref->format, link->w, link->h);
1685     }
1686     av_free_packet(&pkt);
1687
1688     avfilter_copy_frame_props(picref, priv->frame);
1689     picref->pts = pts;
1690
1691     avfilter_start_frame(link, picref);
1692     avfilter_draw_slice(link, 0, link->h, 1);
1693     avfilter_end_frame(link);
1694
1695     return 0;
1696 }
1697
1698 static int input_query_formats(AVFilterContext *ctx)
1699 {
1700     FilterPriv *priv = ctx->priv;
1701     enum PixelFormat pix_fmts[] = {
1702         priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1703     };
1704
1705     avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
1706     return 0;
1707 }
1708
1709 static int input_config_props(AVFilterLink *link)
1710 {
1711     FilterPriv *priv  = link->src->priv;
1712     AVStream *s = priv->is->video_st;
1713
1714     link->w = s->codec->width;
1715     link->h = s->codec->height;
1716     link->sample_aspect_ratio = s->sample_aspect_ratio.num ?
1717         s->sample_aspect_ratio : s->codec->sample_aspect_ratio;
1718     link->time_base = s->time_base;
1719
1720     return 0;
1721 }
1722
1723 static AVFilter input_filter =
1724 {
1725     .name      = "ffplay_input",
1726
1727     .priv_size = sizeof(FilterPriv),
1728
1729     .init      = input_init,
1730     .uninit    = input_uninit,
1731
1732     .query_formats = input_query_formats,
1733
1734     .inputs    = (AVFilterPad[]) {{ .name = NULL }},
1735     .outputs   = (AVFilterPad[]) {{ .name = "default",
1736                                     .type = AVMEDIA_TYPE_VIDEO,
1737                                     .request_frame = input_request_frame,
1738                                     .config_props  = input_config_props, },
1739                                   { .name = NULL }},
1740 };
1741
1742 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
1743 {
1744     char sws_flags_str[128];
1745     int ret;
1746     enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
1747     AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
1748     AVFilterContext *filt_src = NULL, *filt_out = NULL;
1749     snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1750     graph->scale_sws_opts = av_strdup(sws_flags_str);
1751
1752     if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
1753                                             NULL, is, graph)) < 0)
1754         return ret;
1755
1756 #if FF_API_OLD_VSINK_API
1757     ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
1758                                        NULL, pix_fmts, graph);
1759 #else
1760     buffersink_params->pixel_fmts = pix_fmts;
1761     ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
1762                                        NULL, buffersink_params, graph);
1763 #endif
1764     av_freep(&buffersink_params);
1765     if (ret < 0)
1766         return ret;
1767
1768     if (vfilters) {
1769         AVFilterInOut *outputs = avfilter_inout_alloc();
1770         AVFilterInOut *inputs  = avfilter_inout_alloc();
1771
1772         outputs->name    = av_strdup("in");
1773         outputs->filter_ctx = filt_src;
1774         outputs->pad_idx = 0;
1775         outputs->next    = NULL;
1776
1777         inputs->name    = av_strdup("out");
1778         inputs->filter_ctx = filt_out;
1779         inputs->pad_idx = 0;
1780         inputs->next    = NULL;
1781
1782         if ((ret = avfilter_graph_parse(graph, vfilters, &inputs, &outputs, NULL)) < 0)
1783             return ret;
1784     } else {
1785         if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
1786             return ret;
1787     }
1788
1789     if ((ret = avfilter_graph_config(graph, NULL)) < 0)
1790         return ret;
1791
1792     is->out_video_filter = filt_out;
1793
1794     return ret;
1795 }
1796
1797 #endif  /* CONFIG_AVFILTER */
1798
1799 static int video_thread(void *arg)
1800 {
1801     VideoState *is = arg;
1802     AVFrame *frame = avcodec_alloc_frame();
1803     int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
1804     double pts;
1805     int ret;
1806
1807 #if CONFIG_AVFILTER
1808     AVFilterGraph *graph = avfilter_graph_alloc();
1809     AVFilterContext *filt_out = NULL;
1810     int last_w = is->video_st->codec->width;
1811     int last_h = is->video_st->codec->height;
1812
1813     if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1814         goto the_end;
1815     filt_out = is->out_video_filter;
1816 #endif
1817
1818     for (;;) {
1819 #if !CONFIG_AVFILTER
1820         AVPacket pkt;
1821 #else
1822         AVFilterBufferRef *picref;
1823         AVRational tb = filt_out->inputs[0]->time_base;
1824 #endif
1825         while (is->paused && !is->videoq.abort_request)
1826             SDL_Delay(10);
1827 #if CONFIG_AVFILTER
1828         if (   last_w != is->video_st->codec->width
1829             || last_h != is->video_st->codec->height) {
1830             av_log(NULL, AV_LOG_INFO, "Frame changed from size:%dx%d to size:%dx%d\n",
1831                    last_w, last_h, is->video_st->codec->width, is->video_st->codec->height);
1832             avfilter_graph_free(&graph);
1833             graph = avfilter_graph_alloc();
1834             if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1835                 goto the_end;
1836             filt_out = is->out_video_filter;
1837             last_w = is->video_st->codec->width;
1838             last_h = is->video_st->codec->height;
1839         }
1840         ret = av_buffersink_get_buffer_ref(filt_out, &picref, 0);
1841         if (picref) {
1842             avfilter_fill_frame_from_video_buffer_ref(frame, picref);
1843             pts_int = picref->pts;
1844             pos     = picref->pos;
1845             frame->opaque = picref;
1846         }
1847
1848         if (av_cmp_q(tb, is->video_st->time_base)) {
1849             av_unused int64_t pts1 = pts_int;
1850             pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
1851             av_dlog(NULL, "video_thread(): "
1852                     "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
1853                     tb.num, tb.den, pts1,
1854                     is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1855         }
1856 #else
1857         ret = get_video_frame(is, frame, &pts_int, &pkt);
1858         pos = pkt.pos;
1859         av_free_packet(&pkt);
1860 #endif
1861
1862         if (ret < 0)
1863             goto the_end;
1864
1865         is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
1866         if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
1867             is->frame_last_filter_delay = 0;
1868
1869 #if CONFIG_AVFILTER
1870         if (!picref)
1871             continue;
1872 #endif
1873
1874         pts = pts_int * av_q2d(is->video_st->time_base);
1875
1876         ret = queue_picture(is, frame, pts, pos);
1877
1878         if (ret < 0)
1879             goto the_end;
1880
1881         if (is->step)
1882             stream_toggle_pause(is);
1883     }
1884  the_end:
1885 #if CONFIG_AVFILTER
1886     avfilter_graph_free(&graph);
1887 #endif
1888     av_free(frame);
1889     return 0;
1890 }
1891
1892 static int subtitle_thread(void *arg)
1893 {
1894     VideoState *is = arg;
1895     SubPicture *sp;
1896     AVPacket pkt1, *pkt = &pkt1;
1897     int got_subtitle;
1898     double pts;
1899     int i, j;
1900     int r, g, b, y, u, v, a;
1901
1902     for (;;) {
1903         while (is->paused && !is->subtitleq.abort_request) {
1904             SDL_Delay(10);
1905         }
1906         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1907             break;
1908
1909         if (pkt->data == flush_pkt.data) {
1910             avcodec_flush_buffers(is->subtitle_st->codec);
1911             continue;
1912         }
1913         SDL_LockMutex(is->subpq_mutex);
1914         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1915                !is->subtitleq.abort_request) {
1916             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1917         }
1918         SDL_UnlockMutex(is->subpq_mutex);
1919
1920         if (is->subtitleq.abort_request)
1921             return 0;
1922
1923         sp = &is->subpq[is->subpq_windex];
1924
1925        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1926            this packet, if any */
1927         pts = 0;
1928         if (pkt->pts != AV_NOPTS_VALUE)
1929             pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
1930
1931         avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
1932                                  &got_subtitle, pkt);
1933
1934         if (got_subtitle && sp->sub.format == 0) {
1935             sp->pts = pts;
1936
1937             for (i = 0; i < sp->sub.num_rects; i++)
1938             {
1939                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1940                 {
1941                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1942                     y = RGB_TO_Y_CCIR(r, g, b);
1943                     u = RGB_TO_U_CCIR(r, g, b, 0);
1944                     v = RGB_TO_V_CCIR(r, g, b, 0);
1945                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1946                 }
1947             }
1948
1949             /* now we can update the picture count */
1950             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1951                 is->subpq_windex = 0;
1952             SDL_LockMutex(is->subpq_mutex);
1953             is->subpq_size++;
1954             SDL_UnlockMutex(is->subpq_mutex);
1955         }
1956         av_free_packet(pkt);
1957     }
1958     return 0;
1959 }
1960
1961 /* copy samples for viewing in editor window */
1962 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1963 {
1964     int size, len;
1965
1966     size = samples_size / sizeof(short);
1967     while (size > 0) {
1968         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1969         if (len > size)
1970             len = size;
1971         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1972         samples += len;
1973         is->sample_array_index += len;
1974         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1975             is->sample_array_index = 0;
1976         size -= len;
1977     }
1978 }
1979
1980 /* return the wanted number of samples to get better sync if sync_type is video
1981  * or external master clock */
1982 static int synchronize_audio(VideoState *is, int nb_samples)
1983 {
1984     int wanted_nb_samples = nb_samples;
1985
1986     /* if not master, then we try to remove or add samples to correct the clock */
1987     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1988          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1989         double diff, avg_diff;
1990         int min_nb_samples, max_nb_samples;
1991
1992         diff = get_audio_clock(is) - get_master_clock(is);
1993
1994         if (diff < AV_NOSYNC_THRESHOLD) {
1995             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1996             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1997                 /* not enough measures to have a correct estimate */
1998                 is->audio_diff_avg_count++;
1999             } else {
2000                 /* estimate the A-V difference */
2001                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2002
2003                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2004                     wanted_nb_samples = nb_samples + (int)(diff * is->audio_src_freq);
2005                     min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2006                     max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2007                     wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2008                 }
2009                 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
2010                         diff, avg_diff, wanted_nb_samples - nb_samples,
2011                         is->audio_clock, is->video_clock, is->audio_diff_threshold);
2012             }
2013         } else {
2014             /* too big difference : may be initial PTS errors, so
2015                reset A-V filter */
2016             is->audio_diff_avg_count = 0;
2017             is->audio_diff_cum       = 0;
2018         }
2019     }
2020
2021     return wanted_nb_samples;
2022 }
2023
2024 /* decode one audio frame and returns its uncompressed size */
2025 static int audio_decode_frame(VideoState *is, double *pts_ptr)
2026 {
2027     AVPacket *pkt_temp = &is->audio_pkt_temp;
2028     AVPacket *pkt = &is->audio_pkt;
2029     AVCodecContext *dec = is->audio_st->codec;
2030     int len1, len2, data_size, resampled_data_size;
2031     int64_t dec_channel_layout;
2032     int got_frame;
2033     double pts;
2034     int new_packet = 0;
2035     int flush_complete = 0;
2036     int wanted_nb_samples;
2037
2038     for (;;) {
2039         /* NOTE: the audio packet can contain several frames */
2040         while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
2041             if (!is->frame) {
2042                 if (!(is->frame = avcodec_alloc_frame()))
2043                     return AVERROR(ENOMEM);
2044             } else
2045                 avcodec_get_frame_defaults(is->frame);
2046
2047             if (flush_complete)
2048                 break;
2049             new_packet = 0;
2050             len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2051             if (len1 < 0) {
2052                 /* if error, we skip the frame */
2053                 pkt_temp->size = 0;
2054                 break;
2055             }
2056
2057             pkt_temp->data += len1;
2058             pkt_temp->size -= len1;
2059
2060             if (!got_frame) {
2061                 /* stop sending empty packets if the decoder is finished */
2062                 if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2063                     flush_complete = 1;
2064                 continue;
2065             }
2066             data_size = av_samples_get_buffer_size(NULL, dec->channels,
2067                                                    is->frame->nb_samples,
2068                                                    dec->sample_fmt, 1);
2069
2070             dec_channel_layout = (dec->channel_layout && dec->channels == av_get_channel_layout_nb_channels(dec->channel_layout)) ? dec->channel_layout : av_get_default_channel_layout(dec->channels);
2071             wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2072
2073             if (dec->sample_fmt != is->audio_src_fmt ||
2074                 dec_channel_layout != is->audio_src_channel_layout ||
2075                 dec->sample_rate != is->audio_src_freq ||
2076                 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2077                 if (is->swr_ctx)
2078                     swr_free(&is->swr_ctx);
2079                 is->swr_ctx = swr_alloc_set_opts(NULL,
2080                                                  is->audio_tgt_channel_layout, is->audio_tgt_fmt, is->audio_tgt_freq,
2081                                                  dec_channel_layout,           dec->sample_fmt,   dec->sample_rate,
2082                                                  0, NULL);
2083                 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2084                     fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2085                         dec->sample_rate,
2086                         av_get_sample_fmt_name(dec->sample_fmt),
2087                         dec->channels,
2088                         is->audio_tgt_freq,
2089                         av_get_sample_fmt_name(is->audio_tgt_fmt),
2090                         is->audio_tgt_channels);
2091                     break;
2092                 }
2093                 is->audio_src_channel_layout = dec_channel_layout;
2094                 is->audio_src_channels = dec->channels;
2095                 is->audio_src_freq = dec->sample_rate;
2096                 is->audio_src_fmt = dec->sample_fmt;
2097             }
2098
2099             resampled_data_size = data_size;
2100             if (is->swr_ctx) {
2101                 const uint8_t *in[] = { is->frame->data[0] };
2102                 uint8_t *out[] = {is->audio_buf2};
2103                 if (wanted_nb_samples != is->frame->nb_samples) {
2104                     if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt_freq / dec->sample_rate,
2105                                                 wanted_nb_samples * is->audio_tgt_freq / dec->sample_rate) < 0) {
2106                         fprintf(stderr, "swr_set_compensation() failed\n");
2107                         break;
2108                     }
2109                 }
2110                 len2 = swr_convert(is->swr_ctx, out, sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt),
2111                                                 in, is->frame->nb_samples);
2112                 if (len2 < 0) {
2113                     fprintf(stderr, "audio_resample() failed\n");
2114                     break;
2115                 }
2116                 if (len2 == sizeof(is->audio_buf2) / is->audio_tgt_channels / av_get_bytes_per_sample(is->audio_tgt_fmt)) {
2117                     fprintf(stderr, "warning: audio buffer is probably too small\n");
2118                     swr_init(is->swr_ctx);
2119                 }
2120                 is->audio_buf = is->audio_buf2;
2121                 resampled_data_size = len2 * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt);
2122             } else {
2123                 is->audio_buf = is->frame->data[0];
2124             }
2125
2126             /* if no pts, then compute it */
2127             pts = is->audio_clock;
2128             *pts_ptr = pts;
2129             is->audio_clock += (double)data_size / (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));
2130 #ifdef DEBUG
2131             {
2132                 static double last_clock;
2133                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2134                        is->audio_clock - last_clock,
2135                        is->audio_clock, pts);
2136                 last_clock = is->audio_clock;
2137             }
2138 #endif
2139             return resampled_data_size;
2140         }
2141
2142         /* free the current packet */
2143         if (pkt->data)
2144             av_free_packet(pkt);
2145         memset(pkt_temp, 0, sizeof(*pkt_temp));
2146
2147         if (is->paused || is->audioq.abort_request) {
2148             return -1;
2149         }
2150
2151         /* read next packet */
2152         if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
2153             return -1;
2154
2155         if (pkt->data == flush_pkt.data) {
2156             avcodec_flush_buffers(dec);
2157             flush_complete = 0;
2158         }
2159
2160         *pkt_temp = *pkt;
2161
2162         /* if update the audio clock with the pts */
2163         if (pkt->pts != AV_NOPTS_VALUE) {
2164             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2165         }
2166     }
2167 }
2168
2169 /* prepare a new audio buffer */
2170 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2171 {
2172     VideoState *is = opaque;
2173     int audio_size, len1;
2174     int bytes_per_sec;
2175     int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt_channels, 1, is->audio_tgt_fmt, 1);
2176     double pts;
2177
2178     audio_callback_time = av_gettime();
2179
2180     while (len > 0) {
2181         if (is->audio_buf_index >= is->audio_buf_size) {
2182            audio_size = audio_decode_frame(is, &pts);
2183            if (audio_size < 0) {
2184                 /* if error, just output silence */
2185                is->audio_buf      = is->silence_buf;
2186                is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
2187            } else {
2188                if (is->show_mode != SHOW_MODE_VIDEO)
2189                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2190                is->audio_buf_size = audio_size;
2191            }
2192            is->audio_buf_index = 0;
2193         }
2194         len1 = is->audio_buf_size - is->audio_buf_index;
2195         if (len1 > len)
2196             len1 = len;
2197         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2198         len -= len1;
2199         stream += len1;
2200         is->audio_buf_index += len1;
2201     }
2202     bytes_per_sec = is->audio_tgt_freq * is->audio_tgt_channels * av_get_bytes_per_sample(is->audio_tgt_fmt);
2203     is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2204     /* Let's assume the audio driver that is used by SDL has two periods. */
2205     is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
2206     is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
2207 }
2208
2209 /* open a given stream. Return 0 if OK */
2210 static int stream_component_open(VideoState *is, int stream_index)
2211 {
2212     AVFormatContext *ic = is->ic;
2213     AVCodecContext *avctx;
2214     AVCodec *codec;
2215     SDL_AudioSpec wanted_spec, spec;
2216     AVDictionary *opts;
2217     AVDictionaryEntry *t = NULL;
2218     int64_t wanted_channel_layout = 0;
2219     int wanted_nb_channels;
2220     const char *env;
2221
2222     if (stream_index < 0 || stream_index >= ic->nb_streams)
2223         return -1;
2224     avctx = ic->streams[stream_index]->codec;
2225
2226     codec = avcodec_find_decoder(avctx->codec_id);
2227     opts = filter_codec_opts(codec_opts, codec, ic, ic->streams[stream_index]);
2228
2229     switch(avctx->codec_type){
2230         case AVMEDIA_TYPE_AUDIO   : if(audio_codec_name   ) codec= avcodec_find_decoder_by_name(   audio_codec_name); break;
2231         case AVMEDIA_TYPE_SUBTITLE: if(subtitle_codec_name) codec= avcodec_find_decoder_by_name(subtitle_codec_name); break;
2232         case AVMEDIA_TYPE_VIDEO   : if(video_codec_name   ) codec= avcodec_find_decoder_by_name(   video_codec_name); break;
2233     }
2234     if (!codec)
2235         return -1;
2236
2237     avctx->workaround_bugs   = workaround_bugs;
2238     avctx->lowres            = lowres;
2239     if(avctx->lowres > codec->max_lowres){
2240         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2241                 codec->max_lowres);
2242         avctx->lowres= codec->max_lowres;
2243     }
2244     avctx->idct_algo         = idct;
2245     avctx->skip_frame        = skip_frame;
2246     avctx->skip_idct         = skip_idct;
2247     avctx->skip_loop_filter  = skip_loop_filter;
2248     avctx->error_concealment = error_concealment;
2249
2250     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2251     if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
2252     if(codec->capabilities & CODEC_CAP_DR1)
2253         avctx->flags |= CODEC_FLAG_EMU_EDGE;
2254
2255     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2256         memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2257         env = SDL_getenv("SDL_AUDIO_CHANNELS");
2258         if (env)
2259             wanted_channel_layout = av_get_default_channel_layout(SDL_atoi(env));
2260         if (!wanted_channel_layout) {
2261             wanted_channel_layout = (avctx->channel_layout && avctx->channels == av_get_channel_layout_nb_channels(avctx->channel_layout)) ? avctx->channel_layout : av_get_default_channel_layout(avctx->channels);
2262             wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2263             wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2264             /* SDL only supports 1, 2, 4 or 6 channels at the moment, so we have to make sure not to request anything else. */
2265             while (wanted_nb_channels > 0 && (wanted_nb_channels == 3 || wanted_nb_channels == 5 || wanted_nb_channels > 6)) {
2266                 wanted_nb_channels--;
2267                 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2268             }
2269         }
2270         wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2271         wanted_spec.freq = avctx->sample_rate;
2272         if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2273             fprintf(stderr, "Invalid sample rate or channel count!\n");
2274             return -1;
2275         }
2276     }
2277
2278     if (!av_dict_get(opts, "threads", NULL, 0))
2279         av_dict_set(&opts, "threads", "auto", 0);
2280     if (!codec ||
2281         avcodec_open2(avctx, codec, &opts) < 0)
2282         return -1;
2283     if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2284         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2285         return AVERROR_OPTION_NOT_FOUND;
2286     }
2287
2288     /* prepare audio output */
2289     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2290         wanted_spec.format = AUDIO_S16SYS;
2291         wanted_spec.silence = 0;
2292         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2293         wanted_spec.callback = sdl_audio_callback;
2294         wanted_spec.userdata = is;
2295         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2296             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2297             return -1;
2298         }
2299         is->audio_hw_buf_size = spec.size;
2300         if (spec.format != AUDIO_S16SYS) {
2301             fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
2302             return -1;
2303         }
2304         if (spec.channels != wanted_spec.channels) {
2305             wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2306             if (!wanted_channel_layout) {
2307                 fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
2308                 return -1;
2309             }
2310         }
2311         is->audio_src_fmt = is->audio_tgt_fmt = AV_SAMPLE_FMT_S16;
2312         is->audio_src_freq = is->audio_tgt_freq = spec.freq;
2313         is->audio_src_channel_layout = is->audio_tgt_channel_layout = wanted_channel_layout;
2314         is->audio_src_channels = is->audio_tgt_channels = spec.channels;
2315     }
2316
2317     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2318     switch (avctx->codec_type) {
2319     case AVMEDIA_TYPE_AUDIO:
2320         is->audio_stream = stream_index;
2321         is->audio_st = ic->streams[stream_index];
2322         is->audio_buf_size  = 0;
2323         is->audio_buf_index = 0;
2324
2325         /* init averaging filter */
2326         is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2327         is->audio_diff_avg_count = 0;
2328         /* since we do not have a precise anough audio fifo fullness,
2329            we correct audio sync only if larger than this threshold */
2330         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / wanted_spec.freq;
2331
2332         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2333         packet_queue_init(&is->audioq);
2334         SDL_PauseAudio(0);
2335         break;
2336     case AVMEDIA_TYPE_VIDEO:
2337         is->video_stream = stream_index;
2338         is->video_st = ic->streams[stream_index];
2339
2340         packet_queue_init(&is->videoq);
2341         is->video_tid = SDL_CreateThread(video_thread, is);
2342         break;
2343     case AVMEDIA_TYPE_SUBTITLE:
2344         is->subtitle_stream = stream_index;
2345         is->subtitle_st = ic->streams[stream_index];
2346         packet_queue_init(&is->subtitleq);
2347
2348         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2349         break;
2350     default:
2351         break;
2352     }
2353     return 0;
2354 }
2355
2356 static void stream_component_close(VideoState *is, int stream_index)
2357 {
2358     AVFormatContext *ic = is->ic;
2359     AVCodecContext *avctx;
2360
2361     if (stream_index < 0 || stream_index >= ic->nb_streams)
2362         return;
2363     avctx = ic->streams[stream_index]->codec;
2364
2365     switch (avctx->codec_type) {
2366     case AVMEDIA_TYPE_AUDIO:
2367         packet_queue_abort(&is->audioq);
2368
2369         SDL_CloseAudio();
2370
2371         packet_queue_end(&is->audioq);
2372         if (is->swr_ctx)
2373             swr_free(&is->swr_ctx);
2374         av_free_packet(&is->audio_pkt);
2375         av_freep(&is->audio_buf1);
2376         is->audio_buf = NULL;
2377         av_freep(&is->frame);
2378
2379         if (is->rdft) {
2380             av_rdft_end(is->rdft);
2381             av_freep(&is->rdft_data);
2382             is->rdft = NULL;
2383             is->rdft_bits = 0;
2384         }
2385         break;
2386     case AVMEDIA_TYPE_VIDEO:
2387         packet_queue_abort(&is->videoq);
2388
2389         /* note: we also signal this mutex to make sure we deblock the
2390            video thread in all cases */
2391         SDL_LockMutex(is->pictq_mutex);
2392         SDL_CondSignal(is->pictq_cond);
2393         SDL_UnlockMutex(is->pictq_mutex);
2394
2395         SDL_WaitThread(is->video_tid, NULL);
2396
2397         packet_queue_end(&is->videoq);
2398         break;
2399     case AVMEDIA_TYPE_SUBTITLE:
2400         packet_queue_abort(&is->subtitleq);
2401
2402         /* note: we also signal this mutex to make sure we deblock the
2403            video thread in all cases */
2404         SDL_LockMutex(is->subpq_mutex);
2405         is->subtitle_stream_changed = 1;
2406
2407         SDL_CondSignal(is->subpq_cond);
2408         SDL_UnlockMutex(is->subpq_mutex);
2409
2410         SDL_WaitThread(is->subtitle_tid, NULL);
2411
2412         packet_queue_end(&is->subtitleq);
2413         break;
2414     default:
2415         break;
2416     }
2417
2418     ic->streams[stream_index]->discard = AVDISCARD_ALL;
2419     avcodec_close(avctx);
2420     switch (avctx->codec_type) {
2421     case AVMEDIA_TYPE_AUDIO:
2422         is->audio_st = NULL;
2423         is->audio_stream = -1;
2424         break;
2425     case AVMEDIA_TYPE_VIDEO:
2426         is->video_st = NULL;
2427         is->video_stream = -1;
2428         break;
2429     case AVMEDIA_TYPE_SUBTITLE:
2430         is->subtitle_st = NULL;
2431         is->subtitle_stream = -1;
2432         break;
2433     default:
2434         break;
2435     }
2436 }
2437
2438 static int decode_interrupt_cb(void *ctx)
2439 {
2440     VideoState *is = ctx;
2441     return is->abort_request;
2442 }
2443
2444 /* this thread gets the stream from the disk or the network */
2445 static int read_thread(void *arg)
2446 {
2447     VideoState *is = arg;
2448     AVFormatContext *ic = NULL;
2449     int err, i, ret;
2450     int st_index[AVMEDIA_TYPE_NB];
2451     AVPacket pkt1, *pkt = &pkt1;
2452     int eof = 0;
2453     int pkt_in_play_range = 0;
2454     AVDictionaryEntry *t;
2455     AVDictionary **opts;
2456     int orig_nb_streams;
2457
2458     memset(st_index, -1, sizeof(st_index));
2459     is->video_stream = -1;
2460     is->audio_stream = -1;
2461     is->subtitle_stream = -1;
2462
2463     ic = avformat_alloc_context();
2464     ic->interrupt_callback.callback = decode_interrupt_cb;
2465     ic->interrupt_callback.opaque = is;
2466     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2467     if (err < 0) {
2468         print_error(is->filename, err);
2469         ret = -1;
2470         goto fail;
2471     }
2472     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2473         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2474         ret = AVERROR_OPTION_NOT_FOUND;
2475         goto fail;
2476     }
2477     is->ic = ic;
2478
2479     if (genpts)
2480         ic->flags |= AVFMT_FLAG_GENPTS;
2481
2482     opts = setup_find_stream_info_opts(ic, codec_opts);
2483     orig_nb_streams = ic->nb_streams;
2484
2485     err = avformat_find_stream_info(ic, opts);
2486     if (err < 0) {
2487         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2488         ret = -1;
2489         goto fail;
2490     }
2491     for (i = 0; i < orig_nb_streams; i++)
2492         av_dict_free(&opts[i]);
2493     av_freep(&opts);
2494
2495     if (ic->pb)
2496         ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2497
2498     if (seek_by_bytes < 0)
2499         seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2500
2501     /* if seeking requested, we execute it */
2502     if (start_time != AV_NOPTS_VALUE) {
2503         int64_t timestamp;
2504
2505         timestamp = start_time;
2506         /* add the stream start time */
2507         if (ic->start_time != AV_NOPTS_VALUE)
2508             timestamp += ic->start_time;
2509         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2510         if (ret < 0) {
2511             fprintf(stderr, "%s: could not seek to position %0.3f\n",
2512                     is->filename, (double)timestamp / AV_TIME_BASE);
2513         }
2514     }
2515
2516     for (i = 0; i < ic->nb_streams; i++)
2517         ic->streams[i]->discard = AVDISCARD_ALL;
2518     if (!video_disable)
2519         st_index[AVMEDIA_TYPE_VIDEO] =
2520             av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2521                                 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2522     if (!audio_disable)
2523         st_index[AVMEDIA_TYPE_AUDIO] =
2524             av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2525                                 wanted_stream[AVMEDIA_TYPE_AUDIO],
2526                                 st_index[AVMEDIA_TYPE_VIDEO],
2527                                 NULL, 0);
2528     if (!video_disable)
2529         st_index[AVMEDIA_TYPE_SUBTITLE] =
2530             av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2531                                 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2532                                 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2533                                  st_index[AVMEDIA_TYPE_AUDIO] :
2534                                  st_index[AVMEDIA_TYPE_VIDEO]),
2535                                 NULL, 0);
2536     if (show_status) {
2537         av_dump_format(ic, 0, is->filename, 0);
2538     }
2539
2540     is->show_mode = show_mode;
2541
2542     /* open the streams */
2543     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2544         stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2545     }
2546
2547     ret = -1;
2548     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2549         ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2550     }
2551     is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2552     if (is->show_mode == SHOW_MODE_NONE)
2553         is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2554
2555     if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2556         stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2557     }
2558
2559     if (is->video_stream < 0 && is->audio_stream < 0) {
2560         fprintf(stderr, "%s: could not open codecs\n", is->filename);
2561         ret = -1;
2562         goto fail;
2563     }
2564
2565     for (;;) {
2566         if (is->abort_request)
2567             break;
2568         if (is->paused != is->last_paused) {
2569             is->last_paused = is->paused;
2570             if (is->paused)
2571                 is->read_pause_return = av_read_pause(ic);
2572             else
2573                 av_read_play(ic);
2574         }
2575 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2576         if (is->paused &&
2577                 (!strcmp(ic->iformat->name, "rtsp") ||
2578                  (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2579             /* wait 10 ms to avoid trying to get another packet */
2580             /* XXX: horrible */
2581             SDL_Delay(10);
2582             continue;
2583         }
2584 #endif
2585         if (is->seek_req) {
2586             int64_t seek_target = is->seek_pos;
2587             int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2588             int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2589 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2590 //      of the seek_pos/seek_rel variables
2591
2592             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2593             if (ret < 0) {
2594                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2595             } else {
2596                 if (is->audio_stream >= 0) {
2597                     packet_queue_flush(&is->audioq);
2598                     packet_queue_put(&is->audioq, &flush_pkt);
2599                 }
2600                 if (is->subtitle_stream >= 0) {
2601                     packet_queue_flush(&is->subtitleq);
2602                     packet_queue_put(&is->subtitleq, &flush_pkt);
2603                 }
2604                 if (is->video_stream >= 0) {
2605                     packet_queue_flush(&is->videoq);
2606                     packet_queue_put(&is->videoq, &flush_pkt);
2607                 }
2608             }
2609             is->seek_req = 0;
2610             eof = 0;
2611         }
2612
2613         /* if the queue are full, no need to read more */
2614         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2615             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
2616                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0)
2617                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
2618             /* wait 10 ms */
2619             SDL_Delay(10);
2620             continue;
2621         }
2622         if (eof) {
2623             if (is->video_stream >= 0) {
2624                 av_init_packet(pkt);
2625                 pkt->data = NULL;
2626                 pkt->size = 0;
2627                 pkt->stream_index = is->video_stream;
2628                 packet_queue_put(&is->videoq, pkt);
2629             }
2630             if (is->audio_stream >= 0 &&
2631                 is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
2632                 av_init_packet(pkt);
2633                 pkt->data = NULL;
2634                 pkt->size = 0;
2635                 pkt->stream_index = is->audio_stream;
2636                 packet_queue_put(&is->audioq, pkt);
2637             }
2638             SDL_Delay(10);
2639             if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
2640                 if (loop != 1 && (!loop || --loop)) {
2641                     stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2642                 } else if (autoexit) {
2643                     ret = AVERROR_EOF;
2644                     goto fail;
2645                 }
2646             }
2647             eof=0;
2648             continue;
2649         }
2650         ret = av_read_frame(ic, pkt);
2651         if (ret < 0) {
2652             if (ret == AVERROR_EOF || url_feof(ic->pb))
2653                 eof = 1;
2654             if (ic->pb && ic->pb->error)
2655                 break;
2656             SDL_Delay(100); /* wait for user event */
2657             continue;
2658         }
2659         /* check if packet is in play range specified by user, then queue, otherwise discard */
2660         pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2661                 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2662                 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2663                 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2664                 <= ((double)duration / 1000000);
2665         if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2666             packet_queue_put(&is->audioq, pkt);
2667         } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
2668             packet_queue_put(&is->videoq, pkt);
2669         } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2670             packet_queue_put(&is->subtitleq, pkt);
2671         } else {
2672             av_free_packet(pkt);
2673         }
2674     }
2675     /* wait until the end */
2676     while (!is->abort_request) {
2677         SDL_Delay(100);
2678     }
2679
2680     ret = 0;
2681  fail:
2682     /* close each stream */
2683     if (is->audio_stream >= 0)
2684         stream_component_close(is, is->audio_stream);
2685     if (is->video_stream >= 0)
2686         stream_component_close(is, is->video_stream);
2687     if (is->subtitle_stream >= 0)
2688         stream_component_close(is, is->subtitle_stream);
2689     if (is->ic) {
2690         avformat_close_input(&is->ic);
2691     }
2692
2693     if (ret != 0) {
2694         SDL_Event event;
2695
2696         event.type = FF_QUIT_EVENT;
2697         event.user.data1 = is;
2698         SDL_PushEvent(&event);
2699     }
2700     return 0;
2701 }
2702
2703 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2704 {
2705     VideoState *is;
2706
2707     is = av_mallocz(sizeof(VideoState));
2708     if (!is)
2709         return NULL;
2710     av_strlcpy(is->filename, filename, sizeof(is->filename));
2711     is->iformat = iformat;
2712     is->ytop    = 0;
2713     is->xleft   = 0;
2714
2715     /* start video display */
2716     is->pictq_mutex = SDL_CreateMutex();
2717     is->pictq_cond  = SDL_CreateCond();
2718
2719     is->subpq_mutex = SDL_CreateMutex();
2720     is->subpq_cond  = SDL_CreateCond();
2721
2722     is->av_sync_type = av_sync_type;
2723     is->read_tid     = SDL_CreateThread(read_thread, is);
2724     if (!is->read_tid) {
2725         av_free(is);
2726         return NULL;
2727     }
2728     return is;
2729 }
2730
2731 static void stream_cycle_channel(VideoState *is, int codec_type)
2732 {
2733     AVFormatContext *ic = is->ic;
2734     int start_index, stream_index;
2735     AVStream *st;
2736
2737     if (codec_type == AVMEDIA_TYPE_VIDEO)
2738         start_index = is->video_stream;
2739     else if (codec_type == AVMEDIA_TYPE_AUDIO)
2740         start_index = is->audio_stream;
2741     else
2742         start_index = is->subtitle_stream;
2743     if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
2744         return;
2745     stream_index = start_index;
2746     for (;;) {
2747         if (++stream_index >= is->ic->nb_streams)
2748         {
2749             if (codec_type == AVMEDIA_TYPE_SUBTITLE)
2750             {
2751                 stream_index = -1;
2752                 goto the_end;
2753             } else
2754                 stream_index = 0;
2755         }
2756         if (stream_index == start_index)
2757             return;
2758         st = ic->streams[stream_index];
2759         if (st->codec->codec_type == codec_type) {
2760             /* check that parameters are OK */
2761             switch (codec_type) {
2762             case AVMEDIA_TYPE_AUDIO:
2763                 if (st->codec->sample_rate != 0 &&
2764                     st->codec->channels != 0)
2765                     goto the_end;
2766                 break;
2767             case AVMEDIA_TYPE_VIDEO:
2768             case AVMEDIA_TYPE_SUBTITLE:
2769                 goto the_end;
2770             default:
2771                 break;
2772             }
2773         }
2774     }
2775  the_end:
2776     stream_component_close(is, start_index);
2777     stream_component_open(is, stream_index);
2778 }
2779
2780
2781 static void toggle_full_screen(VideoState *is)
2782 {
2783     av_unused int i;
2784     is_full_screen = !is_full_screen;
2785 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
2786     /* OS X needs to reallocate the SDL overlays */
2787     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
2788         is->pictq[i].reallocate = 1;
2789     }
2790 #endif
2791     video_open(is, 1);
2792 }
2793
2794 static void toggle_pause(VideoState *is)
2795 {
2796     stream_toggle_pause(is);
2797     is->step = 0;
2798 }
2799
2800 static void step_to_next_frame(VideoState *is)
2801 {
2802     /* if the stream is paused unpause it, then step */
2803     if (is->paused)
2804         stream_toggle_pause(is);
2805     is->step = 1;
2806 }
2807
2808 static void toggle_audio_display(VideoState *is)
2809 {
2810     int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2811     is->show_mode = (is->show_mode + 1) % SHOW_MODE_NB;
2812     fill_rectangle(screen,
2813                 is->xleft, is->ytop, is->width, is->height,
2814                 bgcolor);
2815     SDL_UpdateRect(screen, is->xleft, is->ytop, is->width, is->height);
2816 }
2817
2818 /* handle an event sent by the GUI */
2819 static void event_loop(VideoState *cur_stream)
2820 {
2821     SDL_Event event;
2822     double incr, pos, frac;
2823
2824     for (;;) {
2825         double x;
2826         SDL_WaitEvent(&event);
2827         switch (event.type) {
2828         case SDL_KEYDOWN:
2829             if (exit_on_keydown) {
2830                 do_exit(cur_stream);
2831                 break;
2832             }
2833             switch (event.key.keysym.sym) {
2834             case SDLK_ESCAPE:
2835             case SDLK_q:
2836                 do_exit(cur_stream);
2837                 break;
2838             case SDLK_f:
2839                 toggle_full_screen(cur_stream);
2840                 cur_stream->force_refresh = 1;
2841                 break;
2842             case SDLK_p:
2843             case SDLK_SPACE:
2844                 toggle_pause(cur_stream);
2845                 break;
2846             case SDLK_s: // S: Step to next frame
2847                 step_to_next_frame(cur_stream);
2848                 break;
2849             case SDLK_a:
2850                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
2851                 break;
2852             case SDLK_v:
2853                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
2854                 break;
2855             case SDLK_t:
2856                 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
2857                 break;
2858             case SDLK_w:
2859                 toggle_audio_display(cur_stream);
2860                 cur_stream->force_refresh = 1;
2861                 break;
2862             case SDLK_PAGEUP:
2863                 incr = 600.0;
2864                 goto do_seek;
2865             case SDLK_PAGEDOWN:
2866                 incr = -600.0;
2867                 goto do_seek;
2868             case SDLK_LEFT:
2869                 incr = -10.0;
2870                 goto do_seek;
2871             case SDLK_RIGHT:
2872                 incr = 10.0;
2873                 goto do_seek;
2874             case SDLK_UP:
2875                 incr = 60.0;
2876                 goto do_seek;
2877             case SDLK_DOWN:
2878                 incr = -60.0;
2879             do_seek:
2880                     if (seek_by_bytes) {
2881                         if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
2882                             pos = cur_stream->video_current_pos;
2883                         } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
2884                             pos = cur_stream->audio_pkt.pos;
2885                         } else
2886                             pos = avio_tell(cur_stream->ic->pb);
2887                         if (cur_stream->ic->bit_rate)
2888                             incr *= cur_stream->ic->bit_rate / 8.0;
2889                         else
2890                             incr *= 180000.0;
2891                         pos += incr;
2892                         stream_seek(cur_stream, pos, incr, 1);
2893                     } else {
2894                         pos = get_master_clock(cur_stream);
2895                         pos += incr;
2896                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2897                     }
2898                 break;
2899             default:
2900                 break;
2901             }
2902             break;
2903         case SDL_VIDEOEXPOSE:
2904             cur_stream->force_refresh = 1;
2905             break;
2906         case SDL_MOUSEBUTTONDOWN:
2907             if (exit_on_mousedown) {
2908                 do_exit(cur_stream);
2909                 break;
2910             }
2911         case SDL_MOUSEMOTION:
2912             if (event.type == SDL_MOUSEBUTTONDOWN) {
2913                 x = event.button.x;
2914             } else {
2915                 if (event.motion.state != SDL_PRESSED)
2916                     break;
2917                 x = event.motion.x;
2918             }
2919                 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
2920                     uint64_t size =  avio_size(cur_stream->ic->pb);
2921                     stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2922                 } else {
2923                     int64_t ts;
2924                     int ns, hh, mm, ss;
2925                     int tns, thh, tmm, tss;
2926                     tns  = cur_stream->ic->duration / 1000000LL;
2927                     thh  = tns / 3600;
2928                     tmm  = (tns % 3600) / 60;
2929                     tss  = (tns % 60);
2930                     frac = x / cur_stream->width;
2931                     ns   = frac * tns;
2932                     hh   = ns / 3600;
2933                     mm   = (ns % 3600) / 60;
2934                     ss   = (ns % 60);
2935                     fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2936                             hh, mm, ss, thh, tmm, tss);
2937                     ts = frac * cur_stream->ic->duration;
2938                     if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2939                         ts += cur_stream->ic->start_time;
2940                     stream_seek(cur_stream, ts, 0, 0);
2941                 }
2942             break;
2943         case SDL_VIDEORESIZE:
2944                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2945                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2946                 screen_width  = cur_stream->width  = event.resize.w;
2947                 screen_height = cur_stream->height = event.resize.h;
2948                 cur_stream->force_refresh = 1;
2949             break;
2950         case SDL_QUIT:
2951         case FF_QUIT_EVENT:
2952             do_exit(cur_stream);
2953             break;
2954         case FF_ALLOC_EVENT:
2955             video_open(event.user.data1, 0);
2956             alloc_picture(event.user.data1);
2957             break;
2958         case FF_REFRESH_EVENT:
2959             video_refresh(event.user.data1);
2960             cur_stream->refresh = 0;
2961             break;
2962         default:
2963             break;
2964         }
2965     }
2966 }
2967
2968 static int opt_frame_size(const char *opt, const char *arg)
2969 {
2970     av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
2971     return opt_default("video_size", arg);
2972 }
2973
2974 static int opt_width(const char *opt, const char *arg)
2975 {
2976     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2977     return 0;
2978 }
2979
2980 static int opt_height(const char *opt, const char *arg)
2981 {
2982     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2983     return 0;
2984 }
2985
2986 static int opt_format(const char *opt, const char *arg)
2987 {
2988     file_iformat = av_find_input_format(arg);
2989     if (!file_iformat) {
2990         fprintf(stderr, "Unknown input format: %s\n", arg);
2991         return AVERROR(EINVAL);
2992     }
2993     return 0;
2994 }
2995
2996 static int opt_frame_pix_fmt(const char *opt, const char *arg)
2997 {
2998     av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
2999     return opt_default("pixel_format", arg);
3000 }
3001
3002 static int opt_sync(const char *opt, const char *arg)
3003 {
3004     if (!strcmp(arg, "audio"))
3005         av_sync_type = AV_SYNC_AUDIO_MASTER;
3006     else if (!strcmp(arg, "video"))
3007         av_sync_type = AV_SYNC_VIDEO_MASTER;
3008     else if (!strcmp(arg, "ext"))
3009         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3010     else {
3011         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
3012         exit(1);
3013     }
3014     return 0;
3015 }
3016
3017 static int opt_seek(const char *opt, const char *arg)
3018 {
3019     start_time = parse_time_or_die(opt, arg, 1);
3020     return 0;
3021 }
3022
3023 static int opt_duration(const char *opt, const char *arg)
3024 {
3025     duration = parse_time_or_die(opt, arg, 1);
3026     return 0;
3027 }
3028
3029 static int opt_show_mode(const char *opt, const char *arg)
3030 {
3031     show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3032                 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3033                 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT  :
3034                 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3035     return 0;
3036 }
3037
3038 static void opt_input_file(void *optctx, const char *filename)
3039 {
3040     if (input_filename) {
3041         fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3042                 filename, input_filename);
3043         exit_program(1);
3044     }
3045     if (!strcmp(filename, "-"))
3046         filename = "pipe:";
3047     input_filename = filename;
3048 }
3049
3050 static int opt_codec(void *o, const char *opt, const char *arg)
3051 {
3052     switch(opt[strlen(opt)-1]){
3053     case 'a' :    audio_codec_name = arg; break;
3054     case 's' : subtitle_codec_name = arg; break;
3055     case 'v' :    video_codec_name = arg; break;
3056     }
3057     return 0;
3058 }
3059
3060 static int dummy;
3061
3062 static const OptionDef options[] = {
3063 #include "cmdutils_common_opts.h"
3064     { "x", HAS_ARG, { (void*)opt_width }, "force displayed width", "width" },
3065     { "y", HAS_ARG, { (void*)opt_height }, "force displayed height", "height" },
3066     { "s", HAS_ARG | OPT_VIDEO, { (void*)opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3067     { "fs", OPT_BOOL, { (void*)&is_full_screen }, "force full screen" },
3068     { "an", OPT_BOOL, { (void*)&audio_disable }, "disable audio" },
3069     { "vn", OPT_BOOL, { (void*)&video_disable }, "disable video" },
3070     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3071     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3072     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3073     { "ss", HAS_ARG, { (void*)&opt_seek }, "seek to a given position in seconds", "pos" },
3074     { "t", HAS_ARG, { (void*)&opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
3075     { "bytes", OPT_INT | HAS_ARG, { (void*)&seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3076     { "nodisp", OPT_BOOL, { (void*)&display_disable }, "disable graphical display" },
3077     { "f", HAS_ARG, { (void*)opt_format }, "force format", "fmt" },
3078     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { (void*)opt_frame_pix_fmt }, "set pixel format", "format" },
3079     { "stats", OPT_BOOL | OPT_EXPERT, { (void*)&show_status }, "show status", "" },
3080     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&workaround_bugs }, "workaround bugs", "" },
3081     { "fast", OPT_BOOL | OPT_EXPERT, { (void*)&fast }, "non spec compliant optimizations", "" },
3082     { "genpts", OPT_BOOL | OPT_EXPERT, { (void*)&genpts }, "generate pts", "" },
3083     { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3084     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&lowres }, "", "" },
3085     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_loop_filter }, "", "" },
3086     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_frame }, "", "" },
3087     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_idct }, "", "" },
3088     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&idct }, "set idct algo",  "algo" },
3089     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_concealment }, "set error concealment options",  "bit_mask" },
3090     { "sync", HAS_ARG | OPT_EXPERT, { (void*)opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3091     { "autoexit", OPT_BOOL | OPT_EXPERT, { (void*)&autoexit }, "exit at the end", "" },
3092     { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_keydown }, "exit on key down", "" },
3093     { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_mousedown }, "exit on mouse down", "" },
3094     { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&loop }, "set number of times the playback shall be looped", "loop count" },
3095     { "framedrop", OPT_BOOL | OPT_EXPERT, { (void*)&framedrop }, "drop frames when cpu is too slow", "" },
3096     { "window_title", OPT_STRING | HAS_ARG, { (void*)&window_title }, "set window title", "window title" },
3097 #if CONFIG_AVFILTER
3098     { "vf", OPT_STRING | HAS_ARG, { (void*)&vfilters }, "video filters", "filter list" },
3099 #endif
3100     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { (void*)&rdftspeed }, "rdft speed", "msecs" },
3101     { "showmode", HAS_ARG, {(void*)opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3102     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { (void*)opt_default }, "generic catch all option", "" },
3103     { "i", OPT_BOOL, {(void *)&dummy}, "read specified file", "input_file"},
3104     { "codec", HAS_ARG | OPT_FUNC2, {(void*)opt_codec}, "force decoder", "decoder" },
3105     { NULL, },
3106 };
3107
3108 static void show_usage(void)
3109 {
3110     av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3111     av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3112     av_log(NULL, AV_LOG_INFO, "\n");
3113 }
3114
3115 static int opt_help(const char *opt, const char *arg)
3116 {
3117     av_log_set_callback(log_callback_help);
3118     show_usage();
3119     show_help_options(options, "Main options:\n",
3120                       OPT_EXPERT, 0);
3121     show_help_options(options, "\nAdvanced options:\n",
3122                       OPT_EXPERT, OPT_EXPERT);
3123     printf("\n");
3124     show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3125     show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3126 #if !CONFIG_AVFILTER
3127     show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3128 #endif
3129     printf("\nWhile playing:\n"
3130            "q, ESC              quit\n"
3131            "f                   toggle full screen\n"
3132            "p, SPC              pause\n"
3133            "a                   cycle audio channel\n"
3134            "v                   cycle video channel\n"
3135            "t                   cycle subtitle channel\n"
3136            "w                   show audio waves\n"
3137            "s                   activate frame-step mode\n"
3138            "left/right          seek backward/forward 10 seconds\n"
3139            "down/up             seek backward/forward 1 minute\n"
3140            "page down/page up   seek backward/forward 10 minutes\n"
3141            "mouse click         seek to percentage in file corresponding to fraction of width\n"
3142            );
3143     return 0;
3144 }
3145
3146 static int lockmgr(void **mtx, enum AVLockOp op)
3147 {
3148    switch(op) {
3149       case AV_LOCK_CREATE:
3150           *mtx = SDL_CreateMutex();
3151           if(!*mtx)
3152               return 1;
3153           return 0;
3154       case AV_LOCK_OBTAIN:
3155           return !!SDL_LockMutex(*mtx);
3156       case AV_LOCK_RELEASE:
3157           return !!SDL_UnlockMutex(*mtx);
3158       case AV_LOCK_DESTROY:
3159           SDL_DestroyMutex(*mtx);
3160           return 0;
3161    }
3162    return 1;
3163 }
3164
3165 /* Called from the main */
3166 int main(int argc, char **argv)
3167 {
3168     int flags;
3169     VideoState *is;
3170
3171     av_log_set_flags(AV_LOG_SKIP_REPEATED);
3172     parse_loglevel(argc, argv, options);
3173
3174     /* register all codecs, demux and protocols */
3175     avcodec_register_all();
3176 #if CONFIG_AVDEVICE
3177     avdevice_register_all();
3178 #endif
3179 #if CONFIG_AVFILTER
3180     avfilter_register_all();
3181 #endif
3182     av_register_all();
3183     avformat_network_init();
3184
3185     init_opts();
3186
3187     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
3188     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
3189
3190     show_banner(argc, argv, options);
3191
3192     parse_options(NULL, argc, argv, options, opt_input_file);
3193
3194     if (!input_filename) {
3195         show_usage();
3196         fprintf(stderr, "An input file must be specified\n");
3197         fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3198         exit(1);
3199     }
3200
3201     if (display_disable) {
3202         video_disable = 1;
3203     }
3204     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3205     if (audio_disable)
3206         flags &= ~SDL_INIT_AUDIO;
3207 #if !defined(__MINGW32__) && !defined(__APPLE__)
3208     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3209 #endif
3210     if (SDL_Init (flags)) {
3211         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3212         fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
3213         exit(1);
3214     }
3215
3216     if (!display_disable) {
3217 #if HAVE_SDL_VIDEO_SIZE
3218         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3219         fs_screen_width = vi->current_w;
3220         fs_screen_height = vi->current_h;
3221 #endif
3222     }
3223
3224     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3225     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3226     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3227
3228     if (av_lockmgr_register(lockmgr)) {
3229         fprintf(stderr, "Could not initialize lock manager!\n");
3230         do_exit(NULL);
3231     }
3232
3233     av_init_packet(&flush_pkt);
3234     flush_pkt.data = (char *)(intptr_t)"FLUSH";
3235
3236     is = stream_open(input_filename, file_iformat);
3237     if (!is) {
3238         fprintf(stderr, "Failed to initialize VideoState!\n");
3239         do_exit(NULL);
3240     }
3241
3242     event_loop(is);
3243
3244     /* never returns */
3245
3246     return 0;
3247 }