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