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