]> git.sesse.net Git - ffmpeg/blob - ffplay.c
remove outdated comment
[ffmpeg] / 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(thread_count>1)
1708         avcodec_thread_init(enc, thread_count);
1709     enc->thread_count= thread_count;
1710     switch(enc->codec_type) {
1711     case CODEC_TYPE_AUDIO:
1712         is->audio_stream = stream_index;
1713         is->audio_st = ic->streams[stream_index];
1714         is->audio_buf_size = 0;
1715         is->audio_buf_index = 0;
1716
1717         /* init averaging filter */
1718         is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1719         is->audio_diff_avg_count = 0;
1720         /* since we do not have a precise anough audio fifo fullness,
1721            we correct audio sync only if larger than this threshold */
1722         is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1723
1724         memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1725         packet_queue_init(&is->audioq);
1726         SDL_PauseAudio(0);
1727         break;
1728     case CODEC_TYPE_VIDEO:
1729         is->video_stream = stream_index;
1730         is->video_st = ic->streams[stream_index];
1731
1732         is->frame_last_delay = 40e-3;
1733         is->frame_timer = (double)av_gettime() / 1000000.0;
1734         is->video_current_pts_time = av_gettime();
1735
1736         packet_queue_init(&is->videoq);
1737         is->video_tid = SDL_CreateThread(video_thread, is);
1738         break;
1739     case CODEC_TYPE_SUBTITLE:
1740         is->subtitle_stream = stream_index;
1741         is->subtitle_st = ic->streams[stream_index];
1742         packet_queue_init(&is->subtitleq);
1743
1744         is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1745         break;
1746     default:
1747         break;
1748     }
1749     return 0;
1750 }
1751
1752 static void stream_component_close(VideoState *is, int stream_index)
1753 {
1754     AVFormatContext *ic = is->ic;
1755     AVCodecContext *enc;
1756
1757     if (stream_index < 0 || stream_index >= ic->nb_streams)
1758         return;
1759     enc = ic->streams[stream_index]->codec;
1760
1761     switch(enc->codec_type) {
1762     case CODEC_TYPE_AUDIO:
1763         packet_queue_abort(&is->audioq);
1764
1765         SDL_CloseAudio();
1766
1767         packet_queue_end(&is->audioq);
1768         break;
1769     case CODEC_TYPE_VIDEO:
1770         packet_queue_abort(&is->videoq);
1771
1772         /* note: we also signal this mutex to make sure we deblock the
1773            video thread in all cases */
1774         SDL_LockMutex(is->pictq_mutex);
1775         SDL_CondSignal(is->pictq_cond);
1776         SDL_UnlockMutex(is->pictq_mutex);
1777
1778         SDL_WaitThread(is->video_tid, NULL);
1779
1780         packet_queue_end(&is->videoq);
1781         break;
1782     case CODEC_TYPE_SUBTITLE:
1783         packet_queue_abort(&is->subtitleq);
1784
1785         /* note: we also signal this mutex to make sure we deblock the
1786            video thread in all cases */
1787         SDL_LockMutex(is->subpq_mutex);
1788         is->subtitle_stream_changed = 1;
1789
1790         SDL_CondSignal(is->subpq_cond);
1791         SDL_UnlockMutex(is->subpq_mutex);
1792
1793         SDL_WaitThread(is->subtitle_tid, NULL);
1794
1795         packet_queue_end(&is->subtitleq);
1796         break;
1797     default:
1798         break;
1799     }
1800
1801     avcodec_close(enc);
1802     switch(enc->codec_type) {
1803     case CODEC_TYPE_AUDIO:
1804         is->audio_st = NULL;
1805         is->audio_stream = -1;
1806         break;
1807     case CODEC_TYPE_VIDEO:
1808         is->video_st = NULL;
1809         is->video_stream = -1;
1810         break;
1811     case CODEC_TYPE_SUBTITLE:
1812         is->subtitle_st = NULL;
1813         is->subtitle_stream = -1;
1814         break;
1815     default:
1816         break;
1817     }
1818 }
1819
1820 static void dump_stream_info(const AVFormatContext *s)
1821 {
1822     if (s->track != 0)
1823         fprintf(stderr, "Track: %d\n", s->track);
1824     if (s->title[0] != '\0')
1825         fprintf(stderr, "Title: %s\n", s->title);
1826     if (s->author[0] != '\0')
1827         fprintf(stderr, "Author: %s\n", s->author);
1828     if (s->copyright[0] != '\0')
1829         fprintf(stderr, "Copyright: %s\n", s->copyright);
1830     if (s->comment[0] != '\0')
1831         fprintf(stderr, "Comment: %s\n", s->comment);
1832     if (s->album[0] != '\0')
1833         fprintf(stderr, "Album: %s\n", s->album);
1834     if (s->year != 0)
1835         fprintf(stderr, "Year: %d\n", s->year);
1836     if (s->genre[0] != '\0')
1837         fprintf(stderr, "Genre: %s\n", s->genre);
1838 }
1839
1840 /* since we have only one decoding thread, we can use a global
1841    variable instead of a thread local variable */
1842 static VideoState *global_video_state;
1843
1844 static int decode_interrupt_cb(void)
1845 {
1846     return (global_video_state && global_video_state->abort_request);
1847 }
1848
1849 /* this thread gets the stream from the disk or the network */
1850 static int decode_thread(void *arg)
1851 {
1852     VideoState *is = arg;
1853     AVFormatContext *ic;
1854     int err, i, ret, video_index, audio_index, use_play;
1855     AVPacket pkt1, *pkt = &pkt1;
1856     AVFormatParameters params, *ap = &params;
1857
1858     video_index = -1;
1859     audio_index = -1;
1860     is->video_stream = -1;
1861     is->audio_stream = -1;
1862     is->subtitle_stream = -1;
1863
1864     global_video_state = is;
1865     url_set_interrupt_cb(decode_interrupt_cb);
1866
1867     memset(ap, 0, sizeof(*ap));
1868     ap->initial_pause = 1; /* we force a pause when starting an RTSP
1869                               stream */
1870
1871     ap->width = frame_width;
1872     ap->height= frame_height;
1873     ap->time_base= (AVRational){1, 25};
1874     ap->pix_fmt = frame_pix_fmt;
1875
1876     err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1877     if (err < 0) {
1878         print_error(is->filename, err);
1879         ret = -1;
1880         goto fail;
1881     }
1882     is->ic = ic;
1883 #ifdef CONFIG_NETWORK
1884     use_play = (ic->iformat == &rtsp_demuxer);
1885 #else
1886     use_play = 0;
1887 #endif
1888
1889     if(genpts)
1890         ic->flags |= AVFMT_FLAG_GENPTS;
1891
1892     if (!use_play) {
1893         err = av_find_stream_info(ic);
1894         if (err < 0) {
1895             fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1896             ret = -1;
1897             goto fail;
1898         }
1899         ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
1900     }
1901
1902     /* if seeking requested, we execute it */
1903     if (start_time != AV_NOPTS_VALUE) {
1904         int64_t timestamp;
1905
1906         timestamp = start_time;
1907         /* add the stream start time */
1908         if (ic->start_time != AV_NOPTS_VALUE)
1909             timestamp += ic->start_time;
1910         ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1911         if (ret < 0) {
1912             fprintf(stderr, "%s: could not seek to position %0.3f\n",
1913                     is->filename, (double)timestamp / AV_TIME_BASE);
1914         }
1915     }
1916
1917     /* now we can begin to play (RTSP stream only) */
1918     av_read_play(ic);
1919
1920     if (use_play) {
1921         err = av_find_stream_info(ic);
1922         if (err < 0) {
1923             fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1924             ret = -1;
1925             goto fail;
1926         }
1927     }
1928
1929     for(i = 0; i < ic->nb_streams; i++) {
1930         AVCodecContext *enc = ic->streams[i]->codec;
1931         switch(enc->codec_type) {
1932         case CODEC_TYPE_AUDIO:
1933             if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)
1934                 audio_index = i;
1935             break;
1936         case CODEC_TYPE_VIDEO:
1937             if (video_index < 0 && !video_disable)
1938                 video_index = i;
1939             break;
1940         default:
1941             break;
1942         }
1943     }
1944     if (show_status) {
1945         dump_format(ic, 0, is->filename, 0);
1946         dump_stream_info(ic);
1947     }
1948
1949     /* open the streams */
1950     if (audio_index >= 0) {
1951         stream_component_open(is, audio_index);
1952     }
1953
1954     if (video_index >= 0) {
1955         stream_component_open(is, video_index);
1956     } else {
1957         if (!display_disable)
1958             is->show_audio = 1;
1959     }
1960
1961     if (is->video_stream < 0 && is->audio_stream < 0) {
1962         fprintf(stderr, "%s: could not open codecs\n", is->filename);
1963         ret = -1;
1964         goto fail;
1965     }
1966
1967     for(;;) {
1968         if (is->abort_request)
1969             break;
1970 #ifdef CONFIG_NETWORK
1971         if (is->paused != is->last_paused) {
1972             is->last_paused = is->paused;
1973             if (is->paused)
1974                 av_read_pause(ic);
1975             else
1976                 av_read_play(ic);
1977         }
1978         if (is->paused && ic->iformat == &rtsp_demuxer) {
1979             /* wait 10 ms to avoid trying to get another packet */
1980             /* XXX: horrible */
1981             SDL_Delay(10);
1982             continue;
1983         }
1984 #endif
1985         if (is->seek_req) {
1986             int stream_index= -1;
1987             int64_t seek_target= is->seek_pos;
1988
1989             if     (is->   video_stream >= 0) stream_index= is->   video_stream;
1990             else if(is->   audio_stream >= 0) stream_index= is->   audio_stream;
1991             else if(is->subtitle_stream >= 0) stream_index= is->subtitle_stream;
1992
1993             if(stream_index>=0){
1994                 seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);
1995             }
1996
1997             ret = av_seek_frame(is->ic, stream_index, seek_target, is->seek_flags);
1998             if (ret < 0) {
1999                 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2000             }else{
2001                 if (is->audio_stream >= 0) {
2002                     packet_queue_flush(&is->audioq);
2003                     packet_queue_put(&is->audioq, &flush_pkt);
2004                 }
2005                 if (is->subtitle_stream >= 0) {
2006                     packet_queue_flush(&is->subtitleq);
2007                     packet_queue_put(&is->subtitleq, &flush_pkt);
2008                 }
2009                 if (is->video_stream >= 0) {
2010                     packet_queue_flush(&is->videoq);
2011                     packet_queue_put(&is->videoq, &flush_pkt);
2012                 }
2013             }
2014             is->seek_req = 0;
2015         }
2016
2017         /* if the queue are full, no need to read more */
2018         if (is->audioq.size > MAX_AUDIOQ_SIZE ||
2019             is->videoq.size > MAX_VIDEOQ_SIZE ||
2020             is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
2021             url_feof(&ic->pb)) {
2022             /* wait 10 ms */
2023             SDL_Delay(10);
2024             continue;
2025         }
2026         ret = av_read_frame(ic, pkt);
2027         if (ret < 0) {
2028             if (url_ferror(&ic->pb) == 0) {
2029                 SDL_Delay(100); /* wait for user event */
2030                 continue;
2031             } else
2032                 break;
2033         }
2034         if (pkt->stream_index == is->audio_stream) {
2035             packet_queue_put(&is->audioq, pkt);
2036         } else if (pkt->stream_index == is->video_stream) {
2037             packet_queue_put(&is->videoq, pkt);
2038         } else if (pkt->stream_index == is->subtitle_stream) {
2039             packet_queue_put(&is->subtitleq, pkt);
2040         } else {
2041             av_free_packet(pkt);
2042         }
2043     }
2044     /* wait until the end */
2045     while (!is->abort_request) {
2046         SDL_Delay(100);
2047     }
2048
2049     ret = 0;
2050  fail:
2051     /* disable interrupting */
2052     global_video_state = NULL;
2053
2054     /* close each stream */
2055     if (is->audio_stream >= 0)
2056         stream_component_close(is, is->audio_stream);
2057     if (is->video_stream >= 0)
2058         stream_component_close(is, is->video_stream);
2059     if (is->subtitle_stream >= 0)
2060         stream_component_close(is, is->subtitle_stream);
2061     if (is->ic) {
2062         av_close_input_file(is->ic);
2063         is->ic = NULL; /* safety */
2064     }
2065     url_set_interrupt_cb(NULL);
2066
2067     if (ret != 0) {
2068         SDL_Event event;
2069
2070         event.type = FF_QUIT_EVENT;
2071         event.user.data1 = is;
2072         SDL_PushEvent(&event);
2073     }
2074     return 0;
2075 }
2076
2077 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2078 {
2079     VideoState *is;
2080
2081     is = av_mallocz(sizeof(VideoState));
2082     if (!is)
2083         return NULL;
2084     pstrcpy(is->filename, sizeof(is->filename), filename);
2085     is->iformat = iformat;
2086     is->ytop = 0;
2087     is->xleft = 0;
2088
2089     /* start video display */
2090     is->pictq_mutex = SDL_CreateMutex();
2091     is->pictq_cond = SDL_CreateCond();
2092
2093     is->subpq_mutex = SDL_CreateMutex();
2094     is->subpq_cond = SDL_CreateCond();
2095
2096     /* add the refresh timer to draw the picture */
2097     schedule_refresh(is, 40);
2098
2099     is->av_sync_type = av_sync_type;
2100     is->parse_tid = SDL_CreateThread(decode_thread, is);
2101     if (!is->parse_tid) {
2102         av_free(is);
2103         return NULL;
2104     }
2105     return is;
2106 }
2107
2108 static void stream_close(VideoState *is)
2109 {
2110     VideoPicture *vp;
2111     int i;
2112     /* XXX: use a special url_shutdown call to abort parse cleanly */
2113     is->abort_request = 1;
2114     SDL_WaitThread(is->parse_tid, NULL);
2115
2116     /* free all pictures */
2117     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2118         vp = &is->pictq[i];
2119         if (vp->bmp) {
2120             SDL_FreeYUVOverlay(vp->bmp);
2121             vp->bmp = NULL;
2122         }
2123     }
2124     SDL_DestroyMutex(is->pictq_mutex);
2125     SDL_DestroyCond(is->pictq_cond);
2126     SDL_DestroyMutex(is->subpq_mutex);
2127     SDL_DestroyCond(is->subpq_cond);
2128 }
2129
2130 static void stream_cycle_channel(VideoState *is, int codec_type)
2131 {
2132     AVFormatContext *ic = is->ic;
2133     int start_index, stream_index;
2134     AVStream *st;
2135
2136     if (codec_type == CODEC_TYPE_VIDEO)
2137         start_index = is->video_stream;
2138     else if (codec_type == CODEC_TYPE_AUDIO)
2139         start_index = is->audio_stream;
2140     else
2141         start_index = is->subtitle_stream;
2142     if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2143         return;
2144     stream_index = start_index;
2145     for(;;) {
2146         if (++stream_index >= is->ic->nb_streams)
2147         {
2148             if (codec_type == CODEC_TYPE_SUBTITLE)
2149             {
2150                 stream_index = -1;
2151                 goto the_end;
2152             } else
2153                 stream_index = 0;
2154         }
2155         if (stream_index == start_index)
2156             return;
2157         st = ic->streams[stream_index];
2158         if (st->codec->codec_type == codec_type) {
2159             /* check that parameters are OK */
2160             switch(codec_type) {
2161             case CODEC_TYPE_AUDIO:
2162                 if (st->codec->sample_rate != 0 &&
2163                     st->codec->channels != 0)
2164                     goto the_end;
2165                 break;
2166             case CODEC_TYPE_VIDEO:
2167             case CODEC_TYPE_SUBTITLE:
2168                 goto the_end;
2169             default:
2170                 break;
2171             }
2172         }
2173     }
2174  the_end:
2175     stream_component_close(is, start_index);
2176     stream_component_open(is, stream_index);
2177 }
2178
2179
2180 static void toggle_full_screen(void)
2181 {
2182     is_full_screen = !is_full_screen;
2183     if (!fs_screen_width) {
2184         /* use default SDL method */
2185 //        SDL_WM_ToggleFullScreen(screen);
2186     }
2187     video_open(cur_stream);
2188 }
2189
2190 static void toggle_pause(void)
2191 {
2192     if (cur_stream)
2193         stream_pause(cur_stream);
2194     step = 0;
2195 }
2196
2197 static void step_to_next_frame(void)
2198 {
2199     if (cur_stream) {
2200         if (cur_stream->paused)
2201             cur_stream->paused=0;
2202         cur_stream->video_current_pts = get_video_clock(cur_stream);
2203     }
2204     step = 1;
2205 }
2206
2207 static void do_exit(void)
2208 {
2209     if (cur_stream) {
2210         stream_close(cur_stream);
2211         cur_stream = NULL;
2212     }
2213     if (show_status)
2214         printf("\n");
2215     SDL_Quit();
2216     exit(0);
2217 }
2218
2219 static void toggle_audio_display(void)
2220 {
2221     if (cur_stream) {
2222         cur_stream->show_audio = !cur_stream->show_audio;
2223     }
2224 }
2225
2226 /* handle an event sent by the GUI */
2227 static void event_loop(void)
2228 {
2229     SDL_Event event;
2230     double incr, pos, frac;
2231
2232     for(;;) {
2233         SDL_WaitEvent(&event);
2234         switch(event.type) {
2235         case SDL_KEYDOWN:
2236             switch(event.key.keysym.sym) {
2237             case SDLK_ESCAPE:
2238             case SDLK_q:
2239                 do_exit();
2240                 break;
2241             case SDLK_f:
2242                 toggle_full_screen();
2243                 break;
2244             case SDLK_p:
2245             case SDLK_SPACE:
2246                 toggle_pause();
2247                 break;
2248             case SDLK_s: //S: Step to next frame
2249                 step_to_next_frame();
2250                 break;
2251             case SDLK_a:
2252                 if (cur_stream)
2253                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2254                 break;
2255             case SDLK_v:
2256                 if (cur_stream)
2257                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2258                 break;
2259             case SDLK_t:
2260                 if (cur_stream)
2261                     stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2262                 break;
2263             case SDLK_w:
2264                 toggle_audio_display();
2265                 break;
2266             case SDLK_LEFT:
2267                 incr = -10.0;
2268                 goto do_seek;
2269             case SDLK_RIGHT:
2270                 incr = 10.0;
2271                 goto do_seek;
2272             case SDLK_UP:
2273                 incr = 60.0;
2274                 goto do_seek;
2275             case SDLK_DOWN:
2276                 incr = -60.0;
2277             do_seek:
2278                 if (cur_stream) {
2279                     if (seek_by_bytes) {
2280                         pos = url_ftell(&cur_stream->ic->pb);
2281                         if (cur_stream->ic->bit_rate)
2282                             incr *= cur_stream->ic->bit_rate / 60.0;
2283                         else
2284                             incr *= 180000.0;
2285                         pos += incr;
2286                         stream_seek(cur_stream, pos, incr);
2287                     } else {
2288                         pos = get_master_clock(cur_stream);
2289                         pos += incr;
2290                         stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2291                     }
2292                 }
2293                 break;
2294             default:
2295                 break;
2296             }
2297             break;
2298         case SDL_MOUSEBUTTONDOWN:
2299             if (cur_stream) {
2300                 int ns, hh, mm, ss;
2301                 int tns, thh, tmm, tss;
2302                 tns = cur_stream->ic->duration/1000000LL;
2303                 thh = tns/3600;
2304                 tmm = (tns%3600)/60;
2305                 tss = (tns%60);
2306                 frac = (double)event.button.x/(double)cur_stream->width;
2307                 ns = frac*tns;
2308                 hh = ns/3600;
2309                 mm = (ns%3600)/60;
2310                 ss = (ns%60);
2311                 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2312                         hh, mm, ss, thh, tmm, tss);
2313                 stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2314             }
2315             break;
2316         case SDL_VIDEORESIZE:
2317             if (cur_stream) {
2318                 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2319                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2320                 screen_width = cur_stream->width = event.resize.w;
2321                 screen_height= cur_stream->height= event.resize.h;
2322             }
2323             break;
2324         case SDL_QUIT:
2325         case FF_QUIT_EVENT:
2326             do_exit();
2327             break;
2328         case FF_ALLOC_EVENT:
2329             video_open(event.user.data1);
2330             alloc_picture(event.user.data1);
2331             break;
2332         case FF_REFRESH_EVENT:
2333             video_refresh_timer(event.user.data1);
2334             break;
2335         default:
2336             break;
2337         }
2338     }
2339 }
2340
2341 static void opt_frame_size(const char *arg)
2342 {
2343     if (parse_image_size(&frame_width, &frame_height, arg) < 0) {
2344         fprintf(stderr, "Incorrect frame size\n");
2345         exit(1);
2346     }
2347     if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2348         fprintf(stderr, "Frame size must be a multiple of 2\n");
2349         exit(1);
2350     }
2351 }
2352
2353 void opt_width(const char *arg)
2354 {
2355     screen_width = atoi(arg);
2356     if(screen_width<=0){
2357         fprintf(stderr, "invalid width\n");
2358         exit(1);
2359     }
2360 }
2361
2362 void opt_height(const char *arg)
2363 {
2364     screen_height = atoi(arg);
2365     if(screen_height<=0){
2366         fprintf(stderr, "invalid height\n");
2367         exit(1);
2368     }
2369 }
2370
2371 static void opt_format(const char *arg)
2372 {
2373     file_iformat = av_find_input_format(arg);
2374     if (!file_iformat) {
2375         fprintf(stderr, "Unknown input format: %s\n", arg);
2376         exit(1);
2377     }
2378 }
2379
2380 static void opt_frame_pix_fmt(const char *arg)
2381 {
2382     frame_pix_fmt = avcodec_get_pix_fmt(arg);
2383 }
2384
2385 #ifdef CONFIG_NETWORK
2386 void opt_rtp_tcp(void)
2387 {
2388     /* only tcp protocol */
2389     rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2390 }
2391 #endif
2392
2393 void opt_sync(const char *arg)
2394 {
2395     if (!strcmp(arg, "audio"))
2396         av_sync_type = AV_SYNC_AUDIO_MASTER;
2397     else if (!strcmp(arg, "video"))
2398         av_sync_type = AV_SYNC_VIDEO_MASTER;
2399     else if (!strcmp(arg, "ext"))
2400         av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2401     else
2402         show_help();
2403 }
2404
2405 void opt_seek(const char *arg)
2406 {
2407     start_time = parse_date(arg, 1);
2408 }
2409
2410 static void opt_debug(const char *arg)
2411 {
2412     av_log_level = 99;
2413     debug = atoi(arg);
2414 }
2415
2416 static void opt_vismv(const char *arg)
2417 {
2418     debug_mv = atoi(arg);
2419 }
2420
2421 static void opt_thread_count(const char *arg)
2422 {
2423     thread_count= atoi(arg);
2424 #if !defined(HAVE_THREADS)
2425     fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2426 #endif
2427 }
2428
2429 const OptionDef options[] = {
2430     { "h", 0, {(void*)show_help}, "show help" },
2431     { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2432     { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2433     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2434     { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2435     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2436     { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2437     { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "", "" },
2438     { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2439     { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2440     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2441     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2442     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2443     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2444     { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2445     { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2446     { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2447     { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2448     { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2449     { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2450     { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2451     { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2452     { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2453     { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2454     { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
2455     { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2456 #ifdef CONFIG_NETWORK
2457     { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2458 #endif
2459     { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2460     { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2461     { NULL, },
2462 };
2463
2464 void show_help(void)
2465 {
2466     printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
2467            "usage: ffplay [options] input_file\n"
2468            "Simple media player\n");
2469     printf("\n");
2470     show_help_options(options, "Main options:\n",
2471                       OPT_EXPERT, 0);
2472     show_help_options(options, "\nAdvanced options:\n",
2473                       OPT_EXPERT, OPT_EXPERT);
2474     printf("\nWhile playing:\n"
2475            "q, ESC              quit\n"
2476            "f                   toggle full screen\n"
2477            "p, SPC              pause\n"
2478            "a                   cycle audio channel\n"
2479            "v                   cycle video channel\n"
2480            "t                   cycle subtitle channel\n"
2481            "w                   show audio waves\n"
2482            "left/right          seek backward/forward 10 seconds\n"
2483            "down/up             seek backward/forward 1 minute\n"
2484            "mouse click         seek to percentage in file corresponding to fraction of width\n"
2485            );
2486     exit(1);
2487 }
2488
2489 void parse_arg_file(const char *filename)
2490 {
2491     if (!strcmp(filename, "-"))
2492                     filename = "pipe:";
2493     input_filename = filename;
2494 }
2495
2496 /* Called from the main */
2497 int main(int argc, char **argv)
2498 {
2499     int flags;
2500
2501     /* register all codecs, demux and protocols */
2502     av_register_all();
2503
2504     #ifdef CONFIG_OS2
2505       MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2506
2507       // Make stdout and stderr unbuffered
2508       setbuf( stdout, NULL );
2509       setbuf( stderr, NULL );
2510     #endif
2511
2512     parse_options(argc, argv, options);
2513
2514     if (!input_filename)
2515         show_help();
2516
2517     if (display_disable) {
2518         video_disable = 1;
2519     }
2520     flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2521 #if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2522     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2523 #endif
2524     if (SDL_Init (flags)) {
2525         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2526         exit(1);
2527     }
2528
2529     if (!display_disable) {
2530 #ifdef HAVE_SDL_VIDEO_SIZE
2531         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2532         fs_screen_width = vi->current_w;
2533         fs_screen_height = vi->current_h;
2534 #endif
2535     }
2536
2537     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2538     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2539     SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2540     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2541
2542     av_init_packet(&flush_pkt);
2543     flush_pkt.data= "FLUSH";
2544
2545     cur_stream = stream_open(input_filename, file_iformat);
2546
2547     event_loop();
2548
2549     /* never returns */
2550
2551     return 0;
2552 }