automatically detect Cinepak data from Sega FILM/CPK files
[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
3ca4b654
MN
31#ifdef CONFIG_OS2
32#define INCL_DOS
33 #include <os2.h>
34 #include <stdio.h>
35
36 void MorphToPM()
37 {
38 PPIB pib;
39 PTIB tib;
40
41 DosGetInfoBlocks(&tib, &pib);
42
43 // Change flag from VIO to PM:
44 if (pib->pib_ultype==2) pib->pib_ultype = 3;
45 }
46#endif
47
01310af2
FB
48#if defined(__linux__)
49#define HAVE_X11
50#endif
51
52#ifdef HAVE_X11
53#include <X11/Xlib.h>
54#endif
55
638c9d91
FB
56//#define DEBUG_SYNC
57
01310af2
FB
58#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
59#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
72ce053b 60#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
01310af2 61
638c9d91
FB
62/* SDL audio buffer size, in samples. Should be small to have precise
63 A/V sync as SDL does not have hardware buffer fullness info. */
64#define SDL_AUDIO_BUFFER_SIZE 1024
65
66/* no AV sync correction is done if below the AV sync threshold */
7e0140cb 67#define AV_SYNC_THRESHOLD 0.01
638c9d91
FB
68/* no AV correction is done if too big error */
69#define AV_NOSYNC_THRESHOLD 10.0
70
71/* maximum audio speed change to get correct sync */
72#define SAMPLE_CORRECTION_PERCENT_MAX 10
73
74/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
75#define AUDIO_DIFF_AVG_NB 20
76
01310af2
FB
77/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
78#define SAMPLE_ARRAY_SIZE (2*65536)
79
80typedef struct PacketQueue {
81 AVPacketList *first_pkt, *last_pkt;
82 int nb_packets;
83 int size;
84 int abort_request;
85 SDL_mutex *mutex;
86 SDL_cond *cond;
87} PacketQueue;
88
89#define VIDEO_PICTURE_QUEUE_SIZE 1
72ce053b 90#define SUBPICTURE_QUEUE_SIZE 4
01310af2
FB
91
92typedef struct VideoPicture {
638c9d91 93 double pts; /* presentation time stamp for this picture */
01310af2
FB
94 SDL_Overlay *bmp;
95 int width, height; /* source height & width */
96 int allocated;
97} VideoPicture;
98
72ce053b
IC
99typedef struct SubPicture {
100 double pts; /* presentation time stamp for this picture */
101 AVSubtitle sub;
102} SubPicture;
103
01310af2
FB
104enum {
105 AV_SYNC_AUDIO_MASTER, /* default choice */
106 AV_SYNC_VIDEO_MASTER,
638c9d91 107 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
01310af2
FB
108};
109
110typedef struct VideoState {
111 SDL_Thread *parse_tid;
112 SDL_Thread *video_tid;
638c9d91 113 AVInputFormat *iformat;
01310af2
FB
114 int no_background;
115 int abort_request;
116 int paused;
416e3508 117 int last_paused;
72ea344b 118 int seek_req;
3ba1438d 119 int seek_flags;
72ea344b 120 int64_t seek_pos;
01310af2
FB
121 AVFormatContext *ic;
122 int dtg_active_format;
123
124 int audio_stream;
125
126 int av_sync_type;
638c9d91
FB
127 double external_clock; /* external clock base */
128 int64_t external_clock_time;
129
130 double audio_clock;
131 double audio_diff_cum; /* used for AV difference average computation */
132 double audio_diff_avg_coef;
133 double audio_diff_threshold;
134 int audio_diff_avg_count;
01310af2
FB
135 AVStream *audio_st;
136 PacketQueue audioq;
137 int audio_hw_buf_size;
138 /* samples output by the codec. we reserve more space for avsync
139 compensation */
140 uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
7fea94ce 141 unsigned int audio_buf_size; /* in bytes */
01310af2
FB
142 int audio_buf_index; /* in bytes */
143 AVPacket audio_pkt;
144 uint8_t *audio_pkt_data;
145 int audio_pkt_size;
01310af2
FB
146
147 int show_audio; /* if true, display audio samples */
148 int16_t sample_array[SAMPLE_ARRAY_SIZE];
149 int sample_array_index;
5e0257e3 150 int last_i_start;
01310af2 151
72ce053b
IC
152 SDL_Thread *subtitle_tid;
153 int subtitle_stream;
154 int subtitle_stream_changed;
155 AVStream *subtitle_st;
156 PacketQueue subtitleq;
157 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
158 int subpq_size, subpq_rindex, subpq_windex;
159 SDL_mutex *subpq_mutex;
160 SDL_cond *subpq_cond;
161
638c9d91
FB
162 double frame_timer;
163 double frame_last_pts;
164 double frame_last_delay;
165 double video_clock;
01310af2
FB
166 int video_stream;
167 AVStream *video_st;
168 PacketQueue videoq;
638c9d91
FB
169 double video_last_P_pts; /* pts of the last P picture (needed if B
170 frames are present) */
171 double video_current_pts; /* current displayed pts (different from
172 video_clock if frame fifos are used) */
173 int64_t video_current_pts_time; /* time at which we updated
174 video_current_pts - used to
175 have running video pts */
01310af2
FB
176 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
177 int pictq_size, pictq_rindex, pictq_windex;
178 SDL_mutex *pictq_mutex;
179 SDL_cond *pictq_cond;
180
b514ed3c
MN
181 SDL_mutex *video_decoder_mutex;
182 SDL_mutex *audio_decoder_mutex;
72ce053b 183 SDL_mutex *subtitle_decoder_mutex;
b514ed3c 184
01310af2
FB
185 // QETimer *video_timer;
186 char filename[1024];
187 int width, height, xleft, ytop;
188} VideoState;
189
190void show_help(void);
638c9d91 191static int audio_write_get_buf_size(VideoState *is);
01310af2
FB
192
193/* options specified by the user */
194static AVInputFormat *file_iformat;
61890b02 195static AVImageFormat *image_format;
01310af2
FB
196static const char *input_filename;
197static int fs_screen_width;
198static int fs_screen_height;
199static int screen_width = 640;
200static int screen_height = 480;
201static int audio_disable;
202static int video_disable;
203static int display_disable;
204static int show_status;
638c9d91 205static int av_sync_type = AV_SYNC_AUDIO_MASTER;
72ea344b 206static int64_t start_time = AV_NOPTS_VALUE;
e26a8335 207static int debug = 0;
0c9bbaec 208static int debug_mv = 0;
bba04f1e 209static int step = 0;
c62c07d3 210static int thread_count = 1;
6387c3e6 211static int workaround_bugs = 1;
6fc5b059 212static int fast = 0;
178fcca8
MN
213static int lowres = 0;
214static int idct = FF_IDCT_AUTO;
8c3eba7c
MN
215static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
216static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
217static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
1b51e051
MN
218static int error_resilience = FF_ER_CAREFULL;
219static int error_concealment = 3;
01310af2
FB
220
221/* current context */
222static int is_full_screen;
223static VideoState *cur_stream;
5e0257e3 224static int64_t audio_callback_time;
01310af2
FB
225
226#define FF_ALLOC_EVENT (SDL_USEREVENT)
227#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
638c9d91 228#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
01310af2
FB
229
230SDL_Surface *screen;
231
232/* packet queue handling */
233static void packet_queue_init(PacketQueue *q)
234{
235 memset(q, 0, sizeof(PacketQueue));
236 q->mutex = SDL_CreateMutex();
237 q->cond = SDL_CreateCond();
238}
239
72ea344b 240static void packet_queue_flush(PacketQueue *q)
01310af2
FB
241{
242 AVPacketList *pkt, *pkt1;
243
687fae2b 244 SDL_LockMutex(q->mutex);
01310af2
FB
245 for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
246 pkt1 = pkt->next;
247 av_free_packet(&pkt->pkt);
da6c4573 248 av_freep(&pkt);
01310af2 249 }
72ea344b
FB
250 q->last_pkt = NULL;
251 q->first_pkt = NULL;
252 q->nb_packets = 0;
253 q->size = 0;
687fae2b 254 SDL_UnlockMutex(q->mutex);
72ea344b
FB
255}
256
257static void packet_queue_end(PacketQueue *q)
258{
259 packet_queue_flush(q);
01310af2
FB
260 SDL_DestroyMutex(q->mutex);
261 SDL_DestroyCond(q->cond);
262}
263
264static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
265{
266 AVPacketList *pkt1;
267
72ea344b
FB
268 /* duplicate the packet */
269 if (av_dup_packet(pkt) < 0)
270 return -1;
271
01310af2
FB
272 pkt1 = av_malloc(sizeof(AVPacketList));
273 if (!pkt1)
274 return -1;
275 pkt1->pkt = *pkt;
276 pkt1->next = NULL;
277
72ea344b 278
01310af2
FB
279 SDL_LockMutex(q->mutex);
280
281 if (!q->last_pkt)
282
283 q->first_pkt = pkt1;
284 else
285 q->last_pkt->next = pkt1;
286 q->last_pkt = pkt1;
287 q->nb_packets++;
288 q->size += pkt1->pkt.size;
289 /* XXX: should duplicate packet data in DV case */
290 SDL_CondSignal(q->cond);
291
292 SDL_UnlockMutex(q->mutex);
293 return 0;
294}
295
296static void packet_queue_abort(PacketQueue *q)
297{
298 SDL_LockMutex(q->mutex);
299
300 q->abort_request = 1;
301
302 SDL_CondSignal(q->cond);
303
304 SDL_UnlockMutex(q->mutex);
305}
306
307/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
308static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
309{
310 AVPacketList *pkt1;
311 int ret;
312
313 SDL_LockMutex(q->mutex);
314
315 for(;;) {
316 if (q->abort_request) {
317 ret = -1;
318 break;
319 }
320
321 pkt1 = q->first_pkt;
322 if (pkt1) {
323 q->first_pkt = pkt1->next;
324 if (!q->first_pkt)
325 q->last_pkt = NULL;
326 q->nb_packets--;
327 q->size -= pkt1->pkt.size;
328 *pkt = pkt1->pkt;
329 av_free(pkt1);
330 ret = 1;
331 break;
332 } else if (!block) {
333 ret = 0;
334 break;
335 } else {
336 SDL_CondWait(q->cond, q->mutex);
337 }
338 }
339 SDL_UnlockMutex(q->mutex);
340 return ret;
341}
342
343static inline void fill_rectangle(SDL_Surface *screen,
344 int x, int y, int w, int h, int color)
345{
346 SDL_Rect rect;
347 rect.x = x;
348 rect.y = y;
349 rect.w = w;
350 rect.h = h;
351 SDL_FillRect(screen, &rect, color);
352}
353
354#if 0
355/* draw only the border of a rectangle */
356void fill_border(VideoState *s, int x, int y, int w, int h, int color)
357{
358 int w1, w2, h1, h2;
359
360 /* fill the background */
361 w1 = x;
362 if (w1 < 0)
363 w1 = 0;
364 w2 = s->width - (x + w);
365 if (w2 < 0)
366 w2 = 0;
367 h1 = y;
368 if (h1 < 0)
369 h1 = 0;
370 h2 = s->height - (y + h);
371 if (h2 < 0)
372 h2 = 0;
373 fill_rectangle(screen,
374 s->xleft, s->ytop,
375 w1, s->height,
376 color);
377 fill_rectangle(screen,
378 s->xleft + s->width - w2, s->ytop,
379 w2, s->height,
380 color);
381 fill_rectangle(screen,
382 s->xleft + w1, s->ytop,
383 s->width - w1 - w2, h1,
384 color);
385 fill_rectangle(screen,
386 s->xleft + w1, s->ytop + s->height - h2,
387 s->width - w1 - w2, h2,
388 color);
389}
390#endif
391
72ce053b
IC
392
393
394#define SCALEBITS 10
395#define ONE_HALF (1 << (SCALEBITS - 1))
396#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
397
398#define RGB_TO_Y_CCIR(r, g, b) \
399((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
400 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
401
402#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
403(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
404 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
405
406#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
407(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
408 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
409
410#define ALPHA_BLEND(a, oldp, newp, s)\
411((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
412
413#define RGBA_IN(r, g, b, a, s)\
414{\
415 unsigned int v = ((const uint32_t *)(s))[0];\
416 a = (v >> 24) & 0xff;\
417 r = (v >> 16) & 0xff;\
418 g = (v >> 8) & 0xff;\
419 b = v & 0xff;\
420}
421
422#define YUVA_IN(y, u, v, a, s, pal)\
423{\
424 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\
425 a = (val >> 24) & 0xff;\
426 y = (val >> 16) & 0xff;\
427 u = (val >> 8) & 0xff;\
428 v = val & 0xff;\
429}
430
431#define YUVA_OUT(d, y, u, v, a)\
432{\
433 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
434}
435
436
437#define BPP 1
438
439static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
440{
441 int wrap, wrap3, width2, skip2;
442 int y, u, v, a, u1, v1, a1, w, h;
443 uint8_t *lum, *cb, *cr;
444 const uint8_t *p;
445 const uint32_t *pal;
446
447 lum = dst->data[0] + rect->y * dst->linesize[0];
448 cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
449 cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
450
451 width2 = (rect->w + 1) >> 1;
452 skip2 = rect->x >> 1;
453 wrap = dst->linesize[0];
454 wrap3 = rect->linesize;
455 p = rect->bitmap;
456 pal = rect->rgba_palette; /* Now in YCrCb! */
457
458 if (rect->y & 1) {
459 lum += rect->x;
460 cb += skip2;
461 cr += skip2;
462
463 if (rect->x & 1) {
464 YUVA_IN(y, u, v, a, p, pal);
465 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
466 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
467 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
468 cb++;
469 cr++;
470 lum++;
471 p += BPP;
472 }
473 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
474 YUVA_IN(y, u, v, a, p, pal);
475 u1 = u;
476 v1 = v;
477 a1 = a;
478 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
479
480 YUVA_IN(y, u, v, a, p + BPP, pal);
481 u1 += u;
482 v1 += v;
483 a1 += a;
484 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
485 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
486 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
487 cb++;
488 cr++;
489 p += 2 * BPP;
490 lum += 2;
491 }
492 if (w) {
493 YUVA_IN(y, u, v, a, p, pal);
494 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
495 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
496 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
497 }
498 p += wrap3 + (wrap3 - rect->w * BPP);
499 lum += wrap + (wrap - rect->w - rect->x);
500 cb += dst->linesize[1] - width2 - skip2;
501 cr += dst->linesize[2] - width2 - skip2;
502 }
503 for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
504 lum += rect->x;
505 cb += skip2;
506 cr += skip2;
507
508 if (rect->x & 1) {
509 YUVA_IN(y, u, v, a, p, pal);
510 u1 = u;
511 v1 = v;
512 a1 = a;
513 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
514 p += wrap3;
515 lum += wrap;
516 YUVA_IN(y, u, v, a, p, pal);
517 u1 += u;
518 v1 += v;
519 a1 += a;
520 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
521 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
522 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
523 cb++;
524 cr++;
525 p += -wrap3 + BPP;
526 lum += -wrap + 1;
527 }
528 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
529 YUVA_IN(y, u, v, a, p, pal);
530 u1 = u;
531 v1 = v;
532 a1 = a;
533 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
534
535 YUVA_IN(y, u, v, a, p, pal);
536 u1 += u;
537 v1 += v;
538 a1 += a;
539 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
540 p += wrap3;
541 lum += wrap;
542
543 YUVA_IN(y, u, v, a, p, pal);
544 u1 += u;
545 v1 += v;
546 a1 += a;
547 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
548
549 YUVA_IN(y, u, v, a, p, pal);
550 u1 += u;
551 v1 += v;
552 a1 += a;
553 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
554
555 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
556 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
557
558 cb++;
559 cr++;
560 p += -wrap3 + 2 * BPP;
561 lum += -wrap + 2;
562 }
563 if (w) {
564 YUVA_IN(y, u, v, a, p, pal);
565 u1 = u;
566 v1 = v;
567 a1 = a;
568 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
569 p += wrap3;
570 lum += wrap;
571 YUVA_IN(y, u, v, a, p, pal);
572 u1 += u;
573 v1 += v;
574 a1 += a;
575 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
576 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
577 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
578 cb++;
579 cr++;
580 p += -wrap3 + BPP;
581 lum += -wrap + 1;
582 }
583 p += wrap3 + (wrap3 - rect->w * BPP);
584 lum += wrap + (wrap - rect->w - rect->x);
585 cb += dst->linesize[1] - width2 - skip2;
586 cr += dst->linesize[2] - width2 - skip2;
587 }
588 /* handle odd height */
589 if (h) {
590 lum += rect->x;
591 cb += skip2;
592 cr += skip2;
593
594 if (rect->x & 1) {
595 YUVA_IN(y, u, v, a, p, pal);
596 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
597 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
598 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
599 cb++;
600 cr++;
601 lum++;
602 p += BPP;
603 }
604 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
605 YUVA_IN(y, u, v, a, p, pal);
606 u1 = u;
607 v1 = v;
608 a1 = a;
609 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
610
611 YUVA_IN(y, u, v, a, p + BPP, pal);
612 u1 += u;
613 v1 += v;
614 a1 += a;
615 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
616 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
617 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
618 cb++;
619 cr++;
620 p += 2 * BPP;
621 lum += 2;
622 }
623 if (w) {
624 YUVA_IN(y, u, v, a, p, pal);
625 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
626 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
627 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
628 }
629 }
630}
631
632static void free_subpicture(SubPicture *sp)
633{
634 int i;
635
636 for (i = 0; i < sp->sub.num_rects; i++)
637 {
638 av_free(sp->sub.rects[i].bitmap);
639 av_free(sp->sub.rects[i].rgba_palette);
640 }
641
642 av_free(sp->sub.rects);
643
644 memset(&sp->sub, 0, sizeof(AVSubtitle));
645}
646
01310af2
FB
647static void video_image_display(VideoState *is)
648{
649 VideoPicture *vp;
72ce053b
IC
650 SubPicture *sp;
651 AVPicture pict;
01310af2
FB
652 float aspect_ratio;
653 int width, height, x, y;
654 SDL_Rect rect;
72ce053b 655 int i;
01310af2
FB
656
657 vp = &is->pictq[is->pictq_rindex];
658 if (vp->bmp) {
659 /* XXX: use variable in the frame */
01f4895c 660 if (is->video_st->codec->sample_aspect_ratio.num == 0)
72ea344b
FB
661 aspect_ratio = 0;
662 else
01f4895c
MN
663 aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)
664 * is->video_st->codec->width / is->video_st->codec->height;;
01310af2 665 if (aspect_ratio <= 0.0)
01f4895c
MN
666 aspect_ratio = (float)is->video_st->codec->width /
667 (float)is->video_st->codec->height;
01310af2
FB
668 /* if an active format is indicated, then it overrides the
669 mpeg format */
670#if 0
01f4895c
MN
671 if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
672 is->dtg_active_format = is->video_st->codec->dtg_active_format;
01310af2
FB
673 printf("dtg_active_format=%d\n", is->dtg_active_format);
674 }
675#endif
676#if 0
01f4895c 677 switch(is->video_st->codec->dtg_active_format) {
01310af2
FB
678 case FF_DTG_AFD_SAME:
679 default:
680 /* nothing to do */
681 break;
682 case FF_DTG_AFD_4_3:
683 aspect_ratio = 4.0 / 3.0;
684 break;
685 case FF_DTG_AFD_16_9:
686 aspect_ratio = 16.0 / 9.0;
687 break;
688 case FF_DTG_AFD_14_9:
689 aspect_ratio = 14.0 / 9.0;
690 break;
691 case FF_DTG_AFD_4_3_SP_14_9:
692 aspect_ratio = 14.0 / 9.0;
693 break;
694 case FF_DTG_AFD_16_9_SP_14_9:
695 aspect_ratio = 14.0 / 9.0;
696 break;
697 case FF_DTG_AFD_SP_4_3:
698 aspect_ratio = 4.0 / 3.0;
699 break;
700 }
701#endif
702
72ce053b
IC
703 if (is->subtitle_st)
704 {
705 if (is->subpq_size > 0)
706 {
707 sp = &is->subpq[is->subpq_rindex];
708
709 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
710 {
711 SDL_LockYUVOverlay (vp->bmp);
712
713 pict.data[0] = vp->bmp->pixels[0];
714 pict.data[1] = vp->bmp->pixels[2];
715 pict.data[2] = vp->bmp->pixels[1];
716
717 pict.linesize[0] = vp->bmp->pitches[0];
718 pict.linesize[1] = vp->bmp->pitches[2];
719 pict.linesize[2] = vp->bmp->pitches[1];
720
721 for (i = 0; i < sp->sub.num_rects; i++)
722 blend_subrect(&pict, &sp->sub.rects[i]);
723
724 SDL_UnlockYUVOverlay (vp->bmp);
725 }
726 }
727 }
728
729
01310af2
FB
730 /* XXX: we suppose the screen has a 1.0 pixel ratio */
731 height = is->height;
732 width = ((int)rint(height * aspect_ratio)) & -3;
733 if (width > is->width) {
734 width = is->width;
735 height = ((int)rint(width / aspect_ratio)) & -3;
736 }
737 x = (is->width - width) / 2;
738 y = (is->height - height) / 2;
739 if (!is->no_background) {
740 /* fill the background */
741 // fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
742 } else {
743 is->no_background = 0;
744 }
745 rect.x = is->xleft + x;
746 rect.y = is->xleft + y;
747 rect.w = width;
748 rect.h = height;
749 SDL_DisplayYUVOverlay(vp->bmp, &rect);
750 } else {
751#if 0
752 fill_rectangle(screen,
753 is->xleft, is->ytop, is->width, is->height,
754 QERGB(0x00, 0x00, 0x00));
755#endif
756 }
757}
758
759static inline int compute_mod(int a, int b)
760{
761 a = a % b;
762 if (a >= 0)
763 return a;
764 else
765 return a + b;
766}
767
768static void video_audio_display(VideoState *s)
769{
770 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
771 int ch, channels, h, h2, bgcolor, fgcolor;
772 int16_t time_diff;
773
774 /* compute display index : center on currently output samples */
01f4895c 775 channels = s->audio_st->codec->channels;
01310af2 776 nb_display_channels = channels;
5e0257e3
FB
777 if (!s->paused) {
778 n = 2 * channels;
779 delay = audio_write_get_buf_size(s);
780 delay /= n;
781
782 /* to be more precise, we take into account the time spent since
783 the last buffer computation */
784 if (audio_callback_time) {
785 time_diff = av_gettime() - audio_callback_time;
01f4895c 786 delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
5e0257e3
FB
787 }
788
789 delay -= s->width / 2;
790 if (delay < s->width)
791 delay = s->width;
792 i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
793 s->last_i_start = i_start;
794 } else {
795 i_start = s->last_i_start;
01310af2
FB
796 }
797
01310af2
FB
798 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
799 fill_rectangle(screen,
800 s->xleft, s->ytop, s->width, s->height,
801 bgcolor);
802
803 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
804
805 /* total height for one channel */
806 h = s->height / nb_display_channels;
807 /* graph height / 2 */
808 h2 = (h * 9) / 20;
809 for(ch = 0;ch < nb_display_channels; ch++) {
810 i = i_start + ch;
811 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
812 for(x = 0; x < s->width; x++) {
813 y = (s->sample_array[i] * h2) >> 15;
814 if (y < 0) {
815 y = -y;
816 ys = y1 - y;
817 } else {
818 ys = y1;
819 }
820 fill_rectangle(screen,
821 s->xleft + x, ys, 1, y,
822 fgcolor);
823 i += channels;
824 if (i >= SAMPLE_ARRAY_SIZE)
825 i -= SAMPLE_ARRAY_SIZE;
826 }
827 }
828
829 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
830
831 for(ch = 1;ch < nb_display_channels; ch++) {
832 y = s->ytop + ch * h;
833 fill_rectangle(screen,
834 s->xleft, y, s->width, 1,
835 fgcolor);
836 }
837 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
838}
839
840/* display the current picture, if any */
841static void video_display(VideoState *is)
842{
843 if (is->audio_st && is->show_audio)
844 video_audio_display(is);
845 else if (is->video_st)
846 video_image_display(is);
847}
848
849static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
850{
851 SDL_Event event;
852 event.type = FF_REFRESH_EVENT;
853 event.user.data1 = opaque;
854 SDL_PushEvent(&event);
855 return 0; /* 0 means stop timer */
856}
857
858/* schedule a video refresh in 'delay' ms */
859static void schedule_refresh(VideoState *is, int delay)
860{
861 SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
862}
863
638c9d91
FB
864/* get the current audio clock value */
865static double get_audio_clock(VideoState *is)
866{
867 double pts;
868 int hw_buf_size, bytes_per_sec;
869 pts = is->audio_clock;
870 hw_buf_size = audio_write_get_buf_size(is);
871 bytes_per_sec = 0;
872 if (is->audio_st) {
01f4895c
MN
873 bytes_per_sec = is->audio_st->codec->sample_rate *
874 2 * is->audio_st->codec->channels;
638c9d91
FB
875 }
876 if (bytes_per_sec)
877 pts -= (double)hw_buf_size / bytes_per_sec;
878 return pts;
879}
880
881/* get the current video clock value */
882static double get_video_clock(VideoState *is)
883{
884 double delta;
04108619 885 if (is->paused) {
72ea344b
FB
886 delta = 0;
887 } else {
888 delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
889 }
638c9d91
FB
890 return is->video_current_pts + delta;
891}
892
893/* get the current external clock value */
894static double get_external_clock(VideoState *is)
895{
896 int64_t ti;
897 ti = av_gettime();
898 return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
899}
900
901/* get the current master clock value */
902static double get_master_clock(VideoState *is)
903{
904 double val;
905
72ea344b
FB
906 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
907 if (is->video_st)
908 val = get_video_clock(is);
909 else
910 val = get_audio_clock(is);
911 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
912 if (is->audio_st)
913 val = get_audio_clock(is);
914 else
915 val = get_video_clock(is);
916 } else {
638c9d91 917 val = get_external_clock(is);
72ea344b 918 }
638c9d91
FB
919 return val;
920}
921
72ea344b 922/* seek in the stream */
3ba1438d 923static void stream_seek(VideoState *is, int64_t pos, int rel)
72ea344b 924{
687fae2b
IW
925 if (!is->seek_req) {
926 is->seek_pos = pos;
927 is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
928 is->seek_req = 1;
929 }
72ea344b
FB
930}
931
932/* pause or resume the video */
933static void stream_pause(VideoState *is)
934{
935 is->paused = !is->paused;
936 if (is->paused) {
937 is->video_current_pts = get_video_clock(is);
938 }
939}
940
01310af2
FB
941/* called to display each frame */
942static void video_refresh_timer(void *opaque)
943{
944 VideoState *is = opaque;
945 VideoPicture *vp;
638c9d91
FB
946 double actual_delay, delay, sync_threshold, ref_clock, diff;
947
72ce053b 948 SubPicture *sp, *sp2;
01310af2
FB
949
950 if (is->video_st) {
951 if (is->pictq_size == 0) {
952 /* if no picture, need to wait */
7e0140cb 953 schedule_refresh(is, 1);
01310af2 954 } else {
638c9d91 955 /* dequeue the picture */
01310af2 956 vp = &is->pictq[is->pictq_rindex];
638c9d91
FB
957
958 /* update current video pts */
959 is->video_current_pts = vp->pts;
960 is->video_current_pts_time = av_gettime();
961
962 /* compute nominal delay */
963 delay = vp->pts - is->frame_last_pts;
964 if (delay <= 0 || delay >= 1.0) {
965 /* if incorrect delay, use previous one */
966 delay = is->frame_last_delay;
967 }
968 is->frame_last_delay = delay;
969 is->frame_last_pts = vp->pts;
970
971 /* update delay to follow master synchronisation source */
972 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
973 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
974 /* if video is slave, we try to correct big delays by
975 duplicating or deleting a frame */
976 ref_clock = get_master_clock(is);
977 diff = vp->pts - ref_clock;
978
979 /* skip or repeat frame. We take into account the
980 delay to compute the threshold. I still don't know
981 if it is the best guess */
982 sync_threshold = AV_SYNC_THRESHOLD;
983 if (delay > sync_threshold)
984 sync_threshold = delay;
985 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
986 if (diff <= -sync_threshold)
987 delay = 0;
988 else if (diff >= sync_threshold)
989 delay = 2 * delay;
990 }
991 }
992
993 is->frame_timer += delay;
994 /* compute the REAL delay (we need to do that to avoid
995 long term errors */
996 actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
997 if (actual_delay < 0.010) {
998 /* XXX: should skip picture */
999 actual_delay = 0.010;
1000 }
01310af2 1001 /* launch timer for next picture */
638c9d91
FB
1002 schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
1003
1004#if defined(DEBUG_SYNC)
1005 printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1006 delay, actual_delay, vp->pts, -diff);
1007#endif
01310af2 1008
72ce053b
IC
1009 if(is->subtitle_st) {
1010 if (is->subtitle_stream_changed) {
1011 SDL_LockMutex(is->subpq_mutex);
1012
1013 while (is->subpq_size) {
1014 free_subpicture(&is->subpq[is->subpq_rindex]);
1015
1016 /* update queue size and signal for next picture */
1017 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1018 is->subpq_rindex = 0;
1019
1020 is->subpq_size--;
1021 }
1022 is->subtitle_stream_changed = 0;
1023
1024 SDL_CondSignal(is->subpq_cond);
1025 SDL_UnlockMutex(is->subpq_mutex);
1026 } else {
1027 if (is->subpq_size > 0) {
1028 sp = &is->subpq[is->subpq_rindex];
1029
1030 if (is->subpq_size > 1)
1031 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1032 else
1033 sp2 = NULL;
1034
1035 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1036 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1037 {
1038 free_subpicture(sp);
1039
1040 /* update queue size and signal for next picture */
1041 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1042 is->subpq_rindex = 0;
1043
1044 SDL_LockMutex(is->subpq_mutex);
1045 is->subpq_size--;
1046 SDL_CondSignal(is->subpq_cond);
1047 SDL_UnlockMutex(is->subpq_mutex);
1048 }
1049 }
1050 }
1051 }
1052
01310af2
FB
1053 /* display picture */
1054 video_display(is);
1055
1056 /* update queue size and signal for next picture */
1057 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1058 is->pictq_rindex = 0;
1059
1060 SDL_LockMutex(is->pictq_mutex);
1061 is->pictq_size--;
1062 SDL_CondSignal(is->pictq_cond);
1063 SDL_UnlockMutex(is->pictq_mutex);
1064 }
1065 } else if (is->audio_st) {
1066 /* draw the next audio frame */
1067
1068 schedule_refresh(is, 40);
1069
1070 /* if only audio stream, then display the audio bars (better
1071 than nothing, just to test the implementation */
1072
1073 /* display picture */
1074 video_display(is);
1075 } else {
1076 schedule_refresh(is, 100);
1077 }
1078 if (show_status) {
1079 static int64_t last_time;
1080 int64_t cur_time;
72ce053b 1081 int aqsize, vqsize, sqsize;
638c9d91 1082 double av_diff;
01310af2
FB
1083
1084 cur_time = av_gettime();
1085 if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1086 aqsize = 0;
1087 vqsize = 0;
72ce053b 1088 sqsize = 0;
01310af2
FB
1089 if (is->audio_st)
1090 aqsize = is->audioq.size;
1091 if (is->video_st)
1092 vqsize = is->videoq.size;
72ce053b
IC
1093 if (is->subtitle_st)
1094 sqsize = is->subtitleq.size;
638c9d91
FB
1095 av_diff = 0;
1096 if (is->audio_st && is->video_st)
1097 av_diff = get_audio_clock(is) - get_video_clock(is);
72ce053b
IC
1098 printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB \r",
1099 get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
01310af2
FB
1100 fflush(stdout);
1101 last_time = cur_time;
1102 }
1103 }
1104}
1105
1106/* allocate a picture (needs to do that in main thread to avoid
1107 potential locking problems */
1108static void alloc_picture(void *opaque)
1109{
1110 VideoState *is = opaque;
1111 VideoPicture *vp;
01310af2
FB
1112
1113 vp = &is->pictq[is->pictq_windex];
1114
1115 if (vp->bmp)
1116 SDL_FreeYUVOverlay(vp->bmp);
1117
61890b02 1118#if 0
01310af2 1119 /* XXX: use generic function */
61890b02 1120 /* XXX: disable overlay if no hardware acceleration or if RGB format */
01f4895c 1121 switch(is->video_st->codec->pix_fmt) {
01310af2
FB
1122 case PIX_FMT_YUV420P:
1123 case PIX_FMT_YUV422P:
1124 case PIX_FMT_YUV444P:
1125 case PIX_FMT_YUV422:
1126 case PIX_FMT_YUV410P:
1127 case PIX_FMT_YUV411P:
1128 is_yuv = 1;
1129 break;
1130 default:
1131 is_yuv = 0;
1132 break;
1133 }
01310af2 1134#endif
01f4895c
MN
1135 vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1136 is->video_st->codec->height,
61890b02
FB
1137 SDL_YV12_OVERLAY,
1138 screen);
01f4895c
MN
1139 vp->width = is->video_st->codec->width;
1140 vp->height = is->video_st->codec->height;
01310af2
FB
1141
1142 SDL_LockMutex(is->pictq_mutex);
1143 vp->allocated = 1;
1144 SDL_CondSignal(is->pictq_cond);
1145 SDL_UnlockMutex(is->pictq_mutex);
1146}
1147
638c9d91 1148static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
01310af2
FB
1149{
1150 VideoPicture *vp;
1151 int dst_pix_fmt;
1152 AVPicture pict;
01310af2
FB
1153
1154 /* wait until we have space to put a new picture */
1155 SDL_LockMutex(is->pictq_mutex);
1156 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1157 !is->videoq.abort_request) {
1158 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1159 }
1160 SDL_UnlockMutex(is->pictq_mutex);
1161
1162 if (is->videoq.abort_request)
1163 return -1;
1164
1165 vp = &is->pictq[is->pictq_windex];
1166
1167 /* alloc or resize hardware picture buffer */
1168 if (!vp->bmp ||
01f4895c
MN
1169 vp->width != is->video_st->codec->width ||
1170 vp->height != is->video_st->codec->height) {
01310af2
FB
1171 SDL_Event event;
1172
1173 vp->allocated = 0;
1174
1175 /* the allocation must be done in the main thread to avoid
1176 locking problems */
1177 event.type = FF_ALLOC_EVENT;
1178 event.user.data1 = is;
1179 SDL_PushEvent(&event);
1180
1181 /* wait until the picture is allocated */
1182 SDL_LockMutex(is->pictq_mutex);
1183 while (!vp->allocated && !is->videoq.abort_request) {
1184 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1185 }
1186 SDL_UnlockMutex(is->pictq_mutex);
1187
1188 if (is->videoq.abort_request)
1189 return -1;
1190 }
1191
638c9d91 1192 /* if the frame is not skipped, then display it */
01310af2
FB
1193 if (vp->bmp) {
1194 /* get a pointer on the bitmap */
1195 SDL_LockYUVOverlay (vp->bmp);
1196
1197 dst_pix_fmt = PIX_FMT_YUV420P;
1198 pict.data[0] = vp->bmp->pixels[0];
1199 pict.data[1] = vp->bmp->pixels[2];
1200 pict.data[2] = vp->bmp->pixels[1];
1201
1202 pict.linesize[0] = vp->bmp->pitches[0];
1203 pict.linesize[1] = vp->bmp->pitches[2];
1204 pict.linesize[2] = vp->bmp->pitches[1];
01310af2 1205 img_convert(&pict, dst_pix_fmt,
01f4895c
MN
1206 (AVPicture *)src_frame, is->video_st->codec->pix_fmt,
1207 is->video_st->codec->width, is->video_st->codec->height);
01310af2
FB
1208 /* update the bitmap content */
1209 SDL_UnlockYUVOverlay(vp->bmp);
1210
638c9d91 1211 vp->pts = pts;
01310af2
FB
1212
1213 /* now we can update the picture count */
1214 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1215 is->pictq_windex = 0;
1216 SDL_LockMutex(is->pictq_mutex);
1217 is->pictq_size++;
1218 SDL_UnlockMutex(is->pictq_mutex);
1219 }
638c9d91
FB
1220 return 0;
1221}
1222
1223/* compute the exact PTS for the picture if it is omitted in the stream */
1224static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1225{
1226 double frame_delay, pts;
1227
1228 pts = pts1;
1229
01310af2 1230 if (pts != 0) {
638c9d91 1231 /* update video clock with pts, if present */
01310af2
FB
1232 is->video_clock = pts;
1233 } else {
72ea344b
FB
1234 pts = is->video_clock;
1235 }
1236 /* update video clock for next frame */
01f4895c 1237 frame_delay = av_q2d(is->video_st->codec->time_base);
72ea344b
FB
1238 /* for MPEG2, the frame can be repeated, so we update the
1239 clock accordingly */
1240 if (src_frame->repeat_pict) {
1241 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
01310af2 1242 }
72ea344b 1243 is->video_clock += frame_delay;
638c9d91
FB
1244
1245#if defined(DEBUG_SYNC) && 0
1246 {
1247 int ftype;
1248 if (src_frame->pict_type == FF_B_TYPE)
1249 ftype = 'B';
1250 else if (src_frame->pict_type == FF_I_TYPE)
1251 ftype = 'I';
1252 else
1253 ftype = 'P';
1254 printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
72ea344b 1255 ftype, pts, pts1);
638c9d91
FB
1256 }
1257#endif
72ea344b 1258 return queue_picture(is, src_frame, pts);
01310af2
FB
1259}
1260
1261static int video_thread(void *arg)
1262{
1263 VideoState *is = arg;
1264 AVPacket pkt1, *pkt = &pkt1;
72ea344b 1265 int len1, got_picture;
c6b1edc9 1266 AVFrame *frame= avcodec_alloc_frame();
01310af2
FB
1267 double pts;
1268
1269 for(;;) {
1270 while (is->paused && !is->videoq.abort_request) {
1271 SDL_Delay(10);
1272 }
1273 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1274 break;
638c9d91
FB
1275 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1276 this packet, if any */
72ea344b 1277 pts = 0;
61c1d8e2 1278 if (pkt->dts != AV_NOPTS_VALUE)
c0df9d75 1279 pts = av_q2d(is->video_st->time_base)*pkt->dts;
72ea344b 1280
b514ed3c 1281 SDL_LockMutex(is->video_decoder_mutex);
01f4895c 1282 len1 = avcodec_decode_video(is->video_st->codec,
72ea344b
FB
1283 frame, &got_picture,
1284 pkt->data, pkt->size);
b514ed3c 1285 SDL_UnlockMutex(is->video_decoder_mutex);
fb966f99
MN
1286// if (len1 < 0)
1287// break;
72ea344b
FB
1288 if (got_picture) {
1289 if (output_picture2(is, frame, pts) < 0)
1290 goto the_end;
01310af2 1291 }
01310af2 1292 av_free_packet(pkt);
bba04f1e
WH
1293 if (step)
1294 if (cur_stream)
1295 stream_pause(cur_stream);
01310af2
FB
1296 }
1297 the_end:
c6b1edc9 1298 av_free(frame);
01310af2
FB
1299 return 0;
1300}
1301
72ce053b
IC
1302static int subtitle_thread(void *arg)
1303{
1304 VideoState *is = arg;
1305 SubPicture *sp;
1306 AVPacket pkt1, *pkt = &pkt1;
1307 int len1, got_subtitle;
1308 double pts;
1309 int i, j;
1310 int r, g, b, y, u, v, a;
1311
1312 for(;;) {
1313 while (is->paused && !is->subtitleq.abort_request) {
1314 SDL_Delay(10);
1315 }
1316 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1317 break;
1318
1319 SDL_LockMutex(is->subpq_mutex);
1320 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1321 !is->subtitleq.abort_request) {
1322 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1323 }
1324 SDL_UnlockMutex(is->subpq_mutex);
1325
1326 if (is->subtitleq.abort_request)
1327 goto the_end;
1328
1329 sp = &is->subpq[is->subpq_windex];
1330
1331 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1332 this packet, if any */
1333 pts = 0;
1334 if (pkt->pts != AV_NOPTS_VALUE)
1335 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1336
1337 SDL_LockMutex(is->subtitle_decoder_mutex);
1338 len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1339 &sp->sub, &got_subtitle,
1340 pkt->data, pkt->size);
1341 SDL_UnlockMutex(is->subtitle_decoder_mutex);
1342// if (len1 < 0)
1343// break;
1344 if (got_subtitle && sp->sub.format == 0) {
1345 sp->pts = pts;
1346
1347 for (i = 0; i < sp->sub.num_rects; i++)
1348 {
1349 for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1350 {
1351 RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1352 y = RGB_TO_Y_CCIR(r, g, b);
1353 u = RGB_TO_U_CCIR(r, g, b, 0);
1354 v = RGB_TO_V_CCIR(r, g, b, 0);
1355 YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1356 }
1357 }
1358
1359 /* now we can update the picture count */
1360 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1361 is->subpq_windex = 0;
1362 SDL_LockMutex(is->subpq_mutex);
1363 is->subpq_size++;
1364 SDL_UnlockMutex(is->subpq_mutex);
1365 }
1366 av_free_packet(pkt);
1367// if (step)
1368// if (cur_stream)
1369// stream_pause(cur_stream);
1370 }
1371 the_end:
1372 return 0;
1373}
1374
01310af2
FB
1375/* copy samples for viewing in editor window */
1376static void update_sample_display(VideoState *is, short *samples, int samples_size)
1377{
1378 int size, len, channels;
1379
01f4895c 1380 channels = is->audio_st->codec->channels;
01310af2
FB
1381
1382 size = samples_size / sizeof(short);
1383 while (size > 0) {
1384 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1385 if (len > size)
1386 len = size;
1387 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1388 samples += len;
1389 is->sample_array_index += len;
1390 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1391 is->sample_array_index = 0;
1392 size -= len;
1393 }
1394}
1395
01310af2
FB
1396/* return the new audio buffer size (samples can be added or deleted
1397 to get better sync if video or external master clock) */
1398static int synchronize_audio(VideoState *is, short *samples,
638c9d91 1399 int samples_size1, double pts)
01310af2 1400{
638c9d91 1401 int n, samples_size;
01310af2
FB
1402 double ref_clock;
1403
01f4895c 1404 n = 2 * is->audio_st->codec->channels;
638c9d91 1405 samples_size = samples_size1;
01310af2 1406
01310af2 1407 /* if not master, then we try to remove or add samples to correct the clock */
01310af2 1408 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
638c9d91
FB
1409 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1410 double diff, avg_diff;
01310af2 1411 int wanted_size, min_size, max_size, nb_samples;
638c9d91
FB
1412
1413 ref_clock = get_master_clock(is);
1414 diff = get_audio_clock(is) - ref_clock;
01310af2 1415
638c9d91
FB
1416 if (diff < AV_NOSYNC_THRESHOLD) {
1417 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1418 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1419 /* not enough measures to have a correct estimate */
1420 is->audio_diff_avg_count++;
1421 } else {
1422 /* estimate the A-V difference */
1423 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1424
1425 if (fabs(avg_diff) >= is->audio_diff_threshold) {
01f4895c 1426 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
638c9d91
FB
1427 nb_samples = samples_size / n;
1428
1429 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1430 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1431 if (wanted_size < min_size)
1432 wanted_size = min_size;
1433 else if (wanted_size > max_size)
1434 wanted_size = max_size;
1435
1436 /* add or remove samples to correction the synchro */
1437 if (wanted_size < samples_size) {
1438 /* remove samples */
1439 samples_size = wanted_size;
1440 } else if (wanted_size > samples_size) {
1441 uint8_t *samples_end, *q;
1442 int nb;
1443
1444 /* add samples */
1445 nb = (samples_size - wanted_size);
1446 samples_end = (uint8_t *)samples + samples_size - n;
1447 q = samples_end + n;
1448 while (nb > 0) {
1449 memcpy(q, samples_end, n);
1450 q += n;
1451 nb -= n;
1452 }
1453 samples_size = wanted_size;
1454 }
1455 }
1456#if 0
1457 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1458 diff, avg_diff, samples_size - samples_size1,
1459 is->audio_clock, is->video_clock, is->audio_diff_threshold);
1460#endif
01310af2 1461 }
638c9d91
FB
1462 } else {
1463 /* too big difference : may be initial PTS errors, so
1464 reset A-V filter */
1465 is->audio_diff_avg_count = 0;
1466 is->audio_diff_cum = 0;
01310af2
FB
1467 }
1468 }
1469
01310af2
FB
1470 return samples_size;
1471}
1472
1473/* decode one audio frame and returns its uncompressed size */
1474static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
1475{
1476 AVPacket *pkt = &is->audio_pkt;
72ea344b 1477 int n, len1, data_size;
01310af2
FB
1478 double pts;
1479
1480 for(;;) {
72ea344b 1481 /* NOTE: the audio packet can contain several frames */
01310af2 1482 while (is->audio_pkt_size > 0) {
b514ed3c 1483 SDL_LockMutex(is->audio_decoder_mutex);
01f4895c 1484 len1 = avcodec_decode_audio(is->audio_st->codec,
01310af2
FB
1485 (int16_t *)audio_buf, &data_size,
1486 is->audio_pkt_data, is->audio_pkt_size);
b514ed3c 1487 SDL_UnlockMutex(is->audio_decoder_mutex);
72ea344b
FB
1488 if (len1 < 0) {
1489 /* if error, we skip the frame */
1490 is->audio_pkt_size = 0;
01310af2 1491 break;
72ea344b
FB
1492 }
1493
01310af2
FB
1494 is->audio_pkt_data += len1;
1495 is->audio_pkt_size -= len1;
72ea344b
FB
1496 if (data_size <= 0)
1497 continue;
1498 /* if no pts, then compute it */
1499 pts = is->audio_clock;
1500 *pts_ptr = pts;
01f4895c 1501 n = 2 * is->audio_st->codec->channels;
72ea344b 1502 is->audio_clock += (double)data_size /
01f4895c 1503 (double)(n * is->audio_st->codec->sample_rate);
638c9d91 1504#if defined(DEBUG_SYNC)
72ea344b
FB
1505 {
1506 static double last_clock;
1507 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1508 is->audio_clock - last_clock,
1509 is->audio_clock, pts);
1510 last_clock = is->audio_clock;
01310af2 1511 }
72ea344b
FB
1512#endif
1513 return data_size;
01310af2
FB
1514 }
1515
72ea344b
FB
1516 /* free the current packet */
1517 if (pkt->data)
01310af2 1518 av_free_packet(pkt);
72ea344b
FB
1519
1520 if (is->paused || is->audioq.abort_request) {
1521 return -1;
1522 }
1523
01310af2
FB
1524 /* read next packet */
1525 if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1526 return -1;
1527 is->audio_pkt_data = pkt->data;
1528 is->audio_pkt_size = pkt->size;
72ea344b
FB
1529
1530 /* if update the audio clock with the pts */
1531 if (pkt->pts != AV_NOPTS_VALUE) {
c0df9d75 1532 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
72ea344b 1533 }
01310af2
FB
1534 }
1535}
1536
638c9d91
FB
1537/* get the current audio output buffer size, in samples. With SDL, we
1538 cannot have a precise information */
1539static int audio_write_get_buf_size(VideoState *is)
01310af2 1540{
638c9d91 1541 return is->audio_hw_buf_size - is->audio_buf_index;
01310af2
FB
1542}
1543
1544
1545/* prepare a new audio buffer */
1546void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1547{
1548 VideoState *is = opaque;
1549 int audio_size, len1;
1550 double pts;
1551
1552 audio_callback_time = av_gettime();
1553
1554 while (len > 0) {
1555 if (is->audio_buf_index >= is->audio_buf_size) {
1556 audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1557 if (audio_size < 0) {
1558 /* if error, just output silence */
1559 is->audio_buf_size = 1024;
1560 memset(is->audio_buf, 0, is->audio_buf_size);
1561 } else {
1562 if (is->show_audio)
1563 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1564 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1565 pts);
1566 is->audio_buf_size = audio_size;
1567 }
1568 is->audio_buf_index = 0;
1569 }
1570 len1 = is->audio_buf_size - is->audio_buf_index;
1571 if (len1 > len)
1572 len1 = len;
1573 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1574 len -= len1;
1575 stream += len1;
1576 is->audio_buf_index += len1;
1577 }
1578}
1579
1580
1581/* open a given stream. Return 0 if OK */
1582static int stream_component_open(VideoState *is, int stream_index)
1583{
1584 AVFormatContext *ic = is->ic;
1585 AVCodecContext *enc;
1586 AVCodec *codec;
1587 SDL_AudioSpec wanted_spec, spec;
1588
1589 if (stream_index < 0 || stream_index >= ic->nb_streams)
1590 return -1;
01f4895c 1591 enc = ic->streams[stream_index]->codec;
01310af2 1592
01310af2
FB
1593 /* prepare audio output */
1594 if (enc->codec_type == CODEC_TYPE_AUDIO) {
1595 wanted_spec.freq = enc->sample_rate;
1596 wanted_spec.format = AUDIO_S16SYS;
638c9d91
FB
1597 /* hack for AC3. XXX: suppress that */
1598 if (enc->channels > 2)
1599 enc->channels = 2;
01310af2
FB
1600 wanted_spec.channels = enc->channels;
1601 wanted_spec.silence = 0;
638c9d91 1602 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
01310af2
FB
1603 wanted_spec.callback = sdl_audio_callback;
1604 wanted_spec.userdata = is;
638c9d91
FB
1605 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1606 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
01310af2 1607 return -1;
638c9d91 1608 }
01310af2
FB
1609 is->audio_hw_buf_size = spec.size;
1610 }
1611
1612 codec = avcodec_find_decoder(enc->codec_id);
13d1512c
MN
1613 enc->debug_mv = debug_mv;
1614 enc->debug = debug;
1ab1f099
MN
1615 if(debug)
1616 av_log_set_level(AV_LOG_DEBUG);
6387c3e6 1617 enc->workaround_bugs = workaround_bugs;
178fcca8 1618 enc->lowres = lowres;
61846e9a 1619 if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
178fcca8 1620 enc->idct_algo= idct;
6fc5b059 1621 if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
8c3eba7c
MN
1622 enc->skip_frame= skip_frame;
1623 enc->skip_idct= skip_idct;
1624 enc->skip_loop_filter= skip_loop_filter;
1b51e051
MN
1625 enc->error_resilience= error_resilience;
1626 enc->error_concealment= error_concealment;
01310af2
FB
1627 if (!codec ||
1628 avcodec_open(enc, codec) < 0)
1629 return -1;
2450cff2 1630#if defined(HAVE_THREADS)
c62c07d3
MN
1631 if(thread_count>1)
1632 avcodec_thread_init(enc, thread_count);
1633#endif
1634 enc->thread_count= thread_count;
638c9d91 1635 switch(enc->codec_type) {
01310af2
FB
1636 case CODEC_TYPE_AUDIO:
1637 is->audio_stream = stream_index;
1638 is->audio_st = ic->streams[stream_index];
1639 is->audio_buf_size = 0;
1640 is->audio_buf_index = 0;
638c9d91
FB
1641
1642 /* init averaging filter */
1643 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1644 is->audio_diff_avg_count = 0;
1645 /* since we do not have a precise anough audio fifo fullness,
1646 we correct audio sync only if larger than this threshold */
1647 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1648
01310af2
FB
1649 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1650 packet_queue_init(&is->audioq);
1651 SDL_PauseAudio(0);
1652 break;
1653 case CODEC_TYPE_VIDEO:
1654 is->video_stream = stream_index;
1655 is->video_st = ic->streams[stream_index];
1656
638c9d91
FB
1657 is->frame_last_delay = 40e-3;
1658 is->frame_timer = (double)av_gettime() / 1000000.0;
638c9d91
FB
1659 is->video_current_pts_time = av_gettime();
1660
01310af2
FB
1661 packet_queue_init(&is->videoq);
1662 is->video_tid = SDL_CreateThread(video_thread, is);
1663 break;
72ce053b
IC
1664 case CODEC_TYPE_SUBTITLE:
1665 is->subtitle_stream = stream_index;
1666 is->subtitle_st = ic->streams[stream_index];
1667 packet_queue_init(&is->subtitleq);
1668
1669 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1670 break;
01310af2
FB
1671 default:
1672 break;
1673 }
1674 return 0;
1675}
1676
1677static void stream_component_close(VideoState *is, int stream_index)
1678{
1679 AVFormatContext *ic = is->ic;
1680 AVCodecContext *enc;
1681
72ce053b
IC
1682 if (stream_index < 0 || stream_index >= ic->nb_streams)
1683 return;
01f4895c 1684 enc = ic->streams[stream_index]->codec;
01310af2
FB
1685
1686 switch(enc->codec_type) {
1687 case CODEC_TYPE_AUDIO:
1688 packet_queue_abort(&is->audioq);
1689
1690 SDL_CloseAudio();
1691
1692 packet_queue_end(&is->audioq);
1693 break;
1694 case CODEC_TYPE_VIDEO:
1695 packet_queue_abort(&is->videoq);
1696
1697 /* note: we also signal this mutex to make sure we deblock the
1698 video thread in all cases */
1699 SDL_LockMutex(is->pictq_mutex);
1700 SDL_CondSignal(is->pictq_cond);
1701 SDL_UnlockMutex(is->pictq_mutex);
1702
1703 SDL_WaitThread(is->video_tid, NULL);
1704
1705 packet_queue_end(&is->videoq);
1706 break;
72ce053b
IC
1707 case CODEC_TYPE_SUBTITLE:
1708 packet_queue_abort(&is->subtitleq);
1709
1710 /* note: we also signal this mutex to make sure we deblock the
1711 video thread in all cases */
1712 SDL_LockMutex(is->subpq_mutex);
1713 is->subtitle_stream_changed = 1;
1714
1715 SDL_CondSignal(is->subpq_cond);
1716 SDL_UnlockMutex(is->subpq_mutex);
1717
1718 SDL_WaitThread(is->subtitle_tid, NULL);
1719
1720 packet_queue_end(&is->subtitleq);
1721 break;
01310af2
FB
1722 default:
1723 break;
1724 }
1725
1726 avcodec_close(enc);
1727 switch(enc->codec_type) {
1728 case CODEC_TYPE_AUDIO:
1729 is->audio_st = NULL;
1730 is->audio_stream = -1;
1731 break;
1732 case CODEC_TYPE_VIDEO:
1733 is->video_st = NULL;
1734 is->video_stream = -1;
1735 break;
72ce053b
IC
1736 case CODEC_TYPE_SUBTITLE:
1737 is->subtitle_st = NULL;
1738 is->subtitle_stream = -1;
1739 break;
01310af2
FB
1740 default:
1741 break;
1742 }
1743}
1744
d0526ecf
FB
1745void dump_stream_info(AVFormatContext *s)
1746{
1747 if (s->track != 0)
1748 fprintf(stderr, "Track: %d\n", s->track);
1749 if (s->title[0] != '\0')
1750 fprintf(stderr, "Title: %s\n", s->title);
1751 if (s->author[0] != '\0')
1752 fprintf(stderr, "Author: %s\n", s->author);
1753 if (s->album[0] != '\0')
1754 fprintf(stderr, "Album: %s\n", s->album);
1755 if (s->year != 0)
1756 fprintf(stderr, "Year: %d\n", s->year);
1757 if (s->genre[0] != '\0')
1758 fprintf(stderr, "Genre: %s\n", s->genre);
1759}
1760
416e3508
FB
1761/* since we have only one decoding thread, we can use a global
1762 variable instead of a thread local variable */
1763static VideoState *global_video_state;
1764
1765static int decode_interrupt_cb(void)
1766{
1767 return (global_video_state && global_video_state->abort_request);
1768}
01310af2
FB
1769
1770/* this thread gets the stream from the disk or the network */
1771static int decode_thread(void *arg)
1772{
1773 VideoState *is = arg;
1774 AVFormatContext *ic;
72ea344b 1775 int err, i, ret, video_index, audio_index, use_play;
01310af2 1776 AVPacket pkt1, *pkt = &pkt1;
61890b02 1777 AVFormatParameters params, *ap = &params;
01310af2
FB
1778
1779 video_index = -1;
1780 audio_index = -1;
1781 is->video_stream = -1;
1782 is->audio_stream = -1;
72ce053b 1783 is->subtitle_stream = -1;
01310af2 1784
416e3508
FB
1785 global_video_state = is;
1786 url_set_interrupt_cb(decode_interrupt_cb);
1787
61890b02
FB
1788 memset(ap, 0, sizeof(*ap));
1789 ap->image_format = image_format;
72ea344b
FB
1790 ap->initial_pause = 1; /* we force a pause when starting an RTSP
1791 stream */
1792
61890b02 1793 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
638c9d91
FB
1794 if (err < 0) {
1795 print_error(is->filename, err);
1796 ret = -1;
1797 goto fail;
1798 }
01310af2 1799 is->ic = ic;
72ea344b
FB
1800#ifdef CONFIG_NETWORK
1801 use_play = (ic->iformat == &rtsp_demux);
1802#else
1803 use_play = 0;
1804#endif
1805 if (!use_play) {
1806 err = av_find_stream_info(ic);
1807 if (err < 0) {
1808 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1809 ret = -1;
1810 goto fail;
1811 }
2536c5fd 1812 ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
638c9d91 1813 }
72ea344b
FB
1814
1815 /* if seeking requested, we execute it */
1816 if (start_time != AV_NOPTS_VALUE) {
1817 int64_t timestamp;
1818
1819 timestamp = start_time;
1820 /* add the stream start time */
1821 if (ic->start_time != AV_NOPTS_VALUE)
1822 timestamp += ic->start_time;
3ba1438d 1823 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
72ea344b
FB
1824 if (ret < 0) {
1825 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1826 is->filename, (double)timestamp / AV_TIME_BASE);
1827 }
1828 }
1829
1830 /* now we can begin to play (RTSP stream only) */
1831 av_read_play(ic);
1832
1833 if (use_play) {
1834 err = av_find_stream_info(ic);
1835 if (err < 0) {
1836 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1837 ret = -1;
1838 goto fail;
1839 }
1840 }
1841
01310af2 1842 for(i = 0; i < ic->nb_streams; i++) {
01f4895c 1843 AVCodecContext *enc = ic->streams[i]->codec;
01310af2
FB
1844 switch(enc->codec_type) {
1845 case CODEC_TYPE_AUDIO:
1846 if (audio_index < 0 && !audio_disable)
1847 audio_index = i;
1848 break;
1849 case CODEC_TYPE_VIDEO:
1850 if (video_index < 0 && !video_disable)
1851 video_index = i;
1852 break;
1853 default:
1854 break;
1855 }
1856 }
1857 if (show_status) {
1858 dump_format(ic, 0, is->filename, 0);
d0526ecf 1859 dump_stream_info(ic);
01310af2
FB
1860 }
1861
1862 /* open the streams */
1863 if (audio_index >= 0) {
1864 stream_component_open(is, audio_index);
1865 }
1866
1867 if (video_index >= 0) {
1868 stream_component_open(is, video_index);
1869 } else {
1870 if (!display_disable)
1871 is->show_audio = 1;
1872 }
1873
1874 if (is->video_stream < 0 && is->audio_stream < 0) {
638c9d91
FB
1875 fprintf(stderr, "%s: could not open codecs\n", is->filename);
1876 ret = -1;
01310af2
FB
1877 goto fail;
1878 }
1879
1880 for(;;) {
1881 if (is->abort_request)
1882 break;
400738b1 1883#ifdef CONFIG_NETWORK
416e3508
FB
1884 if (is->paused != is->last_paused) {
1885 is->last_paused = is->paused;
72ea344b
FB
1886 if (is->paused)
1887 av_read_pause(ic);
1888 else
1889 av_read_play(ic);
416e3508
FB
1890 }
1891 if (is->paused && ic->iformat == &rtsp_demux) {
1892 /* wait 10 ms to avoid trying to get another packet */
1893 /* XXX: horrible */
1894 SDL_Delay(10);
1895 continue;
1896 }
400738b1 1897#endif
72ea344b
FB
1898 if (is->seek_req) {
1899 /* XXX: must lock decoder threads */
687fae2b
IW
1900 SDL_LockMutex(is->video_decoder_mutex);
1901 SDL_LockMutex(is->audio_decoder_mutex);
72ce053b 1902 SDL_LockMutex(is->subtitle_decoder_mutex);
3ba1438d 1903 ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
72ea344b
FB
1904 if (ret < 0) {
1905 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
e6c0297f
MN
1906 }else{
1907 if (is->audio_stream >= 0) {
1908 packet_queue_flush(&is->audioq);
1909 }
72ce053b
IC
1910 if (is->subtitle_stream >= 0) {
1911 packet_queue_flush(&is->subtitleq);
1912 }
e6c0297f
MN
1913 if (is->video_stream >= 0) {
1914 packet_queue_flush(&is->videoq);
01f4895c 1915 avcodec_flush_buffers(ic->streams[video_index]->codec);
e6c0297f 1916 }
72ea344b 1917 }
72ce053b 1918 SDL_UnlockMutex(is->subtitle_decoder_mutex);
687fae2b
IW
1919 SDL_UnlockMutex(is->audio_decoder_mutex);
1920 SDL_UnlockMutex(is->video_decoder_mutex);
72ea344b
FB
1921 is->seek_req = 0;
1922 }
416e3508 1923
01310af2
FB
1924 /* if the queue are full, no need to read more */
1925 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
0c904df2 1926 is->videoq.size > MAX_VIDEOQ_SIZE ||
72ce053b 1927 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
0c904df2 1928 url_feof(&ic->pb)) {
01310af2
FB
1929 /* wait 10 ms */
1930 SDL_Delay(10);
1931 continue;
1932 }
72ea344b 1933 ret = av_read_frame(ic, pkt);
01310af2 1934 if (ret < 0) {
22e50022 1935 if (url_ferror(&ic->pb) == 0) {
6e1f8725
RS
1936 SDL_Delay(100); /* wait for user event */
1937 continue;
1938 } else
1939 break;
01310af2
FB
1940 }
1941 if (pkt->stream_index == is->audio_stream) {
1942 packet_queue_put(&is->audioq, pkt);
1943 } else if (pkt->stream_index == is->video_stream) {
1944 packet_queue_put(&is->videoq, pkt);
72ce053b
IC
1945 } else if (pkt->stream_index == is->subtitle_stream) {
1946 packet_queue_put(&is->subtitleq, pkt);
01310af2
FB
1947 } else {
1948 av_free_packet(pkt);
1949 }
1950 }
1951 /* wait until the end */
1952 while (!is->abort_request) {
1953 SDL_Delay(100);
1954 }
1955
638c9d91 1956 ret = 0;
01310af2 1957 fail:
416e3508
FB
1958 /* disable interrupting */
1959 global_video_state = NULL;
1960
01310af2
FB
1961 /* close each stream */
1962 if (is->audio_stream >= 0)
1963 stream_component_close(is, is->audio_stream);
1964 if (is->video_stream >= 0)
1965 stream_component_close(is, is->video_stream);
72ce053b
IC
1966 if (is->subtitle_stream >= 0)
1967 stream_component_close(is, is->subtitle_stream);
638c9d91
FB
1968 if (is->ic) {
1969 av_close_input_file(is->ic);
1970 is->ic = NULL; /* safety */
1971 }
416e3508
FB
1972 url_set_interrupt_cb(NULL);
1973
638c9d91
FB
1974 if (ret != 0) {
1975 SDL_Event event;
1976
1977 event.type = FF_QUIT_EVENT;
1978 event.user.data1 = is;
1979 SDL_PushEvent(&event);
1980 }
01310af2
FB
1981 return 0;
1982}
1983
638c9d91 1984static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
01310af2
FB
1985{
1986 VideoState *is;
1987
1988 is = av_mallocz(sizeof(VideoState));
1989 if (!is)
1990 return NULL;
1991 pstrcpy(is->filename, sizeof(is->filename), filename);
638c9d91 1992 is->iformat = iformat;
01310af2
FB
1993 if (screen) {
1994 is->width = screen->w;
1995 is->height = screen->h;
1996 }
1997 is->ytop = 0;
1998 is->xleft = 0;
1999
2000 /* start video display */
2001 is->pictq_mutex = SDL_CreateMutex();
2002 is->pictq_cond = SDL_CreateCond();
b514ed3c 2003
72ce053b
IC
2004 is->subpq_mutex = SDL_CreateMutex();
2005 is->subpq_cond = SDL_CreateCond();
2006
2007 is->subtitle_decoder_mutex = SDL_CreateMutex();
b514ed3c
MN
2008 is->audio_decoder_mutex = SDL_CreateMutex();
2009 is->video_decoder_mutex = SDL_CreateMutex();
01310af2
FB
2010
2011 /* add the refresh timer to draw the picture */
2012 schedule_refresh(is, 40);
2013
638c9d91 2014 is->av_sync_type = av_sync_type;
01310af2
FB
2015 is->parse_tid = SDL_CreateThread(decode_thread, is);
2016 if (!is->parse_tid) {
2017 av_free(is);
2018 return NULL;
2019 }
2020 return is;
2021}
2022
2023static void stream_close(VideoState *is)
2024{
2025 VideoPicture *vp;
2026 int i;
2027 /* XXX: use a special url_shutdown call to abort parse cleanly */
2028 is->abort_request = 1;
2029 SDL_WaitThread(is->parse_tid, NULL);
2030
2031 /* free all pictures */
2032 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2033 vp = &is->pictq[i];
2034 if (vp->bmp) {
2035 SDL_FreeYUVOverlay(vp->bmp);
2036 vp->bmp = NULL;
2037 }
2038 }
2039 SDL_DestroyMutex(is->pictq_mutex);
2040 SDL_DestroyCond(is->pictq_cond);
72ce053b
IC
2041 SDL_DestroyMutex(is->subpq_mutex);
2042 SDL_DestroyCond(is->subpq_cond);
2043 SDL_DestroyMutex(is->subtitle_decoder_mutex);
b514ed3c
MN
2044 SDL_DestroyMutex(is->audio_decoder_mutex);
2045 SDL_DestroyMutex(is->video_decoder_mutex);
01310af2
FB
2046}
2047
638c9d91
FB
2048void stream_cycle_channel(VideoState *is, int codec_type)
2049{
2050 AVFormatContext *ic = is->ic;
2051 int start_index, stream_index;
2052 AVStream *st;
2053
2054 if (codec_type == CODEC_TYPE_VIDEO)
2055 start_index = is->video_stream;
72ce053b 2056 else if (codec_type == CODEC_TYPE_AUDIO)
638c9d91 2057 start_index = is->audio_stream;
72ce053b
IC
2058 else
2059 start_index = is->subtitle_stream;
2060 if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
638c9d91
FB
2061 return;
2062 stream_index = start_index;
2063 for(;;) {
2064 if (++stream_index >= is->ic->nb_streams)
72ce053b
IC
2065 {
2066 if (codec_type == CODEC_TYPE_SUBTITLE)
2067 {
2068 stream_index = -1;
2069 goto the_end;
2070 } else
2071 stream_index = 0;
2072 }
638c9d91
FB
2073 if (stream_index == start_index)
2074 return;
2075 st = ic->streams[stream_index];
01f4895c 2076 if (st->codec->codec_type == codec_type) {
638c9d91
FB
2077 /* check that parameters are OK */
2078 switch(codec_type) {
2079 case CODEC_TYPE_AUDIO:
01f4895c
MN
2080 if (st->codec->sample_rate != 0 &&
2081 st->codec->channels != 0)
638c9d91
FB
2082 goto the_end;
2083 break;
2084 case CODEC_TYPE_VIDEO:
72ce053b 2085 case CODEC_TYPE_SUBTITLE:
638c9d91
FB
2086 goto the_end;
2087 default:
2088 break;
2089 }
2090 }
2091 }
2092 the_end:
2093 stream_component_close(is, start_index);
2094 stream_component_open(is, stream_index);
2095}
2096
2097
01310af2
FB
2098void toggle_full_screen(void)
2099{
2100 int w, h, flags;
2101 is_full_screen = !is_full_screen;
2102 if (!fs_screen_width) {
2103 /* use default SDL method */
2104 SDL_WM_ToggleFullScreen(screen);
2105 } else {
2106 /* use the recorded resolution */
2107 flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
2108 if (is_full_screen) {
2109 w = fs_screen_width;
2110 h = fs_screen_height;
2111 flags |= SDL_FULLSCREEN;
2112 } else {
2113 w = screen_width;
2114 h = screen_height;
2115 flags |= SDL_RESIZABLE;
2116 }
2117 screen = SDL_SetVideoMode(w, h, 0, flags);
2118 cur_stream->width = w;
2119 cur_stream->height = h;
2120 }
2121}
2122
2123void toggle_pause(void)
2124{
2125 if (cur_stream)
2126 stream_pause(cur_stream);
bba04f1e
WH
2127 step = 0;
2128}
2129
2130void step_to_next_frame(void)
2131{
2132 if (cur_stream) {
2133 if (cur_stream->paused)
2134 cur_stream->paused=0;
2135 cur_stream->video_current_pts = get_video_clock(cur_stream);
2136 }
2137 step = 1;
01310af2
FB
2138}
2139
2140void do_exit(void)
2141{
2142 if (cur_stream) {
2143 stream_close(cur_stream);
2144 cur_stream = NULL;
2145 }
2146 if (show_status)
2147 printf("\n");
2148 SDL_Quit();
2149 exit(0);
2150}
2151
2152void toggle_audio_display(void)
2153{
2154 if (cur_stream) {
2155 cur_stream->show_audio = !cur_stream->show_audio;
2156 }
2157}
2158
2159/* handle an event sent by the GUI */
2160void event_loop(void)
2161{
2162 SDL_Event event;
a11d11aa 2163 double incr, pos, frac;
01310af2
FB
2164
2165 for(;;) {
2166 SDL_WaitEvent(&event);
2167 switch(event.type) {
2168 case SDL_KEYDOWN:
2169 switch(event.key.keysym.sym) {
2170 case SDLK_ESCAPE:
2171 case SDLK_q:
2172 do_exit();
2173 break;
2174 case SDLK_f:
2175 toggle_full_screen();
2176 break;
2177 case SDLK_p:
2178 case SDLK_SPACE:
2179 toggle_pause();
2180 break;
bba04f1e
WH
2181 case SDLK_s: //S: Step to next frame
2182 step_to_next_frame();
2183 break;
01310af2 2184 case SDLK_a:
638c9d91
FB
2185 if (cur_stream)
2186 stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2187 break;
2188 case SDLK_v:
2189 if (cur_stream)
2190 stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2191 break;
72ce053b
IC
2192 case SDLK_t:
2193 if (cur_stream)
2194 stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2195 break;
638c9d91 2196 case SDLK_w:
01310af2
FB
2197 toggle_audio_display();
2198 break;
72ea344b
FB
2199 case SDLK_LEFT:
2200 incr = -10.0;
2201 goto do_seek;
2202 case SDLK_RIGHT:
2203 incr = 10.0;
2204 goto do_seek;
2205 case SDLK_UP:
2206 incr = 60.0;
2207 goto do_seek;
2208 case SDLK_DOWN:
2209 incr = -60.0;
2210 do_seek:
2211 if (cur_stream) {
2212 pos = get_master_clock(cur_stream);
2213 pos += incr;
3ba1438d 2214 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
72ea344b
FB
2215 }
2216 break;
01310af2
FB
2217 default:
2218 break;
2219 }
2220 break;
a11d11aa
MB
2221 case SDL_MOUSEBUTTONDOWN:
2222 if (cur_stream) {
2223 int ns, hh, mm, ss;
2224 int tns, thh, tmm, tss;
2225 tns = cur_stream->ic->duration/1000000LL;
2226 thh = tns/3600;
2227 tmm = (tns%3600)/60;
2228 tss = (tns%60);
2229 frac = (double)event.button.x/(double)cur_stream->width;
2230 ns = frac*tns;
2231 hh = ns/3600;
2232 mm = (ns%3600)/60;
2233 ss = (ns%60);
2234 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2235 hh, mm, ss, thh, tmm, tss);
3ba1438d 2236 stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
a11d11aa
MB
2237 }
2238 break;
01310af2
FB
2239 case SDL_VIDEORESIZE:
2240 if (cur_stream) {
2241 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2242 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2243 cur_stream->width = event.resize.w;
2244 cur_stream->height = event.resize.h;
2245 }
2246 break;
2247 case SDL_QUIT:
638c9d91 2248 case FF_QUIT_EVENT:
01310af2
FB
2249 do_exit();
2250 break;
2251 case FF_ALLOC_EVENT:
2252 alloc_picture(event.user.data1);
2253 break;
2254 case FF_REFRESH_EVENT:
2255 video_refresh_timer(event.user.data1);
2256 break;
2257 default:
2258 break;
2259 }
2260 }
2261}
2262
2263void opt_width(const char *arg)
2264{
2265 screen_width = atoi(arg);
2266}
2267
2268void opt_height(const char *arg)
2269{
2270 screen_height = atoi(arg);
2271}
2272
2273static void opt_format(const char *arg)
2274{
2275 file_iformat = av_find_input_format(arg);
2276 if (!file_iformat) {
2277 fprintf(stderr, "Unknown input format: %s\n", arg);
2278 exit(1);
2279 }
2280}
61890b02
FB
2281
2282static void opt_image_format(const char *arg)
2283{
2284 AVImageFormat *f;
2285
2286 for(f = first_image_format; f != NULL; f = f->next) {
2287 if (!strcmp(arg, f->name))
2288 break;
2289 }
2290 if (!f) {
2291 fprintf(stderr, "Unknown image format: '%s'\n", arg);
2292 exit(1);
2293 }
2294 image_format = f;
2295}
2296
400738b1 2297#ifdef CONFIG_NETWORK
416e3508
FB
2298void opt_rtp_tcp(void)
2299{
2300 /* only tcp protocol */
2301 rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2302}
400738b1 2303#endif
416e3508 2304
638c9d91
FB
2305void opt_sync(const char *arg)
2306{
2307 if (!strcmp(arg, "audio"))
2308 av_sync_type = AV_SYNC_AUDIO_MASTER;
2309 else if (!strcmp(arg, "video"))
2310 av_sync_type = AV_SYNC_VIDEO_MASTER;
2311 else if (!strcmp(arg, "ext"))
2312 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2313 else
2314 show_help();
2315}
2316
72ea344b
FB
2317void opt_seek(const char *arg)
2318{
2319 start_time = parse_date(arg, 1);
2320}
2321
e26a8335
WH
2322static void opt_debug(const char *arg)
2323{
2324 debug = atoi(arg);
2325}
2326
0c9bbaec
WH
2327static void opt_vismv(const char *arg)
2328{
2329 debug_mv = atoi(arg);
2330}
c62c07d3
MN
2331
2332static void opt_thread_count(const char *arg)
2333{
2334 thread_count= atoi(arg);
2450cff2 2335#if !defined(HAVE_THREADS)
c62c07d3
MN
2336 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2337#endif
2338}
0c9bbaec 2339
01310af2 2340const OptionDef options[] = {
e26a8335 2341 { "h", 0, {(void*)show_help}, "show help" },
01310af2
FB
2342 { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2343 { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
638c9d91
FB
2344#if 0
2345 /* disabled as SDL/X11 does not support it correctly on application launch */
2346 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2347#endif
01310af2
FB
2348 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2349 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
72ea344b 2350 { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
01310af2
FB
2351 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2352 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
61890b02 2353 { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },
01310af2 2354 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
e26a8335 2355 { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
6387c3e6 2356 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
0c9bbaec 2357 { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
6fc5b059 2358 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
178fcca8 2359 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
8c3eba7c
MN
2360 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2361 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2362 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
178fcca8 2363 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
1b51e051
MN
2364 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)", "threshold" },
2365 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
400738b1 2366#ifdef CONFIG_NETWORK
416e3508 2367 { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
400738b1 2368#endif
c62c07d3
MN
2369 { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2370 { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
01310af2
FB
2371 { NULL, },
2372};
2373
2374void show_help(void)
2375{
02d504a7
FB
2376 printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
2377 "usage: ffplay [options] input_file\n"
01310af2
FB
2378 "Simple media player\n");
2379 printf("\n");
02d504a7
FB
2380 show_help_options(options, "Main options:\n",
2381 OPT_EXPERT, 0);
2382 show_help_options(options, "\nAdvanced options:\n",
2383 OPT_EXPERT, OPT_EXPERT);
01310af2
FB
2384 printf("\nWhile playing:\n"
2385 "q, ESC quit\n"
2386 "f toggle full screen\n"
2387 "p, SPC pause\n"
638c9d91
FB
2388 "a cycle audio channel\n"
2389 "v cycle video channel\n"
72ce053b 2390 "t cycle subtitle channel\n"
638c9d91 2391 "w show audio waves\n"
72ea344b
FB
2392 "left/right seek backward/forward 10 seconds\n"
2393 "down/up seek backward/forward 1 minute\n"
a11d11aa 2394 "mouse click seek to percentage in file corresponding to fraction of width\n"
01310af2
FB
2395 );
2396 exit(1);
2397}
2398
2399void parse_arg_file(const char *filename)
2400{
e8d83e1c
MN
2401 if (!strcmp(filename, "-"))
2402 filename = "pipe:";
01310af2
FB
2403 input_filename = filename;
2404}
2405
2406/* Called from the main */
2407int main(int argc, char **argv)
2408{
638c9d91 2409 int flags, w, h;
01310af2
FB
2410
2411 /* register all codecs, demux and protocols */
2412 av_register_all();
2413
3ca4b654
MN
2414 #ifdef CONFIG_OS2
2415 MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2416
2417 // Make stdout and stderr unbuffered
2418 setbuf( stdout, NULL );
2419 setbuf( stderr, NULL );
2420 #endif
2421
01310af2
FB
2422 parse_options(argc, argv, options);
2423
2424 if (!input_filename)
2425 show_help();
2426
2427 if (display_disable) {
2428 video_disable = 1;
2429 }
31319a8c
FB
2430 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2431#ifndef CONFIG_WIN32
2432 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 */
2433#endif
01310af2 2434 if (SDL_Init (flags)) {
05ab0b76 2435 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
01310af2
FB
2436 exit(1);
2437 }
2438
2439 if (!display_disable) {
01310af2
FB
2440#ifdef HAVE_X11
2441 /* save the screen resolution... SDL should allow full screen
2442 by resizing the window */
2443 {
2444 Display *dpy;
2445 dpy = XOpenDisplay(NULL);
2446 if (dpy) {
2447 fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy));
2448 fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy));
2449 XCloseDisplay(dpy);
2450 }
2451 }
2452#endif
638c9d91
FB
2453 flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
2454 if (is_full_screen && fs_screen_width) {
2455 w = fs_screen_width;
2456 h = fs_screen_height;
2457 flags |= SDL_FULLSCREEN;
2458 } else {
2459 w = screen_width;
2460 h = screen_height;
2461 flags |= SDL_RESIZABLE;
2462 }
2463 screen = SDL_SetVideoMode(w, h, 0, flags);
2464 if (!screen) {
2465 fprintf(stderr, "SDL: could not set video mode - exiting\n");
2466 exit(1);
2467 }
2468 SDL_WM_SetCaption("FFplay", "FFplay");
01310af2
FB
2469 }
2470
2471 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2472 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2473 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2474 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2475
638c9d91 2476 cur_stream = stream_open(input_filename, file_iformat);
01310af2
FB
2477
2478 event_loop();
2479
2480 /* never returns */
2481
2482 return 0;
2483}