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