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