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