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