Set AVPacket.pos in MPEG-PS demuxer.
[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;
3890dd3a 988 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
94b594c6
SH
989 if (seek_by_bytes)
990 is->seek_flags |= AVSEEK_FLAG_BYTE;
687fae2b
IW
991 is->seek_req = 1;
992 }
72ea344b
FB
993}
994
995/* pause or resume the video */
996static void stream_pause(VideoState *is)
997{
68aefbe8
MN
998 if (is->paused) {
999 is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
f5668147 1000 if(is->read_pause_return != AVERROR(ENOSYS)){
68aefbe8 1001 is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
f5668147 1002 }
68aefbe8 1003 is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
72ea344b 1004 }
68aefbe8 1005 is->paused = !is->paused;
72ea344b
FB
1006}
1007
49410784
TB
1008static double compute_frame_delay(double frame_current_pts, VideoState *is)
1009{
1010 double actual_delay, delay, sync_threshold, ref_clock, diff;
1011
1012 /* compute nominal delay */
1013 delay = frame_current_pts - is->frame_last_pts;
1014 if (delay <= 0 || delay >= 10.0) {
1015 /* if incorrect delay, use previous one */
1016 delay = is->frame_last_delay;
443658fd 1017 } else {
712de377 1018 is->frame_last_delay = delay;
443658fd 1019 }
49410784
TB
1020 is->frame_last_pts = frame_current_pts;
1021
1022 /* update delay to follow master synchronisation source */
1023 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1024 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1025 /* if video is slave, we try to correct big delays by
1026 duplicating or deleting a frame */
1027 ref_clock = get_master_clock(is);
1028 diff = frame_current_pts - ref_clock;
1029
1030 /* skip or repeat frame. We take into account the
1031 delay to compute the threshold. I still don't know
1032 if it is the best guess */
1033 sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1034 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1035 if (diff <= -sync_threshold)
1036 delay = 0;
1037 else if (diff >= sync_threshold)
1038 delay = 2 * delay;
1039 }
1040 }
1041
1042 is->frame_timer += delay;
1043 /* compute the REAL delay (we need to do that to avoid
1044 long term errors */
1045 actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1046 if (actual_delay < 0.010) {
1047 /* XXX: should skip picture */
1048 actual_delay = 0.010;
1049 }
1050
eecc17a7
TB
1051#if defined(DEBUG_SYNC)
1052 printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1053 delay, actual_delay, frame_current_pts, -diff);
1054#endif
1055
49410784
TB
1056 return actual_delay;
1057}
1058
01310af2
FB
1059/* called to display each frame */
1060static void video_refresh_timer(void *opaque)
1061{
1062 VideoState *is = opaque;
1063 VideoPicture *vp;
638c9d91 1064
72ce053b 1065 SubPicture *sp, *sp2;
01310af2
FB
1066
1067 if (is->video_st) {
1068 if (is->pictq_size == 0) {
b8bb398a 1069// fprintf(stderr, "Internal error detected in the SDL timer\n");
01310af2 1070 } else {
638c9d91 1071 /* dequeue the picture */
01310af2 1072 vp = &is->pictq[is->pictq_rindex];
638c9d91
FB
1073
1074 /* update current video pts */
1075 is->video_current_pts = vp->pts;
68aefbe8 1076 is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
638c9d91 1077
72ce053b
IC
1078 if(is->subtitle_st) {
1079 if (is->subtitle_stream_changed) {
1080 SDL_LockMutex(is->subpq_mutex);
115329f1 1081
72ce053b
IC
1082 while (is->subpq_size) {
1083 free_subpicture(&is->subpq[is->subpq_rindex]);
115329f1 1084
72ce053b
IC
1085 /* update queue size and signal for next picture */
1086 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1087 is->subpq_rindex = 0;
115329f1 1088
72ce053b
IC
1089 is->subpq_size--;
1090 }
1091 is->subtitle_stream_changed = 0;
1092
1093 SDL_CondSignal(is->subpq_cond);
1094 SDL_UnlockMutex(is->subpq_mutex);
1095 } else {
1096 if (is->subpq_size > 0) {
1097 sp = &is->subpq[is->subpq_rindex];
1098
1099 if (is->subpq_size > 1)
1100 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1101 else
1102 sp2 = NULL;
1103
1104 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1105 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1106 {
1107 free_subpicture(sp);
1108
1109 /* update queue size and signal for next picture */
1110 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1111 is->subpq_rindex = 0;
1112
1113 SDL_LockMutex(is->subpq_mutex);
1114 is->subpq_size--;
1115 SDL_CondSignal(is->subpq_cond);
1116 SDL_UnlockMutex(is->subpq_mutex);
1117 }
1118 }
1119 }
1120 }
1121
01310af2
FB
1122 /* display picture */
1123 video_display(is);
115329f1 1124
01310af2
FB
1125 /* update queue size and signal for next picture */
1126 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1127 is->pictq_rindex = 0;
115329f1 1128
01310af2 1129 SDL_LockMutex(is->pictq_mutex);
6c7d3ead 1130 vp->timer_id= 0;
01310af2
FB
1131 is->pictq_size--;
1132 SDL_CondSignal(is->pictq_cond);
1133 SDL_UnlockMutex(is->pictq_mutex);
1134 }
1135 } else if (is->audio_st) {
1136 /* draw the next audio frame */
1137
1138 schedule_refresh(is, 40);
1139
1140 /* if only audio stream, then display the audio bars (better
1141 than nothing, just to test the implementation */
115329f1 1142
01310af2
FB
1143 /* display picture */
1144 video_display(is);
1145 } else {
1146 schedule_refresh(is, 100);
1147 }
1148 if (show_status) {
1149 static int64_t last_time;
1150 int64_t cur_time;
72ce053b 1151 int aqsize, vqsize, sqsize;
638c9d91 1152 double av_diff;
115329f1 1153
01310af2 1154 cur_time = av_gettime();
1e1a0b18 1155 if (!last_time || (cur_time - last_time) >= 30000) {
01310af2
FB
1156 aqsize = 0;
1157 vqsize = 0;
72ce053b 1158 sqsize = 0;
01310af2
FB
1159 if (is->audio_st)
1160 aqsize = is->audioq.size;
1161 if (is->video_st)
1162 vqsize = is->videoq.size;
72ce053b
IC
1163 if (is->subtitle_st)
1164 sqsize = is->subtitleq.size;
638c9d91
FB
1165 av_diff = 0;
1166 if (is->audio_st && is->video_st)
1167 av_diff = get_audio_clock(is) - get_video_clock(is);
41db429d
MN
1168 printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB f=%Ld/%Ld \r",
1169 get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
01310af2
FB
1170 fflush(stdout);
1171 last_time = cur_time;
1172 }
1173 }
1174}
1175
1176/* allocate a picture (needs to do that in main thread to avoid
1177 potential locking problems */
1178static void alloc_picture(void *opaque)
1179{
1180 VideoState *is = opaque;
1181 VideoPicture *vp;
01310af2
FB
1182
1183 vp = &is->pictq[is->pictq_windex];
1184
1185 if (vp->bmp)
1186 SDL_FreeYUVOverlay(vp->bmp);
1187
01f4895c
MN
1188 vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1189 is->video_st->codec->height,
115329f1 1190 SDL_YV12_OVERLAY,
61890b02 1191 screen);
01f4895c
MN
1192 vp->width = is->video_st->codec->width;
1193 vp->height = is->video_st->codec->height;
01310af2
FB
1194
1195 SDL_LockMutex(is->pictq_mutex);
1196 vp->allocated = 1;
1197 SDL_CondSignal(is->pictq_cond);
1198 SDL_UnlockMutex(is->pictq_mutex);
1199}
1200
267e9dfa
MN
1201/**
1202 *
1203 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1204 */
638c9d91 1205static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
01310af2
FB
1206{
1207 VideoPicture *vp;
1208 int dst_pix_fmt;
115329f1 1209
01310af2
FB
1210 /* wait until we have space to put a new picture */
1211 SDL_LockMutex(is->pictq_mutex);
1212 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1213 !is->videoq.abort_request) {
1214 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1215 }
1216 SDL_UnlockMutex(is->pictq_mutex);
115329f1 1217
01310af2
FB
1218 if (is->videoq.abort_request)
1219 return -1;
1220
1221 vp = &is->pictq[is->pictq_windex];
1222
1223 /* alloc or resize hardware picture buffer */
115329f1 1224 if (!vp->bmp ||
01f4895c
MN
1225 vp->width != is->video_st->codec->width ||
1226 vp->height != is->video_st->codec->height) {
01310af2
FB
1227 SDL_Event event;
1228
1229 vp->allocated = 0;
1230
1231 /* the allocation must be done in the main thread to avoid
1232 locking problems */
1233 event.type = FF_ALLOC_EVENT;
1234 event.user.data1 = is;
1235 SDL_PushEvent(&event);
115329f1 1236
01310af2
FB
1237 /* wait until the picture is allocated */
1238 SDL_LockMutex(is->pictq_mutex);
1239 while (!vp->allocated && !is->videoq.abort_request) {
1240 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1241 }
1242 SDL_UnlockMutex(is->pictq_mutex);
1243
1244 if (is->videoq.abort_request)
1245 return -1;
1246 }
1247
638c9d91 1248 /* if the frame is not skipped, then display it */
01310af2 1249 if (vp->bmp) {
fbf1b885 1250 AVPicture pict;
1251
01310af2
FB
1252 /* get a pointer on the bitmap */
1253 SDL_LockYUVOverlay (vp->bmp);
1254
1255 dst_pix_fmt = PIX_FMT_YUV420P;
fbf1b885 1256 memset(&pict,0,sizeof(AVPicture));
01310af2
FB
1257 pict.data[0] = vp->bmp->pixels[0];
1258 pict.data[1] = vp->bmp->pixels[2];
1259 pict.data[2] = vp->bmp->pixels[1];
1260
1261 pict.linesize[0] = vp->bmp->pitches[0];
1262 pict.linesize[1] = vp->bmp->pitches[2];
1263 pict.linesize[2] = vp->bmp->pitches[1];
e43d7a18 1264 sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
3ac56e28 1265 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
feb7bc67
AB
1266 is->video_st->codec->width, is->video_st->codec->height,
1267 is->video_st->codec->pix_fmt,
1268 is->video_st->codec->width, is->video_st->codec->height,
1269 dst_pix_fmt, sws_flags, NULL, NULL, NULL);
3ac56e28 1270 if (is->img_convert_ctx == NULL) {
26ba8235
AB
1271 fprintf(stderr, "Cannot initialize the conversion context\n");
1272 exit(1);
1273 }
3ac56e28 1274 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
03ae87a3 1275 0, is->video_st->codec->height, pict.data, pict.linesize);
01310af2
FB
1276 /* update the bitmap content */
1277 SDL_UnlockYUVOverlay(vp->bmp);
1278
638c9d91 1279 vp->pts = pts;
01310af2
FB
1280
1281 /* now we can update the picture count */
1282 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1283 is->pictq_windex = 0;
1284 SDL_LockMutex(is->pictq_mutex);
1285 is->pictq_size++;
6c7d3ead
MN
1286 //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
1287 vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
01310af2
FB
1288 SDL_UnlockMutex(is->pictq_mutex);
1289 }
638c9d91
FB
1290 return 0;
1291}
1292
115329f1
DB
1293/**
1294 * compute the exact PTS for the picture if it is omitted in the stream
267e9dfa
MN
1295 * @param pts1 the dts of the pkt / pts of the frame
1296 */
638c9d91
FB
1297static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1298{
1299 double frame_delay, pts;
115329f1 1300
638c9d91
FB
1301 pts = pts1;
1302
01310af2 1303 if (pts != 0) {
638c9d91 1304 /* update video clock with pts, if present */
01310af2
FB
1305 is->video_clock = pts;
1306 } else {
72ea344b
FB
1307 pts = is->video_clock;
1308 }
1309 /* update video clock for next frame */
01f4895c 1310 frame_delay = av_q2d(is->video_st->codec->time_base);
72ea344b
FB
1311 /* for MPEG2, the frame can be repeated, so we update the
1312 clock accordingly */
267e9dfa 1313 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
72ea344b 1314 is->video_clock += frame_delay;
638c9d91
FB
1315
1316#if defined(DEBUG_SYNC) && 0
1317 {
1318 int ftype;
1319 if (src_frame->pict_type == FF_B_TYPE)
1320 ftype = 'B';
1321 else if (src_frame->pict_type == FF_I_TYPE)
1322 ftype = 'I';
1323 else
1324 ftype = 'P';
115329f1 1325 printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
72ea344b 1326 ftype, pts, pts1);
638c9d91
FB
1327 }
1328#endif
72ea344b 1329 return queue_picture(is, src_frame, pts);
01310af2
FB
1330}
1331
1332static int video_thread(void *arg)
1333{
1334 VideoState *is = arg;
1335 AVPacket pkt1, *pkt = &pkt1;
6c7d3ead 1336 int len1, got_picture, i;
c6b1edc9 1337 AVFrame *frame= avcodec_alloc_frame();
01310af2
FB
1338 double pts;
1339
1340 for(;;) {
1341 while (is->paused && !is->videoq.abort_request) {
1342 SDL_Delay(10);
1343 }
1344 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1345 break;
39c6a118
MN
1346
1347 if(pkt->data == flush_pkt.data){
1348 avcodec_flush_buffers(is->video_st->codec);
6c7d3ead
MN
1349
1350 SDL_LockMutex(is->pictq_mutex);
1351 //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1352 for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1353 if(is->pictq[i].timer_id){
1354 SDL_RemoveTimer(is->pictq[i].timer_id);
1355 is->pictq[i].timer_id=0;
1356 schedule_refresh(is, 1);
1357 }
1358 }
1359 while (is->pictq_size && !is->videoq.abort_request) {
1360 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1361 }
1362 SDL_UnlockMutex(is->pictq_mutex);
1363
41db429d
MN
1364 is->last_dts_for_fault_detection=
1365 is->last_pts_for_fault_detection= INT64_MIN;
967030eb 1366 is->frame_last_pts= AV_NOPTS_VALUE;
f7119e42 1367 is->frame_last_delay = 0;
967030eb 1368
39c6a118
MN
1369 continue;
1370 }
1371
638c9d91
FB
1372 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1373 this packet, if any */
7fb262b5 1374 is->video_st->codec->reordered_opaque= pkt->pts;
bea18375 1375 len1 = avcodec_decode_video2(is->video_st->codec,
620e8baf 1376 frame, &got_picture,
bea18375 1377 pkt);
620e8baf 1378
99e0b12b 1379 if (got_picture) {
df7d6e48
SS
1380 if(pkt->dts != AV_NOPTS_VALUE){
1381 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1382 is->last_dts_for_fault_detection= pkt->dts;
1383 }
1384 if(frame->reordered_opaque != AV_NOPTS_VALUE){
1385 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1386 is->last_pts_for_fault_detection= frame->reordered_opaque;
1387 }
99e0b12b 1388 }
41db429d
MN
1389
1390 if( ( decoder_reorder_pts==1
ecbed31c 1391 || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
41db429d 1392 || pkt->dts == AV_NOPTS_VALUE)
7fb262b5
MN
1393 && frame->reordered_opaque != AV_NOPTS_VALUE)
1394 pts= frame->reordered_opaque;
620e8baf
MN
1395 else if(pkt->dts != AV_NOPTS_VALUE)
1396 pts= pkt->dts;
1397 else
1398 pts= 0;
1399 pts *= av_q2d(is->video_st->time_base);
5039185a 1400
fb966f99
MN
1401// if (len1 < 0)
1402// break;
620e8baf
MN
1403 if (got_picture) {
1404 if (output_picture2(is, frame, pts) < 0)
1405 goto the_end;
1406 }
01310af2 1407 av_free_packet(pkt);
115329f1 1408 if (step)
bba04f1e
WH
1409 if (cur_stream)
1410 stream_pause(cur_stream);
01310af2
FB
1411 }
1412 the_end:
c6b1edc9 1413 av_free(frame);
01310af2
FB
1414 return 0;
1415}
1416
72ce053b
IC
1417static int subtitle_thread(void *arg)
1418{
1419 VideoState *is = arg;
1420 SubPicture *sp;
1421 AVPacket pkt1, *pkt = &pkt1;
1422 int len1, got_subtitle;
1423 double pts;
1424 int i, j;
1425 int r, g, b, y, u, v, a;
1426
1427 for(;;) {
1428 while (is->paused && !is->subtitleq.abort_request) {
1429 SDL_Delay(10);
1430 }
1431 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1432 break;
115329f1 1433
39c6a118
MN
1434 if(pkt->data == flush_pkt.data){
1435 avcodec_flush_buffers(is->subtitle_st->codec);
1436 continue;
1437 }
72ce053b
IC
1438 SDL_LockMutex(is->subpq_mutex);
1439 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1440 !is->subtitleq.abort_request) {
1441 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1442 }
1443 SDL_UnlockMutex(is->subpq_mutex);
115329f1 1444
72ce053b
IC
1445 if (is->subtitleq.abort_request)
1446 goto the_end;
115329f1 1447
72ce053b
IC
1448 sp = &is->subpq[is->subpq_windex];
1449
1450 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1451 this packet, if any */
1452 pts = 0;
1453 if (pkt->pts != AV_NOPTS_VALUE)
1454 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1455
bea18375 1456 len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
115329f1 1457 &sp->sub, &got_subtitle,
bea18375 1458 pkt);
72ce053b
IC
1459// if (len1 < 0)
1460// break;
1461 if (got_subtitle && sp->sub.format == 0) {
1462 sp->pts = pts;
115329f1 1463
72ce053b
IC
1464 for (i = 0; i < sp->sub.num_rects; i++)
1465 {
db4fac64 1466 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
72ce053b 1467 {
25b4c651 1468 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
72ce053b
IC
1469 y = RGB_TO_Y_CCIR(r, g, b);
1470 u = RGB_TO_U_CCIR(r, g, b, 0);
1471 v = RGB_TO_V_CCIR(r, g, b, 0);
25b4c651 1472 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
72ce053b
IC
1473 }
1474 }
1475
1476 /* now we can update the picture count */
1477 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1478 is->subpq_windex = 0;
1479 SDL_LockMutex(is->subpq_mutex);
1480 is->subpq_size++;
1481 SDL_UnlockMutex(is->subpq_mutex);
1482 }
1483 av_free_packet(pkt);
115329f1 1484// if (step)
72ce053b
IC
1485// if (cur_stream)
1486// stream_pause(cur_stream);
1487 }
1488 the_end:
1489 return 0;
1490}
1491
01310af2
FB
1492/* copy samples for viewing in editor window */
1493static void update_sample_display(VideoState *is, short *samples, int samples_size)
1494{
1495 int size, len, channels;
1496
01f4895c 1497 channels = is->audio_st->codec->channels;
01310af2
FB
1498
1499 size = samples_size / sizeof(short);
1500 while (size > 0) {
1501 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1502 if (len > size)
1503 len = size;
1504 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1505 samples += len;
1506 is->sample_array_index += len;
1507 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1508 is->sample_array_index = 0;
1509 size -= len;
1510 }
1511}
1512
01310af2
FB
1513/* return the new audio buffer size (samples can be added or deleted
1514 to get better sync if video or external master clock) */
115329f1 1515static int synchronize_audio(VideoState *is, short *samples,
638c9d91 1516 int samples_size1, double pts)
01310af2 1517{
638c9d91 1518 int n, samples_size;
01310af2 1519 double ref_clock;
115329f1 1520
01f4895c 1521 n = 2 * is->audio_st->codec->channels;
638c9d91 1522 samples_size = samples_size1;
01310af2 1523
01310af2 1524 /* if not master, then we try to remove or add samples to correct the clock */
01310af2 1525 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
638c9d91
FB
1526 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1527 double diff, avg_diff;
01310af2 1528 int wanted_size, min_size, max_size, nb_samples;
115329f1 1529
638c9d91
FB
1530 ref_clock = get_master_clock(is);
1531 diff = get_audio_clock(is) - ref_clock;
115329f1 1532
638c9d91
FB
1533 if (diff < AV_NOSYNC_THRESHOLD) {
1534 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1535 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1536 /* not enough measures to have a correct estimate */
1537 is->audio_diff_avg_count++;
1538 } else {
1539 /* estimate the A-V difference */
1540 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1541
1542 if (fabs(avg_diff) >= is->audio_diff_threshold) {
01f4895c 1543 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
638c9d91 1544 nb_samples = samples_size / n;
115329f1 1545
638c9d91
FB
1546 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1547 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1548 if (wanted_size < min_size)
1549 wanted_size = min_size;
1550 else if (wanted_size > max_size)
1551 wanted_size = max_size;
115329f1 1552
638c9d91
FB
1553 /* add or remove samples to correction the synchro */
1554 if (wanted_size < samples_size) {
1555 /* remove samples */
1556 samples_size = wanted_size;
1557 } else if (wanted_size > samples_size) {
1558 uint8_t *samples_end, *q;
1559 int nb;
115329f1 1560
638c9d91
FB
1561 /* add samples */
1562 nb = (samples_size - wanted_size);
1563 samples_end = (uint8_t *)samples + samples_size - n;
1564 q = samples_end + n;
1565 while (nb > 0) {
1566 memcpy(q, samples_end, n);
1567 q += n;
1568 nb -= n;
1569 }
1570 samples_size = wanted_size;
1571 }
1572 }
1573#if 0
115329f1
DB
1574 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1575 diff, avg_diff, samples_size - samples_size1,
638c9d91
FB
1576 is->audio_clock, is->video_clock, is->audio_diff_threshold);
1577#endif
01310af2 1578 }
638c9d91
FB
1579 } else {
1580 /* too big difference : may be initial PTS errors, so
1581 reset A-V filter */
1582 is->audio_diff_avg_count = 0;
1583 is->audio_diff_cum = 0;
01310af2
FB
1584 }
1585 }
1586
01310af2
FB
1587 return samples_size;
1588}
1589
1590/* decode one audio frame and returns its uncompressed size */
5a4476e2 1591static int audio_decode_frame(VideoState *is, double *pts_ptr)
01310af2 1592{
bea18375 1593 AVPacket *pkt_temp = &is->audio_pkt_temp;
01310af2 1594 AVPacket *pkt = &is->audio_pkt;
abdff646 1595 AVCodecContext *dec= is->audio_st->codec;
72ea344b 1596 int n, len1, data_size;
01310af2
FB
1597 double pts;
1598
1599 for(;;) {
72ea344b 1600 /* NOTE: the audio packet can contain several frames */
bea18375 1601 while (pkt_temp->size > 0) {
5a4476e2 1602 data_size = sizeof(is->audio_buf1);
bea18375 1603 len1 = avcodec_decode_audio3(dec,
5a4476e2 1604 (int16_t *)is->audio_buf1, &data_size,
bea18375 1605 pkt_temp);
72ea344b
FB
1606 if (len1 < 0) {
1607 /* if error, we skip the frame */
bea18375 1608 pkt_temp->size = 0;
01310af2 1609 break;
72ea344b 1610 }
115329f1 1611
bea18375
TB
1612 pkt_temp->data += len1;
1613 pkt_temp->size -= len1;
72ea344b
FB
1614 if (data_size <= 0)
1615 continue;
5a4476e2
PR
1616
1617 if (dec->sample_fmt != is->audio_src_fmt) {
1618 if (is->reformat_ctx)
1619 av_audio_convert_free(is->reformat_ctx);
1620 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1621 dec->sample_fmt, 1, NULL, 0);
1622 if (!is->reformat_ctx) {
1623 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1624 avcodec_get_sample_fmt_name(dec->sample_fmt),
1625 avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1626 break;
1627 }
1628 is->audio_src_fmt= dec->sample_fmt;
1629 }
1630
1631 if (is->reformat_ctx) {
1632 const void *ibuf[6]= {is->audio_buf1};
1633 void *obuf[6]= {is->audio_buf2};
1634 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1635 int ostride[6]= {2};
1636 int len= data_size/istride[0];
1637 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1638 printf("av_audio_convert() failed\n");
1639 break;
1640 }
1641 is->audio_buf= is->audio_buf2;
1642 /* FIXME: existing code assume that data_size equals framesize*channels*2
1643 remove this legacy cruft */
1644 data_size= len*2;
1645 }else{
1646 is->audio_buf= is->audio_buf1;
1647 }
1648
72ea344b
FB
1649 /* if no pts, then compute it */
1650 pts = is->audio_clock;
1651 *pts_ptr = pts;
abdff646 1652 n = 2 * dec->channels;
115329f1 1653 is->audio_clock += (double)data_size /
abdff646 1654 (double)(n * dec->sample_rate);
638c9d91 1655#if defined(DEBUG_SYNC)
72ea344b
FB
1656 {
1657 static double last_clock;
1658 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1659 is->audio_clock - last_clock,
1660 is->audio_clock, pts);
1661 last_clock = is->audio_clock;
01310af2 1662 }
72ea344b
FB
1663#endif
1664 return data_size;
01310af2
FB
1665 }
1666
72ea344b
FB
1667 /* free the current packet */
1668 if (pkt->data)
01310af2 1669 av_free_packet(pkt);
115329f1 1670
72ea344b
FB
1671 if (is->paused || is->audioq.abort_request) {
1672 return -1;
1673 }
115329f1 1674
01310af2
FB
1675 /* read next packet */
1676 if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1677 return -1;
39c6a118 1678 if(pkt->data == flush_pkt.data){
abdff646 1679 avcodec_flush_buffers(dec);
39c6a118
MN
1680 continue;
1681 }
1682
bea18375
TB
1683 pkt_temp->data = pkt->data;
1684 pkt_temp->size = pkt->size;
115329f1 1685
72ea344b
FB
1686 /* if update the audio clock with the pts */
1687 if (pkt->pts != AV_NOPTS_VALUE) {
c0df9d75 1688 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
72ea344b 1689 }
01310af2
FB
1690 }
1691}
1692
638c9d91
FB
1693/* get the current audio output buffer size, in samples. With SDL, we
1694 cannot have a precise information */
1695static int audio_write_get_buf_size(VideoState *is)
01310af2 1696{
b09b580b 1697 return is->audio_buf_size - is->audio_buf_index;
01310af2
FB
1698}
1699
1700
1701/* prepare a new audio buffer */
358061f6 1702static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
01310af2
FB
1703{
1704 VideoState *is = opaque;
1705 int audio_size, len1;
1706 double pts;
1707
1708 audio_callback_time = av_gettime();
115329f1 1709
01310af2
FB
1710 while (len > 0) {
1711 if (is->audio_buf_index >= is->audio_buf_size) {
5a4476e2 1712 audio_size = audio_decode_frame(is, &pts);
01310af2
FB
1713 if (audio_size < 0) {
1714 /* if error, just output silence */
1a1078fa 1715 is->audio_buf = is->audio_buf1;
01310af2
FB
1716 is->audio_buf_size = 1024;
1717 memset(is->audio_buf, 0, is->audio_buf_size);
1718 } else {
1719 if (is->show_audio)
1720 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
115329f1 1721 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
01310af2
FB
1722 pts);
1723 is->audio_buf_size = audio_size;
1724 }
1725 is->audio_buf_index = 0;
1726 }
1727 len1 = is->audio_buf_size - is->audio_buf_index;
1728 if (len1 > len)
1729 len1 = len;
1730 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1731 len -= len1;
1732 stream += len1;
1733 is->audio_buf_index += len1;
1734 }
1735}
1736
01310af2
FB
1737/* open a given stream. Return 0 if OK */
1738static int stream_component_open(VideoState *is, int stream_index)
1739{
1740 AVFormatContext *ic = is->ic;
1741 AVCodecContext *enc;
1742 AVCodec *codec;
1743 SDL_AudioSpec wanted_spec, spec;
1744
1745 if (stream_index < 0 || stream_index >= ic->nb_streams)
1746 return -1;
01f4895c 1747 enc = ic->streams[stream_index]->codec;
115329f1 1748
01310af2
FB
1749 /* prepare audio output */
1750 if (enc->codec_type == CODEC_TYPE_AUDIO) {
51b73087
JR
1751 if (enc->channels > 0) {
1752 enc->request_channels = FFMIN(2, enc->channels);
94eadc8b 1753 } else {
51b73087 1754 enc->request_channels = 2;
638c9d91 1755 }
01310af2
FB
1756 }
1757
1758 codec = avcodec_find_decoder(enc->codec_id);
13d1512c
MN
1759 enc->debug_mv = debug_mv;
1760 enc->debug = debug;
6387c3e6 1761 enc->workaround_bugs = workaround_bugs;
178fcca8 1762 enc->lowres = lowres;
61846e9a 1763 if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
178fcca8 1764 enc->idct_algo= idct;
6fc5b059 1765 if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
8c3eba7c
MN
1766 enc->skip_frame= skip_frame;
1767 enc->skip_idct= skip_idct;
1768 enc->skip_loop_filter= skip_loop_filter;
047599a4 1769 enc->error_recognition= error_recognition;
1b51e051 1770 enc->error_concealment= error_concealment;
40ccc754 1771 avcodec_thread_init(enc, thread_count);
e43d7a18 1772
636f1c4c 1773 set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
e43d7a18 1774
01310af2
FB
1775 if (!codec ||
1776 avcodec_open(enc, codec) < 0)
1777 return -1;
51b73087
JR
1778
1779 /* prepare audio output */
1780 if (enc->codec_type == CODEC_TYPE_AUDIO) {
1781 wanted_spec.freq = enc->sample_rate;
1782 wanted_spec.format = AUDIO_S16SYS;
1783 wanted_spec.channels = enc->channels;
1784 wanted_spec.silence = 0;
1785 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1786 wanted_spec.callback = sdl_audio_callback;
1787 wanted_spec.userdata = is;
1788 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1789 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1790 return -1;
1791 }
1792 is->audio_hw_buf_size = spec.size;
5a4476e2 1793 is->audio_src_fmt= SAMPLE_FMT_S16;
51b73087
JR
1794 }
1795
3f3fe38d 1796 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
638c9d91 1797 switch(enc->codec_type) {
01310af2
FB
1798 case CODEC_TYPE_AUDIO:
1799 is->audio_stream = stream_index;
1800 is->audio_st = ic->streams[stream_index];
1801 is->audio_buf_size = 0;
1802 is->audio_buf_index = 0;
638c9d91
FB
1803
1804 /* init averaging filter */
1805 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1806 is->audio_diff_avg_count = 0;
1807 /* since we do not have a precise anough audio fifo fullness,
1808 we correct audio sync only if larger than this threshold */
1809 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1810
01310af2
FB
1811 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1812 packet_queue_init(&is->audioq);
bb270c08 1813 SDL_PauseAudio(0);
01310af2
FB
1814 break;
1815 case CODEC_TYPE_VIDEO:
1816 is->video_stream = stream_index;
1817 is->video_st = ic->streams[stream_index];
1818
638c9d91 1819 is->frame_timer = (double)av_gettime() / 1000000.0;
68aefbe8 1820// is->video_current_pts_time = av_gettime();
638c9d91 1821
01310af2
FB
1822 packet_queue_init(&is->videoq);
1823 is->video_tid = SDL_CreateThread(video_thread, is);
1824 break;
72ce053b
IC
1825 case CODEC_TYPE_SUBTITLE:
1826 is->subtitle_stream = stream_index;
1827 is->subtitle_st = ic->streams[stream_index];
1828 packet_queue_init(&is->subtitleq);
115329f1 1829
72ce053b
IC
1830 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1831 break;
01310af2
FB
1832 default:
1833 break;
1834 }
1835 return 0;
1836}
1837
1838static void stream_component_close(VideoState *is, int stream_index)
1839{
1840 AVFormatContext *ic = is->ic;
1841 AVCodecContext *enc;
115329f1 1842
72ce053b
IC
1843 if (stream_index < 0 || stream_index >= ic->nb_streams)
1844 return;
01f4895c 1845 enc = ic->streams[stream_index]->codec;
01310af2
FB
1846
1847 switch(enc->codec_type) {
1848 case CODEC_TYPE_AUDIO:
1849 packet_queue_abort(&is->audioq);
1850
1851 SDL_CloseAudio();
1852
1853 packet_queue_end(&is->audioq);
5a4476e2
PR
1854 if (is->reformat_ctx)
1855 av_audio_convert_free(is->reformat_ctx);
01310af2
FB
1856 break;
1857 case CODEC_TYPE_VIDEO:
1858 packet_queue_abort(&is->videoq);
1859
1860 /* note: we also signal this mutex to make sure we deblock the
1861 video thread in all cases */
1862 SDL_LockMutex(is->pictq_mutex);
1863 SDL_CondSignal(is->pictq_cond);
1864 SDL_UnlockMutex(is->pictq_mutex);
1865
1866 SDL_WaitThread(is->video_tid, NULL);
1867
1868 packet_queue_end(&is->videoq);
1869 break;
72ce053b
IC
1870 case CODEC_TYPE_SUBTITLE:
1871 packet_queue_abort(&is->subtitleq);
115329f1 1872
72ce053b
IC
1873 /* note: we also signal this mutex to make sure we deblock the
1874 video thread in all cases */
1875 SDL_LockMutex(is->subpq_mutex);
1876 is->subtitle_stream_changed = 1;
115329f1 1877
72ce053b
IC
1878 SDL_CondSignal(is->subpq_cond);
1879 SDL_UnlockMutex(is->subpq_mutex);
1880
1881 SDL_WaitThread(is->subtitle_tid, NULL);
1882
1883 packet_queue_end(&is->subtitleq);
1884 break;
01310af2
FB
1885 default:
1886 break;
1887 }
1888
3f3fe38d 1889 ic->streams[stream_index]->discard = AVDISCARD_ALL;
01310af2
FB
1890 avcodec_close(enc);
1891 switch(enc->codec_type) {
1892 case CODEC_TYPE_AUDIO:
1893 is->audio_st = NULL;
1894 is->audio_stream = -1;
1895 break;
1896 case CODEC_TYPE_VIDEO:
1897 is->video_st = NULL;
1898 is->video_stream = -1;
1899 break;
72ce053b
IC
1900 case CODEC_TYPE_SUBTITLE:
1901 is->subtitle_st = NULL;
1902 is->subtitle_stream = -1;
1903 break;
01310af2
FB
1904 default:
1905 break;
1906 }
1907}
1908
416e3508
FB
1909/* since we have only one decoding thread, we can use a global
1910 variable instead of a thread local variable */
1911static VideoState *global_video_state;
1912
1913static int decode_interrupt_cb(void)
1914{
1915 return (global_video_state && global_video_state->abort_request);
1916}
01310af2
FB
1917
1918/* this thread gets the stream from the disk or the network */
1919static int decode_thread(void *arg)
1920{
1921 VideoState *is = arg;
1922 AVFormatContext *ic;
16a59a7b 1923 int err, i, ret, video_index, audio_index, subtitle_index;
01310af2 1924 AVPacket pkt1, *pkt = &pkt1;
61890b02 1925 AVFormatParameters params, *ap = &params;
75bb7b0a 1926 int eof=0;
01310af2 1927
6299a229
MN
1928 ic = avformat_alloc_context();
1929
01310af2
FB
1930 video_index = -1;
1931 audio_index = -1;
16a59a7b 1932 subtitle_index = -1;
01310af2
FB
1933 is->video_stream = -1;
1934 is->audio_stream = -1;
72ce053b 1935 is->subtitle_stream = -1;
01310af2 1936
416e3508
FB
1937 global_video_state = is;
1938 url_set_interrupt_cb(decode_interrupt_cb);
1939
61890b02 1940 memset(ap, 0, sizeof(*ap));
115329f1 1941
6299a229 1942 ap->prealloced_context = 1;
e4b89522
LW
1943 ap->width = frame_width;
1944 ap->height= frame_height;
7e042912 1945 ap->time_base= (AVRational){1, 25};
e4b89522 1946 ap->pix_fmt = frame_pix_fmt;
7e042912 1947
6299a229
MN
1948 set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1949
61890b02 1950 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
638c9d91
FB
1951 if (err < 0) {
1952 print_error(is->filename, err);
1953 ret = -1;
1954 goto fail;
1955 }
01310af2 1956 is->ic = ic;
30bc6613
MN
1957
1958 if(genpts)
1959 ic->flags |= AVFMT_FLAG_GENPTS;
1960
24c07998
LA
1961 err = av_find_stream_info(ic);
1962 if (err < 0) {
1963 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1964 ret = -1;
1965 goto fail;
1966 }
899681cd
BA
1967 if(ic->pb)
1968 ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
72ea344b
FB
1969
1970 /* if seeking requested, we execute it */
1971 if (start_time != AV_NOPTS_VALUE) {
1972 int64_t timestamp;
1973
1974 timestamp = start_time;
1975 /* add the stream start time */
1976 if (ic->start_time != AV_NOPTS_VALUE)
1977 timestamp += ic->start_time;
4ed29207 1978 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
72ea344b 1979 if (ret < 0) {
115329f1 1980 fprintf(stderr, "%s: could not seek to position %0.3f\n",
72ea344b
FB
1981 is->filename, (double)timestamp / AV_TIME_BASE);
1982 }
1983 }
72ea344b 1984
01310af2 1985 for(i = 0; i < ic->nb_streams; i++) {
01f4895c 1986 AVCodecContext *enc = ic->streams[i]->codec;
3f3fe38d 1987 ic->streams[i]->discard = AVDISCARD_ALL;
01310af2
FB
1988 switch(enc->codec_type) {
1989 case CODEC_TYPE_AUDIO:
5dbb63fe 1990 if (wanted_audio_stream-- >= 0 && !audio_disable)
01310af2
FB
1991 audio_index = i;
1992 break;
1993 case CODEC_TYPE_VIDEO:
5dbb63fe 1994 if (wanted_video_stream-- >= 0 && !video_disable)
01310af2
FB
1995 video_index = i;
1996 break;
16a59a7b 1997 case CODEC_TYPE_SUBTITLE:
5ad4f0d4 1998 if (wanted_subtitle_stream-- >= 0 && !video_disable)
16a59a7b
BA
1999 subtitle_index = i;
2000 break;
01310af2
FB
2001 default:
2002 break;
2003 }
2004 }
2005 if (show_status) {
2006 dump_format(ic, 0, is->filename, 0);
2007 }
2008
2009 /* open the streams */
2010 if (audio_index >= 0) {
2011 stream_component_open(is, audio_index);
2012 }
2013
2014 if (video_index >= 0) {
2015 stream_component_open(is, video_index);
2016 } else {
2017 if (!display_disable)
2018 is->show_audio = 1;
2019 }
2020
16a59a7b
BA
2021 if (subtitle_index >= 0) {
2022 stream_component_open(is, subtitle_index);
2023 }
2024
01310af2 2025 if (is->video_stream < 0 && is->audio_stream < 0) {
638c9d91
FB
2026 fprintf(stderr, "%s: could not open codecs\n", is->filename);
2027 ret = -1;
01310af2
FB
2028 goto fail;
2029 }
2030
2031 for(;;) {
2032 if (is->abort_request)
2033 break;
416e3508
FB
2034 if (is->paused != is->last_paused) {
2035 is->last_paused = is->paused;
72ea344b 2036 if (is->paused)
f5668147 2037 is->read_pause_return= av_read_pause(ic);
72ea344b
FB
2038 else
2039 av_read_play(ic);
416e3508 2040 }
2f642393
AJ
2041#if CONFIG_RTSP_DEMUXER
2042 if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
416e3508
FB
2043 /* wait 10 ms to avoid trying to get another packet */
2044 /* XXX: horrible */
2045 SDL_Delay(10);
2046 continue;
2047 }
400738b1 2048#endif
72ea344b 2049 if (is->seek_req) {
8e606cc8 2050 int64_t seek_target= is->seek_pos;
4ed29207
MN
2051 int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2052 int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2053//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2054// of the seek_pos/seek_rel variables
8e606cc8 2055
4ed29207 2056 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
72ea344b
FB
2057 if (ret < 0) {
2058 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
e6c0297f
MN
2059 }else{
2060 if (is->audio_stream >= 0) {
2061 packet_queue_flush(&is->audioq);
39c6a118 2062 packet_queue_put(&is->audioq, &flush_pkt);
e6c0297f 2063 }
72ce053b
IC
2064 if (is->subtitle_stream >= 0) {
2065 packet_queue_flush(&is->subtitleq);
39c6a118 2066 packet_queue_put(&is->subtitleq, &flush_pkt);
72ce053b 2067 }
e6c0297f
MN
2068 if (is->video_stream >= 0) {
2069 packet_queue_flush(&is->videoq);
39c6a118 2070 packet_queue_put(&is->videoq, &flush_pkt);
e6c0297f 2071 }
72ea344b
FB
2072 }
2073 is->seek_req = 0;
e45aeb38 2074 eof= 0;
72ea344b 2075 }
416e3508 2076
01310af2 2077 /* if the queue are full, no need to read more */
79ee4683
MN
2078 if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2079 || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2080 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0)
2081 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
01310af2
FB
2082 /* wait 10 ms */
2083 SDL_Delay(10);
2084 continue;
2085 }
75bb7b0a 2086 if(url_feof(ic->pb) || eof) {
9dc41767 2087 if(is->video_stream >= 0){
26534fe8
MN
2088 av_init_packet(pkt);
2089 pkt->data=NULL;
2090 pkt->size=0;
2091 pkt->stream_index= is->video_stream;
2092 packet_queue_put(&is->videoq, pkt);
9dc41767 2093 }
b4083171 2094 SDL_Delay(10);
600a331c
MN
2095 continue;
2096 }
72ea344b 2097 ret = av_read_frame(ic, pkt);
01310af2 2098 if (ret < 0) {
75bb7b0a
MN
2099 if (ret == AVERROR_EOF)
2100 eof=1;
2101 if (url_ferror(ic->pb))
bb270c08 2102 break;
75bb7b0a
MN
2103 SDL_Delay(100); /* wait for user event */
2104 continue;
01310af2
FB
2105 }
2106 if (pkt->stream_index == is->audio_stream) {
2107 packet_queue_put(&is->audioq, pkt);
2108 } else if (pkt->stream_index == is->video_stream) {
2109 packet_queue_put(&is->videoq, pkt);
72ce053b
IC
2110 } else if (pkt->stream_index == is->subtitle_stream) {
2111 packet_queue_put(&is->subtitleq, pkt);
01310af2
FB
2112 } else {
2113 av_free_packet(pkt);
2114 }
2115 }
2116 /* wait until the end */
2117 while (!is->abort_request) {
2118 SDL_Delay(100);
2119 }
2120
638c9d91 2121 ret = 0;
01310af2 2122 fail:
416e3508
FB
2123 /* disable interrupting */
2124 global_video_state = NULL;
2125
01310af2
FB
2126 /* close each stream */
2127 if (is->audio_stream >= 0)
2128 stream_component_close(is, is->audio_stream);
2129 if (is->video_stream >= 0)
2130 stream_component_close(is, is->video_stream);
72ce053b
IC
2131 if (is->subtitle_stream >= 0)
2132 stream_component_close(is, is->subtitle_stream);
638c9d91
FB
2133 if (is->ic) {
2134 av_close_input_file(is->ic);
2135 is->ic = NULL; /* safety */
2136 }
416e3508
FB
2137 url_set_interrupt_cb(NULL);
2138
638c9d91
FB
2139 if (ret != 0) {
2140 SDL_Event event;
115329f1 2141
638c9d91
FB
2142 event.type = FF_QUIT_EVENT;
2143 event.user.data1 = is;
2144 SDL_PushEvent(&event);
2145 }
01310af2
FB
2146 return 0;
2147}
2148
638c9d91 2149static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
01310af2
FB
2150{
2151 VideoState *is;
2152
2153 is = av_mallocz(sizeof(VideoState));
2154 if (!is)
2155 return NULL;
f7d78f36 2156 av_strlcpy(is->filename, filename, sizeof(is->filename));
638c9d91 2157 is->iformat = iformat;
01310af2
FB
2158 is->ytop = 0;
2159 is->xleft = 0;
2160
2161 /* start video display */
2162 is->pictq_mutex = SDL_CreateMutex();
2163 is->pictq_cond = SDL_CreateCond();
115329f1 2164
72ce053b
IC
2165 is->subpq_mutex = SDL_CreateMutex();
2166 is->subpq_cond = SDL_CreateCond();
115329f1 2167
01310af2
FB
2168 /* add the refresh timer to draw the picture */
2169 schedule_refresh(is, 40);
2170
638c9d91 2171 is->av_sync_type = av_sync_type;
01310af2
FB
2172 is->parse_tid = SDL_CreateThread(decode_thread, is);
2173 if (!is->parse_tid) {
2174 av_free(is);
2175 return NULL;
2176 }
2177 return is;
2178}
2179
2180static void stream_close(VideoState *is)
2181{
2182 VideoPicture *vp;
2183 int i;
2184 /* XXX: use a special url_shutdown call to abort parse cleanly */
2185 is->abort_request = 1;
2186 SDL_WaitThread(is->parse_tid, NULL);
2187
2188 /* free all pictures */
2189 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2190 vp = &is->pictq[i];
2191 if (vp->bmp) {
2192 SDL_FreeYUVOverlay(vp->bmp);
2193 vp->bmp = NULL;
2194 }
2195 }
2196 SDL_DestroyMutex(is->pictq_mutex);
2197 SDL_DestroyCond(is->pictq_cond);
72ce053b
IC
2198 SDL_DestroyMutex(is->subpq_mutex);
2199 SDL_DestroyCond(is->subpq_cond);
3ac56e28
MS
2200 if (is->img_convert_ctx)
2201 sws_freeContext(is->img_convert_ctx);
7c5ab145 2202 av_free(is);
01310af2
FB
2203}
2204
7b49ce2e 2205static void stream_cycle_channel(VideoState *is, int codec_type)
638c9d91
FB
2206{
2207 AVFormatContext *ic = is->ic;
2208 int start_index, stream_index;
2209 AVStream *st;
2210
2211 if (codec_type == CODEC_TYPE_VIDEO)
2212 start_index = is->video_stream;
72ce053b 2213 else if (codec_type == CODEC_TYPE_AUDIO)
638c9d91 2214 start_index = is->audio_stream;
72ce053b
IC
2215 else
2216 start_index = is->subtitle_stream;
2217 if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
638c9d91
FB
2218 return;
2219 stream_index = start_index;
2220 for(;;) {
2221 if (++stream_index >= is->ic->nb_streams)
72ce053b
IC
2222 {
2223 if (codec_type == CODEC_TYPE_SUBTITLE)
2224 {
2225 stream_index = -1;
2226 goto the_end;
2227 } else
2228 stream_index = 0;
2229 }
638c9d91
FB
2230 if (stream_index == start_index)
2231 return;
2232 st = ic->streams[stream_index];
01f4895c 2233 if (st->codec->codec_type == codec_type) {
638c9d91
FB
2234 /* check that parameters are OK */
2235 switch(codec_type) {
2236 case CODEC_TYPE_AUDIO:
01f4895c
MN
2237 if (st->codec->sample_rate != 0 &&
2238 st->codec->channels != 0)
638c9d91
FB
2239 goto the_end;
2240 break;
2241 case CODEC_TYPE_VIDEO:
72ce053b 2242 case CODEC_TYPE_SUBTITLE:
638c9d91
FB
2243 goto the_end;
2244 default:
2245 break;
2246 }
2247 }
2248 }
2249 the_end:
2250 stream_component_close(is, start_index);
2251 stream_component_open(is, stream_index);
2252}
2253
2254
7b49ce2e 2255static void toggle_full_screen(void)
01310af2 2256{
01310af2 2257 is_full_screen = !is_full_screen;
29f3b38a
MR
2258 if (!fs_screen_width) {
2259 /* use default SDL method */
fb84155b 2260// SDL_WM_ToggleFullScreen(screen);
01310af2 2261 }
fb84155b 2262 video_open(cur_stream);
01310af2
FB
2263}
2264
7b49ce2e 2265static void toggle_pause(void)
01310af2
FB
2266{
2267 if (cur_stream)
2268 stream_pause(cur_stream);
bba04f1e
WH
2269 step = 0;
2270}
2271
7b49ce2e 2272static void step_to_next_frame(void)
bba04f1e
WH
2273{
2274 if (cur_stream) {
19cc524a 2275 /* if the stream is paused unpause it, then step */
bba04f1e 2276 if (cur_stream->paused)
19cc524a 2277 stream_pause(cur_stream);
bba04f1e
WH
2278 }
2279 step = 1;
01310af2
FB
2280}
2281
7b49ce2e 2282static void do_exit(void)
01310af2 2283{
7c5ab145 2284 int i;
01310af2
FB
2285 if (cur_stream) {
2286 stream_close(cur_stream);
2287 cur_stream = NULL;
2288 }
7c5ab145
MS
2289 for (i = 0; i < CODEC_TYPE_NB; i++)
2290 av_free(avcodec_opts[i]);
2291 av_free(avformat_opts);
2292 av_free(sws_opts);
01310af2
FB
2293 if (show_status)
2294 printf("\n");
2295 SDL_Quit();
2296 exit(0);
2297}
2298
7b49ce2e 2299static void toggle_audio_display(void)
01310af2
FB
2300{
2301 if (cur_stream) {
2302 cur_stream->show_audio = !cur_stream->show_audio;
2303 }
2304}
2305
2306/* handle an event sent by the GUI */
7b49ce2e 2307static void event_loop(void)
01310af2
FB
2308{
2309 SDL_Event event;
a11d11aa 2310 double incr, pos, frac;
01310af2
FB
2311
2312 for(;;) {
2313 SDL_WaitEvent(&event);
2314 switch(event.type) {
2315 case SDL_KEYDOWN:
2316 switch(event.key.keysym.sym) {
2317 case SDLK_ESCAPE:
2318 case SDLK_q:
2319 do_exit();
2320 break;
2321 case SDLK_f:
2322 toggle_full_screen();
2323 break;
2324 case SDLK_p:
2325 case SDLK_SPACE:
2326 toggle_pause();
2327 break;
bba04f1e
WH
2328 case SDLK_s: //S: Step to next frame
2329 step_to_next_frame();
2330 break;
01310af2 2331 case SDLK_a:
115329f1 2332 if (cur_stream)
638c9d91
FB
2333 stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2334 break;
2335 case SDLK_v:
115329f1 2336 if (cur_stream)
638c9d91
FB
2337 stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2338 break;
72ce053b 2339 case SDLK_t:
115329f1 2340 if (cur_stream)
72ce053b
IC
2341 stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2342 break;
638c9d91 2343 case SDLK_w:
01310af2
FB
2344 toggle_audio_display();
2345 break;
72ea344b
FB
2346 case SDLK_LEFT:
2347 incr = -10.0;
2348 goto do_seek;
2349 case SDLK_RIGHT:
2350 incr = 10.0;
2351 goto do_seek;
2352 case SDLK_UP:
2353 incr = 60.0;
2354 goto do_seek;
2355 case SDLK_DOWN:
2356 incr = -60.0;
2357 do_seek:
2358 if (cur_stream) {
94b594c6 2359 if (seek_by_bytes) {
899681cd 2360 pos = url_ftell(cur_stream->ic->pb);
94b594c6
SH
2361 if (cur_stream->ic->bit_rate)
2362 incr *= cur_stream->ic->bit_rate / 60.0;
2363 else
2364 incr *= 180000.0;
2365 pos += incr;
2ef46053 2366 stream_seek(cur_stream, pos, incr, 1);
94b594c6
SH
2367 } else {
2368 pos = get_master_clock(cur_stream);
2369 pos += incr;
2ef46053 2370 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
94b594c6 2371 }
72ea344b
FB
2372 }
2373 break;
01310af2
FB
2374 default:
2375 break;
2376 }
2377 break;
a11d11aa 2378 case SDL_MOUSEBUTTONDOWN:
bb270c08 2379 if (cur_stream) {
2ef46053
MN
2380 if(seek_by_bytes || cur_stream->ic->duration<=0){
2381 uint64_t size= url_fsize(cur_stream->ic->pb);
2382 stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2383 }else{
6371c81a
MN
2384 int64_t ts;
2385 int ns, hh, mm, ss;
2386 int tns, thh, tmm, tss;
2387 tns = cur_stream->ic->duration/1000000LL;
2388 thh = tns/3600;
2389 tmm = (tns%3600)/60;
2390 tss = (tns%60);
2391 frac = (double)event.button.x/(double)cur_stream->width;
2392 ns = frac*tns;
2393 hh = ns/3600;
2394 mm = (ns%3600)/60;
2395 ss = (ns%60);
2396 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2397 hh, mm, ss, thh, tmm, tss);
2398 ts = frac*cur_stream->ic->duration;
2399 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2400 ts += cur_stream->ic->start_time;
2401 stream_seek(cur_stream, ts, 0, 0);
2ef46053 2402 }
bb270c08
DB
2403 }
2404 break;
01310af2
FB
2405 case SDL_VIDEORESIZE:
2406 if (cur_stream) {
115329f1 2407 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
01310af2 2408 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
c57d3469
MN
2409 screen_width = cur_stream->width = event.resize.w;
2410 screen_height= cur_stream->height= event.resize.h;
01310af2
FB
2411 }
2412 break;
2413 case SDL_QUIT:
638c9d91 2414 case FF_QUIT_EVENT:
01310af2
FB
2415 do_exit();
2416 break;
2417 case FF_ALLOC_EVENT:
fccb19e3 2418 video_open(event.user.data1);
01310af2
FB
2419 alloc_picture(event.user.data1);
2420 break;
2421 case FF_REFRESH_EVENT:
2422 video_refresh_timer(event.user.data1);
2423 break;
2424 default:
2425 break;
2426 }
2427 }
2428}
2429
e4b89522
LW
2430static void opt_frame_size(const char *arg)
2431{
b33ece16 2432 if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
e4b89522
LW
2433 fprintf(stderr, "Incorrect frame size\n");
2434 exit(1);
2435 }
2436 if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2437 fprintf(stderr, "Frame size must be a multiple of 2\n");
2438 exit(1);
2439 }
2440}
2441
a5b3b5f6 2442static int opt_width(const char *opt, const char *arg)
01310af2 2443{
a5b3b5f6
SS
2444 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2445 return 0;
01310af2
FB
2446}
2447
a5b3b5f6 2448static int opt_height(const char *opt, const char *arg)
01310af2 2449{
a5b3b5f6
SS
2450 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2451 return 0;
01310af2
FB
2452}
2453
2454static void opt_format(const char *arg)
2455{
2456 file_iformat = av_find_input_format(arg);
2457 if (!file_iformat) {
2458 fprintf(stderr, "Unknown input format: %s\n", arg);
2459 exit(1);
2460 }
2461}
61890b02 2462
e4b89522
LW
2463static void opt_frame_pix_fmt(const char *arg)
2464{
718c7b18 2465 frame_pix_fmt = av_get_pix_fmt(arg);
e4b89522
LW
2466}
2467
b81d6235 2468static int opt_sync(const char *opt, const char *arg)
638c9d91
FB
2469{
2470 if (!strcmp(arg, "audio"))
2471 av_sync_type = AV_SYNC_AUDIO_MASTER;
2472 else if (!strcmp(arg, "video"))
2473 av_sync_type = AV_SYNC_VIDEO_MASTER;
2474 else if (!strcmp(arg, "ext"))
2475 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
aab1b7e5 2476 else {
b81d6235 2477 fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
aab1b7e5
SS
2478 exit(1);
2479 }
b81d6235 2480 return 0;
638c9d91
FB
2481}
2482
e11bc2c6 2483static int opt_seek(const char *opt, const char *arg)
72ea344b 2484{
e11bc2c6
SS
2485 start_time = parse_time_or_die(opt, arg, 1);
2486 return 0;
72ea344b
FB
2487}
2488
a5b3b5f6 2489static int opt_debug(const char *opt, const char *arg)
e26a8335 2490{
a309073b 2491 av_log_set_level(99);
a5b3b5f6
SS
2492 debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2493 return 0;
e26a8335 2494}
115329f1 2495
a5b3b5f6 2496static int opt_vismv(const char *opt, const char *arg)
0c9bbaec 2497{
a5b3b5f6
SS
2498 debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2499 return 0;
0c9bbaec 2500}
c62c07d3 2501
a5b3b5f6 2502static int opt_thread_count(const char *opt, const char *arg)
c62c07d3 2503{
a5b3b5f6 2504 thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
b250f9c6 2505#if !HAVE_THREADS
c62c07d3
MN
2506 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2507#endif
a5b3b5f6 2508 return 0;
c62c07d3 2509}
115329f1 2510
358061f6 2511static const OptionDef options[] = {
992f8eae 2512#include "cmdutils_common_opts.h"
a5b3b5f6
SS
2513 { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2514 { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
e4b89522 2515 { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
638c9d91 2516 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
01310af2
FB
2517 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2518 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
4b037567
SS
2519 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2520 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2521 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
e11bc2c6 2522 { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
94b594c6 2523 { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
01310af2
FB
2524 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2525 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
e4b89522 2526 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
98ae6acf 2527 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
a5b3b5f6 2528 { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
6387c3e6 2529 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
a5b3b5f6 2530 { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
6fc5b059 2531 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
30bc6613 2532 { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
59055363 2533 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
178fcca8 2534 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
8c3eba7c
MN
2535 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2536 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2537 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
178fcca8 2538 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
047599a4 2539 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" },
1b51e051 2540 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
b81d6235 2541 { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
a5b3b5f6 2542 { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
e43d7a18 2543 { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
01310af2
FB
2544 { NULL, },
2545};
2546
0c2a18cb 2547static void show_usage(void)
01310af2 2548{
27daa420
RP
2549 printf("Simple media player\n");
2550 printf("usage: ffplay [options] input_file\n");
01310af2 2551 printf("\n");
0c2a18cb
RP
2552}
2553
2554static void show_help(void)
2555{
2556 show_usage();
02d504a7
FB
2557 show_help_options(options, "Main options:\n",
2558 OPT_EXPERT, 0);
2559 show_help_options(options, "\nAdvanced options:\n",
2560 OPT_EXPERT, OPT_EXPERT);
01310af2
FB
2561 printf("\nWhile playing:\n"
2562 "q, ESC quit\n"
2563 "f toggle full screen\n"
2564 "p, SPC pause\n"
638c9d91
FB
2565 "a cycle audio channel\n"
2566 "v cycle video channel\n"
72ce053b 2567 "t cycle subtitle channel\n"
638c9d91 2568 "w show audio waves\n"
72ea344b
FB
2569 "left/right seek backward/forward 10 seconds\n"
2570 "down/up seek backward/forward 1 minute\n"
a11d11aa 2571 "mouse click seek to percentage in file corresponding to fraction of width\n"
01310af2 2572 );
01310af2
FB
2573}
2574
358061f6 2575static void opt_input_file(const char *filename)
01310af2 2576{
e8d83e1c 2577 if (!strcmp(filename, "-"))
9fcfc0b7 2578 filename = "pipe:";
01310af2
FB
2579 input_filename = filename;
2580}
2581
2582/* Called from the main */
2583int main(int argc, char **argv)
2584{
e43d7a18 2585 int flags, i;
115329f1 2586
01310af2 2587 /* register all codecs, demux and protocols */
c721d803
LA
2588 avcodec_register_all();
2589 avdevice_register_all();
01310af2
FB
2590 av_register_all();
2591
e43d7a18 2592 for(i=0; i<CODEC_TYPE_NB; i++){
636f1c4c 2593 avcodec_opts[i]= avcodec_alloc_context2(i);
e43d7a18 2594 }
8e2fd8e1 2595 avformat_opts = avformat_alloc_context();
e43d7a18
MN
2596 sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2597
ea9c581f 2598 show_banner();
4cfac5bc 2599
f5da5c93 2600 parse_options(argc, argv, options, opt_input_file);
01310af2 2601
aab1b7e5 2602 if (!input_filename) {
7f11e745 2603 show_usage();
7a7da6b4 2604 fprintf(stderr, "An input file must be specified\n");
7f11e745 2605 fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
aab1b7e5
SS
2606 exit(1);
2607 }
01310af2
FB
2608
2609 if (display_disable) {
2610 video_disable = 1;
2611 }
31319a8c 2612 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
c97f5402
DB
2613#if !defined(__MINGW32__) && !defined(__APPLE__)
2614 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
31319a8c 2615#endif
01310af2 2616 if (SDL_Init (flags)) {
05ab0b76 2617 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
01310af2
FB
2618 exit(1);
2619 }
2620
2621 if (!display_disable) {
b250f9c6 2622#if HAVE_SDL_VIDEO_SIZE
3ef17d62
MR
2623 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2624 fs_screen_width = vi->current_w;
2625 fs_screen_height = vi->current_h;
29f3b38a 2626#endif
01310af2
FB
2627 }
2628
2629 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2630 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2631 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2632 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2633
39c6a118
MN
2634 av_init_packet(&flush_pkt);
2635 flush_pkt.data= "FLUSH";
2636
638c9d91 2637 cur_stream = stream_open(input_filename, file_iformat);
01310af2
FB
2638
2639 event_loop();
2640
2641 /* never returns */
2642
2643 return 0;
2644}