command line option to select the audio stream
[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         i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
786         s->last_i_start = i_start;
787     } else {
788         i_start = s->last_i_start;
789     }
790
791     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
792     fill_rectangle(screen,
793                    s->xleft, s->ytop, s->width, s->height,
794                    bgcolor);
795
796     fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
797
798     /* total height for one channel */
799     h = s->height / nb_display_channels;
800     /* graph height / 2 */
801     h2 = (h * 9) / 20;
802     for(ch = 0;ch < nb_display_channels; ch++) {
803         i = i_start + ch;
804         y1 = s->ytop + ch * h + (h / 2); /* position of center line */
805         for(x = 0; x < s->width; x++) {
806             y = (s->sample_array[i] * h2) >> 15;
807             if (y < 0) {
808                 y = -y;
809                 ys = y1 - y;
810             } else {
811                 ys = y1;
812             }
813             fill_rectangle(screen,
814                            s->xleft + x, ys, 1, y,
815                            fgcolor);
816             i += channels;
817             if (i >= SAMPLE_ARRAY_SIZE)
818                 i -= SAMPLE_ARRAY_SIZE;
819         }
820     }
821
822     fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
823
824     for(ch = 1;ch < nb_display_channels; ch++) {
825         y = s->ytop + ch * h;
826         fill_rectangle(screen,
827                        s->xleft, y, s->width, 1,
828                        fgcolor);
829     }
830     SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
831 }
832
833 static int video_open(VideoState *is){
834     int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
835     int w,h;
836
837     if(is_full_screen) flags |= SDL_FULLSCREEN;
838     else               flags |= SDL_RESIZABLE;
839
840     if (is_full_screen && fs_screen_width) {
841         w = fs_screen_width;
842         h = fs_screen_height;
843     } else if(!is_full_screen && screen_width){
844         w = screen_width;
845         h = screen_height;
846     }else if (is->video_st && is->video_st->codec->width){
847         w = is->video_st->codec->width;
848         h = is->video_st->codec->height;
849     } else {
850         w = 640;
851         h = 480;
852     }
853 #ifndef CONFIG_DARWIN
854     screen = SDL_SetVideoMode(w, h, 0, flags);
855 #else
856     /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
857     screen = SDL_SetVideoMode(w, h, 24, flags);
858 #endif
859     if (!screen) {
860         fprintf(stderr, "SDL: could not set video mode - exiting\n");
861         return -1;
862     }
863     SDL_WM_SetCaption("FFplay", "FFplay");
864
865     is->width = screen->w;
866     is->height = screen->h;
867
868     return 0;
869 }
870
871 /* display the current picture, if any */
872 static void video_display(VideoState *is)
873 {
874     if(!screen)
875         video_open(cur_stream);
876     if (is->audio_st && is->show_audio)
877         video_audio_display(is);
878     else if (is->video_st)
879         video_image_display(is);
880 }
881
882 static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
883 {
884     SDL_Event event;
885     event.type = FF_REFRESH_EVENT;
886     event.user.data1 = opaque;
887     SDL_PushEvent(&event);
888     return 0; /* 0 means stop timer */
889 }
890
891 /* schedule a video refresh in 'delay' ms */
892 static void schedule_refresh(VideoState *is, int delay)
893 {
894     SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
895 }
896
897 /* get the current audio clock value */
898 static double get_audio_clock(VideoState *is)
899 {
900     double pts;
901     int hw_buf_size, bytes_per_sec;
902     pts = is->audio_clock;
903     hw_buf_size = audio_write_get_buf_size(is);
904     bytes_per_sec = 0;
905     if (is->audio_st) {
906         bytes_per_sec = is->audio_st->codec->sample_rate *
907             2 * is->audio_st->codec->channels;
908     }
909     if (bytes_per_sec)
910         pts -= (double)hw_buf_size / bytes_per_sec;
911     return pts;
912 }
913
914 /* get the current video clock value */
915 static double get_video_clock(VideoState *is)
916 {
917     double delta;
918     if (is->paused) {
919         delta = 0;
920     } else {
921         delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
922     }
923     return is->video_current_pts + delta;
924 }
925
926 /* get the current external clock value */
927 static double get_external_clock(VideoState *is)
928 {
929     int64_t ti;
930     ti = av_gettime();
931     return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
932 }
933
934 /* get the current master clock value */
935 static double get_master_clock(VideoState *is)
936 {
937     double val;
938
939     if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
940         if (is->video_st)
941             val = get_video_clock(is);
942         else
943             val = get_audio_clock(is);
944     } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
945         if (is->audio_st)
946             val = get_audio_clock(is);
947         else
948             val = get_video_clock(is);
949     } else {
950         val = get_external_clock(is);
951     }
952     return val;
953 }
954
955 /* seek in the stream */
956 static void stream_seek(VideoState *is, int64_t pos, int rel)
957 {
958     if (!is->seek_req) {
959         is->seek_pos = pos;
960         is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
961         if (seek_by_bytes)
962             is->seek_flags |= AVSEEK_FLAG_BYTE;
963         is->seek_req = 1;
964     }
965 }
966
967 /* pause or resume the video */
968 static void stream_pause(VideoState *is)
969 {
970     is->paused = !is->paused;
971     if (is->paused) {
972         is->video_current_pts = get_video_clock(is);
973     }
974 }
975
976 /* called to display each frame */
977 static void video_refresh_timer(void *opaque)
978 {
979     VideoState *is = opaque;
980     VideoPicture *vp;
981     double actual_delay, delay, sync_threshold, ref_clock, diff;
982
983     SubPicture *sp, *sp2;
984
985     if (is->video_st) {
986         if (is->pictq_size == 0) {
987             /* if no picture, need to wait */
988             schedule_refresh(is, 1);
989         } else {
990             /* dequeue the picture */
991             vp = &is->pictq[is->pictq_rindex];
992
993             /* update current video pts */
994             is->video_current_pts = vp->pts;
995             is->video_current_pts_time = av_gettime();
996
997             /* compute nominal delay */
998             delay = vp->pts - is->frame_last_pts;
999             if (delay <= 0 || delay >= 1.0) {
1000                 /* if incorrect delay, use previous one */
1001                 delay = is->frame_last_delay;
1002             }
1003             is->frame_last_delay = delay;
1004             is->frame_last_pts = vp->pts;
1005
1006             /* update delay to follow master synchronisation source */
1007             if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1008                  is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1009                 /* if video is slave, we try to correct big delays by
1010                    duplicating or deleting a frame */
1011                 ref_clock = get_master_clock(is);
1012                 diff = vp->pts - ref_clock;
1013
1014                 /* skip or repeat frame. We take into account the
1015                    delay to compute the threshold. I still don't know
1016                    if it is the best guess */
1017                 sync_threshold = AV_SYNC_THRESHOLD;
1018                 if (delay > sync_threshold)
1019                     sync_threshold = delay;
1020                 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1021                     if (diff <= -sync_threshold)
1022                         delay = 0;
1023                     else if (diff >= sync_threshold)
1024                         delay = 2 * delay;
1025                 }
1026             }
1027
1028             is->frame_timer += delay;
1029             /* compute the REAL delay (we need to do that to avoid
1030                long term errors */
1031             actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1032             if (actual_delay < 0.010) {
1033                 /* XXX: should skip picture */
1034                 actual_delay = 0.010;
1035             }
1036             /* launch timer for next picture */
1037             schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
1038
1039 #if defined(DEBUG_SYNC)
1040             printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1041                    delay, actual_delay, vp->pts, -diff);
1042 #endif
1043
1044             if(is->subtitle_st) {
1045                 if (is->subtitle_stream_changed) {
1046                     SDL_LockMutex(is->subpq_mutex);
1047
1048                     while (is->subpq_size) {
1049                         free_subpicture(&is->subpq[is->subpq_rindex]);
1050
1051                         /* update queue size and signal for next picture */
1052                         if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1053                             is->subpq_rindex = 0;
1054
1055                         is->subpq_size--;
1056                     }
1057                     is->subtitle_stream_changed = 0;
1058
1059                     SDL_CondSignal(is->subpq_cond);
1060                     SDL_UnlockMutex(is->subpq_mutex);
1061                 } else {
1062                     if (is->subpq_size > 0) {
1063                         sp = &is->subpq[is->subpq_rindex];
1064
1065                         if (is->subpq_size > 1)
1066                             sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1067                         else
1068                             sp2 = NULL;
1069
1070                         if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1071                                 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1072                         {
1073                             free_subpicture(sp);
1074
1075                             /* update queue size and signal for next picture */
1076                             if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1077                                 is->subpq_rindex = 0;
1078
1079                             SDL_LockMutex(is->subpq_mutex);
1080                             is->subpq_size--;
1081                             SDL_CondSignal(is->subpq_cond);
1082                             SDL_UnlockMutex(is->subpq_mutex);
1083                         }
1084                     }
1085                 }
1086             }
1087
1088             /* display picture */
1089             video_display(is);
1090
1091             /* update queue size and signal for next picture */
1092             if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1093                 is->pictq_rindex = 0;
1094
1095             SDL_LockMutex(is->pictq_mutex);
1096             is->pictq_size--;
1097             SDL_CondSignal(is->pictq_cond);
1098             SDL_UnlockMutex(is->pictq_mutex);
1099         }
1100     } else if (is->audio_st) {
1101         /* draw the next audio frame */
1102
1103         schedule_refresh(is, 40);
1104
1105         /* if only audio stream, then display the audio bars (better
1106            than nothing, just to test the implementation */
1107
1108         /* display picture */
1109         video_display(is);
1110     } else {
1111         schedule_refresh(is, 100);
1112     }
1113     if (show_status) {
1114         static int64_t last_time;
1115         int64_t cur_time;
1116         int aqsize, vqsize, sqsize;
1117         double av_diff;
1118
1119         cur_time = av_gettime();
1120         if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1121             aqsize = 0;
1122             vqsize = 0;
1123             sqsize = 0;
1124             if (is->audio_st)
1125                 aqsize = is->audioq.size;
1126             if (is->video_st)
1127                 vqsize = is->videoq.size;
1128             if (is->subtitle_st)
1129                 sqsize = is->subtitleq.size;
1130             av_diff = 0;
1131             if (is->audio_st && is->video_st)
1132                 av_diff = get_audio_clock(is) - get_video_clock(is);
1133             printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1134                    get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1135             fflush(stdout);
1136             last_time = cur_time;
1137         }
1138     }
1139 }
1140
1141 /* allocate a picture (needs to do that in main thread to avoid
1142    potential locking problems */
1143 static void alloc_picture(void *opaque)
1144 {
1145     VideoState *is = opaque;
1146     VideoPicture *vp;
1147
1148     vp = &is->pictq[is->pictq_windex];
1149
1150     if (vp->bmp)
1151         SDL_FreeYUVOverlay(vp->bmp);
1152
1153 #if 0
1154     /* XXX: use generic function */
1155     /* XXX: disable overlay if no hardware acceleration or if RGB format */
1156     switch(is->video_st->codec->pix_fmt) {
1157     case PIX_FMT_YUV420P:
1158     case PIX_FMT_YUV422P:
1159     case PIX_FMT_YUV444P:
1160     case PIX_FMT_YUV422:
1161     case PIX_FMT_YUV410P:
1162     case PIX_FMT_YUV411P:
1163         is_yuv = 1;
1164         break;
1165     default:
1166         is_yuv = 0;
1167         break;
1168     }
1169 #endif
1170     vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1171                                    is->video_st->codec->height,
1172                                    SDL_YV12_OVERLAY,
1173                                    screen);
1174     vp->width = is->video_st->codec->width;
1175     vp->height = is->video_st->codec->height;
1176
1177     SDL_LockMutex(is->pictq_mutex);
1178     vp->allocated = 1;
1179     SDL_CondSignal(is->pictq_cond);
1180     SDL_UnlockMutex(is->pictq_mutex);
1181 }
1182
1183 /**
1184  *
1185  * @param pts the dts of the pkt / pts of the frame and guessed if not known
1186  */
1187 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1188 {
1189     VideoPicture *vp;
1190     int dst_pix_fmt;
1191     AVPicture pict;
1192     static struct SwsContext *img_convert_ctx;
1193
1194     /* wait until we have space to put a new picture */
1195     SDL_LockMutex(is->pictq_mutex);
1196     while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1197            !is->videoq.abort_request) {
1198         SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1199     }
1200     SDL_UnlockMutex(is->pictq_mutex);
1201
1202     if (is->videoq.abort_request)
1203         return -1;
1204
1205     vp = &is->pictq[is->pictq_windex];
1206
1207     /* alloc or resize hardware picture buffer */
1208     if (!vp->bmp ||
1209         vp->width != is->video_st->codec->width ||
1210         vp->height != is->video_st->codec->height) {
1211         SDL_Event event;
1212
1213         vp->allocated = 0;
1214
1215         /* the allocation must be done in the main thread to avoid
1216            locking problems */
1217         event.type = FF_ALLOC_EVENT;
1218         event.user.data1 = is;
1219         SDL_PushEvent(&event);
1220
1221         /* wait until the picture is allocated */
1222         SDL_LockMutex(is->pictq_mutex);
1223         while (!vp->allocated && !is->videoq.abort_request) {
1224             SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1225         }
1226         SDL_UnlockMutex(is->pictq_mutex);
1227
1228         if (is->videoq.abort_request)
1229             return -1;
1230     }
1231
1232     /* if the frame is not skipped, then display it */
1233     if (vp->bmp) {
1234         /* get a pointer on the bitmap */
1235         SDL_LockYUVOverlay (vp->bmp);
1236
1237         dst_pix_fmt = PIX_FMT_YUV420P;
1238         pict.data[0] = vp->bmp->pixels[0];
1239         pict.data[1] = vp->bmp->pixels[2];
1240         pict.data[2] = vp->bmp->pixels[1];
1241
1242         pict.linesize[0] = vp->bmp->pitches[0];
1243         pict.linesize[1] = vp->bmp->pitches[2];
1244         pict.linesize[2] = vp->bmp->pitches[1];
1245         if (img_convert_ctx == NULL) {
1246             img_convert_ctx = sws_getContext(is->video_st->codec->width,
1247                     is->video_st->codec->height, is->video_st->codec->pix_fmt,
1248                     is->video_st->codec->width, is->video_st->codec->height,
1249                     dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1250             if (img_convert_ctx == NULL) {
1251                 fprintf(stderr, "Cannot initialize the conversion context\n");
1252                 exit(1);
1253             }
1254         }
1255         sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1256                   0, is->video_st->codec->height, pict.data, pict.linesize);
1257         /* update the bitmap content */
1258         SDL_UnlockYUVOverlay(vp->bmp);
1259
1260         vp->pts = pts;
1261
1262         /* now we can update the picture count */
1263         if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1264             is->pictq_windex = 0;
1265         SDL_LockMutex(is->pictq_mutex);
1266         is->pictq_size++;
1267         SDL_UnlockMutex(is->pictq_mutex);
1268     }
1269     return 0;
1270 }
1271
1272 /**
1273  * compute the exact PTS for the picture if it is omitted in the stream
1274  * @param pts1 the dts of the pkt / pts of the frame
1275  */
1276 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1277 {
1278     double frame_delay, pts;
1279
1280     pts = pts1;
1281
1282     if (pts != 0) {
1283         /* update video clock with pts, if present */
1284         is->video_clock = pts;
1285     } else {
1286         pts = is->video_clock;
1287     }
1288     /* update video clock for next frame */
1289     frame_delay = av_q2d(is->video_st->codec->time_base);
1290     /* for MPEG2, the frame can be repeated, so we update the
1291        clock accordingly */
1292     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1293     is->video_clock += frame_delay;
1294
1295 #if defined(DEBUG_SYNC) && 0
1296     {
1297         int ftype;
1298         if (src_frame->pict_type == FF_B_TYPE)
1299             ftype = 'B';
1300         else if (src_frame->pict_type == FF_I_TYPE)
1301             ftype = 'I';
1302         else
1303             ftype = 'P';
1304         printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1305                ftype, pts, pts1);
1306     }
1307 #endif
1308     return queue_picture(is, src_frame, pts);
1309 }
1310
1311 static int video_thread(void *arg)
1312 {
1313     VideoState *is = arg;
1314     AVPacket pkt1, *pkt = &pkt1;
1315     int len1, got_picture;
1316     AVFrame *frame= avcodec_alloc_frame();
1317     double pts;
1318
1319     for(;;) {
1320         while (is->paused && !is->videoq.abort_request) {
1321             SDL_Delay(10);
1322         }
1323         if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1324             break;
1325
1326         if(pkt->data == flush_pkt.data){
1327             avcodec_flush_buffers(is->video_st->codec);
1328             continue;
1329         }
1330
1331         /* NOTE: ipts is the PTS of the _first_ picture beginning in
1332            this packet, if any */
1333         pts = 0;
1334         if (pkt->dts != AV_NOPTS_VALUE)
1335             pts = av_q2d(is->video_st->time_base)*pkt->dts;
1336
1337             len1 = avcodec_decode_video(is->video_st->codec,
1338                                         frame, &got_picture,
1339                                         pkt->data, pkt->size);
1340 //            if (len1 < 0)
1341 //                break;
1342             if (got_picture) {
1343                 if (output_picture2(is, frame, pts) < 0)
1344                     goto the_end;
1345             }
1346         av_free_packet(pkt);
1347         if (step)
1348             if (cur_stream)
1349                 stream_pause(cur_stream);
1350     }
1351  the_end:
1352     av_free(frame);
1353     return 0;
1354 }
1355
1356 static int subtitle_thread(void *arg)
1357 {
1358     VideoState *is = arg;
1359     SubPicture *sp;
1360     AVPacket pkt1, *pkt = &pkt1;
1361     int len1, got_subtitle;
1362     double pts;
1363     int i, j;
1364     int r, g, b, y, u, v, a;
1365
1366     for(;;) {
1367         while (is->paused && !is->subtitleq.abort_request) {
1368             SDL_Delay(10);
1369         }
1370         if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1371             break;
1372
1373         if(pkt->data == flush_pkt.data){
1374             avcodec_flush_buffers(is->subtitle_st->codec);
1375             continue;
1376         }
1377         SDL_LockMutex(is->subpq_mutex);
1378         while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1379                !is->subtitleq.abort_request) {
1380             SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1381         }
1382         SDL_UnlockMutex(is->subpq_mutex);
1383
1384         if (is->subtitleq.abort_request)
1385             goto the_end;
1386
1387         sp = &is->subpq[is->subpq_windex];
1388
1389        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1390            this packet, if any */
1391         pts = 0;
1392         if (pkt->pts != AV_NOPTS_VALUE)
1393             pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1394
1395         len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1396                                     &sp->sub, &got_subtitle,
1397                                     pkt->data, pkt->size);
1398 //            if (len1 < 0)
1399 //                break;
1400         if (got_subtitle && sp->sub.format == 0) {
1401             sp->pts = pts;
1402
1403             for (i = 0; i < sp->sub.num_rects; i++)
1404             {
1405                 for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1406                 {
1407                     RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1408                     y = RGB_TO_Y_CCIR(r, g, b);
1409                     u = RGB_TO_U_CCIR(r, g, b, 0);
1410                     v = RGB_TO_V_CCIR(r, g, b, 0);
1411                     YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1412                 }
1413             }
1414
1415             /* now we can update the picture count */
1416             if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1417                 is->subpq_windex = 0;
1418             SDL_LockMutex(is->subpq_mutex);
1419             is->subpq_size++;
1420             SDL_UnlockMutex(is->subpq_mutex);
1421         }
1422         av_free_packet(pkt);
1423 //        if (step)
1424 //            if (cur_stream)
1425 //                stream_pause(cur_stream);
1426     }
1427  the_end:
1428     return 0;
1429 }
1430
1431 /* copy samples for viewing in editor window */
1432 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1433 {
1434     int size, len, channels;
1435
1436     channels = is->audio_st->codec->channels;
1437
1438     size = samples_size / sizeof(short);
1439     while (size > 0) {
1440         len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1441         if (len > size)
1442             len = size;
1443         memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1444         samples += len;
1445         is->sample_array_index += len;
1446         if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1447             is->sample_array_index = 0;
1448         size -= len;
1449     }
1450 }
1451
1452 /* return the new audio buffer size (samples can be added or deleted
1453    to get better sync if video or external master clock) */
1454 static int synchronize_audio(VideoState *is, short *samples,
1455                              int samples_size1, double pts)
1456 {
1457     int n, samples_size;
1458     double ref_clock;
1459
1460     n = 2 * is->audio_st->codec->channels;
1461     samples_size = samples_size1;
1462
1463     /* if not master, then we try to remove or add samples to correct the clock */
1464     if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1465          is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1466         double diff, avg_diff;
1467         int wanted_size, min_size, max_size, nb_samples;
1468
1469         ref_clock = get_master_clock(is);
1470         diff = get_audio_clock(is) - ref_clock;
1471
1472         if (diff < AV_NOSYNC_THRESHOLD) {
1473             is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1474             if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1475                 /* not enough measures to have a correct estimate */
1476                 is->audio_diff_avg_count++;
1477             } else {
1478                 /* estimate the A-V difference */
1479                 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1480
1481                 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1482                     wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1483                     nb_samples = samples_size / n;
1484
1485                     min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1486                     max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1487                     if (wanted_size < min_size)
1488                         wanted_size = min_size;
1489                     else if (wanted_size > max_size)
1490                         wanted_size = max_size;
1491
1492                     /* add or remove samples to correction the synchro */
1493                     if (wanted_size < samples_size) {
1494                         /* remove samples */
1495                         samples_size = wanted_size;
1496                     } else if (wanted_size > samples_size) {
1497                         uint8_t *samples_end, *q;
1498                         int nb;
1499
1500                         /* add samples */
1501                         nb = (samples_size - wanted_size);
1502                         samples_end = (uint8_t *)samples + samples_size - n;
1503                         q = samples_end + n;
1504                         while (nb > 0) {
1505                             memcpy(q, samples_end, n);
1506                             q += n;
1507                             nb -= n;
1508                         }
1509                         samples_size = wanted_size;
1510                     }
1511                 }
1512 #if 0
1513                 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1514                        diff, avg_diff, samples_size - samples_size1,
1515                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
1516 #endif
1517             }
1518         } else {
1519             /* too big difference : may be initial PTS errors, so
1520                reset A-V filter */
1521             is->audio_diff_avg_count = 0;
1522             is->audio_diff_cum = 0;
1523         }
1524     }
1525
1526     return samples_size;
1527 }
1528
1529 /* decode one audio frame and returns its uncompressed size */
1530 static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
1531 {
1532     AVPacket *pkt = &is->audio_pkt;
1533     int n, len1, data_size;
1534     double pts;
1535
1536     for(;;) {
1537         /* NOTE: the audio packet can contain several frames */
1538         while (is->audio_pkt_size > 0) {
1539             len1 = avcodec_decode_audio(is->audio_st->codec,
1540                                         (int16_t *)audio_buf, &data_size,
1541                                         is->audio_pkt_data, is->audio_pkt_size);
1542             if (len1 < 0) {
1543                 /* if error, we skip the frame */
1544                 is->audio_pkt_size = 0;
1545                 break;
1546             }
1547
1548             is->audio_pkt_data += len1;
1549             is->audio_pkt_size -= len1;
1550             if (data_size <= 0)
1551                 continue;
1552             /* if no pts, then compute it */
1553             pts = is->audio_clock;
1554             *pts_ptr = pts;
1555             n = 2 * is->audio_st->codec->channels;
1556             is->audio_clock += (double)data_size /
1557                 (double)(n * is->audio_st->codec->sample_rate);
1558 #if defined(DEBUG_SYNC)
1559             {
1560                 static double last_clock;
1561                 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1562                        is->audio_clock - last_clock,
1563                        is->audio_clock, pts);
1564                 last_clock = is->audio_clock;
1565             }
1566 #endif
1567             return data_size;
1568         }
1569
1570         /* free the current packet */
1571         if (pkt->data)
1572             av_free_packet(pkt);
1573
1574         if (is->paused || is->audioq.abort_request) {
1575             return -1;
1576         }
1577
1578         /* read next packet */
1579         if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1580             return -1;
1581         if(pkt->data == flush_pkt.data){
1582             avcodec_flush_buffers(is->audio_st->codec);
1583             continue;
1584         }
1585
1586         is->audio_pkt_data = pkt->data;
1587         is->audio_pkt_size = pkt->size;
1588
1589         /* if update the audio clock with the pts */
1590         if (pkt->pts != AV_NOPTS_VALUE) {
1591             is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1592         }
1593     }
1594 }
1595
1596 /* get the current audio output buffer size, in samples. With SDL, we
1597    cannot have a precise information */
1598 static int audio_write_get_buf_size(VideoState *is)
1599 {
1600     return is->audio_hw_buf_size - is->audio_buf_index;
1601 }
1602
1603
1604 /* prepare a new audio buffer */
1605 void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1606 {
1607     VideoState *is = opaque;
1608     int audio_size, len1;
1609     double pts;
1610
1611     audio_callback_time = av_gettime();
1612
1613     while (len > 0) {
1614         if (is->audio_buf_index >= is->audio_buf_size) {
1615            audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1616            if (audio_size < 0) {
1617                 /* if error, just output silence */
1618                is->audio_buf_size = 1024;
1619                memset(is->audio_buf, 0, is->audio_buf_size);
1620            } else {
1621                if (is->show_audio)
1622                    update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1623                audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1624                                               pts);
1625                is->audio_buf_size = audio_size;
1626            }
1627            is->audio_buf_index = 0;
1628         }
1629         len1 = is->audio_buf_size - is->audio_buf_index;
1630         if (len1 > len)
1631             len1 = len;
1632         memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1633         len -= len1;
1634         stream += len1;
1635         is->audio_buf_index += len1;
1636     }
1637 }
1638
1639 /* open a given stream. Return 0 if OK */
1640 static int stream_component_open(VideoState *is, int stream_index)
1641 {
1642     AVFormatContext *ic = is->ic;
1643     AVCodecContext *enc;
1644     AVCodec *codec;
1645     SDL_AudioSpec wanted_spec, spec;
1646
1647     if (stream_index < 0 || stream_index >= ic->nb_streams)
1648         return -1;
1649     enc = ic->streams[stream_index]->codec;
1650
1651     /* prepare audio output */
1652     if (enc->codec_type == CODEC_TYPE_AUDIO) {
1653         wanted_spec.freq = enc->sample_rate;
1654         wanted_spec.format = AUDIO_S16SYS;
1655         /* hack for AC3. XXX: suppress that */
1656         if (enc->channels > 2)
1657             enc->channels = 2;
1658         wanted_spec.channels = enc->channels;
1659         wanted_spec.silence = 0;
1660         wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1661         wanted_spec.callback = sdl_audio_callback;
1662         wanted_spec.userdata = is;
1663         if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1664             fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1665             return -1;
1666         }
1667         is->audio_hw_buf_size = spec.size;
1668     }
1669
1670     codec = avcodec_find_decoder(enc->codec_id);
1671     enc->debug_mv = debug_mv;
1672     enc->debug = debug;
1673     enc->workaround_bugs = workaround_bugs;
1674     enc->lowres = lowres;
1675     if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1676     enc->idct_algo= idct;
1677     if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1678     enc->skip_frame= skip_frame;
1679     enc->skip_idct= skip_idct;
1680     enc->skip_loop_filter= skip_loop_filter;
1681     enc->error_resilience= error_resilience;
1682     enc->error_concealment= error_concealment;
1683     if (!codec ||
1684         avcodec_open(enc, codec) < 0)
1685         return -1;
1686 #if defined(HAVE_THREADS)
1687     if(thread_count>1)
1688         avcodec_thread_init(enc, thread_count);
1689 #endif
1690     enc->thread_count= thread_count;
1691     switch(enc->codec_type) {
1692     case CODEC_TYPE_AUDIO:
1693         is->audio_stream = stream_index;
1694         is->audio_st = ic->streams[stream_index];
1695         is->audio_buf_size = 0;
1696         is->audio_buf_index = 0;
1697
1698         /* init averaging filter */
1699         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1700         is->audio_diff_avg_count = 0;
1701         /* since we do not have a precise anough audio fifo fullness,
1702            we correct audio sync only if larger than this threshold */
1703         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1704
1705         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1706         packet_queue_init(&is->audioq);
1707         SDL_PauseAudio(0);
1708         break;
1709     case CODEC_TYPE_VIDEO:
1710         is->video_stream = stream_index;
1711         is->video_st = ic->streams[stream_index];
1712
1713         is->frame_last_delay = 40e-3;
1714         is->frame_timer = (double)av_gettime() / 1000000.0;
1715         is->video_current_pts_time = av_gettime();
1716
1717         packet_queue_init(&is->videoq);
1718         is->video_tid = SDL_CreateThread(video_thread, is);
1719         break;
1720     case CODEC_TYPE_SUBTITLE:
1721         is->subtitle_stream = stream_index;
1722         is->subtitle_st = ic->streams[stream_index];
1723         packet_queue_init(&is->subtitleq);
1724
1725         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1726         break;
1727     default:
1728         break;
1729     }
1730     return 0;
1731 }
1732
1733 static void stream_component_close(VideoState *is, int stream_index)
1734 {
1735     AVFormatContext *ic = is->ic;
1736     AVCodecContext *enc;
1737
1738     if (stream_index < 0 || stream_index >= ic->nb_streams)
1739         return;
1740     enc = ic->streams[stream_index]->codec;
1741
1742     switch(enc->codec_type) {
1743     case CODEC_TYPE_AUDIO:
1744         packet_queue_abort(&is->audioq);
1745
1746         SDL_CloseAudio();
1747
1748         packet_queue_end(&is->audioq);
1749         break;
1750     case CODEC_TYPE_VIDEO:
1751         packet_queue_abort(&is->videoq);
1752
1753         /* note: we also signal this mutex to make sure we deblock the
1754            video thread in all cases */
1755         SDL_LockMutex(is->pictq_mutex);
1756         SDL_CondSignal(is->pictq_cond);
1757         SDL_UnlockMutex(is->pictq_mutex);
1758
1759         SDL_WaitThread(is->video_tid, NULL);
1760
1761         packet_queue_end(&is->videoq);
1762         break;
1763     case CODEC_TYPE_SUBTITLE:
1764         packet_queue_abort(&is->subtitleq);
1765
1766         /* note: we also signal this mutex to make sure we deblock the
1767            video thread in all cases */
1768         SDL_LockMutex(is->subpq_mutex);
1769         is->subtitle_stream_changed = 1;
1770
1771         SDL_CondSignal(is->subpq_cond);
1772         SDL_UnlockMutex(is->subpq_mutex);
1773
1774         SDL_WaitThread(is->subtitle_tid, NULL);
1775
1776         packet_queue_end(&is->subtitleq);
1777         break;
1778     default:
1779         break;
1780     }
1781
1782     avcodec_close(enc);
1783     switch(enc->codec_type) {
1784     case CODEC_TYPE_AUDIO:
1785         is->audio_st = NULL;
1786         is->audio_stream = -1;
1787         break;
1788     case CODEC_TYPE_VIDEO:
1789         is->video_st = NULL;
1790         is->video_stream = -1;
1791         break;
1792     case CODEC_TYPE_SUBTITLE:
1793         is->subtitle_st = NULL;
1794         is->subtitle_stream = -1;
1795         break;
1796     default:
1797         break;
1798     }
1799 }
1800
1801 static void dump_stream_info(const AVFormatContext *s)
1802 {
1803     if (s->track != 0)
1804         fprintf(stderr, "Track: %d\n", s->track);
1805     if (s->title[0] != '\0')
1806         fprintf(stderr, "Title: %s\n", s->title);
1807     if (s->author[0] != '\0')
1808         fprintf(stderr, "Author: %s\n", s->author);
1809     if (s->copyright[0] != '\0')
1810         fprintf(stderr, "Copyright: %s\n", s->copyright);
1811     if (s->comment[0] != '\0')
1812         fprintf(stderr, "Comment: %s\n", s->comment);
1813     if (s->album[0] != '\0')
1814         fprintf(stderr, "Album: %s\n", s->album);
1815     if (s->year != 0)
1816         fprintf(stderr, "Year: %d\n", s->year);
1817     if (s->genre[0] != '\0')
1818         fprintf(stderr, "Genre: %s\n", s->genre);
1819 }
1820
1821 /* since we have only one decoding thread, we can use a global
1822    variable instead of a thread local variable */
1823 static VideoState *global_video_state;
1824
1825 static int decode_interrupt_cb(void)
1826 {
1827     return (global_video_state && global_video_state->abort_request);
1828 }
1829
1830 /* this thread gets the stream from the disk or the network */
1831 static int decode_thread(void *arg)
1832 {
1833     VideoState *is = arg;
1834     AVFormatContext *ic;
1835     int err, i, ret, video_index, audio_index, use_play;
1836     AVPacket pkt1, *pkt = &pkt1;
1837     AVFormatParameters params, *ap = &params;
1838
1839     video_index = -1;
1840     audio_index = -1;
1841     is->video_stream = -1;
1842     is->audio_stream = -1;
1843     is->subtitle_stream = -1;
1844
1845     global_video_state = is;
1846     url_set_interrupt_cb(decode_interrupt_cb);
1847
1848     memset(ap, 0, sizeof(*ap));
1849     ap->initial_pause = 1; /* we force a pause when starting an RTSP
1850                               stream */
1851
1852     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1853     if (err < 0) {
1854         print_error(is->filename, err);
1855         ret = -1;
1856         goto fail;
1857     }
1858     is->ic = ic;
1859 #ifdef CONFIG_NETWORK
1860     use_play = (ic->iformat == &rtsp_demuxer);
1861 #else
1862     use_play = 0;
1863 #endif
1864
1865     if(genpts)
1866         ic->flags |= AVFMT_FLAG_GENPTS;
1867
1868     if (!use_play) {
1869         err = av_find_stream_info(ic);
1870         if (err < 0) {
1871             fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1872             ret = -1;
1873             goto fail;
1874         }
1875         ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
1876     }
1877
1878     /* if seeking requested, we execute it */
1879     if (start_time != AV_NOPTS_VALUE) {
1880         int64_t timestamp;
1881
1882         timestamp = start_time;
1883         /* add the stream start time */
1884         if (ic->start_time != AV_NOPTS_VALUE)
1885             timestamp += ic->start_time;
1886         ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1887         if (ret < 0) {
1888             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1889                     is->filename, (double)timestamp / AV_TIME_BASE);
1890         }
1891     }
1892
1893     /* now we can begin to play (RTSP stream only) */
1894     av_read_play(ic);
1895
1896     if (use_play) {
1897         err = av_find_stream_info(ic);
1898         if (err < 0) {
1899             fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1900             ret = -1;
1901             goto fail;
1902         }
1903     }
1904
1905     for(i = 0; i < ic->nb_streams; i++) {
1906         AVCodecContext *enc = ic->streams[i]->codec;
1907         switch(enc->codec_type) {
1908         case CODEC_TYPE_AUDIO:
1909             if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)
1910                 audio_index = i;
1911             break;
1912         case CODEC_TYPE_VIDEO:
1913             if (video_index < 0 && !video_disable)
1914                 video_index = i;
1915             break;
1916         default:
1917             break;
1918         }
1919     }
1920     if (show_status) {
1921         dump_format(ic, 0, is->filename, 0);
1922         dump_stream_info(ic);
1923     }
1924
1925     /* open the streams */
1926     if (audio_index >= 0) {
1927         stream_component_open(is, audio_index);
1928     }
1929
1930     if (video_index >= 0) {
1931         stream_component_open(is, video_index);
1932     } else {
1933         if (!display_disable)
1934             is->show_audio = 1;
1935     }
1936
1937     if (is->video_stream < 0 && is->audio_stream < 0) {
1938         fprintf(stderr, "%s: could not open codecs\n", is->filename);
1939         ret = -1;
1940         goto fail;
1941     }
1942
1943     for(;;) {
1944         if (is->abort_request)
1945             break;
1946 #ifdef CONFIG_NETWORK
1947         if (is->paused != is->last_paused) {
1948             is->last_paused = is->paused;
1949             if (is->paused)
1950                 av_read_pause(ic);
1951             else
1952                 av_read_play(ic);
1953         }
1954         if (is->paused && ic->iformat == &rtsp_demuxer) {
1955             /* wait 10 ms to avoid trying to get another packet */
1956             /* XXX: horrible */
1957             SDL_Delay(10);
1958             continue;
1959         }
1960 #endif
1961         if (is->seek_req) {
1962             ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
1963             if (ret < 0) {
1964                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
1965             }else{
1966                 if (is->audio_stream >= 0) {
1967                     packet_queue_flush(&is->audioq);
1968                     packet_queue_put(&is->audioq, &flush_pkt);
1969                 }
1970                 if (is->subtitle_stream >= 0) {
1971                     packet_queue_flush(&is->subtitleq);
1972                     packet_queue_put(&is->subtitleq, &flush_pkt);
1973                 }
1974                 if (is->video_stream >= 0) {
1975                     packet_queue_flush(&is->videoq);
1976                     packet_queue_put(&is->videoq, &flush_pkt);
1977                 }
1978             }
1979             is->seek_req = 0;
1980         }
1981
1982         /* if the queue are full, no need to read more */
1983         if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1984             is->videoq.size > MAX_VIDEOQ_SIZE ||
1985             is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1986             url_feof(&ic->pb)) {
1987             /* wait 10 ms */
1988             SDL_Delay(10);
1989             continue;
1990         }
1991         ret = av_read_frame(ic, pkt);
1992         if (ret < 0) {
1993             if (url_ferror(&ic->pb) == 0) {
1994                 SDL_Delay(100); /* wait for user event */
1995                 continue;
1996             } else
1997                 break;
1998         }
1999         if (pkt->stream_index == is->audio_stream) {
2000             packet_queue_put(&is->audioq, pkt);
2001         } else if (pkt->stream_index == is->video_stream) {
2002             packet_queue_put(&is->videoq, pkt);
2003         } else if (pkt->stream_index == is->subtitle_stream) {
2004             packet_queue_put(&is->subtitleq, pkt);
2005         } else {
2006             av_free_packet(pkt);
2007         }
2008     }
2009     /* wait until the end */
2010     while (!is->abort_request) {
2011         SDL_Delay(100);
2012     }
2013
2014     ret = 0;
2015  fail:
2016     /* disable interrupting */
2017     global_video_state = NULL;
2018
2019     /* close each stream */
2020     if (is->audio_stream >= 0)
2021         stream_component_close(is, is->audio_stream);
2022     if (is->video_stream >= 0)
2023         stream_component_close(is, is->video_stream);
2024     if (is->subtitle_stream >= 0)
2025         stream_component_close(is, is->subtitle_stream);
2026     if (is->ic) {
2027         av_close_input_file(is->ic);
2028         is->ic = NULL; /* safety */
2029     }
2030     url_set_interrupt_cb(NULL);
2031
2032     if (ret != 0) {
2033         SDL_Event event;
2034
2035         event.type = FF_QUIT_EVENT;
2036         event.user.data1 = is;
2037         SDL_PushEvent(&event);
2038     }
2039     return 0;
2040 }
2041
2042 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2043 {
2044     VideoState *is;
2045
2046     is = av_mallocz(sizeof(VideoState));
2047     if (!is)
2048         return NULL;
2049     pstrcpy(is->filename, sizeof(is->filename), filename);
2050     is->iformat = iformat;
2051     is->ytop = 0;
2052     is->xleft = 0;
2053
2054     /* start video display */
2055     is->pictq_mutex = SDL_CreateMutex();
2056     is->pictq_cond = SDL_CreateCond();
2057
2058     is->subpq_mutex = SDL_CreateMutex();
2059     is->subpq_cond = SDL_CreateCond();
2060
2061     /* add the refresh timer to draw the picture */
2062     schedule_refresh(is, 40);
2063
2064     is->av_sync_type = av_sync_type;
2065     is->parse_tid = SDL_CreateThread(decode_thread, is);
2066     if (!is->parse_tid) {
2067         av_free(is);
2068         return NULL;
2069     }
2070     return is;
2071 }
2072
2073 static void stream_close(VideoState *is)
2074 {
2075     VideoPicture *vp;
2076     int i;
2077     /* XXX: use a special url_shutdown call to abort parse cleanly */
2078     is->abort_request = 1;
2079     SDL_WaitThread(is->parse_tid, NULL);
2080
2081     /* free all pictures */
2082     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2083         vp = &is->pictq[i];
2084         if (vp->bmp) {
2085             SDL_FreeYUVOverlay(vp->bmp);
2086             vp->bmp = NULL;
2087         }
2088     }
2089     SDL_DestroyMutex(is->pictq_mutex);
2090     SDL_DestroyCond(is->pictq_cond);
2091     SDL_DestroyMutex(is->subpq_mutex);
2092     SDL_DestroyCond(is->subpq_cond);
2093 }
2094
2095 static void stream_cycle_channel(VideoState *is, int codec_type)
2096 {
2097     AVFormatContext *ic = is->ic;
2098     int start_index, stream_index;
2099     AVStream *st;
2100
2101     if (codec_type == CODEC_TYPE_VIDEO)
2102         start_index = is->video_stream;
2103     else if (codec_type == CODEC_TYPE_AUDIO)
2104         start_index = is->audio_stream;
2105     else
2106         start_index = is->subtitle_stream;
2107     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2108         return;
2109     stream_index = start_index;
2110     for(;;) {
2111         if (++stream_index >= is->ic->nb_streams)
2112         {
2113             if (codec_type == CODEC_TYPE_SUBTITLE)
2114             {
2115                 stream_index = -1;
2116                 goto the_end;
2117             } else
2118                 stream_index = 0;
2119         }
2120         if (stream_index == start_index)
2121             return;
2122         st = ic->streams[stream_index];
2123         if (st->codec->codec_type == codec_type) {
2124             /* check that parameters are OK */
2125             switch(codec_type) {
2126             case CODEC_TYPE_AUDIO:
2127                 if (st->codec->sample_rate != 0 &&
2128                     st->codec->channels != 0)
2129                     goto the_end;
2130                 break;
2131             case CODEC_TYPE_VIDEO:
2132             case CODEC_TYPE_SUBTITLE:
2133                 goto the_end;
2134             default:
2135                 break;
2136             }
2137         }
2138     }
2139  the_end:
2140     stream_component_close(is, start_index);
2141     stream_component_open(is, stream_index);
2142 }
2143
2144
2145 static void toggle_full_screen(void)
2146 {
2147     is_full_screen = !is_full_screen;
2148     if (!fs_screen_width) {
2149         /* use default SDL method */
2150 //        SDL_WM_ToggleFullScreen(screen);
2151     }
2152     video_open(cur_stream);
2153 }
2154
2155 static void toggle_pause(void)
2156 {
2157     if (cur_stream)
2158         stream_pause(cur_stream);
2159     step = 0;
2160 }
2161
2162 static void step_to_next_frame(void)
2163 {
2164     if (cur_stream) {
2165         if (cur_stream->paused)
2166             cur_stream->paused=0;
2167         cur_stream->video_current_pts = get_video_clock(cur_stream);
2168     }
2169     step = 1;
2170 }
2171
2172 static void do_exit(void)
2173 {
2174     if (cur_stream) {
2175         stream_close(cur_stream);
2176         cur_stream = NULL;
2177     }
2178     if (show_status)
2179         printf("\n");
2180     SDL_Quit();
2181     exit(0);
2182 }
2183
2184 static void toggle_audio_display(void)
2185 {
2186     if (cur_stream) {
2187         cur_stream->show_audio = !cur_stream->show_audio;
2188     }
2189 }
2190
2191 /* handle an event sent by the GUI */
2192 static void event_loop(void)
2193 {
2194     SDL_Event event;
2195     double incr, pos, frac;
2196
2197     for(;;) {
2198         SDL_WaitEvent(&event);
2199         switch(event.type) {
2200         case SDL_KEYDOWN:
2201             switch(event.key.keysym.sym) {
2202             case SDLK_ESCAPE:
2203             case SDLK_q:
2204                 do_exit();
2205                 break;
2206             case SDLK_f:
2207                 toggle_full_screen();
2208                 break;
2209             case SDLK_p:
2210             case SDLK_SPACE:
2211                 toggle_pause();
2212                 break;
2213             case SDLK_s: //S: Step to next frame
2214                 step_to_next_frame();
2215                 break;
2216             case SDLK_a:
2217                 if (cur_stream)
2218                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2219                 break;
2220             case SDLK_v:
2221                 if (cur_stream)
2222                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2223                 break;
2224             case SDLK_t:
2225                 if (cur_stream)
2226                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2227                 break;
2228             case SDLK_w:
2229                 toggle_audio_display();
2230                 break;
2231             case SDLK_LEFT:
2232                 incr = -10.0;
2233                 goto do_seek;
2234             case SDLK_RIGHT:
2235                 incr = 10.0;
2236                 goto do_seek;
2237             case SDLK_UP:
2238                 incr = 60.0;
2239                 goto do_seek;
2240             case SDLK_DOWN:
2241                 incr = -60.0;
2242             do_seek:
2243                 if (cur_stream) {
2244                     if (seek_by_bytes) {
2245                         pos = url_ftell(&cur_stream->ic->pb);
2246                         if (cur_stream->ic->bit_rate)
2247                             incr *= cur_stream->ic->bit_rate / 60.0;
2248                         else
2249                             incr *= 180000.0;
2250                         pos += incr;
2251                         stream_seek(cur_stream, pos, incr);
2252                     } else {
2253                         pos = get_master_clock(cur_stream);
2254                         pos += incr;
2255                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2256                     }
2257                 }
2258                 break;
2259             default:
2260                 break;
2261             }
2262             break;
2263         case SDL_MOUSEBUTTONDOWN:
2264             if (cur_stream) {
2265                 int ns, hh, mm, ss;
2266                 int tns, thh, tmm, tss;
2267                 tns = cur_stream->ic->duration/1000000LL;
2268                 thh = tns/3600;
2269                 tmm = (tns%3600)/60;
2270                 tss = (tns%60);
2271                 frac = (double)event.button.x/(double)cur_stream->width;
2272                 ns = frac*tns;
2273                 hh = ns/3600;
2274                 mm = (ns%3600)/60;
2275                 ss = (ns%60);
2276                 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2277                         hh, mm, ss, thh, tmm, tss);
2278                 stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2279             }
2280             break;
2281         case SDL_VIDEORESIZE:
2282             if (cur_stream) {
2283                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2284                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2285                 screen_width = cur_stream->width = event.resize.w;
2286                 screen_height= cur_stream->height= event.resize.h;
2287             }
2288             break;
2289         case SDL_QUIT:
2290         case FF_QUIT_EVENT:
2291             do_exit();
2292             break;
2293         case FF_ALLOC_EVENT:
2294             video_open(event.user.data1);
2295             alloc_picture(event.user.data1);
2296             break;
2297         case FF_REFRESH_EVENT:
2298             video_refresh_timer(event.user.data1);
2299             break;
2300         default:
2301             break;
2302         }
2303     }
2304 }
2305
2306 void opt_width(const char *arg)
2307 {
2308     screen_width = atoi(arg);
2309     if(screen_width<=0){
2310         fprintf(stderr, "invalid width\n");
2311         exit(1);
2312     }
2313 }
2314
2315 void opt_height(const char *arg)
2316 {
2317     screen_height = atoi(arg);
2318     if(screen_height<=0){
2319         fprintf(stderr, "invalid height\n");
2320         exit(1);
2321     }
2322 }
2323
2324 static void opt_format(const char *arg)
2325 {
2326     file_iformat = av_find_input_format(arg);
2327     if (!file_iformat) {
2328         fprintf(stderr, "Unknown input format: %s\n", arg);
2329         exit(1);
2330     }
2331 }
2332
2333 #ifdef CONFIG_NETWORK
2334 void opt_rtp_tcp(void)
2335 {
2336     /* only tcp protocol */
2337     rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2338 }
2339 #endif
2340
2341 void opt_sync(const char *arg)
2342 {
2343     if (!strcmp(arg, "audio"))
2344         av_sync_type = AV_SYNC_AUDIO_MASTER;
2345     else if (!strcmp(arg, "video"))
2346         av_sync_type = AV_SYNC_VIDEO_MASTER;
2347     else if (!strcmp(arg, "ext"))
2348         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2349     else
2350         show_help();
2351 }
2352
2353 void opt_seek(const char *arg)
2354 {
2355     start_time = parse_date(arg, 1);
2356 }
2357
2358 static void opt_debug(const char *arg)
2359 {
2360     av_log_set_level(99);
2361     debug = atoi(arg);
2362 }
2363
2364 static void opt_vismv(const char *arg)
2365 {
2366     debug_mv = atoi(arg);
2367 }
2368
2369 static void opt_thread_count(const char *arg)
2370 {
2371     thread_count= atoi(arg);
2372 #if !defined(HAVE_THREADS)
2373     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2374 #endif
2375 }
2376
2377 const OptionDef options[] = {
2378     { "h", 0, {(void*)show_help}, "show help" },
2379     { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2380     { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2381     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2382     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2383     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2384     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "", "" },
2385     { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2386     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2387     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2388     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2389     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2390     { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2391     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2392     { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2393     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2394     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2395     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2396     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2397     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2398     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2399     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2400     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
2401     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2402 #ifdef CONFIG_NETWORK
2403     { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2404 #endif
2405     { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2406     { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2407     { NULL, },
2408 };
2409
2410 void show_help(void)
2411 {
2412     printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
2413            "usage: ffplay [options] input_file\n"
2414            "Simple media player\n");
2415     printf("\n");
2416     show_help_options(options, "Main options:\n",
2417                       OPT_EXPERT, 0);
2418     show_help_options(options, "\nAdvanced options:\n",
2419                       OPT_EXPERT, OPT_EXPERT);
2420     printf("\nWhile playing:\n"
2421            "q, ESC              quit\n"
2422            "f                   toggle full screen\n"
2423            "p, SPC              pause\n"
2424            "a                   cycle audio channel\n"
2425            "v                   cycle video channel\n"
2426            "t                   cycle subtitle channel\n"
2427            "w                   show audio waves\n"
2428            "left/right          seek backward/forward 10 seconds\n"
2429            "down/up             seek backward/forward 1 minute\n"
2430            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2431            );
2432     exit(1);
2433 }
2434
2435 void parse_arg_file(const char *filename)
2436 {
2437     if (!strcmp(filename, "-"))
2438                     filename = "pipe:";
2439     input_filename = filename;
2440 }
2441
2442 /* Called from the main */
2443 int main(int argc, char **argv)
2444 {
2445     int flags;
2446
2447     /* register all codecs, demux and protocols */
2448     av_register_all();
2449
2450     #ifdef CONFIG_OS2
2451       MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2452
2453       // Make stdout and stderr unbuffered
2454       setbuf( stdout, NULL );
2455       setbuf( stderr, NULL );
2456     #endif
2457
2458     parse_options(argc, argv, options);
2459
2460     if (!input_filename)
2461         show_help();
2462
2463     if (display_disable) {
2464         video_disable = 1;
2465     }
2466     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2467 #if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2468     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2469 #endif
2470     if (SDL_Init (flags)) {
2471         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2472         exit(1);
2473     }
2474
2475     if (!display_disable) {
2476 #ifdef HAVE_SDL_VIDEO_SIZE
2477         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2478         fs_screen_width = vi->current_w;
2479         fs_screen_height = vi->current_h;
2480 #endif
2481     }
2482
2483     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2484     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2485     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2486     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2487
2488     av_init_packet(&flush_pkt);
2489     flush_pkt.data= "FLUSH";
2490
2491     cur_stream = stream_open(input_filename, file_iformat);
2492
2493     event_loop();
2494
2495     /* never returns */
2496
2497     return 0;
2498 }