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