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