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