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