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