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