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