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