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