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