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