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