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