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