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