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