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