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