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