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