8a346867de6ee50b5eea2e3713cf5732dd4fd907
[ffmpeg.git] / ffplay.c
1 /*
2  * FFplay : Simple Media Player based on the ffmpeg libraries
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 <math.h>
24 #include <limits.h>
25 #include "libavutil/avstring.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavformat/avformat.h"
28 #include "libavdevice/avdevice.h"
29 #include "libswscale/swscale.h"
30 #include "libavcodec/audioconvert.h"
31 #include "libavcodec/colorspace.h"
32 #include "libavcodec/opt.h"
33
34 #include "cmdutils.h"
35
36 #include <SDL.h>
37 #include <SDL_thread.h>
38
39 #ifdef __MINGW32__
40 #undef main /* We don't want SDL to override our main() */
41 #endif
42
43 #undef exit
44 #undef printf
45 #undef fprintf
46
47 const char program_name[] = "FFplay";
48 const int program_birth_year = 2003;
49
50 //#define DEBUG_SYNC
51
52 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
53 #define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
54 #define MIN_FRAMES 5
55
56 /* SDL audio buffer size, in samples. Should be small to have precise
57    A/V sync as SDL does not have hardware buffer fullness info. */
58 #define SDL_AUDIO_BUFFER_SIZE 1024
59
60 /* no AV sync correction is done if below the AV sync threshold */
61 #define AV_SYNC_THRESHOLD 0.01
62 /* no AV correction is done if too big error */
63 #define AV_NOSYNC_THRESHOLD 10.0
64
65 /* maximum audio speed change to get correct sync */
66 #define SAMPLE_CORRECTION_PERCENT_MAX 10
67
68 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
69 #define AUDIO_DIFF_AVG_NB   20
70
71 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
72 #define SAMPLE_ARRAY_SIZE (2*65536)
73
74 static int sws_flags = SWS_BICUBIC;
75
76 typedef struct PacketQueue {
77     AVPacketList *first_pkt, *last_pkt;
78     int nb_packets;
79     int size;
80     int abort_request;
81     SDL_mutex *mutex;
82     SDL_cond *cond;
83 } PacketQueue;
84
85 #define VIDEO_PICTURE_QUEUE_SIZE 1
86 #define SUBPICTURE_QUEUE_SIZE 4
87
88 typedef struct VideoPicture {
89     double pts;                                  ///<presentation time stamp for this picture
90     SDL_Overlay *bmp;
91     int width, height; /* source height & width */
92     int allocated;
93 } VideoPicture;
94
95 typedef struct SubPicture {
96     double pts; /* presentation time stamp for this picture */
97     AVSubtitle sub;
98 } SubPicture;
99
100 enum {
101     AV_SYNC_AUDIO_MASTER, /* default choice */
102     AV_SYNC_VIDEO_MASTER,
103     AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
104 };
105
106 typedef struct VideoState {
107     SDL_Thread *parse_tid;
108     SDL_Thread *video_tid;
109     AVInputFormat *iformat;
110     int no_background;
111     int abort_request;
112     int paused;
113     int last_paused;
114     int seek_req;
115     int seek_flags;
116     int64_t seek_pos;
117     int64_t seek_rel;
118     AVFormatContext *ic;
119     int dtg_active_format;
120
121     int audio_stream;
122
123     int av_sync_type;
124     double external_clock; /* external clock base */
125     int64_t external_clock_time;
126
127     double audio_clock;
128     double audio_diff_cum; /* used for AV difference average computation */
129     double audio_diff_avg_coef;
130     double audio_diff_threshold;
131     int audio_diff_avg_count;
132     AVStream *audio_st;
133     PacketQueue audioq;
134     int audio_hw_buf_size;
135     /* samples output by the codec. we reserve more space for avsync
136        compensation */
137     DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
138     DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
139     uint8_t *audio_buf;
140     unsigned int audio_buf_size; /* in bytes */
141     int audio_buf_index; /* in bytes */
142     AVPacket audio_pkt_temp;
143     AVPacket audio_pkt;
144     enum SampleFormat audio_src_fmt;
145     AVAudioConvert *reformat_ctx;
146
147     int show_audio; /* if true, display audio samples */
148     int16_t sample_array[SAMPLE_ARRAY_SIZE];
149     int sample_array_index;
150     int last_i_start;
151
152     SDL_Thread *subtitle_tid;
153     int subtitle_stream;
154     int subtitle_stream_changed;
155     AVStream *subtitle_st;
156     PacketQueue subtitleq;
157     SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
158     int subpq_size, subpq_rindex, subpq_windex;
159     SDL_mutex *subpq_mutex;
160     SDL_cond *subpq_cond;
161
162     double frame_timer;
163     double frame_last_pts;
164     double frame_last_delay;
165     double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
166     int video_stream;
167     AVStream *video_st;
168     PacketQueue videoq;
169     double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
170     int64_t video_current_pts_time;              ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
171     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
172     int pictq_size, pictq_rindex, pictq_windex;
173     SDL_mutex *pictq_mutex;
174     SDL_cond *pictq_cond;
175     struct SwsContext *img_convert_ctx;
176
177     //    QETimer *video_timer;
178     char filename[1024];
179     int width, height, xleft, ytop;
180 } VideoState;
181
182 static void show_help(void);
183 static int audio_write_get_buf_size(VideoState *is);
184
185 /* options specified by the user */
186 static AVInputFormat *file_iformat;
187 static const char *input_filename;
188 static int fs_screen_width;
189 static int fs_screen_height;
190 static int screen_width = 0;
191 static int screen_height = 0;
192 static int frame_width = 0;
193 static int frame_height = 0;
194 static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
195 static int audio_disable;
196 static int video_disable;
197 static int wanted_audio_stream= 0;
198 static int wanted_video_stream= 0;
199 static int wanted_subtitle_stream= -1;
200 static int seek_by_bytes;
201 static int display_disable;
202 static int show_status = 1;
203 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
204 static int64_t start_time = AV_NOPTS_VALUE;
205 static int debug = 0;
206 static int debug_mv = 0;
207 static int step = 0;
208 static int thread_count = 1;
209 static int workaround_bugs = 1;
210 static int fast = 0;
211 static int genpts = 0;
212 static int lowres = 0;
213 static int idct = FF_IDCT_AUTO;
214 static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
215 static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
216 static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
217 static int error_recognition = FF_ER_CAREFUL;
218 static int error_concealment = 3;
219 static int decoder_reorder_pts= 0;
220
221 /* current context */
222 static int is_full_screen;
223 static VideoState *cur_stream;
224 static int64_t audio_callback_time;
225
226 static AVPacket flush_pkt;
227
228 #define FF_ALLOC_EVENT   (SDL_USEREVENT)
229 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
230 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
231
232 static SDL_Surface *screen;
233
234 /* packet queue handling */
235 static void packet_queue_init(PacketQueue *q)
236 {
237     memset(q, 0, sizeof(PacketQueue));
238     q->mutex = SDL_CreateMutex();
239     q->cond = SDL_CreateCond();
240 }
241
242 static void packet_queue_flush(PacketQueue *q)
243 {
244     AVPacketList *pkt, *pkt1;
245
246     SDL_LockMutex(q->mutex);
247     for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
248         pkt1 = pkt->next;
249         av_free_packet(&pkt->pkt);
250         av_freep(&pkt);
251     }
252     q->last_pkt = NULL;
253     q->first_pkt = NULL;
254     q->nb_packets = 0;
255     q->size = 0;
256     SDL_UnlockMutex(q->mutex);
257 }
258
259 static void packet_queue_end(PacketQueue *q)
260 {
261     packet_queue_flush(q);
262     SDL_DestroyMutex(q->mutex);
263     SDL_DestroyCond(q->cond);
264 }
265
266 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
267 {
268     AVPacketList *pkt1;
269
270     /* duplicate the packet */
271     if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
272         return -1;
273
274     pkt1 = av_malloc(sizeof(AVPacketList));
275     if (!pkt1)
276         return -1;
277     pkt1->pkt = *pkt;
278     pkt1->next = NULL;
279
280
281     SDL_LockMutex(q->mutex);
282
283     if (!q->last_pkt)
284
285         q->first_pkt = pkt1;
286     else
287         q->last_pkt->next = pkt1;
288     q->last_pkt = pkt1;
289     q->nb_packets++;
290     q->size += pkt1->pkt.size + sizeof(*pkt1);
291     /* XXX: should duplicate packet data in DV case */
292     SDL_CondSignal(q->cond);
293
294     SDL_UnlockMutex(q->mutex);
295     return 0;
296 }
297
298 static void packet_queue_abort(PacketQueue *q)
299 {
300     SDL_LockMutex(q->mutex);
301
302     q->abort_request = 1;
303
304     SDL_CondSignal(q->cond);
305
306     SDL_UnlockMutex(q->mutex);
307 }
308
309 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
310 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
311 {
312     AVPacketList *pkt1;
313     int ret;
314
315     SDL_LockMutex(q->mutex);
316
317     for(;;) {
318         if (q->abort_request) {
319             ret = -1;
320             break;
321         }
322
323         pkt1 = q->first_pkt;
324         if (pkt1) {
325             q->first_pkt = pkt1->next;
326             if (!q->first_pkt)
327                 q->last_pkt = NULL;
328             q->nb_packets--;
329             q->size -= pkt1->pkt.size + sizeof(*pkt1);
330             *pkt = pkt1->pkt;
331             av_free(pkt1);
332             ret = 1;
333             break;
334         } else if (!block) {
335             ret = 0;
336             break;
337         } else {
338             SDL_CondWait(q->cond, q->mutex);
339         }
340     }
341     SDL_UnlockMutex(q->mutex);
342     return ret;
343 }
344
345 static inline void fill_rectangle(SDL_Surface *screen,
346                                   int x, int y, int w, int h, int color)
347 {
348     SDL_Rect rect;
349     rect.x = x;
350     rect.y = y;
351     rect.w = w;
352     rect.h = h;
353     SDL_FillRect(screen, &rect, color);
354 }
355
356 #if 0
357 /* draw only the border of a rectangle */
358 void fill_border(VideoState *s, int x, int y, int w, int h, int color)
359 {
360     int w1, w2, h1, h2;
361
362     /* fill the background */
363     w1 = x;
364     if (w1 < 0)
365         w1 = 0;
366     w2 = s->width - (x + w);
367     if (w2 < 0)
368         w2 = 0;
369     h1 = y;
370     if (h1 < 0)
371         h1 = 0;
372     h2 = s->height - (y + h);
373     if (h2 < 0)
374         h2 = 0;
375     fill_rectangle(screen,
376                    s->xleft, s->ytop,
377                    w1, s->height,
378                    color);
379     fill_rectangle(screen,
380                    s->xleft + s->width - w2, s->ytop,
381                    w2, s->height,
382                    color);
383     fill_rectangle(screen,
384                    s->xleft + w1, s->ytop,
385                    s->width - w1 - w2, h1,
386                    color);
387     fill_rectangle(screen,
388                    s->xleft + w1, s->ytop + s->height - h2,
389                    s->width - w1 - w2, h2,
390                    color);
391 }
392 #endif
393
394 #define ALPHA_BLEND(a, oldp, newp, s)\
395 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
396
397 #define RGBA_IN(r, g, b, a, s)\
398 {\
399     unsigned int v = ((const uint32_t *)(s))[0];\
400     a = (v >> 24) & 0xff;\
401     r = (v >> 16) & 0xff;\
402     g = (v >> 8) & 0xff;\
403     b = v & 0xff;\
404 }
405
406 #define YUVA_IN(y, u, v, a, s, pal)\
407 {\
408     unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
409     a = (val >> 24) & 0xff;\
410     y = (val >> 16) & 0xff;\
411     u = (val >> 8) & 0xff;\
412     v = val & 0xff;\
413 }
414
415 #define YUVA_OUT(d, y, u, v, a)\
416 {\
417     ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
418 }
419
420
421 #define BPP 1
422
423 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
424 {
425     int wrap, wrap3, width2, skip2;
426     int y, u, v, a, u1, v1, a1, w, h;
427     uint8_t *lum, *cb, *cr;
428     const uint8_t *p;
429     const uint32_t *pal;
430     int dstx, dsty, dstw, dsth;
431
432     dstw = av_clip(rect->w, 0, imgw);
433     dsth = av_clip(rect->h, 0, imgh);
434     dstx = av_clip(rect->x, 0, imgw - dstw);
435     dsty = av_clip(rect->y, 0, imgh - dsth);
436     lum = dst->data[0] + dsty * dst->linesize[0];
437     cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
438     cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
439
440     width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
441     skip2 = dstx >> 1;
442     wrap = dst->linesize[0];
443     wrap3 = rect->pict.linesize[0];
444     p = rect->pict.data[0];
445     pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
446
447     if (dsty & 1) {
448         lum += dstx;
449         cb += skip2;
450         cr += skip2;
451
452         if (dstx & 1) {
453             YUVA_IN(y, u, v, a, p, pal);
454             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
455             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
456             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
457             cb++;
458             cr++;
459             lum++;
460             p += BPP;
461         }
462         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
463             YUVA_IN(y, u, v, a, p, pal);
464             u1 = u;
465             v1 = v;
466             a1 = a;
467             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
468
469             YUVA_IN(y, u, v, a, p + BPP, pal);
470             u1 += u;
471             v1 += v;
472             a1 += a;
473             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
474             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
475             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
476             cb++;
477             cr++;
478             p += 2 * BPP;
479             lum += 2;
480         }
481         if (w) {
482             YUVA_IN(y, u, v, a, p, pal);
483             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
484             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
485             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
486             p++;
487             lum++;
488         }
489         p += wrap3 - dstw * BPP;
490         lum += wrap - dstw - dstx;
491         cb += dst->linesize[1] - width2 - skip2;
492         cr += dst->linesize[2] - width2 - skip2;
493     }
494     for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
495         lum += dstx;
496         cb += skip2;
497         cr += skip2;
498
499         if (dstx & 1) {
500             YUVA_IN(y, u, v, a, p, pal);
501             u1 = u;
502             v1 = v;
503             a1 = a;
504             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
505             p += wrap3;
506             lum += wrap;
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             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
513             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
514             cb++;
515             cr++;
516             p += -wrap3 + BPP;
517             lum += -wrap + 1;
518         }
519         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
520             YUVA_IN(y, u, v, a, p, pal);
521             u1 = u;
522             v1 = v;
523             a1 = a;
524             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
525
526             YUVA_IN(y, u, v, a, p + BPP, pal);
527             u1 += u;
528             v1 += v;
529             a1 += a;
530             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
531             p += wrap3;
532             lum += wrap;
533
534             YUVA_IN(y, u, v, a, p, pal);
535             u1 += u;
536             v1 += v;
537             a1 += a;
538             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
539
540             YUVA_IN(y, u, v, a, p + BPP, pal);
541             u1 += u;
542             v1 += v;
543             a1 += a;
544             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
545
546             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
547             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
548
549             cb++;
550             cr++;
551             p += -wrap3 + 2 * BPP;
552             lum += -wrap + 2;
553         }
554         if (w) {
555             YUVA_IN(y, u, v, a, p, pal);
556             u1 = u;
557             v1 = v;
558             a1 = a;
559             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
560             p += wrap3;
561             lum += wrap;
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             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
568             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
569             cb++;
570             cr++;
571             p += -wrap3 + BPP;
572             lum += -wrap + 1;
573         }
574         p += wrap3 + (wrap3 - dstw * BPP);
575         lum += wrap + (wrap - dstw - dstx);
576         cb += dst->linesize[1] - width2 - skip2;
577         cr += dst->linesize[2] - width2 - skip2;
578     }
579     /* handle odd height */
580     if (h) {
581         lum += dstx;
582         cb += skip2;
583         cr += skip2;
584
585         if (dstx & 1) {
586             YUVA_IN(y, u, v, a, p, pal);
587             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
588             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
589             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
590             cb++;
591             cr++;
592             lum++;
593             p += BPP;
594         }
595         for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
596             YUVA_IN(y, u, v, a, p, pal);
597             u1 = u;
598             v1 = v;
599             a1 = a;
600             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
601
602             YUVA_IN(y, u, v, a, p + BPP, pal);
603             u1 += u;
604             v1 += v;
605             a1 += a;
606             lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
607             cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
608             cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
609             cb++;
610             cr++;
611             p += 2 * BPP;
612             lum += 2;
613         }
614         if (w) {
615             YUVA_IN(y, u, v, a, p, pal);
616             lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
617             cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
618             cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
619         }
620     }
621 }
622
623 static void free_subpicture(SubPicture *sp)
624 {
625     int i;
626
627     for (i = 0; i < sp->sub.num_rects; i++)
628     {
629         av_freep(&sp->sub.rects[i]->pict.data[0]);
630         av_freep(&sp->sub.rects[i]->pict.data[1]);
631         av_freep(&sp->sub.rects[i]);
632     }
633
634     av_free(sp->sub.rects);
635
636     memset(&sp->sub, 0, sizeof(AVSubtitle));
637 }
638
639 static void video_image_display(VideoState *is)
640 {
641     VideoPicture *vp;
642     SubPicture *sp;
643     AVPicture pict;
644     float aspect_ratio;
645     int width, height, x, y;
646     SDL_Rect rect;
647     int i;
648
649     vp = &is->pictq[is->pictq_rindex];
650     if (vp->bmp) {
651         /* XXX: use variable in the frame */
652         if (is->video_st->sample_aspect_ratio.num)
653             aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
654         else if (is->video_st->codec->sample_aspect_ratio.num)
655             aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
656         else
657             aspect_ratio = 0;
658         if (aspect_ratio <= 0.0)
659             aspect_ratio = 1.0;
660         aspect_ratio *= (float)is->video_st->codec->width / is->video_st->codec->height;
661         /* if an active format is indicated, then it overrides the
662            mpeg format */
663 #if 0
664         if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
665             is->dtg_active_format = is->video_st->codec->dtg_active_format;
666             printf("dtg_active_format=%d\n", is->dtg_active_format);
667         }
668 #endif
669 #if 0
670         switch(is->video_st->codec->dtg_active_format) {
671         case FF_DTG_AFD_SAME:
672         default:
673             /* nothing to do */
674             break;
675         case FF_DTG_AFD_4_3:
676             aspect_ratio = 4.0 / 3.0;
677             break;
678         case FF_DTG_AFD_16_9:
679             aspect_ratio = 16.0 / 9.0;
680             break;
681         case FF_DTG_AFD_14_9:
682             aspect_ratio = 14.0 / 9.0;
683             break;
684         case FF_DTG_AFD_4_3_SP_14_9:
685             aspect_ratio = 14.0 / 9.0;
686             break;
687         case FF_DTG_AFD_16_9_SP_14_9:
688             aspect_ratio = 14.0 / 9.0;
689             break;
690         case FF_DTG_AFD_SP_4_3:
691             aspect_ratio = 4.0 / 3.0;
692             break;
693         }
694 #endif
695
696         if (is->subtitle_st)
697         {
698             if (is->subpq_size > 0)
699             {
700                 sp = &is->subpq[is->subpq_rindex];
701
702                 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
703                 {
704                     SDL_LockYUVOverlay (vp->bmp);
705
706                     pict.data[0] = vp->bmp->pixels[0];
707                     pict.data[1] = vp->bmp->pixels[2];
708                     pict.data[2] = vp->bmp->pixels[1];
709
710                     pict.linesize[0] = vp->bmp->pitches[0];
711                     pict.linesize[1] = vp->bmp->pitches[2];
712                     pict.linesize[2] = vp->bmp->pitches[1];
713
714                     for (i = 0; i < sp->sub.num_rects; i++)
715                         blend_subrect(&pict, sp->sub.rects[i],
716                                       vp->bmp->w, vp->bmp->h);
717
718                     SDL_UnlockYUVOverlay (vp->bmp);
719                 }
720             }
721         }
722
723
724         /* XXX: we suppose the screen has a 1.0 pixel ratio */
725         height = is->height;
726         width = ((int)rint(height * aspect_ratio)) & ~1;
727         if (width > is->width) {
728             width = is->width;
729             height = ((int)rint(width / aspect_ratio)) & ~1;
730         }
731         x = (is->width - width) / 2;
732         y = (is->height - height) / 2;
733         if (!is->no_background) {
734             /* fill the background */
735             //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
736         } else {
737             is->no_background = 0;
738         }
739         rect.x = is->xleft + x;
740         rect.y = is->ytop  + y;
741         rect.w = width;
742         rect.h = height;
743         SDL_DisplayYUVOverlay(vp->bmp, &rect);
744     } else {
745 #if 0
746         fill_rectangle(screen,
747                        is->xleft, is->ytop, is->width, is->height,
748                        QERGB(0x00, 0x00, 0x00));
749 #endif
750     }
751 }
752
753 static inline int compute_mod(int a, int b)
754 {
755     a = a % b;
756     if (a >= 0)
757         return a;
758     else
759         return a + b;
760 }
761
762 static void video_audio_display(VideoState *s)
763 {
764     int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
765     int ch, channels, h, h2, bgcolor, fgcolor;
766     int16_t time_diff;
767
768     /* compute display index : center on currently output samples */
769     channels = s->audio_st->codec->channels;
770     nb_display_channels = channels;
771     if (!s->paused) {
772         n = 2 * channels;
773         delay = audio_write_get_buf_size(s);
774         delay /= n;
775
776         /* to be more precise, we take into account the time spent since
777            the last buffer computation */
778         if (audio_callback_time) {
779             time_diff = av_gettime() - audio_callback_time;
780             delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
781         }
782
783         delay -= s->width / 2;
784         if (delay < s->width)
785             delay = s->width;
786
787         i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
788
789         h= INT_MIN;
790         for(i=0; i<1000; i+=channels){
791             int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
792             int a= s->sample_array[idx];
793             int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
794             int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
795             int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
796             int score= a-d;
797             if(h<score && (b^c)<0){
798                 h= score;
799                 i_start= idx;
800             }
801         }
802
803         s->last_i_start = i_start;
804     } else {
805         i_start = s->last_i_start;
806     }
807
808     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
809     fill_rectangle(screen,
810                    s->xleft, s->ytop, s->width, s->height,
811                    bgcolor);
812
813     fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
814
815     /* total height for one channel */
816     h = s->height / nb_display_channels;
817     /* graph height / 2 */
818     h2 = (h * 9) / 20;
819     for(ch = 0;ch < nb_display_channels; ch++) {
820         i = i_start + ch;
821         y1 = s->ytop + ch * h + (h / 2); /* position of center line */
822         for(x = 0; x < s->width; x++) {
823             y = (s->sample_array[i] * h2) >> 15;
824             if (y < 0) {
825                 y = -y;
826                 ys = y1 - y;
827             } else {
828                 ys = y1;
829             }
830             fill_rectangle(screen,
831                            s->xleft + x, ys, 1, y,
832                            fgcolor);
833             i += channels;
834             if (i >= SAMPLE_ARRAY_SIZE)
835                 i -= SAMPLE_ARRAY_SIZE;
836         }
837     }
838
839     fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
840
841     for(ch = 1;ch < nb_display_channels; ch++) {
842         y = s->ytop + ch * h;
843         fill_rectangle(screen,
844                        s->xleft, y, s->width, 1,
845                        fgcolor);
846     }
847     SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
848 }
849
850 static int video_open(VideoState *is){
851     int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
852     int w,h;
853
854     if(is_full_screen) flags |= SDL_FULLSCREEN;
855     else               flags |= SDL_RESIZABLE;
856
857     if (is_full_screen && fs_screen_width) {
858         w = fs_screen_width;
859         h = fs_screen_height;
860     } else if(!is_full_screen && screen_width){
861         w = screen_width;
862         h = screen_height;
863     }else if (is->video_st && is->video_st->codec->width){
864         w = is->video_st->codec->width;
865         h = is->video_st->codec->height;
866     } else {
867         w = 640;
868         h = 480;
869     }
870 #ifndef __APPLE__
871     screen = SDL_SetVideoMode(w, h, 0, flags);
872 #else
873     /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
874     screen = SDL_SetVideoMode(w, h, 24, flags);
875 #endif
876     if (!screen) {
877         fprintf(stderr, "SDL: could not set video mode - exiting\n");
878         return -1;
879     }
880     SDL_WM_SetCaption("FFplay", "FFplay");
881
882     is->width = screen->w;
883     is->height = screen->h;
884
885     return 0;
886 }
887
888 /* display the current picture, if any */
889 static void video_display(VideoState *is)
890 {
891     if(!screen)
892         video_open(cur_stream);
893     if (is->audio_st && is->show_audio)
894         video_audio_display(is);
895     else if (is->video_st)
896         video_image_display(is);
897 }
898
899 static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
900 {
901     SDL_Event event;
902     event.type = FF_REFRESH_EVENT;
903     event.user.data1 = opaque;
904     SDL_PushEvent(&event);
905     return 0; /* 0 means stop timer */
906 }
907
908 /* schedule a video refresh in 'delay' ms */
909 static void schedule_refresh(VideoState *is, int delay)
910 {
911     if(!delay) delay=1; //SDL seems to be buggy when the delay is 0
912     SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
913 }
914
915 /* get the current audio clock value */
916 static double get_audio_clock(VideoState *is)
917 {
918     double pts;
919     int hw_buf_size, bytes_per_sec;
920     pts = is->audio_clock;
921     hw_buf_size = audio_write_get_buf_size(is);
922     bytes_per_sec = 0;
923     if (is->audio_st) {
924         bytes_per_sec = is->audio_st->codec->sample_rate *
925             2 * is->audio_st->codec->channels;
926     }
927     if (bytes_per_sec)
928         pts -= (double)hw_buf_size / bytes_per_sec;
929     return pts;
930 }
931
932 /* get the current video clock value */
933 static double get_video_clock(VideoState *is)
934 {
935     double delta;
936     if (is->paused) {
937         delta = 0;
938     } else {
939         delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
940     }
941     return is->video_current_pts + delta;
942 }
943
944 /* get the current external clock value */
945 static double get_external_clock(VideoState *is)
946 {
947     int64_t ti;
948     ti = av_gettime();
949     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
950 }
951
952 /* get the current master clock value */
953 static double get_master_clock(VideoState *is)
954 {
955     double val;
956
957     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
958         if (is->video_st)
959             val = get_video_clock(is);
960         else
961             val = get_audio_clock(is);
962     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
963         if (is->audio_st)
964             val = get_audio_clock(is);
965         else
966             val = get_video_clock(is);
967     } else {
968         val = get_external_clock(is);
969     }
970     return val;
971 }
972
973 /* seek in the stream */
974 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
975 {
976     if (!is->seek_req) {
977         is->seek_pos = pos;
978         is->seek_rel = rel;
979         if (seek_by_bytes)
980             is->seek_flags |= AVSEEK_FLAG_BYTE;
981         is->seek_req = 1;
982     }
983 }
984
985 /* pause or resume the video */
986 static void stream_pause(VideoState *is)
987 {
988     is->paused = !is->paused;
989     if (!is->paused) {
990         is->video_current_pts = get_video_clock(is);
991         is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;
992     }
993 }
994
995 static double compute_frame_delay(double frame_current_pts, VideoState *is)
996 {
997     double actual_delay, delay, sync_threshold, ref_clock, diff;
998
999     /* compute nominal delay */
1000     delay = frame_current_pts - is->frame_last_pts;
1001     if (delay <= 0 || delay >= 10.0) {
1002         /* if incorrect delay, use previous one */
1003         delay = is->frame_last_delay;
1004     } else {
1005         is->frame_last_delay = delay;
1006     }
1007     is->frame_last_pts = frame_current_pts;
1008
1009     /* update delay to follow master synchronisation source */
1010     if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1011          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1012         /* if video is slave, we try to correct big delays by
1013            duplicating or deleting a frame */
1014         ref_clock = get_master_clock(is);
1015         diff = frame_current_pts - ref_clock;
1016
1017         /* skip or repeat frame. We take into account the
1018            delay to compute the threshold. I still don't know
1019            if it is the best guess */
1020         sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1021         if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1022             if (diff <= -sync_threshold)
1023                 delay = 0;
1024             else if (diff >= sync_threshold)
1025                 delay = 2 * delay;
1026         }
1027     }
1028
1029     is->frame_timer += delay;
1030     /* compute the REAL delay (we need to do that to avoid
1031        long term errors */
1032     actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1033     if (actual_delay < 0.010) {
1034         /* XXX: should skip picture */
1035         actual_delay = 0.010;
1036     }
1037
1038 #if defined(DEBUG_SYNC)
1039     printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1040             delay, actual_delay, frame_current_pts, -diff);
1041 #endif
1042
1043     return actual_delay;
1044 }
1045
1046 /* called to display each frame */
1047 static void video_refresh_timer(void *opaque)
1048 {
1049     VideoState *is = opaque;
1050     VideoPicture *vp;
1051
1052     SubPicture *sp, *sp2;
1053
1054     if (is->video_st) {
1055         if (is->pictq_size == 0) {
1056             /* if no picture, need to wait */
1057             schedule_refresh(is, 1);
1058         } else {
1059             /* dequeue the picture */
1060             vp = &is->pictq[is->pictq_rindex];
1061
1062             /* update current video pts */
1063             is->video_current_pts = vp->pts;
1064             is->video_current_pts_time = av_gettime();
1065
1066             /* launch timer for next picture */
1067             schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1068
1069             if(is->subtitle_st) {
1070                 if (is->subtitle_stream_changed) {
1071                     SDL_LockMutex(is->subpq_mutex);
1072
1073                     while (is->subpq_size) {
1074                         free_subpicture(&is->subpq[is->subpq_rindex]);
1075
1076                         /* update queue size and signal for next picture */
1077                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1078                             is->subpq_rindex = 0;
1079
1080                         is->subpq_size--;
1081                     }
1082                     is->subtitle_stream_changed = 0;
1083
1084                     SDL_CondSignal(is->subpq_cond);
1085                     SDL_UnlockMutex(is->subpq_mutex);
1086                 } else {
1087                     if (is->subpq_size > 0) {
1088                         sp = &is->subpq[is->subpq_rindex];
1089
1090                         if (is->subpq_size > 1)
1091                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1092                         else
1093                             sp2 = NULL;
1094
1095                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1096                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1097                         {
1098                             free_subpicture(sp);
1099
1100                             /* update queue size and signal for next picture */
1101                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1102                                 is->subpq_rindex = 0;
1103
1104                             SDL_LockMutex(is->subpq_mutex);
1105                             is->subpq_size--;
1106                             SDL_CondSignal(is->subpq_cond);
1107                             SDL_UnlockMutex(is->subpq_mutex);
1108                         }
1109                     }
1110                 }
1111             }
1112
1113             /* display picture */
1114             video_display(is);
1115
1116             /* update queue size and signal for next picture */
1117             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1118                 is->pictq_rindex = 0;
1119
1120             SDL_LockMutex(is->pictq_mutex);
1121             is->pictq_size--;
1122             SDL_CondSignal(is->pictq_cond);
1123             SDL_UnlockMutex(is->pictq_mutex);
1124         }
1125     } else if (is->audio_st) {
1126         /* draw the next audio frame */
1127
1128         schedule_refresh(is, 40);
1129
1130         /* if only audio stream, then display the audio bars (better
1131            than nothing, just to test the implementation */
1132
1133         /* display picture */
1134         video_display(is);
1135     } else {
1136         schedule_refresh(is, 100);
1137     }
1138     if (show_status) {
1139         static int64_t last_time;
1140         int64_t cur_time;
1141         int aqsize, vqsize, sqsize;
1142         double av_diff;
1143
1144         cur_time = av_gettime();
1145         if (!last_time || (cur_time - last_time) >= 30000) {
1146             aqsize = 0;
1147             vqsize = 0;
1148             sqsize = 0;
1149             if (is->audio_st)
1150                 aqsize = is->audioq.size;
1151             if (is->video_st)
1152                 vqsize = is->videoq.size;
1153             if (is->subtitle_st)
1154                 sqsize = is->subtitleq.size;
1155             av_diff = 0;
1156             if (is->audio_st && is->video_st)
1157                 av_diff = get_audio_clock(is) - get_video_clock(is);
1158             printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1159                    get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1160             fflush(stdout);
1161             last_time = cur_time;
1162         }
1163     }
1164 }
1165
1166 /* allocate a picture (needs to do that in main thread to avoid
1167    potential locking problems */
1168 static void alloc_picture(void *opaque)
1169 {
1170     VideoState *is = opaque;
1171     VideoPicture *vp;
1172
1173     vp = &is->pictq[is->pictq_windex];
1174
1175     if (vp->bmp)
1176         SDL_FreeYUVOverlay(vp->bmp);
1177
1178     vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1179                                    is->video_st->codec->height,
1180                                    SDL_YV12_OVERLAY,
1181                                    screen);
1182     vp->width = is->video_st->codec->width;
1183     vp->height = is->video_st->codec->height;
1184
1185     SDL_LockMutex(is->pictq_mutex);
1186     vp->allocated = 1;
1187     SDL_CondSignal(is->pictq_cond);
1188     SDL_UnlockMutex(is->pictq_mutex);
1189 }
1190
1191 /**
1192  *
1193  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1194  */
1195 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1196 {
1197     VideoPicture *vp;
1198     int dst_pix_fmt;
1199
1200     /* wait until we have space to put a new picture */
1201     SDL_LockMutex(is->pictq_mutex);
1202     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1203            !is->videoq.abort_request) {
1204         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1205     }
1206     SDL_UnlockMutex(is->pictq_mutex);
1207
1208     if (is->videoq.abort_request)
1209         return -1;
1210
1211     vp = &is->pictq[is->pictq_windex];
1212
1213     /* alloc or resize hardware picture buffer */
1214     if (!vp->bmp ||
1215         vp->width != is->video_st->codec->width ||
1216         vp->height != is->video_st->codec->height) {
1217         SDL_Event event;
1218
1219         vp->allocated = 0;
1220
1221         /* the allocation must be done in the main thread to avoid
1222            locking problems */
1223         event.type = FF_ALLOC_EVENT;
1224         event.user.data1 = is;
1225         SDL_PushEvent(&event);
1226
1227         /* wait until the picture is allocated */
1228         SDL_LockMutex(is->pictq_mutex);
1229         while (!vp->allocated && !is->videoq.abort_request) {
1230             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1231         }
1232         SDL_UnlockMutex(is->pictq_mutex);
1233
1234         if (is->videoq.abort_request)
1235             return -1;
1236     }
1237
1238     /* if the frame is not skipped, then display it */
1239     if (vp->bmp) {
1240         AVPicture pict;
1241
1242         /* get a pointer on the bitmap */
1243         SDL_LockYUVOverlay (vp->bmp);
1244
1245         dst_pix_fmt = PIX_FMT_YUV420P;
1246         memset(&pict,0,sizeof(AVPicture));
1247         pict.data[0] = vp->bmp->pixels[0];
1248         pict.data[1] = vp->bmp->pixels[2];
1249         pict.data[2] = vp->bmp->pixels[1];
1250
1251         pict.linesize[0] = vp->bmp->pitches[0];
1252         pict.linesize[1] = vp->bmp->pitches[2];
1253         pict.linesize[2] = vp->bmp->pitches[1];
1254         sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1255         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1256             is->video_st->codec->width, is->video_st->codec->height,
1257             is->video_st->codec->pix_fmt,
1258             is->video_st->codec->width, is->video_st->codec->height,
1259             dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1260         if (is->img_convert_ctx == NULL) {
1261             fprintf(stderr, "Cannot initialize the conversion context\n");
1262             exit(1);
1263         }
1264         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1265                   0, is->video_st->codec->height, pict.data, pict.linesize);
1266         /* update the bitmap content */
1267         SDL_UnlockYUVOverlay(vp->bmp);
1268
1269         vp->pts = pts;
1270
1271         /* now we can update the picture count */
1272         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1273             is->pictq_windex = 0;
1274         SDL_LockMutex(is->pictq_mutex);
1275         is->pictq_size++;
1276         SDL_UnlockMutex(is->pictq_mutex);
1277     }
1278     return 0;
1279 }
1280
1281 /**
1282  * compute the exact PTS for the picture if it is omitted in the stream
1283  * @param pts1 the dts of the pkt / pts of the frame
1284  */
1285 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1286 {
1287     double frame_delay, pts;
1288
1289     pts = pts1;
1290
1291     if (pts != 0) {
1292         /* update video clock with pts, if present */
1293         is->video_clock = pts;
1294     } else {
1295         pts = is->video_clock;
1296     }
1297     /* update video clock for next frame */
1298     frame_delay = av_q2d(is->video_st->codec->time_base);
1299     /* for MPEG2, the frame can be repeated, so we update the
1300        clock accordingly */
1301     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1302     is->video_clock += frame_delay;
1303
1304 #if defined(DEBUG_SYNC) && 0
1305     {
1306         int ftype;
1307         if (src_frame->pict_type == FF_B_TYPE)
1308             ftype = 'B';
1309         else if (src_frame->pict_type == FF_I_TYPE)
1310             ftype = 'I';
1311         else
1312             ftype = 'P';
1313         printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1314                ftype, pts, pts1);
1315     }
1316 #endif
1317     return queue_picture(is, src_frame, pts);
1318 }
1319
1320 static int video_thread(void *arg)
1321 {
1322     VideoState *is = arg;
1323     AVPacket pkt1, *pkt = &pkt1;
1324     int len1, got_picture;
1325     AVFrame *frame= avcodec_alloc_frame();
1326     double pts;
1327
1328     for(;;) {
1329         while (is->paused && !is->videoq.abort_request) {
1330             SDL_Delay(10);
1331         }
1332         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1333             break;
1334
1335         if(pkt->data == flush_pkt.data){
1336             avcodec_flush_buffers(is->video_st->codec);
1337             continue;
1338         }
1339
1340         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1341            this packet, if any */
1342         is->video_st->codec->reordered_opaque= pkt->pts;
1343         len1 = avcodec_decode_video2(is->video_st->codec,
1344                                     frame, &got_picture,
1345                                     pkt);
1346
1347         if(   (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
1348            && frame->reordered_opaque != AV_NOPTS_VALUE)
1349             pts= frame->reordered_opaque;
1350         else if(pkt->dts != AV_NOPTS_VALUE)
1351             pts= pkt->dts;
1352         else
1353             pts= 0;
1354         pts *= av_q2d(is->video_st->time_base);
1355
1356 //            if (len1 < 0)
1357 //                break;
1358         if (got_picture) {
1359             if (output_picture2(is, frame, pts) < 0)
1360                 goto the_end;
1361         }
1362         av_free_packet(pkt);
1363         if (step)
1364             if (cur_stream)
1365                 stream_pause(cur_stream);
1366     }
1367  the_end:
1368     av_free(frame);
1369     return 0;
1370 }
1371
1372 static int subtitle_thread(void *arg)
1373 {
1374     VideoState *is = arg;
1375     SubPicture *sp;
1376     AVPacket pkt1, *pkt = &pkt1;
1377     int len1, got_subtitle;
1378     double pts;
1379     int i, j;
1380     int r, g, b, y, u, v, a;
1381
1382     for(;;) {
1383         while (is->paused && !is->subtitleq.abort_request) {
1384             SDL_Delay(10);
1385         }
1386         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1387             break;
1388
1389         if(pkt->data == flush_pkt.data){
1390             avcodec_flush_buffers(is->subtitle_st->codec);
1391             continue;
1392         }
1393         SDL_LockMutex(is->subpq_mutex);
1394         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1395                !is->subtitleq.abort_request) {
1396             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1397         }
1398         SDL_UnlockMutex(is->subpq_mutex);
1399
1400         if (is->subtitleq.abort_request)
1401             goto the_end;
1402
1403         sp = &is->subpq[is->subpq_windex];
1404
1405        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1406            this packet, if any */
1407         pts = 0;
1408         if (pkt->pts != AV_NOPTS_VALUE)
1409             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1410
1411         len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1412                                     &sp->sub, &got_subtitle,
1413                                     pkt);
1414 //            if (len1 < 0)
1415 //                break;
1416         if (got_subtitle && sp->sub.format == 0) {
1417             sp->pts = pts;
1418
1419             for (i = 0; i < sp->sub.num_rects; i++)
1420             {
1421                 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1422                 {
1423                     RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1424                     y = RGB_TO_Y_CCIR(r, g, b);
1425                     u = RGB_TO_U_CCIR(r, g, b, 0);
1426                     v = RGB_TO_V_CCIR(r, g, b, 0);
1427                     YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1428                 }
1429             }
1430
1431             /* now we can update the picture count */
1432             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1433                 is->subpq_windex = 0;
1434             SDL_LockMutex(is->subpq_mutex);
1435             is->subpq_size++;
1436             SDL_UnlockMutex(is->subpq_mutex);
1437         }
1438         av_free_packet(pkt);
1439 //        if (step)
1440 //            if (cur_stream)
1441 //                stream_pause(cur_stream);
1442     }
1443  the_end:
1444     return 0;
1445 }
1446
1447 /* copy samples for viewing in editor window */
1448 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1449 {
1450     int size, len, channels;
1451
1452     channels = is->audio_st->codec->channels;
1453
1454     size = samples_size / sizeof(short);
1455     while (size > 0) {
1456         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1457         if (len > size)
1458             len = size;
1459         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1460         samples += len;
1461         is->sample_array_index += len;
1462         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1463             is->sample_array_index = 0;
1464         size -= len;
1465     }
1466 }
1467
1468 /* return the new audio buffer size (samples can be added or deleted
1469    to get better sync if video or external master clock) */
1470 static int synchronize_audio(VideoState *is, short *samples,
1471                              int samples_size1, double pts)
1472 {
1473     int n, samples_size;
1474     double ref_clock;
1475
1476     n = 2 * is->audio_st->codec->channels;
1477     samples_size = samples_size1;
1478
1479     /* if not master, then we try to remove or add samples to correct the clock */
1480     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1481          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1482         double diff, avg_diff;
1483         int wanted_size, min_size, max_size, nb_samples;
1484
1485         ref_clock = get_master_clock(is);
1486         diff = get_audio_clock(is) - ref_clock;
1487
1488         if (diff < AV_NOSYNC_THRESHOLD) {
1489             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1490             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1491                 /* not enough measures to have a correct estimate */
1492                 is->audio_diff_avg_count++;
1493             } else {
1494                 /* estimate the A-V difference */
1495                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1496
1497                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1498                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1499                     nb_samples = samples_size / n;
1500
1501                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1502                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1503                     if (wanted_size < min_size)
1504                         wanted_size = min_size;
1505                     else if (wanted_size > max_size)
1506                         wanted_size = max_size;
1507
1508                     /* add or remove samples to correction the synchro */
1509                     if (wanted_size < samples_size) {
1510                         /* remove samples */
1511                         samples_size = wanted_size;
1512                     } else if (wanted_size > samples_size) {
1513                         uint8_t *samples_end, *q;
1514                         int nb;
1515
1516                         /* add samples */
1517                         nb = (samples_size - wanted_size);
1518                         samples_end = (uint8_t *)samples + samples_size - n;
1519                         q = samples_end + n;
1520                         while (nb > 0) {
1521                             memcpy(q, samples_end, n);
1522                             q += n;
1523                             nb -= n;
1524                         }
1525                         samples_size = wanted_size;
1526                     }
1527                 }
1528 #if 0
1529                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1530                        diff, avg_diff, samples_size - samples_size1,
1531                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1532 #endif
1533             }
1534         } else {
1535             /* too big difference : may be initial PTS errors, so
1536                reset A-V filter */
1537             is->audio_diff_avg_count = 0;
1538             is->audio_diff_cum = 0;
1539         }
1540     }
1541
1542     return samples_size;
1543 }
1544
1545 /* decode one audio frame and returns its uncompressed size */
1546 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1547 {
1548     AVPacket *pkt_temp = &is->audio_pkt_temp;
1549     AVPacket *pkt = &is->audio_pkt;
1550     AVCodecContext *dec= is->audio_st->codec;
1551     int n, len1, data_size;
1552     double pts;
1553
1554     for(;;) {
1555         /* NOTE: the audio packet can contain several frames */
1556         while (pkt_temp->size > 0) {
1557             data_size = sizeof(is->audio_buf1);
1558             len1 = avcodec_decode_audio3(dec,
1559                                         (int16_t *)is->audio_buf1, &data_size,
1560                                         pkt_temp);
1561             if (len1 < 0) {
1562                 /* if error, we skip the frame */
1563                 pkt_temp->size = 0;
1564                 break;
1565             }
1566
1567             pkt_temp->data += len1;
1568             pkt_temp->size -= len1;
1569             if (data_size <= 0)
1570                 continue;
1571
1572             if (dec->sample_fmt != is->audio_src_fmt) {
1573                 if (is->reformat_ctx)
1574                     av_audio_convert_free(is->reformat_ctx);
1575                 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1576                                                          dec->sample_fmt, 1, NULL, 0);
1577                 if (!is->reformat_ctx) {
1578                     fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1579                         avcodec_get_sample_fmt_name(dec->sample_fmt),
1580                         avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1581                         break;
1582                 }
1583                 is->audio_src_fmt= dec->sample_fmt;
1584             }
1585
1586             if (is->reformat_ctx) {
1587                 const void *ibuf[6]= {is->audio_buf1};
1588                 void *obuf[6]= {is->audio_buf2};
1589                 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1590                 int ostride[6]= {2};
1591                 int len= data_size/istride[0];
1592                 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1593                     printf("av_audio_convert() failed\n");
1594                     break;
1595                 }
1596                 is->audio_buf= is->audio_buf2;
1597                 /* FIXME: existing code assume that data_size equals framesize*channels*2
1598                           remove this legacy cruft */
1599                 data_size= len*2;
1600             }else{
1601                 is->audio_buf= is->audio_buf1;
1602             }
1603
1604             /* if no pts, then compute it */
1605             pts = is->audio_clock;
1606             *pts_ptr = pts;
1607             n = 2 * dec->channels;
1608             is->audio_clock += (double)data_size /
1609                 (double)(n * dec->sample_rate);
1610 #if defined(DEBUG_SYNC)
1611             {
1612                 static double last_clock;
1613                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1614                        is->audio_clock - last_clock,
1615                        is->audio_clock, pts);
1616                 last_clock = is->audio_clock;
1617             }
1618 #endif
1619             return data_size;
1620         }
1621
1622         /* free the current packet */
1623         if (pkt->data)
1624             av_free_packet(pkt);
1625
1626         if (is->paused || is->audioq.abort_request) {
1627             return -1;
1628         }
1629
1630         /* read next packet */
1631         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1632             return -1;
1633         if(pkt->data == flush_pkt.data){
1634             avcodec_flush_buffers(dec);
1635             continue;
1636         }
1637
1638         pkt_temp->data = pkt->data;
1639         pkt_temp->size = pkt->size;
1640
1641         /* if update the audio clock with the pts */
1642         if (pkt->pts != AV_NOPTS_VALUE) {
1643             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1644         }
1645     }
1646 }
1647
1648 /* get the current audio output buffer size, in samples. With SDL, we
1649    cannot have a precise information */
1650 static int audio_write_get_buf_size(VideoState *is)
1651 {
1652     return is->audio_buf_size - is->audio_buf_index;
1653 }
1654
1655
1656 /* prepare a new audio buffer */
1657 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1658 {
1659     VideoState *is = opaque;
1660     int audio_size, len1;
1661     double pts;
1662
1663     audio_callback_time = av_gettime();
1664
1665     while (len > 0) {
1666         if (is->audio_buf_index >= is->audio_buf_size) {
1667            audio_size = audio_decode_frame(is, &pts);
1668            if (audio_size < 0) {
1669                 /* if error, just output silence */
1670                is->audio_buf = is->audio_buf1;
1671                is->audio_buf_size = 1024;
1672                memset(is->audio_buf, 0, is->audio_buf_size);
1673            } else {
1674                if (is->show_audio)
1675                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1676                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1677                                               pts);
1678                is->audio_buf_size = audio_size;
1679            }
1680            is->audio_buf_index = 0;
1681         }
1682         len1 = is->audio_buf_size - is->audio_buf_index;
1683         if (len1 > len)
1684             len1 = len;
1685         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1686         len -= len1;
1687         stream += len1;
1688         is->audio_buf_index += len1;
1689     }
1690 }
1691
1692 /* open a given stream. Return 0 if OK */
1693 static int stream_component_open(VideoState *is, int stream_index)
1694 {
1695     AVFormatContext *ic = is->ic;
1696     AVCodecContext *enc;
1697     AVCodec *codec;
1698     SDL_AudioSpec wanted_spec, spec;
1699
1700     if (stream_index < 0 || stream_index >= ic->nb_streams)
1701         return -1;
1702     enc = ic->streams[stream_index]->codec;
1703
1704     /* prepare audio output */
1705     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1706         if (enc->channels > 0) {
1707             enc->request_channels = FFMIN(2, enc->channels);
1708         } else {
1709             enc->request_channels = 2;
1710         }
1711     }
1712
1713     codec = avcodec_find_decoder(enc->codec_id);
1714     enc->debug_mv = debug_mv;
1715     enc->debug = debug;
1716     enc->workaround_bugs = workaround_bugs;
1717     enc->lowres = lowres;
1718     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1719     enc->idct_algo= idct;
1720     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1721     enc->skip_frame= skip_frame;
1722     enc->skip_idct= skip_idct;
1723     enc->skip_loop_filter= skip_loop_filter;
1724     enc->error_recognition= error_recognition;
1725     enc->error_concealment= error_concealment;
1726     avcodec_thread_init(enc, thread_count);
1727
1728     set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1729
1730     if (!codec ||
1731         avcodec_open(enc, codec) < 0)
1732         return -1;
1733
1734     /* prepare audio output */
1735     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1736         wanted_spec.freq = enc->sample_rate;
1737         wanted_spec.format = AUDIO_S16SYS;
1738         wanted_spec.channels = enc->channels;
1739         wanted_spec.silence = 0;
1740         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1741         wanted_spec.callback = sdl_audio_callback;
1742         wanted_spec.userdata = is;
1743         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1744             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1745             return -1;
1746         }
1747         is->audio_hw_buf_size = spec.size;
1748         is->audio_src_fmt= SAMPLE_FMT_S16;
1749     }
1750
1751     ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1752     switch(enc->codec_type) {
1753     case CODEC_TYPE_AUDIO:
1754         is->audio_stream = stream_index;
1755         is->audio_st = ic->streams[stream_index];
1756         is->audio_buf_size = 0;
1757         is->audio_buf_index = 0;
1758
1759         /* init averaging filter */
1760         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1761         is->audio_diff_avg_count = 0;
1762         /* since we do not have a precise anough audio fifo fullness,
1763            we correct audio sync only if larger than this threshold */
1764         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1765
1766         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1767         packet_queue_init(&is->audioq);
1768         SDL_PauseAudio(0);
1769         break;
1770     case CODEC_TYPE_VIDEO:
1771         is->video_stream = stream_index;
1772         is->video_st = ic->streams[stream_index];
1773
1774         is->frame_last_delay = 40e-3;
1775         is->frame_timer = (double)av_gettime() / 1000000.0;
1776         is->video_current_pts_time = av_gettime();
1777
1778         packet_queue_init(&is->videoq);
1779         is->video_tid = SDL_CreateThread(video_thread, is);
1780         break;
1781     case CODEC_TYPE_SUBTITLE:
1782         is->subtitle_stream = stream_index;
1783         is->subtitle_st = ic->streams[stream_index];
1784         packet_queue_init(&is->subtitleq);
1785
1786         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1787         break;
1788     default:
1789         break;
1790     }
1791     return 0;
1792 }
1793
1794 static void stream_component_close(VideoState *is, int stream_index)
1795 {
1796     AVFormatContext *ic = is->ic;
1797     AVCodecContext *enc;
1798
1799     if (stream_index < 0 || stream_index >= ic->nb_streams)
1800         return;
1801     enc = ic->streams[stream_index]->codec;
1802
1803     switch(enc->codec_type) {
1804     case CODEC_TYPE_AUDIO:
1805         packet_queue_abort(&is->audioq);
1806
1807         SDL_CloseAudio();
1808
1809         packet_queue_end(&is->audioq);
1810         if (is->reformat_ctx)
1811             av_audio_convert_free(is->reformat_ctx);
1812         break;
1813     case CODEC_TYPE_VIDEO:
1814         packet_queue_abort(&is->videoq);
1815
1816         /* note: we also signal this mutex to make sure we deblock the
1817            video thread in all cases */
1818         SDL_LockMutex(is->pictq_mutex);
1819         SDL_CondSignal(is->pictq_cond);
1820         SDL_UnlockMutex(is->pictq_mutex);
1821
1822         SDL_WaitThread(is->video_tid, NULL);
1823
1824         packet_queue_end(&is->videoq);
1825         break;
1826     case CODEC_TYPE_SUBTITLE:
1827         packet_queue_abort(&is->subtitleq);
1828
1829         /* note: we also signal this mutex to make sure we deblock the
1830            video thread in all cases */
1831         SDL_LockMutex(is->subpq_mutex);
1832         is->subtitle_stream_changed = 1;
1833
1834         SDL_CondSignal(is->subpq_cond);
1835         SDL_UnlockMutex(is->subpq_mutex);
1836
1837         SDL_WaitThread(is->subtitle_tid, NULL);
1838
1839         packet_queue_end(&is->subtitleq);
1840         break;
1841     default:
1842         break;
1843     }
1844
1845     ic->streams[stream_index]->discard = AVDISCARD_ALL;
1846     avcodec_close(enc);
1847     switch(enc->codec_type) {
1848     case CODEC_TYPE_AUDIO:
1849         is->audio_st = NULL;
1850         is->audio_stream = -1;
1851         break;
1852     case CODEC_TYPE_VIDEO:
1853         is->video_st = NULL;
1854         is->video_stream = -1;
1855         break;
1856     case CODEC_TYPE_SUBTITLE:
1857         is->subtitle_st = NULL;
1858         is->subtitle_stream = -1;
1859         break;
1860     default:
1861         break;
1862     }
1863 }
1864
1865 /* since we have only one decoding thread, we can use a global
1866    variable instead of a thread local variable */
1867 static VideoState *global_video_state;
1868
1869 static int decode_interrupt_cb(void)
1870 {
1871     return (global_video_state && global_video_state->abort_request);
1872 }
1873
1874 /* this thread gets the stream from the disk or the network */
1875 static int decode_thread(void *arg)
1876 {
1877     VideoState *is = arg;
1878     AVFormatContext *ic;
1879     int err, i, ret, video_index, audio_index, subtitle_index;
1880     AVPacket pkt1, *pkt = &pkt1;
1881     AVFormatParameters params, *ap = &params;
1882     int eof=0;
1883
1884     ic = avformat_alloc_context();
1885
1886     video_index = -1;
1887     audio_index = -1;
1888     subtitle_index = -1;
1889     is->video_stream = -1;
1890     is->audio_stream = -1;
1891     is->subtitle_stream = -1;
1892
1893     global_video_state = is;
1894     url_set_interrupt_cb(decode_interrupt_cb);
1895
1896     memset(ap, 0, sizeof(*ap));
1897
1898     ap->prealloced_context = 1;
1899     ap->width = frame_width;
1900     ap->height= frame_height;
1901     ap->time_base= (AVRational){1, 25};
1902     ap->pix_fmt = frame_pix_fmt;
1903
1904     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1905
1906     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1907     if (err < 0) {
1908         print_error(is->filename, err);
1909         ret = -1;
1910         goto fail;
1911     }
1912     is->ic = ic;
1913
1914     if(genpts)
1915         ic->flags |= AVFMT_FLAG_GENPTS;
1916
1917     err = av_find_stream_info(ic);
1918     if (err < 0) {
1919         fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1920         ret = -1;
1921         goto fail;
1922     }
1923     if(ic->pb)
1924         ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1925
1926     /* if seeking requested, we execute it */
1927     if (start_time != AV_NOPTS_VALUE) {
1928         int64_t timestamp;
1929
1930         timestamp = start_time;
1931         /* add the stream start time */
1932         if (ic->start_time != AV_NOPTS_VALUE)
1933             timestamp += ic->start_time;
1934         ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1935         if (ret < 0) {
1936             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1937                     is->filename, (double)timestamp / AV_TIME_BASE);
1938         }
1939     }
1940
1941     for(i = 0; i < ic->nb_streams; i++) {
1942         AVCodecContext *enc = ic->streams[i]->codec;
1943         ic->streams[i]->discard = AVDISCARD_ALL;
1944         switch(enc->codec_type) {
1945         case CODEC_TYPE_AUDIO:
1946             if (wanted_audio_stream-- >= 0 && !audio_disable)
1947                 audio_index = i;
1948             break;
1949         case CODEC_TYPE_VIDEO:
1950             if (wanted_video_stream-- >= 0 && !video_disable)
1951                 video_index = i;
1952             break;
1953         case CODEC_TYPE_SUBTITLE:
1954             if (wanted_subtitle_stream-- >= 0 && !video_disable)
1955                 subtitle_index = i;
1956             break;
1957         default:
1958             break;
1959         }
1960     }
1961     if (show_status) {
1962         dump_format(ic, 0, is->filename, 0);
1963     }
1964
1965     /* open the streams */
1966     if (audio_index >= 0) {
1967         stream_component_open(is, audio_index);
1968     }
1969
1970     if (video_index >= 0) {
1971         stream_component_open(is, video_index);
1972     } else {
1973         if (!display_disable)
1974             is->show_audio = 1;
1975     }
1976
1977     if (subtitle_index >= 0) {
1978         stream_component_open(is, subtitle_index);
1979     }
1980
1981     if (is->video_stream < 0 && is->audio_stream < 0) {
1982         fprintf(stderr, "%s: could not open codecs\n", is->filename);
1983         ret = -1;
1984         goto fail;
1985     }
1986
1987     for(;;) {
1988         if (is->abort_request)
1989             break;
1990         if (is->paused != is->last_paused) {
1991             is->last_paused = is->paused;
1992             if (is->paused)
1993                 av_read_pause(ic);
1994             else
1995                 av_read_play(ic);
1996         }
1997 #if CONFIG_RTSP_DEMUXER
1998         if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
1999             /* wait 10 ms to avoid trying to get another packet */
2000             /* XXX: horrible */
2001             SDL_Delay(10);
2002             continue;
2003         }
2004 #endif
2005         if (is->seek_req) {
2006             int64_t seek_target= is->seek_pos;
2007             int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2008             int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2009 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2010 //      of the seek_pos/seek_rel variables
2011
2012             ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2013             if (ret < 0) {
2014                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2015             }else{
2016                 if (is->audio_stream >= 0) {
2017                     packet_queue_flush(&is->audioq);
2018                     packet_queue_put(&is->audioq, &flush_pkt);
2019                 }
2020                 if (is->subtitle_stream >= 0) {
2021                     packet_queue_flush(&is->subtitleq);
2022                     packet_queue_put(&is->subtitleq, &flush_pkt);
2023                 }
2024                 if (is->video_stream >= 0) {
2025                     packet_queue_flush(&is->videoq);
2026                     packet_queue_put(&is->videoq, &flush_pkt);
2027                 }
2028             }
2029             is->seek_req = 0;
2030             eof= 0;
2031         }
2032
2033         /* if the queue are full, no need to read more */
2034         if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2035             || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2036                 && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2037                 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2038             /* wait 10 ms */
2039             SDL_Delay(10);
2040             continue;
2041         }
2042         if(url_feof(ic->pb) || eof) {
2043             if(is->video_stream >= 0){
2044                 av_init_packet(pkt);
2045                 pkt->data=NULL;
2046                 pkt->size=0;
2047                 pkt->stream_index= is->video_stream;
2048                 packet_queue_put(&is->videoq, pkt);
2049             }
2050             SDL_Delay(10);
2051             continue;
2052         }
2053         ret = av_read_frame(ic, pkt);
2054         if (ret < 0) {
2055             if (ret == AVERROR_EOF)
2056                 eof=1;
2057             if (url_ferror(ic->pb))
2058                 break;
2059             SDL_Delay(100); /* wait for user event */
2060             continue;
2061         }
2062         if (pkt->stream_index == is->audio_stream) {
2063             packet_queue_put(&is->audioq, pkt);
2064         } else if (pkt->stream_index == is->video_stream) {
2065             packet_queue_put(&is->videoq, pkt);
2066         } else if (pkt->stream_index == is->subtitle_stream) {
2067             packet_queue_put(&is->subtitleq, pkt);
2068         } else {
2069             av_free_packet(pkt);
2070         }
2071     }
2072     /* wait until the end */
2073     while (!is->abort_request) {
2074         SDL_Delay(100);
2075     }
2076
2077     ret = 0;
2078  fail:
2079     /* disable interrupting */
2080     global_video_state = NULL;
2081
2082     /* close each stream */
2083     if (is->audio_stream >= 0)
2084         stream_component_close(is, is->audio_stream);
2085     if (is->video_stream >= 0)
2086         stream_component_close(is, is->video_stream);
2087     if (is->subtitle_stream >= 0)
2088         stream_component_close(is, is->subtitle_stream);
2089     if (is->ic) {
2090         av_close_input_file(is->ic);
2091         is->ic = NULL; /* safety */
2092     }
2093     url_set_interrupt_cb(NULL);
2094
2095     if (ret != 0) {
2096         SDL_Event event;
2097
2098         event.type = FF_QUIT_EVENT;
2099         event.user.data1 = is;
2100         SDL_PushEvent(&event);
2101     }
2102     return 0;
2103 }
2104
2105 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2106 {
2107     VideoState *is;
2108
2109     is = av_mallocz(sizeof(VideoState));
2110     if (!is)
2111         return NULL;
2112     av_strlcpy(is->filename, filename, sizeof(is->filename));
2113     is->iformat = iformat;
2114     is->ytop = 0;
2115     is->xleft = 0;
2116
2117     /* start video display */
2118     is->pictq_mutex = SDL_CreateMutex();
2119     is->pictq_cond = SDL_CreateCond();
2120
2121     is->subpq_mutex = SDL_CreateMutex();
2122     is->subpq_cond = SDL_CreateCond();
2123
2124     /* add the refresh timer to draw the picture */
2125     schedule_refresh(is, 40);
2126
2127     is->av_sync_type = av_sync_type;
2128     is->parse_tid = SDL_CreateThread(decode_thread, is);
2129     if (!is->parse_tid) {
2130         av_free(is);
2131         return NULL;
2132     }
2133     return is;
2134 }
2135
2136 static void stream_close(VideoState *is)
2137 {
2138     VideoPicture *vp;
2139     int i;
2140     /* XXX: use a special url_shutdown call to abort parse cleanly */
2141     is->abort_request = 1;
2142     SDL_WaitThread(is->parse_tid, NULL);
2143
2144     /* free all pictures */
2145     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2146         vp = &is->pictq[i];
2147         if (vp->bmp) {
2148             SDL_FreeYUVOverlay(vp->bmp);
2149             vp->bmp = NULL;
2150         }
2151     }
2152     SDL_DestroyMutex(is->pictq_mutex);
2153     SDL_DestroyCond(is->pictq_cond);
2154     SDL_DestroyMutex(is->subpq_mutex);
2155     SDL_DestroyCond(is->subpq_cond);
2156     if (is->img_convert_ctx)
2157         sws_freeContext(is->img_convert_ctx);
2158     av_free(is);
2159 }
2160
2161 static void stream_cycle_channel(VideoState *is, int codec_type)
2162 {
2163     AVFormatContext *ic = is->ic;
2164     int start_index, stream_index;
2165     AVStream *st;
2166
2167     if (codec_type == CODEC_TYPE_VIDEO)
2168         start_index = is->video_stream;
2169     else if (codec_type == CODEC_TYPE_AUDIO)
2170         start_index = is->audio_stream;
2171     else
2172         start_index = is->subtitle_stream;
2173     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2174         return;
2175     stream_index = start_index;
2176     for(;;) {
2177         if (++stream_index >= is->ic->nb_streams)
2178         {
2179             if (codec_type == CODEC_TYPE_SUBTITLE)
2180             {
2181                 stream_index = -1;
2182                 goto the_end;
2183             } else
2184                 stream_index = 0;
2185         }
2186         if (stream_index == start_index)
2187             return;
2188         st = ic->streams[stream_index];
2189         if (st->codec->codec_type == codec_type) {
2190             /* check that parameters are OK */
2191             switch(codec_type) {
2192             case CODEC_TYPE_AUDIO:
2193                 if (st->codec->sample_rate != 0 &&
2194                     st->codec->channels != 0)
2195                     goto the_end;
2196                 break;
2197             case CODEC_TYPE_VIDEO:
2198             case CODEC_TYPE_SUBTITLE:
2199                 goto the_end;
2200             default:
2201                 break;
2202             }
2203         }
2204     }
2205  the_end:
2206     stream_component_close(is, start_index);
2207     stream_component_open(is, stream_index);
2208 }
2209
2210
2211 static void toggle_full_screen(void)
2212 {
2213     is_full_screen = !is_full_screen;
2214     if (!fs_screen_width) {
2215         /* use default SDL method */
2216 //        SDL_WM_ToggleFullScreen(screen);
2217     }
2218     video_open(cur_stream);
2219 }
2220
2221 static void toggle_pause(void)
2222 {
2223     if (cur_stream)
2224         stream_pause(cur_stream);
2225     step = 0;
2226 }
2227
2228 static void step_to_next_frame(void)
2229 {
2230     if (cur_stream) {
2231         /* if the stream is paused unpause it, then step */
2232         if (cur_stream->paused)
2233             stream_pause(cur_stream);
2234     }
2235     step = 1;
2236 }
2237
2238 static void do_exit(void)
2239 {
2240     int i;
2241     if (cur_stream) {
2242         stream_close(cur_stream);
2243         cur_stream = NULL;
2244     }
2245     for (i = 0; i < CODEC_TYPE_NB; i++)
2246         av_free(avcodec_opts[i]);
2247     av_free(avformat_opts);
2248     av_free(sws_opts);
2249     if (show_status)
2250         printf("\n");
2251     SDL_Quit();
2252     exit(0);
2253 }
2254
2255 static void toggle_audio_display(void)
2256 {
2257     if (cur_stream) {
2258         cur_stream->show_audio = !cur_stream->show_audio;
2259     }
2260 }
2261
2262 /* handle an event sent by the GUI */
2263 static void event_loop(void)
2264 {
2265     SDL_Event event;
2266     double incr, pos, frac;
2267
2268     for(;;) {
2269         SDL_WaitEvent(&event);
2270         switch(event.type) {
2271         case SDL_KEYDOWN:
2272             switch(event.key.keysym.sym) {
2273             case SDLK_ESCAPE:
2274             case SDLK_q:
2275                 do_exit();
2276                 break;
2277             case SDLK_f:
2278                 toggle_full_screen();
2279                 break;
2280             case SDLK_p:
2281             case SDLK_SPACE:
2282                 toggle_pause();
2283                 break;
2284             case SDLK_s: //S: Step to next frame
2285                 step_to_next_frame();
2286                 break;
2287             case SDLK_a:
2288                 if (cur_stream)
2289                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2290                 break;
2291             case SDLK_v:
2292                 if (cur_stream)
2293                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2294                 break;
2295             case SDLK_t:
2296                 if (cur_stream)
2297                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2298                 break;
2299             case SDLK_w:
2300                 toggle_audio_display();
2301                 break;
2302             case SDLK_LEFT:
2303                 incr = -10.0;
2304                 goto do_seek;
2305             case SDLK_RIGHT:
2306                 incr = 10.0;
2307                 goto do_seek;
2308             case SDLK_UP:
2309                 incr = 60.0;
2310                 goto do_seek;
2311             case SDLK_DOWN:
2312                 incr = -60.0;
2313             do_seek:
2314                 if (cur_stream) {
2315                     if (seek_by_bytes) {
2316                         pos = url_ftell(cur_stream->ic->pb);
2317                         if (cur_stream->ic->bit_rate)
2318                             incr *= cur_stream->ic->bit_rate / 60.0;
2319                         else
2320                             incr *= 180000.0;
2321                         pos += incr;
2322                         stream_seek(cur_stream, pos, incr, 1);
2323                     } else {
2324                         pos = get_master_clock(cur_stream);
2325                         pos += incr;
2326                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2327                     }
2328                 }
2329                 break;
2330             default:
2331                 break;
2332             }
2333             break;
2334         case SDL_MOUSEBUTTONDOWN:
2335             if (cur_stream) {
2336                 if(seek_by_bytes || cur_stream->ic->duration<=0){
2337                     uint64_t size=  url_fsize(cur_stream->ic->pb);
2338                     stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2339                 }else{
2340                 int64_t ts;
2341                 int ns, hh, mm, ss;
2342                 int tns, thh, tmm, tss;
2343                 tns = cur_stream->ic->duration/1000000LL;
2344                 thh = tns/3600;
2345                 tmm = (tns%3600)/60;
2346                 tss = (tns%60);
2347                 frac = (double)event.button.x/(double)cur_stream->width;
2348                 ns = frac*tns;
2349                 hh = ns/3600;
2350                 mm = (ns%3600)/60;
2351                 ss = (ns%60);
2352                 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2353                         hh, mm, ss, thh, tmm, tss);
2354                 ts = frac*cur_stream->ic->duration;
2355                 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2356                     ts += cur_stream->ic->start_time;
2357                 stream_seek(cur_stream, ts, 0, 0);
2358                 }
2359             }
2360             break;
2361         case SDL_VIDEORESIZE:
2362             if (cur_stream) {
2363                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2364                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2365                 screen_width = cur_stream->width = event.resize.w;
2366                 screen_height= cur_stream->height= event.resize.h;
2367             }
2368             break;
2369         case SDL_QUIT:
2370         case FF_QUIT_EVENT:
2371             do_exit();
2372             break;
2373         case FF_ALLOC_EVENT:
2374             video_open(event.user.data1);
2375             alloc_picture(event.user.data1);
2376             break;
2377         case FF_REFRESH_EVENT:
2378             video_refresh_timer(event.user.data1);
2379             break;
2380         default:
2381             break;
2382         }
2383     }
2384 }
2385
2386 static void opt_frame_size(const char *arg)
2387 {
2388     if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2389         fprintf(stderr, "Incorrect frame size\n");
2390         exit(1);
2391     }
2392     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2393         fprintf(stderr, "Frame size must be a multiple of 2\n");
2394         exit(1);
2395     }
2396 }
2397
2398 static int opt_width(const char *opt, const char *arg)
2399 {
2400     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2401     return 0;
2402 }
2403
2404 static int opt_height(const char *opt, const char *arg)
2405 {
2406     screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2407     return 0;
2408 }
2409
2410 static void opt_format(const char *arg)
2411 {
2412     file_iformat = av_find_input_format(arg);
2413     if (!file_iformat) {
2414         fprintf(stderr, "Unknown input format: %s\n", arg);
2415         exit(1);
2416     }
2417 }
2418
2419 static void opt_frame_pix_fmt(const char *arg)
2420 {
2421     frame_pix_fmt = av_get_pix_fmt(arg);
2422 }
2423
2424 static int opt_sync(const char *opt, const char *arg)
2425 {
2426     if (!strcmp(arg, "audio"))
2427         av_sync_type = AV_SYNC_AUDIO_MASTER;
2428     else if (!strcmp(arg, "video"))
2429         av_sync_type = AV_SYNC_VIDEO_MASTER;
2430     else if (!strcmp(arg, "ext"))
2431         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2432     else {
2433         fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2434         exit(1);
2435     }
2436     return 0;
2437 }
2438
2439 static int opt_seek(const char *opt, const char *arg)
2440 {
2441     start_time = parse_time_or_die(opt, arg, 1);
2442     return 0;
2443 }
2444
2445 static int opt_debug(const char *opt, const char *arg)
2446 {
2447     av_log_set_level(99);
2448     debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2449     return 0;
2450 }
2451
2452 static int opt_vismv(const char *opt, const char *arg)
2453 {
2454     debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2455     return 0;
2456 }
2457
2458 static int opt_thread_count(const char *opt, const char *arg)
2459 {
2460     thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2461 #if !HAVE_THREADS
2462     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2463 #endif
2464     return 0;
2465 }
2466
2467 static const OptionDef options[] = {
2468 #include "cmdutils_common_opts.h"
2469     { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2470     { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2471     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2472     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2473     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2474     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2475     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2476     { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2477     { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2478     { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2479     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2480     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2481     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2482     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2483     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2484     { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2485     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2486     { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2487     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2488     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2489     { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""},
2490     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2491     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2492     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2493     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2494     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2495     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2496     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2497     { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2498     { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2499     { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2500     { NULL, },
2501 };
2502
2503 static void show_usage(void)
2504 {
2505     printf("Simple media player\n");
2506     printf("usage: ffplay [options] input_file\n");
2507     printf("\n");
2508 }
2509
2510 static void show_help(void)
2511 {
2512     show_usage();
2513     show_help_options(options, "Main options:\n",
2514                       OPT_EXPERT, 0);
2515     show_help_options(options, "\nAdvanced options:\n",
2516                       OPT_EXPERT, OPT_EXPERT);
2517     printf("\nWhile playing:\n"
2518            "q, ESC              quit\n"
2519            "f                   toggle full screen\n"
2520            "p, SPC              pause\n"
2521            "a                   cycle audio channel\n"
2522            "v                   cycle video channel\n"
2523            "t                   cycle subtitle channel\n"
2524            "w                   show audio waves\n"
2525            "left/right          seek backward/forward 10 seconds\n"
2526            "down/up             seek backward/forward 1 minute\n"
2527            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2528            );
2529 }
2530
2531 static void opt_input_file(const char *filename)
2532 {
2533     if (!strcmp(filename, "-"))
2534         filename = "pipe:";
2535     input_filename = filename;
2536 }
2537
2538 /* Called from the main */
2539 int main(int argc, char **argv)
2540 {
2541     int flags, i;
2542
2543     /* register all codecs, demux and protocols */
2544     avcodec_register_all();
2545     avdevice_register_all();
2546     av_register_all();
2547
2548     for(i=0; i<CODEC_TYPE_NB; i++){
2549         avcodec_opts[i]= avcodec_alloc_context2(i);
2550     }
2551     avformat_opts = avformat_alloc_context();
2552     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2553
2554     show_banner();
2555
2556     parse_options(argc, argv, options, opt_input_file);
2557
2558     if (!input_filename) {
2559         show_usage();
2560         fprintf(stderr, "An input file must be specified\n");
2561         fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2562         exit(1);
2563     }
2564
2565     if (display_disable) {
2566         video_disable = 1;
2567     }
2568     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2569 #if !defined(__MINGW32__) && !defined(__APPLE__)
2570     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2571 #endif
2572     if (SDL_Init (flags)) {
2573         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2574         exit(1);
2575     }
2576
2577     if (!display_disable) {
2578 #if HAVE_SDL_VIDEO_SIZE
2579         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2580         fs_screen_width = vi->current_w;
2581         fs_screen_height = vi->current_h;
2582 #endif
2583     }
2584
2585     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2586     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2587     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2588     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2589
2590     av_init_packet(&flush_pkt);
2591     flush_pkt.data= "FLUSH";
2592
2593     cur_stream = stream_open(input_filename, file_iformat);
2594
2595     event_loop();
2596
2597     /* never returns */
2598
2599     return 0;
2600 }