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