Fix a bunch of platform name and other typos.
[libav.git] / avplay.c
CommitLineData
01310af2 1/*
266463da 2 * avplay : Simple Media Player based on the Libav libraries
01310af2
FB
3 * Copyright (c) 2003 Fabrice Bellard
4 *
2912e87a 5 * This file is part of Libav.
b78e7197 6 *
2912e87a 7 * Libav 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 *
2912e87a 12 * Libav 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
2912e87a 18 * License along with Libav; 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"
8a3ceaf4 23#include <inttypes.h>
0f4e8165
RB
24#include <math.h>
25#include <limits.h>
245976da 26#include "libavutil/avstring.h"
2b4abbd6 27#include "libavutil/colorspace.h"
0ebcdf5c 28#include "libavutil/mathematics.h"
718c7b18 29#include "libavutil/pixdesc.h"
737eb597 30#include "libavutil/imgutils.h"
d0e142bb 31#include "libavutil/dict.h"
737eb597
RT
32#include "libavutil/parseutils.h"
33#include "libavutil/samplefmt.h"
245976da 34#include "libavformat/avformat.h"
245976da
DB
35#include "libavdevice/avdevice.h"
36#include "libswscale/swscale.h"
5a4476e2 37#include "libavcodec/audioconvert.h"
41d0eb1c 38#include "libavutil/opt.h"
166621ab 39#include "libavcodec/avfft.h"
01310af2 40
917d2bb3
MN
41#if CONFIG_AVFILTER
42# include "libavfilter/avfilter.h"
43# include "libavfilter/avfiltergraph.h"
917d2bb3
MN
44#endif
45
01310af2
FB
46#include "cmdutils.h"
47
48#include <SDL.h>
49#include <SDL_thread.h>
50
2f30a81d 51#ifdef __MINGW32__
31319a8c
FB
52#undef main /* We don't want SDL to override our main() */
53#endif
54
d38c9e7a
MN
55#include <unistd.h>
56#include <assert.h>
57
266463da 58const char program_name[] = "avplay";
ea9c581f 59const int program_birth_year = 2003;
4cfac5bc 60
79ee4683
MN
61#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
62#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
63#define MIN_FRAMES 5
01310af2 64
638c9d91
FB
65/* SDL audio buffer size, in samples. Should be small to have precise
66 A/V sync as SDL does not have hardware buffer fullness info. */
67#define SDL_AUDIO_BUFFER_SIZE 1024
68
69/* no AV sync correction is done if below the AV sync threshold */
7e0140cb 70#define AV_SYNC_THRESHOLD 0.01
638c9d91
FB
71/* no AV correction is done if too big error */
72#define AV_NOSYNC_THRESHOLD 10.0
73
d38c9e7a
MN
74#define FRAME_SKIP_FACTOR 0.05
75
638c9d91
FB
76/* maximum audio speed change to get correct sync */
77#define SAMPLE_CORRECTION_PERCENT_MAX 10
78
79/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
80#define AUDIO_DIFF_AVG_NB 20
81
01310af2 82/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
da7c65f0 83#define SAMPLE_ARRAY_SIZE (2 * 65536)
01310af2 84
03ae87a3
LA
85static int sws_flags = SWS_BICUBIC;
86
01310af2
FB
87typedef struct PacketQueue {
88 AVPacketList *first_pkt, *last_pkt;
89 int nb_packets;
90 int size;
91 int abort_request;
92 SDL_mutex *mutex;
93 SDL_cond *cond;
94} PacketQueue;
95
562f382c 96#define VIDEO_PICTURE_QUEUE_SIZE 2
72ce053b 97#define SUBPICTURE_QUEUE_SIZE 4
01310af2
FB
98
99typedef struct VideoPicture {
da7c65f0
AD
100 double pts; ///< presentation time stamp for this picture
101 double target_clock; ///< av_gettime() time at which this should be displayed ideally
102 int64_t pos; ///< byte position in file
01310af2
FB
103 SDL_Overlay *bmp;
104 int width, height; /* source height & width */
105 int allocated;
fec5777e 106 int reallocate;
917d2bb3
MN
107 enum PixelFormat pix_fmt;
108
109#if CONFIG_AVFILTER
ecc8dada 110 AVFilterBufferRef *picref;
917d2bb3 111#endif
01310af2
FB
112} VideoPicture;
113
72ce053b
IC
114typedef struct SubPicture {
115 double pts; /* presentation time stamp for this picture */
116 AVSubtitle sub;
117} SubPicture;
118
01310af2
FB
119enum {
120 AV_SYNC_AUDIO_MASTER, /* default choice */
121 AV_SYNC_VIDEO_MASTER,
638c9d91 122 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
01310af2
FB
123};
124
125typedef struct VideoState {
126 SDL_Thread *parse_tid;
127 SDL_Thread *video_tid;
d38c9e7a 128 SDL_Thread *refresh_tid;
638c9d91 129 AVInputFormat *iformat;
01310af2
FB
130 int no_background;
131 int abort_request;
132 int paused;
416e3508 133 int last_paused;
72ea344b 134 int seek_req;
3ba1438d 135 int seek_flags;
72ea344b 136 int64_t seek_pos;
4ed29207 137 int64_t seek_rel;
f5668147 138 int read_pause_return;
01310af2
FB
139 AVFormatContext *ic;
140 int dtg_active_format;
141
142 int audio_stream;
115329f1 143
01310af2 144 int av_sync_type;
638c9d91
FB
145 double external_clock; /* external clock base */
146 int64_t external_clock_time;
115329f1 147
638c9d91
FB
148 double audio_clock;
149 double audio_diff_cum; /* used for AV difference average computation */
150 double audio_diff_avg_coef;
151 double audio_diff_threshold;
152 int audio_diff_avg_count;
01310af2
FB
153 AVStream *audio_st;
154 PacketQueue audioq;
155 int audio_hw_buf_size;
e2a2c49f 156 uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
5a4476e2 157 uint8_t *audio_buf;
f199f385 158 uint8_t *audio_buf1;
7fea94ce 159 unsigned int audio_buf_size; /* in bytes */
01310af2 160 int audio_buf_index; /* in bytes */
bea18375 161 AVPacket audio_pkt_temp;
01310af2 162 AVPacket audio_pkt;
5d6e4c16 163 enum AVSampleFormat audio_src_fmt;
5a4476e2 164 AVAudioConvert *reformat_ctx;
f199f385 165 AVFrame *frame;
115329f1 166
01310af2
FB
167 int show_audio; /* if true, display audio samples */
168 int16_t sample_array[SAMPLE_ARRAY_SIZE];
169 int sample_array_index;
5e0257e3 170 int last_i_start;
166621ab 171 RDFTContext *rdft;
12eeda34 172 int rdft_bits;
7dbbf6a1 173 FFTSample *rdft_data;
12eeda34 174 int xpos;
115329f1 175
72ce053b
IC
176 SDL_Thread *subtitle_tid;
177 int subtitle_stream;
178 int subtitle_stream_changed;
179 AVStream *subtitle_st;
180 PacketQueue subtitleq;
181 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
182 int subpq_size, subpq_rindex, subpq_windex;
183 SDL_mutex *subpq_mutex;
184 SDL_cond *subpq_cond;
115329f1 185
638c9d91
FB
186 double frame_timer;
187 double frame_last_pts;
188 double frame_last_delay;
da7c65f0 189 double video_clock; ///< pts of last decoded frame / predicted pts of next decoded frame
01310af2
FB
190 int video_stream;
191 AVStream *video_st;
192 PacketQueue videoq;
da7c65f0
AD
193 double video_current_pts; ///< current displayed pts (different from video_clock if frame fifos are used)
194 double video_current_pts_drift; ///< video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
195 int64_t video_current_pos; ///< current displayed file pos
01310af2
FB
196 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
197 int pictq_size, pictq_rindex, pictq_windex;
198 SDL_mutex *pictq_mutex;
199 SDL_cond *pictq_cond;
917d2bb3 200#if !CONFIG_AVFILTER
3ac56e28 201 struct SwsContext *img_convert_ctx;
917d2bb3 202#endif
115329f1 203
01310af2
FB
204 // QETimer *video_timer;
205 char filename[1024];
206 int width, height, xleft, ytop;
41db429d 207
7a8bfa5d 208 PtsCorrectionContext pts_ctx;
41db429d 209
917d2bb3 210#if CONFIG_AVFILTER
da7c65f0 211 AVFilterContext *out_video_filter; ///< the last filter in the video chain
917d2bb3 212#endif
d38c9e7a
MN
213
214 float skip_frames;
215 float skip_frames_index;
216 int refresh;
01310af2
FB
217} VideoState;
218
358061f6 219static void show_help(void);
01310af2
FB
220
221/* options specified by the user */
222static AVInputFormat *file_iformat;
223static const char *input_filename;
076db5ed 224static const char *window_title;
01310af2
FB
225static int fs_screen_width;
226static int fs_screen_height;
da7c65f0 227static int screen_width = 0;
fccb19e3 228static int screen_height = 0;
01310af2
FB
229static int audio_disable;
230static int video_disable;
da7c65f0
AD
231static int wanted_stream[AVMEDIA_TYPE_NB] = {
232 [AVMEDIA_TYPE_AUDIO] = -1,
233 [AVMEDIA_TYPE_VIDEO] = -1,
234 [AVMEDIA_TYPE_SUBTITLE] = -1,
5b369983 235};
da7c65f0 236static int seek_by_bytes = -1;
01310af2 237static int display_disable;
1e1a0b18 238static int show_status = 1;
638c9d91 239static int av_sync_type = AV_SYNC_AUDIO_MASTER;
72ea344b 240static int64_t start_time = AV_NOPTS_VALUE;
d834d63b 241static int64_t duration = AV_NOPTS_VALUE;
e26a8335 242static int debug = 0;
0c9bbaec 243static int debug_mv = 0;
bba04f1e 244static int step = 0;
c62c07d3 245static int thread_count = 1;
6387c3e6 246static int workaround_bugs = 1;
6fc5b059 247static int fast = 0;
30bc6613 248static int genpts = 0;
178fcca8
MN
249static int lowres = 0;
250static int idct = FF_IDCT_AUTO;
da7c65f0
AD
251static enum AVDiscard skip_frame = AVDISCARD_DEFAULT;
252static enum AVDiscard skip_idct = AVDISCARD_DEFAULT;
253static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT;
047599a4 254static int error_recognition = FF_ER_CAREFUL;
1b51e051 255static int error_concealment = 3;
da7c65f0 256static int decoder_reorder_pts = -1;
2d1653b0 257static int autoexit;
066ce8c9
AS
258static int exit_on_keydown;
259static int exit_on_mousedown;
da7c65f0
AD
260static int loop = 1;
261static int framedrop = 1;
2b3da32f 262
da7c65f0 263static int rdftspeed = 20;
917d2bb3
MN
264#if CONFIG_AVFILTER
265static char *vfilters = NULL;
266#endif
01310af2
FB
267
268/* current context */
269static int is_full_screen;
270static VideoState *cur_stream;
5e0257e3 271static int64_t audio_callback_time;
01310af2 272
2c676c33 273static AVPacket flush_pkt;
39c6a118 274
01310af2
FB
275#define FF_ALLOC_EVENT (SDL_USEREVENT)
276#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
638c9d91 277#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
01310af2 278
2c676c33 279static SDL_Surface *screen;
01310af2 280
dad09ff9
AK
281void exit_program(int ret)
282{
283 exit(ret);
284}
285
515bd00e
MN
286static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
287
01310af2
FB
288/* packet queue handling */
289static void packet_queue_init(PacketQueue *q)
290{
291 memset(q, 0, sizeof(PacketQueue));
292 q->mutex = SDL_CreateMutex();
293 q->cond = SDL_CreateCond();
515bd00e 294 packet_queue_put(q, &flush_pkt);
01310af2
FB
295}
296
72ea344b 297static void packet_queue_flush(PacketQueue *q)
01310af2
FB
298{
299 AVPacketList *pkt, *pkt1;
300
687fae2b 301 SDL_LockMutex(q->mutex);
da7c65f0 302 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
01310af2
FB
303 pkt1 = pkt->next;
304 av_free_packet(&pkt->pkt);
da6c4573 305 av_freep(&pkt);
01310af2 306 }
72ea344b
FB
307 q->last_pkt = NULL;
308 q->first_pkt = NULL;
309 q->nb_packets = 0;
310 q->size = 0;
687fae2b 311 SDL_UnlockMutex(q->mutex);
72ea344b
FB
312}
313
314static void packet_queue_end(PacketQueue *q)
315{
316 packet_queue_flush(q);
01310af2
FB
317 SDL_DestroyMutex(q->mutex);
318 SDL_DestroyCond(q->cond);
319}
320
321static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
322{
323 AVPacketList *pkt1;
324
72ea344b 325 /* duplicate the packet */
da7c65f0 326 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
72ea344b 327 return -1;
115329f1 328
01310af2
FB
329 pkt1 = av_malloc(sizeof(AVPacketList));
330 if (!pkt1)
331 return -1;
332 pkt1->pkt = *pkt;
333 pkt1->next = NULL;
334
72ea344b 335
01310af2
FB
336 SDL_LockMutex(q->mutex);
337
338 if (!q->last_pkt)
339
340 q->first_pkt = pkt1;
341 else
342 q->last_pkt->next = pkt1;
343 q->last_pkt = pkt1;
344 q->nb_packets++;
7b776589 345 q->size += pkt1->pkt.size + sizeof(*pkt1);
01310af2
FB
346 /* XXX: should duplicate packet data in DV case */
347 SDL_CondSignal(q->cond);
348
349 SDL_UnlockMutex(q->mutex);
350 return 0;
351}
352
353static void packet_queue_abort(PacketQueue *q)
354{
355 SDL_LockMutex(q->mutex);
356
357 q->abort_request = 1;
115329f1 358
01310af2
FB
359 SDL_CondSignal(q->cond);
360
361 SDL_UnlockMutex(q->mutex);
362}
363
364/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
365static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
366{
367 AVPacketList *pkt1;
368 int ret;
369
370 SDL_LockMutex(q->mutex);
371
da7c65f0 372 for (;;) {
01310af2
FB
373 if (q->abort_request) {
374 ret = -1;
375 break;
376 }
115329f1 377
01310af2
FB
378 pkt1 = q->first_pkt;
379 if (pkt1) {
380 q->first_pkt = pkt1->next;
381 if (!q->first_pkt)
382 q->last_pkt = NULL;
383 q->nb_packets--;
7b776589 384 q->size -= pkt1->pkt.size + sizeof(*pkt1);
01310af2
FB
385 *pkt = pkt1->pkt;
386 av_free(pkt1);
387 ret = 1;
388 break;
389 } else if (!block) {
390 ret = 0;
391 break;
392 } else {
393 SDL_CondWait(q->cond, q->mutex);
394 }
395 }
396 SDL_UnlockMutex(q->mutex);
397 return ret;
398}
399
115329f1 400static inline void fill_rectangle(SDL_Surface *screen,
01310af2
FB
401 int x, int y, int w, int h, int color)
402{
403 SDL_Rect rect;
404 rect.x = x;
405 rect.y = y;
406 rect.w = w;
407 rect.h = h;
408 SDL_FillRect(screen, &rect, color);
409}
410
72ce053b
IC
411#define ALPHA_BLEND(a, oldp, newp, s)\
412((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
413
414#define RGBA_IN(r, g, b, a, s)\
415{\
416 unsigned int v = ((const uint32_t *)(s))[0];\
417 a = (v >> 24) & 0xff;\
418 r = (v >> 16) & 0xff;\
419 g = (v >> 8) & 0xff;\
420 b = v & 0xff;\
421}
422
423#define YUVA_IN(y, u, v, a, s, pal)\
424{\
57cf99f2 425 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
72ce053b
IC
426 a = (val >> 24) & 0xff;\
427 y = (val >> 16) & 0xff;\
428 u = (val >> 8) & 0xff;\
429 v = val & 0xff;\
430}
431
432#define YUVA_OUT(d, y, u, v, a)\
433{\
434 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
435}
436
437
438#define BPP 1
439
0a8cd696 440static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
72ce053b
IC
441{
442 int wrap, wrap3, width2, skip2;
443 int y, u, v, a, u1, v1, a1, w, h;
444 uint8_t *lum, *cb, *cr;
445 const uint8_t *p;
446 const uint32_t *pal;
9cb5a11e
RD
447 int dstx, dsty, dstw, dsth;
448
7cf9c6ae
MN
449 dstw = av_clip(rect->w, 0, imgw);
450 dsth = av_clip(rect->h, 0, imgh);
451 dstx = av_clip(rect->x, 0, imgw - dstw);
452 dsty = av_clip(rect->y, 0, imgh - dsth);
9cb5a11e 453 lum = dst->data[0] + dsty * dst->linesize[0];
da7c65f0
AD
454 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
455 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
9cb5a11e 456
f54b31b9 457 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
9cb5a11e 458 skip2 = dstx >> 1;
72ce053b 459 wrap = dst->linesize[0];
25b4c651
MN
460 wrap3 = rect->pict.linesize[0];
461 p = rect->pict.data[0];
462 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
115329f1 463
9cb5a11e
RD
464 if (dsty & 1) {
465 lum += dstx;
72ce053b
IC
466 cb += skip2;
467 cr += skip2;
115329f1 468
9cb5a11e 469 if (dstx & 1) {
72ce053b
IC
470 YUVA_IN(y, u, v, a, p, pal);
471 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
472 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
473 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
474 cb++;
475 cr++;
476 lum++;
477 p += BPP;
478 }
da7c65f0 479 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
72ce053b
IC
480 YUVA_IN(y, u, v, a, p, pal);
481 u1 = u;
482 v1 = v;
483 a1 = a;
484 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
485
486 YUVA_IN(y, u, v, a, p + BPP, pal);
487 u1 += u;
488 v1 += v;
489 a1 += a;
490 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
491 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
492 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
493 cb++;
494 cr++;
495 p += 2 * BPP;
496 lum += 2;
497 }
498 if (w) {
499 YUVA_IN(y, u, v, a, p, pal);
500 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
501 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
502 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
676ef505
BA
503 p++;
504 lum++;
72ce053b 505 }
4606a059
BA
506 p += wrap3 - dstw * BPP;
507 lum += wrap - dstw - dstx;
72ce053b
IC
508 cb += dst->linesize[1] - width2 - skip2;
509 cr += dst->linesize[2] - width2 - skip2;
510 }
da7c65f0 511 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
9cb5a11e 512 lum += dstx;
72ce053b
IC
513 cb += skip2;
514 cr += skip2;
115329f1 515
9cb5a11e 516 if (dstx & 1) {
72ce053b
IC
517 YUVA_IN(y, u, v, a, p, pal);
518 u1 = u;
519 v1 = v;
520 a1 = a;
521 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
522 p += wrap3;
523 lum += wrap;
524 YUVA_IN(y, u, v, a, p, pal);
525 u1 += u;
526 v1 += v;
527 a1 += a;
528 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
529 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
530 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
531 cb++;
532 cr++;
533 p += -wrap3 + BPP;
534 lum += -wrap + 1;
535 }
da7c65f0 536 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
72ce053b
IC
537 YUVA_IN(y, u, v, a, p, pal);
538 u1 = u;
539 v1 = v;
540 a1 = a;
541 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
542
f8ca63e8 543 YUVA_IN(y, u, v, a, p + BPP, pal);
72ce053b
IC
544 u1 += u;
545 v1 += v;
546 a1 += a;
547 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
548 p += wrap3;
549 lum += wrap;
550
551 YUVA_IN(y, u, v, a, p, pal);
552 u1 += u;
553 v1 += v;
554 a1 += a;
555 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
556
f8ca63e8 557 YUVA_IN(y, u, v, a, p + BPP, pal);
72ce053b
IC
558 u1 += u;
559 v1 += v;
560 a1 += a;
561 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
562
563 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
564 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
565
566 cb++;
567 cr++;
568 p += -wrap3 + 2 * BPP;
569 lum += -wrap + 2;
570 }
571 if (w) {
572 YUVA_IN(y, u, v, a, p, pal);
573 u1 = u;
574 v1 = v;
575 a1 = a;
576 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
577 p += wrap3;
578 lum += wrap;
579 YUVA_IN(y, u, v, a, p, pal);
580 u1 += u;
581 v1 += v;
582 a1 += a;
583 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
584 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
585 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
586 cb++;
587 cr++;
588 p += -wrap3 + BPP;
589 lum += -wrap + 1;
590 }
9cb5a11e
RD
591 p += wrap3 + (wrap3 - dstw * BPP);
592 lum += wrap + (wrap - dstw - dstx);
72ce053b
IC
593 cb += dst->linesize[1] - width2 - skip2;
594 cr += dst->linesize[2] - width2 - skip2;
595 }
596 /* handle odd height */
597 if (h) {
9cb5a11e 598 lum += dstx;
72ce053b
IC
599 cb += skip2;
600 cr += skip2;
115329f1 601
9cb5a11e 602 if (dstx & 1) {
72ce053b
IC
603 YUVA_IN(y, u, v, a, p, pal);
604 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
605 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
606 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
607 cb++;
608 cr++;
609 lum++;
610 p += BPP;
611 }
da7c65f0 612 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
72ce053b
IC
613 YUVA_IN(y, u, v, a, p, pal);
614 u1 = u;
615 v1 = v;
616 a1 = a;
617 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
618
619 YUVA_IN(y, u, v, a, p + BPP, pal);
620 u1 += u;
621 v1 += v;
622 a1 += a;
623 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
624 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
625 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
626 cb++;
627 cr++;
628 p += 2 * BPP;
629 lum += 2;
630 }
631 if (w) {
632 YUVA_IN(y, u, v, a, p, pal);
633 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
634 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
635 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
636 }
637 }
638}
639
640static void free_subpicture(SubPicture *sp)
641{
e1d7c883 642 avsubtitle_free(&sp->sub);
72ce053b
IC
643}
644
01310af2
FB
645static void video_image_display(VideoState *is)
646{
647 VideoPicture *vp;
72ce053b
IC
648 SubPicture *sp;
649 AVPicture pict;
01310af2
FB
650 float aspect_ratio;
651 int width, height, x, y;
652 SDL_Rect rect;
72ce053b 653 int i;
01310af2
FB
654
655 vp = &is->pictq[is->pictq_rindex];
656 if (vp->bmp) {
917d2bb3 657#if CONFIG_AVFILTER
cc80caff 658 if (vp->picref->video->pixel_aspect.num == 0)
917d2bb3
MN
659 aspect_ratio = 0;
660 else
cc80caff 661 aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
917d2bb3
MN
662#else
663
01310af2 664 /* XXX: use variable in the frame */
c30a4489
AJ
665 if (is->video_st->sample_aspect_ratio.num)
666 aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
667 else if (is->video_st->codec->sample_aspect_ratio.num)
668 aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
72ea344b 669 else
c30a4489 670 aspect_ratio = 0;
917d2bb3 671#endif
01310af2 672 if (aspect_ratio <= 0.0)
c30a4489 673 aspect_ratio = 1.0;
917d2bb3 674 aspect_ratio *= (float)vp->width / (float)vp->height;
01310af2 675
72ce053b
IC
676 if (is->subtitle_st)
677 {
678 if (is->subpq_size > 0)
679 {
680 sp = &is->subpq[is->subpq_rindex];
681
682 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
683 {
684 SDL_LockYUVOverlay (vp->bmp);
685
686 pict.data[0] = vp->bmp->pixels[0];
687 pict.data[1] = vp->bmp->pixels[2];
688 pict.data[2] = vp->bmp->pixels[1];
689
690 pict.linesize[0] = vp->bmp->pitches[0];
691 pict.linesize[1] = vp->bmp->pitches[2];
692 pict.linesize[2] = vp->bmp->pitches[1];
693
694 for (i = 0; i < sp->sub.num_rects; i++)
db4fac64 695 blend_subrect(&pict, sp->sub.rects[i],
0a8cd696 696 vp->bmp->w, vp->bmp->h);
72ce053b
IC
697
698 SDL_UnlockYUVOverlay (vp->bmp);
699 }
700 }
701 }
702
703
01310af2
FB
704 /* XXX: we suppose the screen has a 1.0 pixel ratio */
705 height = is->height;
bb6c34e5 706 width = ((int)rint(height * aspect_ratio)) & ~1;
01310af2
FB
707 if (width > is->width) {
708 width = is->width;
bb6c34e5 709 height = ((int)rint(width / aspect_ratio)) & ~1;
01310af2
FB
710 }
711 x = (is->width - width) / 2;
712 y = (is->height - height) / 2;
6c6c976f 713 is->no_background = 0;
01310af2 714 rect.x = is->xleft + x;
2f6547fb 715 rect.y = is->ytop + y;
01310af2
FB
716 rect.w = width;
717 rect.h = height;
718 SDL_DisplayYUVOverlay(vp->bmp, &rect);
01310af2
FB
719 }
720}
721
3a7c9774
SS
722/* get the current audio output buffer size, in samples. With SDL, we
723 cannot have a precise information */
724static int audio_write_get_buf_size(VideoState *is)
725{
726 return is->audio_buf_size - is->audio_buf_index;
727}
728
01310af2
FB
729static inline int compute_mod(int a, int b)
730{
731 a = a % b;
115329f1 732 if (a >= 0)
01310af2
FB
733 return a;
734 else
735 return a + b;
736}
737
738static void video_audio_display(VideoState *s)
739{
740 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
741 int ch, channels, h, h2, bgcolor, fgcolor;
742 int16_t time_diff;
4c7c7645
MN
743 int rdft_bits, nb_freq;
744
da7c65f0 745 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
4c7c7645 746 ;
da7c65f0 747 nb_freq = 1 << (rdft_bits - 1);
115329f1 748
01310af2 749 /* compute display index : center on currently output samples */
01f4895c 750 channels = s->audio_st->codec->channels;
01310af2 751 nb_display_channels = channels;
5e0257e3 752 if (!s->paused) {
da7c65f0 753 int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq);
5e0257e3
FB
754 n = 2 * channels;
755 delay = audio_write_get_buf_size(s);
756 delay /= n;
115329f1 757
5e0257e3
FB
758 /* to be more precise, we take into account the time spent since
759 the last buffer computation */
760 if (audio_callback_time) {
761 time_diff = av_gettime() - audio_callback_time;
122dcdcb 762 delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
5e0257e3 763 }
115329f1 764
da7c65f0 765 delay += 2 * data_used;
4c7c7645
MN
766 if (delay < data_used)
767 delay = data_used;
ac50bcc8
MN
768
769 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
da7c65f0
AD
770 if (s->show_audio == 1) {
771 h = INT_MIN;
772 for (i = 0; i < 1000; i += channels) {
773 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
774 int a = s->sample_array[idx];
775 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
776 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
777 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
778 int score = a - d;
779 if (h < score && (b ^ c) < 0) {
780 h = score;
781 i_start = idx;
6c7165c7 782 }
ac50bcc8
MN
783 }
784 }
785
5e0257e3
FB
786 s->last_i_start = i_start;
787 } else {
788 i_start = s->last_i_start;
01310af2
FB
789 }
790
01310af2 791 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
da7c65f0 792 if (s->show_audio == 1) {
6c7165c7
JM
793 fill_rectangle(screen,
794 s->xleft, s->ytop, s->width, s->height,
795 bgcolor);
796
797 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
798
799 /* total height for one channel */
800 h = s->height / nb_display_channels;
801 /* graph height / 2 */
802 h2 = (h * 9) / 20;
da7c65f0 803 for (ch = 0; ch < nb_display_channels; ch++) {
6c7165c7
JM
804 i = i_start + ch;
805 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
da7c65f0 806 for (x = 0; x < s->width; x++) {
6c7165c7
JM
807 y = (s->sample_array[i] * h2) >> 15;
808 if (y < 0) {
809 y = -y;
810 ys = y1 - y;
811 } else {
812 ys = y1;
813 }
814 fill_rectangle(screen,
815 s->xleft + x, ys, 1, y,
816 fgcolor);
817 i += channels;
818 if (i >= SAMPLE_ARRAY_SIZE)
819 i -= SAMPLE_ARRAY_SIZE;
01310af2 820 }
01310af2 821 }
01310af2 822
6c7165c7 823 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
01310af2 824
da7c65f0 825 for (ch = 1; ch < nb_display_channels; ch++) {
6c7165c7
JM
826 y = s->ytop + ch * h;
827 fill_rectangle(screen,
828 s->xleft, y, s->width, 1,
829 fgcolor);
830 }
831 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
da7c65f0 832 } else {
12eeda34 833 nb_display_channels= FFMIN(nb_display_channels, 2);
da7c65f0 834 if (rdft_bits != s->rdft_bits) {
166621ab 835 av_rdft_end(s->rdft);
7dbbf6a1 836 av_free(s->rdft_data);
166621ab 837 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
da7c65f0
AD
838 s->rdft_bits = rdft_bits;
839 s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
12eeda34 840 }
12eeda34 841 {
7dbbf6a1 842 FFTSample *data[2];
da7c65f0
AD
843 for (ch = 0; ch < nb_display_channels; ch++) {
844 data[ch] = s->rdft_data + 2 * nb_freq * ch;
12eeda34 845 i = i_start + ch;
da7c65f0
AD
846 for (x = 0; x < 2 * nb_freq; x++) {
847 double w = (x-nb_freq) * (1.0 / nb_freq);
848 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
12eeda34
MN
849 i += channels;
850 if (i >= SAMPLE_ARRAY_SIZE)
851 i -= SAMPLE_ARRAY_SIZE;
852 }
166621ab 853 av_rdft_calc(s->rdft, data[ch]);
12eeda34 854 }
da7c65f0
AD
855 // least efficient way to do this, we should of course directly access it but its more than fast enough
856 for (y = 0; y < s->height; y++) {
857 double w = 1 / sqrt(nb_freq);
858 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]));
859 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
860 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
861 a = FFMIN(a, 255);
862 b = FFMIN(b, 255);
863 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
12eeda34
MN
864
865 fill_rectangle(screen,
866 s->xpos, s->height-y, 1, 1,
867 fgcolor);
868 }
869 }
870 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
871 s->xpos++;
da7c65f0 872 if (s->xpos >= s->width)
12eeda34
MN
873 s->xpos= s->xleft;
874 }
01310af2
FB
875}
876
da7c65f0
AD
877static int video_open(VideoState *is)
878{
879 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
990c8438
MN
880 int w,h;
881
da7c65f0
AD
882 if (is_full_screen) flags |= SDL_FULLSCREEN;
883 else flags |= SDL_RESIZABLE;
fb84155b 884
990c8438
MN
885 if (is_full_screen && fs_screen_width) {
886 w = fs_screen_width;
887 h = fs_screen_height;
da7c65f0 888 } else if (!is_full_screen && screen_width) {
fb84155b
MN
889 w = screen_width;
890 h = screen_height;
917d2bb3 891#if CONFIG_AVFILTER
da7c65f0 892 } else if (is->out_video_filter && is->out_video_filter->inputs[0]) {
917d2bb3
MN
893 w = is->out_video_filter->inputs[0]->w;
894 h = is->out_video_filter->inputs[0]->h;
895#else
da7c65f0 896 } else if (is->video_st && is->video_st->codec->width) {
fb84155b
MN
897 w = is->video_st->codec->width;
898 h = is->video_st->codec->height;
917d2bb3 899#endif
990c8438 900 } else {
fb84155b
MN
901 w = 640;
902 h = 480;
990c8438 903 }
da7c65f0 904 if (screen && is->width == screen->w && screen->w == w
d3d7b12e
MN
905 && is->height== screen->h && screen->h == h)
906 return 0;
907
ec5e5212
LB
908#if defined(__APPLE__) && !SDL_VERSION_ATLEAST(1, 2, 14)
909 /* setting bits_per_pixel = 0 or 32 causes blank video on OS X and older SDL */
990c8438 910 screen = SDL_SetVideoMode(w, h, 24, flags);
ec5e5212
LB
911#else
912 screen = SDL_SetVideoMode(w, h, 0, flags);
990c8438
MN
913#endif
914 if (!screen) {
915 fprintf(stderr, "SDL: could not set video mode - exiting\n");
916 return -1;
917 }
076db5ed
RK
918 if (!window_title)
919 window_title = input_filename;
920 SDL_WM_SetCaption(window_title, window_title);
990c8438 921
da7c65f0 922 is->width = screen->w;
990c8438
MN
923 is->height = screen->h;
924
925 return 0;
926}
8c982c5d 927
01310af2
FB
928/* display the current picture, if any */
929static void video_display(VideoState *is)
930{
da7c65f0 931 if (!screen)
8c982c5d 932 video_open(cur_stream);
115329f1 933 if (is->audio_st && is->show_audio)
01310af2
FB
934 video_audio_display(is);
935 else if (is->video_st)
936 video_image_display(is);
937}
938
d38c9e7a 939static int refresh_thread(void *opaque)
01310af2 940{
d38c9e7a 941 VideoState *is= opaque;
da7c65f0 942 while (!is->abort_request) {
d881a0e8
SS
943 SDL_Event event;
944 event.type = FF_REFRESH_EVENT;
945 event.user.data1 = opaque;
da7c65f0
AD
946 if (!is->refresh) {
947 is->refresh = 1;
d881a0e8 948 SDL_PushEvent(&event);
d38c9e7a 949 }
da7c65f0 950 usleep(is->audio_st && is->show_audio ? rdftspeed * 1000 : 5000); // FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
d38c9e7a
MN
951 }
952 return 0;
01310af2
FB
953}
954
638c9d91
FB
955/* get the current audio clock value */
956static double get_audio_clock(VideoState *is)
957{
958 double pts;
959 int hw_buf_size, bytes_per_sec;
960 pts = is->audio_clock;
961 hw_buf_size = audio_write_get_buf_size(is);
962 bytes_per_sec = 0;
963 if (is->audio_st) {
115329f1 964 bytes_per_sec = is->audio_st->codec->sample_rate *
da7c65f0 965 2 * is->audio_st->codec->channels;
638c9d91
FB
966 }
967 if (bytes_per_sec)
968 pts -= (double)hw_buf_size / bytes_per_sec;
969 return pts;
970}
971
972/* get the current video clock value */
973static double get_video_clock(VideoState *is)
974{
04108619 975 if (is->paused) {
41a4cd0c 976 return is->video_current_pts;
72ea344b 977 } else {
68aefbe8 978 return is->video_current_pts_drift + av_gettime() / 1000000.0;
72ea344b 979 }
638c9d91
FB
980}
981
982/* get the current external clock value */
983static double get_external_clock(VideoState *is)
984{
985 int64_t ti;
986 ti = av_gettime();
987 return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
988}
989
990/* get the current master clock value */
991static double get_master_clock(VideoState *is)
992{
993 double val;
994
72ea344b
FB
995 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
996 if (is->video_st)
997 val = get_video_clock(is);
998 else
999 val = get_audio_clock(is);
1000 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1001 if (is->audio_st)
1002 val = get_audio_clock(is);
1003 else
1004 val = get_video_clock(is);
1005 } else {
638c9d91 1006 val = get_external_clock(is);
72ea344b 1007 }
638c9d91
FB
1008 return val;
1009}
1010
72ea344b 1011/* seek in the stream */
2ef46053 1012static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
72ea344b 1013{
687fae2b
IW
1014 if (!is->seek_req) {
1015 is->seek_pos = pos;
4ed29207 1016 is->seek_rel = rel;
3890dd3a 1017 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
94b594c6
SH
1018 if (seek_by_bytes)
1019 is->seek_flags |= AVSEEK_FLAG_BYTE;
687fae2b
IW
1020 is->seek_req = 1;
1021 }
72ea344b
FB
1022}
1023
1024/* pause or resume the video */
1025static void stream_pause(VideoState *is)
1026{
68aefbe8
MN
1027 if (is->paused) {
1028 is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
da7c65f0 1029 if (is->read_pause_return != AVERROR(ENOSYS)) {
68aefbe8 1030 is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
f5668147 1031 }
68aefbe8 1032 is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
72ea344b 1033 }
68aefbe8 1034 is->paused = !is->paused;
72ea344b
FB
1035}
1036
d38c9e7a 1037static double compute_target_time(double frame_current_pts, VideoState *is)
49410784 1038{
d38c9e7a 1039 double delay, sync_threshold, diff;
49410784
TB
1040
1041 /* compute nominal delay */
1042 delay = frame_current_pts - is->frame_last_pts;
1043 if (delay <= 0 || delay >= 10.0) {
1044 /* if incorrect delay, use previous one */
1045 delay = is->frame_last_delay;
443658fd 1046 } else {
712de377 1047 is->frame_last_delay = delay;
443658fd 1048 }
49410784
TB
1049 is->frame_last_pts = frame_current_pts;
1050
1051 /* update delay to follow master synchronisation source */
1052 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1053 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1054 /* if video is slave, we try to correct big delays by
1055 duplicating or deleting a frame */
f04c6e35 1056 diff = get_video_clock(is) - get_master_clock(is);
49410784
TB
1057
1058 /* skip or repeat frame. We take into account the
1059 delay to compute the threshold. I still don't know
1060 if it is the best guess */
1061 sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1062 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1063 if (diff <= -sync_threshold)
1064 delay = 0;
1065 else if (diff >= sync_threshold)
1066 delay = 2 * delay;
1067 }
1068 }
49410784 1069 is->frame_timer += delay;
8543f0f9
DB
1070
1071 av_dlog(NULL, "video: delay=%0.3f pts=%0.3f A-V=%f\n",
1072 delay, frame_current_pts, -diff);
eecc17a7 1073
d38c9e7a 1074 return is->frame_timer;
49410784
TB
1075}
1076
01310af2
FB
1077/* called to display each frame */
1078static void video_refresh_timer(void *opaque)
1079{
1080 VideoState *is = opaque;
1081 VideoPicture *vp;
638c9d91 1082
72ce053b 1083 SubPicture *sp, *sp2;
01310af2
FB
1084
1085 if (is->video_st) {
d38c9e7a 1086retry:
01310af2 1087 if (is->pictq_size == 0) {
da7c65f0 1088 // nothing to do, no picture to display in the que
01310af2 1089 } else {
da7c65f0 1090 double time = av_gettime() / 1000000.0;
d38c9e7a 1091 double next_target;
638c9d91 1092 /* dequeue the picture */
01310af2 1093 vp = &is->pictq[is->pictq_rindex];
638c9d91 1094
da7c65f0 1095 if (time < vp->target_clock)
d38c9e7a 1096 return;
638c9d91
FB
1097 /* update current video pts */
1098 is->video_current_pts = vp->pts;
d38c9e7a 1099 is->video_current_pts_drift = is->video_current_pts - time;
a3cc2160 1100 is->video_current_pos = vp->pos;
da7c65f0
AD
1101 if (is->pictq_size > 1) {
1102 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
d38c9e7a
MN
1103 assert(nextvp->target_clock >= vp->target_clock);
1104 next_target= nextvp->target_clock;
da7c65f0
AD
1105 } else {
1106 next_target = vp->target_clock + is->video_clock - vp->pts; // FIXME pass durations cleanly
d38c9e7a 1107 }
da7c65f0 1108 if (framedrop && time > next_target) {
d38c9e7a 1109 is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
da7c65f0 1110 if (is->pictq_size > 1 || time > next_target + 0.5) {
d38c9e7a
MN
1111 /* update queue size and signal for next picture */
1112 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1113 is->pictq_rindex = 0;
1114
1115 SDL_LockMutex(is->pictq_mutex);
1116 is->pictq_size--;
1117 SDL_CondSignal(is->pictq_cond);
1118 SDL_UnlockMutex(is->pictq_mutex);
1119 goto retry;
1120 }
1121 }
638c9d91 1122
da7c65f0 1123 if (is->subtitle_st) {
72ce053b
IC
1124 if (is->subtitle_stream_changed) {
1125 SDL_LockMutex(is->subpq_mutex);
115329f1 1126
72ce053b
IC
1127 while (is->subpq_size) {
1128 free_subpicture(&is->subpq[is->subpq_rindex]);
115329f1 1129
72ce053b
IC
1130 /* update queue size and signal for next picture */
1131 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1132 is->subpq_rindex = 0;
115329f1 1133
72ce053b
IC
1134 is->subpq_size--;
1135 }
1136 is->subtitle_stream_changed = 0;
1137
1138 SDL_CondSignal(is->subpq_cond);
1139 SDL_UnlockMutex(is->subpq_mutex);
1140 } else {
1141 if (is->subpq_size > 0) {
1142 sp = &is->subpq[is->subpq_rindex];
1143
1144 if (is->subpq_size > 1)
1145 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1146 else
1147 sp2 = NULL;
1148
1149 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1150 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1151 {
1152 free_subpicture(sp);
1153
1154 /* update queue size and signal for next picture */
1155 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1156 is->subpq_rindex = 0;
1157
1158 SDL_LockMutex(is->subpq_mutex);
1159 is->subpq_size--;
1160 SDL_CondSignal(is->subpq_cond);
1161 SDL_UnlockMutex(is->subpq_mutex);
1162 }
1163 }
1164 }
1165 }
1166
01310af2 1167 /* display picture */
112c4b87 1168 if (!display_disable)
24d13ebc 1169 video_display(is);
115329f1 1170
01310af2
FB
1171 /* update queue size and signal for next picture */
1172 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1173 is->pictq_rindex = 0;
115329f1 1174
01310af2
FB
1175 SDL_LockMutex(is->pictq_mutex);
1176 is->pictq_size--;
1177 SDL_CondSignal(is->pictq_cond);
1178 SDL_UnlockMutex(is->pictq_mutex);
1179 }
1180 } else if (is->audio_st) {
1181 /* draw the next audio frame */
1182
01310af2
FB
1183 /* if only audio stream, then display the audio bars (better
1184 than nothing, just to test the implementation */
115329f1 1185
01310af2 1186 /* display picture */
112c4b87 1187 if (!display_disable)
24d13ebc 1188 video_display(is);
01310af2
FB
1189 }
1190 if (show_status) {
1191 static int64_t last_time;
1192 int64_t cur_time;
72ce053b 1193 int aqsize, vqsize, sqsize;
638c9d91 1194 double av_diff;
115329f1 1195
01310af2 1196 cur_time = av_gettime();
1e1a0b18 1197 if (!last_time || (cur_time - last_time) >= 30000) {
01310af2
FB
1198 aqsize = 0;
1199 vqsize = 0;
72ce053b 1200 sqsize = 0;
01310af2
FB
1201 if (is->audio_st)
1202 aqsize = is->audioq.size;
1203 if (is->video_st)
1204 vqsize = is->videoq.size;
72ce053b
IC
1205 if (is->subtitle_st)
1206 sqsize = is->subtitleq.size;
638c9d91
FB
1207 av_diff = 0;
1208 if (is->audio_st && is->video_st)
1209 av_diff = get_audio_clock(is) - get_video_clock(is);
382f3a5b 1210 printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
da7c65f0
AD
1211 get_master_clock(is), av_diff, FFMAX(is->skip_frames - 1, 0), aqsize / 1024,
1212 vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
01310af2
FB
1213 fflush(stdout);
1214 last_time = cur_time;
1215 }
1216 }
1217}
1218
f7b8c814
MS
1219static void stream_close(VideoState *is)
1220{
1221 VideoPicture *vp;
1222 int i;
1223 /* XXX: use a special url_shutdown call to abort parse cleanly */
1224 is->abort_request = 1;
1225 SDL_WaitThread(is->parse_tid, NULL);
1226 SDL_WaitThread(is->refresh_tid, NULL);
1227
1228 /* free all pictures */
da7c65f0 1229 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
f7b8c814
MS
1230 vp = &is->pictq[i];
1231#if CONFIG_AVFILTER
1232 if (vp->picref) {
1233 avfilter_unref_buffer(vp->picref);
1234 vp->picref = NULL;
1235 }
1236#endif
1237 if (vp->bmp) {
1238 SDL_FreeYUVOverlay(vp->bmp);
1239 vp->bmp = NULL;
1240 }
1241 }
1242 SDL_DestroyMutex(is->pictq_mutex);
1243 SDL_DestroyCond(is->pictq_cond);
1244 SDL_DestroyMutex(is->subpq_mutex);
1245 SDL_DestroyCond(is->subpq_cond);
1246#if !CONFIG_AVFILTER
1247 if (is->img_convert_ctx)
1248 sws_freeContext(is->img_convert_ctx);
1249#endif
1250 av_free(is);
1251}
1252
1253static void do_exit(void)
1254{
f7b8c814
MS
1255 if (cur_stream) {
1256 stream_close(cur_stream);
1257 cur_stream = NULL;
1258 }
a5c33faa 1259 uninit_opts();
f7b8c814
MS
1260#if CONFIG_AVFILTER
1261 avfilter_uninit();
1262#endif
776f2bb9 1263 avformat_network_deinit();
f7b8c814
MS
1264 if (show_status)
1265 printf("\n");
1266 SDL_Quit();
6b6bca64 1267 av_log(NULL, AV_LOG_QUIET, "");
f7b8c814
MS
1268 exit(0);
1269}
1270
01310af2
FB
1271/* allocate a picture (needs to do that in main thread to avoid
1272 potential locking problems */
1273static void alloc_picture(void *opaque)
1274{
1275 VideoState *is = opaque;
1276 VideoPicture *vp;
01310af2
FB
1277
1278 vp = &is->pictq[is->pictq_windex];
1279
1280 if (vp->bmp)
1281 SDL_FreeYUVOverlay(vp->bmp);
1282
917d2bb3
MN
1283#if CONFIG_AVFILTER
1284 if (vp->picref)
7fce481a 1285 avfilter_unref_buffer(vp->picref);
917d2bb3
MN
1286 vp->picref = NULL;
1287
1288 vp->width = is->out_video_filter->inputs[0]->w;
1289 vp->height = is->out_video_filter->inputs[0]->h;
1290 vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1291#else
1292 vp->width = is->video_st->codec->width;
1293 vp->height = is->video_st->codec->height;
1294 vp->pix_fmt = is->video_st->codec->pix_fmt;
1295#endif
1296
1297 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
115329f1 1298 SDL_YV12_OVERLAY,
61890b02 1299 screen);
cb036f90
MS
1300 if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1301 /* SDL allocates a buffer smaller than requested if the video
1302 * overlay hardware is unable to support the requested size. */
1303 fprintf(stderr, "Error: the video system does not support an image\n"
aa78a6d6 1304 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
cb036f90
MS
1305 "to reduce the image size.\n", vp->width, vp->height );
1306 do_exit();
1307 }
01310af2
FB
1308
1309 SDL_LockMutex(is->pictq_mutex);
1310 vp->allocated = 1;
1311 SDL_CondSignal(is->pictq_cond);
1312 SDL_UnlockMutex(is->pictq_mutex);
1313}
1314
267e9dfa
MN
1315/**
1316 *
1317 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1318 */
1a620dd7 1319static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
01310af2
FB
1320{
1321 VideoPicture *vp;
917d2bb3
MN
1322#if CONFIG_AVFILTER
1323 AVPicture pict_src;
f3876ea4
DB
1324#else
1325 int dst_pix_fmt = PIX_FMT_YUV420P;
917d2bb3 1326#endif
01310af2
FB
1327 /* wait until we have space to put a new picture */
1328 SDL_LockMutex(is->pictq_mutex);
d38c9e7a 1329
da7c65f0
AD
1330 if (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
1331 is->skip_frames = FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0 - FRAME_SKIP_FACTOR));
d38c9e7a 1332
01310af2
FB
1333 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1334 !is->videoq.abort_request) {
1335 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1336 }
1337 SDL_UnlockMutex(is->pictq_mutex);
115329f1 1338
01310af2
FB
1339 if (is->videoq.abort_request)
1340 return -1;
1341
1342 vp = &is->pictq[is->pictq_windex];
1343
1344 /* alloc or resize hardware picture buffer */
fec5777e 1345 if (!vp->bmp || vp->reallocate ||
917d2bb3
MN
1346#if CONFIG_AVFILTER
1347 vp->width != is->out_video_filter->inputs[0]->w ||
1348 vp->height != is->out_video_filter->inputs[0]->h) {
1349#else
01f4895c
MN
1350 vp->width != is->video_st->codec->width ||
1351 vp->height != is->video_st->codec->height) {
917d2bb3 1352#endif
01310af2
FB
1353 SDL_Event event;
1354
fec5777e
MB
1355 vp->allocated = 0;
1356 vp->reallocate = 0;
01310af2
FB
1357
1358 /* the allocation must be done in the main thread to avoid
1359 locking problems */
1360 event.type = FF_ALLOC_EVENT;
1361 event.user.data1 = is;
1362 SDL_PushEvent(&event);
115329f1 1363
01310af2
FB
1364 /* wait until the picture is allocated */
1365 SDL_LockMutex(is->pictq_mutex);
1366 while (!vp->allocated && !is->videoq.abort_request) {
1367 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1368 }
1369 SDL_UnlockMutex(is->pictq_mutex);
1370
1371 if (is->videoq.abort_request)
1372 return -1;
1373 }
1374
638c9d91 1375 /* if the frame is not skipped, then display it */
01310af2 1376 if (vp->bmp) {
fbf1b885 1377 AVPicture pict;
917d2bb3 1378#if CONFIG_AVFILTER
da7c65f0 1379 if (vp->picref)
7fce481a 1380 avfilter_unref_buffer(vp->picref);
917d2bb3
MN
1381 vp->picref = src_frame->opaque;
1382#endif
fbf1b885 1383
01310af2
FB
1384 /* get a pointer on the bitmap */
1385 SDL_LockYUVOverlay (vp->bmp);
1386
da7c65f0 1387 memset(&pict, 0, sizeof(AVPicture));
01310af2
FB
1388 pict.data[0] = vp->bmp->pixels[0];
1389 pict.data[1] = vp->bmp->pixels[2];
1390 pict.data[2] = vp->bmp->pixels[1];
1391
1392 pict.linesize[0] = vp->bmp->pitches[0];
1393 pict.linesize[1] = vp->bmp->pitches[2];
1394 pict.linesize[2] = vp->bmp->pitches[1];
917d2bb3
MN
1395
1396#if CONFIG_AVFILTER
1397 pict_src.data[0] = src_frame->data[0];
1398 pict_src.data[1] = src_frame->data[1];
1399 pict_src.data[2] = src_frame->data[2];
1400
1401 pict_src.linesize[0] = src_frame->linesize[0];
1402 pict_src.linesize[1] = src_frame->linesize[1];
1403 pict_src.linesize[2] = src_frame->linesize[2];
1404
da7c65f0 1405 // FIXME use direct rendering
917d2bb3
MN
1406 av_picture_copy(&pict, &pict_src,
1407 vp->pix_fmt, vp->width, vp->height);
1408#else
e43d7a18 1409 sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
3ac56e28 1410 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
917d2bb3 1411 vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
feb7bc67 1412 dst_pix_fmt, sws_flags, NULL, NULL, NULL);
3ac56e28 1413 if (is->img_convert_ctx == NULL) {
26ba8235
AB
1414 fprintf(stderr, "Cannot initialize the conversion context\n");
1415 exit(1);
1416 }
3ac56e28 1417 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
917d2bb3
MN
1418 0, vp->height, pict.data, pict.linesize);
1419#endif
01310af2
FB
1420 /* update the bitmap content */
1421 SDL_UnlockYUVOverlay(vp->bmp);
1422
638c9d91 1423 vp->pts = pts;
1a620dd7 1424 vp->pos = pos;
01310af2
FB
1425
1426 /* now we can update the picture count */
1427 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1428 is->pictq_windex = 0;
1429 SDL_LockMutex(is->pictq_mutex);
da7c65f0 1430 vp->target_clock = compute_target_time(vp->pts, is);
d38c9e7a 1431
01310af2
FB
1432 is->pictq_size++;
1433 SDL_UnlockMutex(is->pictq_mutex);
1434 }
638c9d91
FB
1435 return 0;
1436}
1437
115329f1
DB
1438/**
1439 * compute the exact PTS for the picture if it is omitted in the stream
267e9dfa
MN
1440 * @param pts1 the dts of the pkt / pts of the frame
1441 */
1a620dd7 1442static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
638c9d91
FB
1443{
1444 double frame_delay, pts;
115329f1 1445
638c9d91
FB
1446 pts = pts1;
1447
01310af2 1448 if (pts != 0) {
638c9d91 1449 /* update video clock with pts, if present */
01310af2
FB
1450 is->video_clock = pts;
1451 } else {
72ea344b
FB
1452 pts = is->video_clock;
1453 }
1454 /* update video clock for next frame */
01f4895c 1455 frame_delay = av_q2d(is->video_st->codec->time_base);
72ea344b
FB
1456 /* for MPEG2, the frame can be repeated, so we update the
1457 clock accordingly */
267e9dfa 1458 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
72ea344b 1459 is->video_clock += frame_delay;
638c9d91 1460
1a620dd7 1461 return queue_picture(is, src_frame, pts, pos);
01310af2
FB
1462}
1463
3966a574 1464static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
01310af2 1465{
98704131 1466 int got_picture, i;
01310af2 1467
199c18a7
SS
1468 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1469 return -1;
6c7d3ead 1470
199c18a7
SS
1471 if (pkt->data == flush_pkt.data) {
1472 avcodec_flush_buffers(is->video_st->codec);
6c7d3ead 1473
199c18a7 1474 SDL_LockMutex(is->pictq_mutex);
da7c65f0 1475 // Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
199c18a7
SS
1476 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1477 is->pictq[i].target_clock= 0;
1478 }
1479 while (is->pictq_size && !is->videoq.abort_request) {
1480 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
39c6a118 1481 }
199c18a7
SS
1482 is->video_current_pos = -1;
1483 SDL_UnlockMutex(is->pictq_mutex);
39c6a118 1484
199c18a7
SS
1485 init_pts_correction(&is->pts_ctx);
1486 is->frame_last_pts = AV_NOPTS_VALUE;
1487 is->frame_last_delay = 0;
1488 is->frame_timer = (double)av_gettime() / 1000000.0;
1489 is->skip_frames = 1;
1490 is->skip_frames_index = 0;
1491 return 0;
1492 }
7a8bfa5d 1493
98704131 1494 avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt);
199c18a7
SS
1495
1496 if (got_picture) {
1497 if (decoder_reorder_pts == -1) {
6b474953 1498 *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
199c18a7 1499 } else if (decoder_reorder_pts) {
28550804 1500 *pts = frame->pkt_pts;
199c18a7 1501 } else {
6b474953 1502 *pts = frame->pkt_dts;
199c18a7
SS
1503 }
1504
1505 if (*pts == AV_NOPTS_VALUE) {
1506 *pts = 0;
99e0b12b 1507 }
41db429d 1508
d38c9e7a 1509 is->skip_frames_index += 1;
da7c65f0 1510 if (is->skip_frames_index >= is->skip_frames) {
d38c9e7a
MN
1511 is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1512 return 1;
1513 }
1514
1515 }
917d2bb3
MN
1516 return 0;
1517}
1518
1519#if CONFIG_AVFILTER
1520typedef struct {
1521 VideoState *is;
1522 AVFrame *frame;
dd0c789b 1523 int use_dr1;
917d2bb3
MN
1524} FilterPriv;
1525
dd0c789b
BB
1526static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
1527{
1528 AVFilterContext *ctx = codec->opaque;
ecc8dada 1529 AVFilterBufferRef *ref;
dd0c789b 1530 int perms = AV_PERM_WRITE;
65929418 1531 int i, w, h, stride[4];
dd0c789b 1532 unsigned edge;
6e3ef511 1533 int pixel_size;
dd0c789b 1534
0ccabeea
MN
1535 if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
1536 perms |= AV_PERM_NEG_LINESIZES;
1537
da7c65f0
AD
1538 if (pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
1539 if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
1540 if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
1541 if (pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
dd0c789b 1542 }
da7c65f0 1543 if (pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
dd0c789b
BB
1544
1545 w = codec->width;
1546 h = codec->height;
1547 avcodec_align_dimensions2(codec, &w, &h, stride);
1548 edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
1549 w += edge << 1;
1550 h += edge << 1;
1551
da7c65f0 1552 if (!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
dd0c789b
BB
1553 return -1;
1554
da7c65f0 1555 pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1 + 1;
cc80caff
HM
1556 ref->video->w = codec->width;
1557 ref->video->h = codec->height;
da7c65f0 1558 for (i = 0; i < 4; i ++) {
d54e0948
HM
1559 unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
1560 unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
dd0c789b 1561
3635c07b 1562 if (ref->data[i]) {
6e3ef511 1563 ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
3635c07b 1564 }
dd0c789b
BB
1565 pic->data[i] = ref->data[i];
1566 pic->linesize[i] = ref->linesize[i];
1567 }
1568 pic->opaque = ref;
dd0c789b 1569 pic->type = FF_BUFFER_TYPE_USER;
867ab7fb 1570 pic->reordered_opaque = codec->reordered_opaque;
da7c65f0
AD
1571 if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1572 else pic->pkt_pts = AV_NOPTS_VALUE;
dd0c789b
BB
1573 return 0;
1574}
1575
1576static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1577{
1578 memset(pic->data, 0, sizeof(pic->data));
7fce481a 1579 avfilter_unref_buffer(pic->opaque);
dd0c789b
BB
1580}
1581
12bd3c1f
JM
1582static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1583{
ecc8dada 1584 AVFilterBufferRef *ref = pic->opaque;
12bd3c1f
JM
1585
1586 if (pic->data[0] == NULL) {
1587 pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1588 return codec->get_buffer(codec, pic);
1589 }
1590
cc80caff 1591 if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
d54e0948 1592 (codec->pix_fmt != ref->format)) {
12bd3c1f
JM
1593 av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1594 return -1;
1595 }
1596
1597 pic->reordered_opaque = codec->reordered_opaque;
da7c65f0
AD
1598 if (codec->pkt) pic->pkt_pts = codec->pkt->pts;
1599 else pic->pkt_pts = AV_NOPTS_VALUE;
12bd3c1f
JM
1600 return 0;
1601}
1602
917d2bb3
MN
1603static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1604{
1605 FilterPriv *priv = ctx->priv;
dd0c789b 1606 AVCodecContext *codec;
da7c65f0 1607 if (!opaque) return -1;
917d2bb3
MN
1608
1609 priv->is = opaque;
dd0c789b
BB
1610 codec = priv->is->video_st->codec;
1611 codec->opaque = ctx;
da7c65f0 1612 if (codec->codec->capabilities & CODEC_CAP_DR1) {
dd0c789b
BB
1613 priv->use_dr1 = 1;
1614 codec->get_buffer = input_get_buffer;
1615 codec->release_buffer = input_release_buffer;
12bd3c1f 1616 codec->reget_buffer = input_reget_buffer;
37b00b47 1617 codec->thread_safe_callbacks = 1;
dd0c789b
BB
1618 }
1619
917d2bb3
MN
1620 priv->frame = avcodec_alloc_frame();
1621
1622 return 0;
1623}
1624
1625static void input_uninit(AVFilterContext *ctx)
1626{
1627 FilterPriv *priv = ctx->priv;
1628 av_free(priv->frame);
1629}
1630
1631static int input_request_frame(AVFilterLink *link)
1632{
1633 FilterPriv *priv = link->src->priv;
ecc8dada 1634 AVFilterBufferRef *picref;
3966a574 1635 int64_t pts = 0;
917d2bb3
MN
1636 AVPacket pkt;
1637 int ret;
1638
1639 while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1640 av_free_packet(&pkt);
1641 if (ret < 0)
1642 return -1;
1643
da7c65f0 1644 if (priv->use_dr1) {
7fce481a 1645 picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
dd0c789b 1646 } else {
cf097cbc 1647 picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
34017fd9 1648 av_image_copy(picref->data, picref->linesize,
4afbcf46
SS
1649 priv->frame->data, priv->frame->linesize,
1650 picref->format, link->w, link->h);
dd0c789b 1651 }
917d2bb3
MN
1652 av_free_packet(&pkt);
1653
1c9e340d 1654 avfilter_copy_frame_props(picref, priv->frame);
917d2bb3 1655 picref->pts = pts;
1c9e340d 1656
c41c5b02 1657 avfilter_start_frame(link, picref);
917d2bb3
MN
1658 avfilter_draw_slice(link, 0, link->h, 1);
1659 avfilter_end_frame(link);
917d2bb3
MN
1660
1661 return 0;
1662}
1663
1664static int input_query_formats(AVFilterContext *ctx)
1665{
1666 FilterPriv *priv = ctx->priv;
1667 enum PixelFormat pix_fmts[] = {
1668 priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1669 };
1670
1671 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1672 return 0;
1673}
1674
1675static int input_config_props(AVFilterLink *link)
1676{
1677 FilterPriv *priv = link->src->priv;
1678 AVCodecContext *c = priv->is->video_st->codec;
1679
1680 link->w = c->width;
1681 link->h = c->height;
387b4ac9 1682 link->time_base = priv->is->video_st->time_base;
917d2bb3
MN
1683
1684 return 0;
1685}
1686
1687static AVFilter input_filter =
1688{
266463da 1689 .name = "avplay_input",
917d2bb3
MN
1690
1691 .priv_size = sizeof(FilterPriv),
1692
1693 .init = input_init,
1694 .uninit = input_uninit,
1695
1696 .query_formats = input_query_formats,
1697
1698 .inputs = (AVFilterPad[]) {{ .name = NULL }},
1699 .outputs = (AVFilterPad[]) {{ .name = "default",
72415b2a 1700 .type = AVMEDIA_TYPE_VIDEO,
917d2bb3
MN
1701 .request_frame = input_request_frame,
1702 .config_props = input_config_props, },
1703 { .name = NULL }},
1704};
1705
75ea596d 1706static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
917d2bb3 1707{
3f073fa2 1708 char sws_flags_str[128];
75ea596d 1709 int ret;
f7ead94c 1710 FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
917d2bb3 1711 AVFilterContext *filt_src = NULL, *filt_out = NULL;
3f073fa2
SS
1712 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1713 graph->scale_sws_opts = av_strdup(sws_flags_str);
917d2bb3 1714
75ea596d
SS
1715 if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
1716 NULL, is, graph)) < 0)
71a1d111 1717 return ret;
75ea596d
SS
1718 if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
1719 NULL, &ffsink_ctx, graph)) < 0)
71a1d111 1720 return ret;
917d2bb3 1721
da7c65f0 1722 if (vfilters) {
917d2bb3
MN
1723 AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1724 AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
1725
1726 outputs->name = av_strdup("in");
7313132b 1727 outputs->filter_ctx = filt_src;
917d2bb3
MN
1728 outputs->pad_idx = 0;
1729 outputs->next = NULL;
1730
1731 inputs->name = av_strdup("out");
7313132b 1732 inputs->filter_ctx = filt_out;
917d2bb3
MN
1733 inputs->pad_idx = 0;
1734 inputs->next = NULL;
1735
75ea596d 1736 if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
71a1d111 1737 return ret;
917d2bb3
MN
1738 av_freep(&vfilters);
1739 } else {
75ea596d 1740 if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
71a1d111 1741 return ret;
917d2bb3 1742 }
917d2bb3 1743
75ea596d 1744 if ((ret = avfilter_graph_config(graph, NULL)) < 0)
71a1d111 1745 return ret;
917d2bb3
MN
1746
1747 is->out_video_filter = filt_out;
71a1d111 1748
75ea596d
SS
1749 return ret;
1750}
1751
1752#endif /* CONFIG_AVFILTER */
1753
1754static int video_thread(void *arg)
1755{
1756 VideoState *is = arg;
da7c65f0 1757 AVFrame *frame = avcodec_alloc_frame();
75ea596d
SS
1758 int64_t pts_int;
1759 double pts;
1760 int ret;
1761
1762#if CONFIG_AVFILTER
1763 AVFilterGraph *graph = avfilter_graph_alloc();
1764 AVFilterContext *filt_out = NULL;
1765 int64_t pos;
428c59d9
K
1766 int last_w = is->video_st->codec->width;
1767 int last_h = is->video_st->codec->height;
75ea596d
SS
1768
1769 if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1770 goto the_end;
1771 filt_out = is->out_video_filter;
917d2bb3
MN
1772#endif
1773
da7c65f0 1774 for (;;) {
917d2bb3
MN
1775#if !CONFIG_AVFILTER
1776 AVPacket pkt;
387b4ac9 1777#else
ff0652e5 1778 AVFilterBufferRef *picref;
387b4ac9 1779 AVRational tb;
917d2bb3
MN
1780#endif
1781 while (is->paused && !is->videoq.abort_request)
1782 SDL_Delay(10);
1783#if CONFIG_AVFILTER
428c59d9
K
1784 if ( last_w != is->video_st->codec->width
1785 || last_h != is->video_st->codec->height) {
1786 av_dlog(NULL, "Changing size %dx%d -> %dx%d\n", last_w, last_h,
1787 is->video_st->codec->width, is->video_st->codec->height);
1788 avfilter_graph_free(&graph);
1789 graph = avfilter_graph_alloc();
1790 if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1791 goto the_end;
1792 filt_out = is->out_video_filter;
1793 last_w = is->video_st->codec->width;
1794 last_h = is->video_st->codec->height;
1795 }
ff0652e5
SS
1796 ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
1797 if (picref) {
1798 pts_int = picref->pts;
1799 pos = picref->pos;
1800 frame->opaque = picref;
1801 }
387b4ac9
SS
1802
1803 if (av_cmp_q(tb, is->video_st->time_base)) {
13156f40 1804 av_unused int64_t pts1 = pts_int;
387b4ac9 1805 pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
13156f40
SS
1806 av_dlog(NULL, "video_thread(): "
1807 "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
1808 tb.num, tb.den, pts1,
1809 is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
387b4ac9 1810 }
917d2bb3
MN
1811#else
1812 ret = get_video_frame(is, frame, &pts_int, &pkt);
1813#endif
1814
da7c65f0
AD
1815 if (ret < 0)
1816 goto the_end;
917d2bb3
MN
1817
1818 if (!ret)
1819 continue;
1820
da7c65f0 1821 pts = pts_int * av_q2d(is->video_st->time_base);
917d2bb3
MN
1822
1823#if CONFIG_AVFILTER
bb409513 1824 ret = output_picture2(is, frame, pts, pos);
917d2bb3 1825#else
fca62599 1826 ret = output_picture2(is, frame, pts, pkt.pos);
917d2bb3
MN
1827 av_free_packet(&pkt);
1828#endif
1829 if (ret < 0)
1830 goto the_end;
1831
115329f1 1832 if (step)
bba04f1e
WH
1833 if (cur_stream)
1834 stream_pause(cur_stream);
01310af2
FB
1835 }
1836 the_end:
917d2bb3 1837#if CONFIG_AVFILTER
4359288c 1838 avfilter_graph_free(&graph);
917d2bb3 1839#endif
c6b1edc9 1840 av_free(frame);
01310af2
FB
1841 return 0;
1842}
1843
72ce053b
IC
1844static int subtitle_thread(void *arg)
1845{
1846 VideoState *is = arg;
1847 SubPicture *sp;
1848 AVPacket pkt1, *pkt = &pkt1;
98704131 1849 int got_subtitle;
72ce053b
IC
1850 double pts;
1851 int i, j;
1852 int r, g, b, y, u, v, a;
1853
da7c65f0 1854 for (;;) {
72ce053b
IC
1855 while (is->paused && !is->subtitleq.abort_request) {
1856 SDL_Delay(10);
1857 }
1858 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1859 break;
115329f1 1860
da7c65f0 1861 if (pkt->data == flush_pkt.data) {
39c6a118
MN
1862 avcodec_flush_buffers(is->subtitle_st->codec);
1863 continue;
1864 }
72ce053b
IC
1865 SDL_LockMutex(is->subpq_mutex);
1866 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1867 !is->subtitleq.abort_request) {
1868 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1869 }
1870 SDL_UnlockMutex(is->subpq_mutex);
115329f1 1871
72ce053b 1872 if (is->subtitleq.abort_request)
71a1d111 1873 return 0;
115329f1 1874
72ce053b
IC
1875 sp = &is->subpq[is->subpq_windex];
1876
1877 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1878 this packet, if any */
1879 pts = 0;
1880 if (pkt->pts != AV_NOPTS_VALUE)
da7c65f0 1881 pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
72ce053b 1882
98704131
DB
1883 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
1884 &got_subtitle, pkt);
1885
72ce053b
IC
1886 if (got_subtitle && sp->sub.format == 0) {
1887 sp->pts = pts;
115329f1 1888
72ce053b
IC
1889 for (i = 0; i < sp->sub.num_rects; i++)
1890 {
db4fac64 1891 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
72ce053b 1892 {
25b4c651 1893 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
72ce053b
IC
1894 y = RGB_TO_Y_CCIR(r, g, b);
1895 u = RGB_TO_U_CCIR(r, g, b, 0);
1896 v = RGB_TO_V_CCIR(r, g, b, 0);
25b4c651 1897 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
72ce053b
IC
1898 }
1899 }
1900
1901 /* now we can update the picture count */
1902 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1903 is->subpq_windex = 0;
1904 SDL_LockMutex(is->subpq_mutex);
1905 is->subpq_size++;
1906 SDL_UnlockMutex(is->subpq_mutex);
1907 }
1908 av_free_packet(pkt);
72ce053b 1909 }
72ce053b
IC
1910 return 0;
1911}
1912
01310af2
FB
1913/* copy samples for viewing in editor window */
1914static void update_sample_display(VideoState *is, short *samples, int samples_size)
1915{
c713620b 1916 int size, len;
01310af2
FB
1917
1918 size = samples_size / sizeof(short);
1919 while (size > 0) {
1920 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1921 if (len > size)
1922 len = size;
1923 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1924 samples += len;
1925 is->sample_array_index += len;
1926 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1927 is->sample_array_index = 0;
1928 size -= len;
1929 }
1930}
1931
01310af2
FB
1932/* return the new audio buffer size (samples can be added or deleted
1933 to get better sync if video or external master clock) */
115329f1 1934static int synchronize_audio(VideoState *is, short *samples,
638c9d91 1935 int samples_size1, double pts)
01310af2 1936{
638c9d91 1937 int n, samples_size;
01310af2 1938 double ref_clock;
115329f1 1939
01f4895c 1940 n = 2 * is->audio_st->codec->channels;
638c9d91 1941 samples_size = samples_size1;
01310af2 1942
01310af2 1943 /* if not master, then we try to remove or add samples to correct the clock */
01310af2 1944 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
638c9d91
FB
1945 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1946 double diff, avg_diff;
01310af2 1947 int wanted_size, min_size, max_size, nb_samples;
115329f1 1948
638c9d91
FB
1949 ref_clock = get_master_clock(is);
1950 diff = get_audio_clock(is) - ref_clock;
115329f1 1951
638c9d91
FB
1952 if (diff < AV_NOSYNC_THRESHOLD) {
1953 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1954 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1955 /* not enough measures to have a correct estimate */
1956 is->audio_diff_avg_count++;
1957 } else {
1958 /* estimate the A-V difference */
1959 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1960
1961 if (fabs(avg_diff) >= is->audio_diff_threshold) {
01f4895c 1962 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
638c9d91 1963 nb_samples = samples_size / n;
115329f1 1964
638c9d91
FB
1965 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1966 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1967 if (wanted_size < min_size)
1968 wanted_size = min_size;
1969 else if (wanted_size > max_size)
1970 wanted_size = max_size;
115329f1 1971
638c9d91
FB
1972 /* add or remove samples to correction the synchro */
1973 if (wanted_size < samples_size) {
1974 /* remove samples */
1975 samples_size = wanted_size;
1976 } else if (wanted_size > samples_size) {
1977 uint8_t *samples_end, *q;
1978 int nb;
115329f1 1979
638c9d91
FB
1980 /* add samples */
1981 nb = (samples_size - wanted_size);
1982 samples_end = (uint8_t *)samples + samples_size - n;
1983 q = samples_end + n;
1984 while (nb > 0) {
1985 memcpy(q, samples_end, n);
1986 q += n;
1987 nb -= n;
1988 }
1989 samples_size = wanted_size;
1990 }
1991 }
045dd4b9
DB
1992 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1993 diff, avg_diff, samples_size - samples_size1,
1994 is->audio_clock, is->video_clock, is->audio_diff_threshold);
01310af2 1995 }
638c9d91
FB
1996 } else {
1997 /* too big difference : may be initial PTS errors, so
1998 reset A-V filter */
1999 is->audio_diff_avg_count = 0;
da7c65f0 2000 is->audio_diff_cum = 0;
01310af2
FB
2001 }
2002 }
2003
01310af2
FB
2004 return samples_size;
2005}
2006
2007/* decode one audio frame and returns its uncompressed size */
5a4476e2 2008static int audio_decode_frame(VideoState *is, double *pts_ptr)
01310af2 2009{
bea18375 2010 AVPacket *pkt_temp = &is->audio_pkt_temp;
01310af2 2011 AVPacket *pkt = &is->audio_pkt;
da7c65f0 2012 AVCodecContext *dec = is->audio_st->codec;
f199f385 2013 int n, len1, data_size, got_frame;
01310af2 2014 double pts;
59df4b82
JR
2015 int new_packet = 0;
2016 int flush_complete = 0;
01310af2 2017
da7c65f0 2018 for (;;) {
72ea344b 2019 /* NOTE: the audio packet can contain several frames */
59df4b82 2020 while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
f199f385
JR
2021 if (!is->frame) {
2022 if (!(is->frame = avcodec_alloc_frame()))
2023 return AVERROR(ENOMEM);
2024 } else
2025 avcodec_get_frame_defaults(is->frame);
2026
59df4b82
JR
2027 if (flush_complete)
2028 break;
2029 new_packet = 0;
f199f385 2030 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
72ea344b
FB
2031 if (len1 < 0) {
2032 /* if error, we skip the frame */
bea18375 2033 pkt_temp->size = 0;
01310af2 2034 break;
72ea344b 2035 }
115329f1 2036
bea18375
TB
2037 pkt_temp->data += len1;
2038 pkt_temp->size -= len1;
59df4b82 2039
f199f385 2040 if (!got_frame) {
59df4b82
JR
2041 /* stop sending empty packets if the decoder is finished */
2042 if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2043 flush_complete = 1;
72ea344b 2044 continue;
59df4b82 2045 }
f199f385
JR
2046 data_size = av_samples_get_buffer_size(NULL, dec->channels,
2047 is->frame->nb_samples,
2048 dec->sample_fmt, 1);
5a4476e2
PR
2049
2050 if (dec->sample_fmt != is->audio_src_fmt) {
2051 if (is->reformat_ctx)
2052 av_audio_convert_free(is->reformat_ctx);
5d6e4c16 2053 is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
5a4476e2
PR
2054 dec->sample_fmt, 1, NULL, 0);
2055 if (!is->reformat_ctx) {
2056 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
ba7d6e79 2057 av_get_sample_fmt_name(dec->sample_fmt),
5d6e4c16 2058 av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
5a4476e2
PR
2059 break;
2060 }
2061 is->audio_src_fmt= dec->sample_fmt;
2062 }
2063
2064 if (is->reformat_ctx) {
da7c65f0 2065 const void *ibuf[6] = { is->frame->data[0] };
f199f385 2066 void *obuf[6];
da7c65f0
AD
2067 int istride[6] = { av_get_bytes_per_sample(dec->sample_fmt) };
2068 int ostride[6] = { 2 };
5a4476e2 2069 int len= data_size/istride[0];
f199f385
JR
2070 obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32));
2071 if (!obuf[0]) {
2072 return AVERROR(ENOMEM);
2073 }
2074 is->audio_buf1 = obuf[0];
da7c65f0 2075 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {
5a4476e2
PR
2076 printf("av_audio_convert() failed\n");
2077 break;
2078 }
f199f385 2079 is->audio_buf = is->audio_buf1;
5a4476e2
PR
2080 /* FIXME: existing code assume that data_size equals framesize*channels*2
2081 remove this legacy cruft */
da7c65f0
AD
2082 data_size = len * 2;
2083 } else {
f199f385 2084 is->audio_buf = is->frame->data[0];
5a4476e2
PR
2085 }
2086
72ea344b
FB
2087 /* if no pts, then compute it */
2088 pts = is->audio_clock;
2089 *pts_ptr = pts;
abdff646 2090 n = 2 * dec->channels;
115329f1 2091 is->audio_clock += (double)data_size /
abdff646 2092 (double)(n * dec->sample_rate);
1f6b9cc3 2093#ifdef DEBUG
72ea344b
FB
2094 {
2095 static double last_clock;
2096 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2097 is->audio_clock - last_clock,
2098 is->audio_clock, pts);
2099 last_clock = is->audio_clock;
01310af2 2100 }
72ea344b
FB
2101#endif
2102 return data_size;
01310af2
FB
2103 }
2104
72ea344b
FB
2105 /* free the current packet */
2106 if (pkt->data)
01310af2 2107 av_free_packet(pkt);
c9aa4cfd 2108 memset(pkt_temp, 0, sizeof(*pkt_temp));
115329f1 2109
72ea344b
FB
2110 if (is->paused || is->audioq.abort_request) {
2111 return -1;
2112 }
115329f1 2113
01310af2 2114 /* read next packet */
59df4b82 2115 if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
01310af2 2116 return -1;
59df4b82
JR
2117
2118 if (pkt->data == flush_pkt.data)
abdff646 2119 avcodec_flush_buffers(dec);
39c6a118 2120
f199f385 2121 *pkt_temp = *pkt;
115329f1 2122
72ea344b
FB
2123 /* if update the audio clock with the pts */
2124 if (pkt->pts != AV_NOPTS_VALUE) {
c0df9d75 2125 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
72ea344b 2126 }
01310af2
FB
2127 }
2128}
2129
01310af2 2130/* prepare a new audio buffer */
358061f6 2131static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
01310af2
FB
2132{
2133 VideoState *is = opaque;
2134 int audio_size, len1;
2135 double pts;
2136
2137 audio_callback_time = av_gettime();
115329f1 2138
01310af2
FB
2139 while (len > 0) {
2140 if (is->audio_buf_index >= is->audio_buf_size) {
5a4476e2 2141 audio_size = audio_decode_frame(is, &pts);
01310af2
FB
2142 if (audio_size < 0) {
2143 /* if error, just output silence */
e2a2c49f
JR
2144 is->audio_buf = is->silence_buf;
2145 is->audio_buf_size = sizeof(is->silence_buf);
01310af2
FB
2146 } else {
2147 if (is->show_audio)
2148 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
115329f1 2149 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
01310af2
FB
2150 pts);
2151 is->audio_buf_size = audio_size;
2152 }
2153 is->audio_buf_index = 0;
2154 }
2155 len1 = is->audio_buf_size - is->audio_buf_index;
2156 if (len1 > len)
2157 len1 = len;
2158 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2159 len -= len1;
2160 stream += len1;
2161 is->audio_buf_index += len1;
2162 }
2163}
2164
01310af2
FB
2165/* open a given stream. Return 0 if OK */
2166static int stream_component_open(VideoState *is, int stream_index)
2167{
2168 AVFormatContext *ic = is->ic;
fe74099a 2169 AVCodecContext *avctx;
01310af2
FB
2170 AVCodec *codec;
2171 SDL_AudioSpec wanted_spec, spec;
3009f521
AK
2172 AVDictionary *opts;
2173 AVDictionaryEntry *t = NULL;
01310af2
FB
2174
2175 if (stream_index < 0 || stream_index >= ic->nb_streams)
2176 return -1;
fe74099a 2177 avctx = ic->streams[stream_index]->codec;
115329f1 2178
d4863fc1 2179 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index]);
3009f521 2180
fe74099a 2181 codec = avcodec_find_decoder(avctx->codec_id);
da7c65f0
AD
2182 avctx->debug_mv = debug_mv;
2183 avctx->debug = debug;
2184 avctx->workaround_bugs = workaround_bugs;
2185 avctx->lowres = lowres;
2186 avctx->idct_algo = idct;
2187 avctx->skip_frame = skip_frame;
2188 avctx->skip_idct = skip_idct;
2189 avctx->skip_loop_filter = skip_loop_filter;
2190 avctx->error_recognition = error_recognition;
2191 avctx->error_concealment = error_concealment;
2192 avctx->thread_count = thread_count;
2193
2194 if (lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2195 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
fe74099a 2196
01310af2 2197 if (!codec ||
3009f521 2198 avcodec_open2(avctx, codec, &opts) < 0)
01310af2 2199 return -1;
3009f521
AK
2200 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2201 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2202 return AVERROR_OPTION_NOT_FOUND;
2203 }
51b73087
JR
2204
2205 /* prepare audio output */
72415b2a 2206 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
fe74099a 2207 wanted_spec.freq = avctx->sample_rate;
51b73087 2208 wanted_spec.format = AUDIO_S16SYS;
fe74099a 2209 wanted_spec.channels = avctx->channels;
51b73087
JR
2210 wanted_spec.silence = 0;
2211 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2212 wanted_spec.callback = sdl_audio_callback;
2213 wanted_spec.userdata = is;
2214 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2215 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2216 return -1;
2217 }
2218 is->audio_hw_buf_size = spec.size;
da7c65f0 2219 is->audio_src_fmt = AV_SAMPLE_FMT_S16;
51b73087
JR
2220 }
2221
3f3fe38d 2222 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
da7c65f0 2223 switch (avctx->codec_type) {
72415b2a 2224 case AVMEDIA_TYPE_AUDIO:
01310af2
FB
2225 is->audio_stream = stream_index;
2226 is->audio_st = ic->streams[stream_index];
da7c65f0 2227 is->audio_buf_size = 0;
01310af2 2228 is->audio_buf_index = 0;
638c9d91
FB
2229
2230 /* init averaging filter */
da7c65f0 2231 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
638c9d91
FB
2232 is->audio_diff_avg_count = 0;
2233 /* since we do not have a precise anough audio fifo fullness,
2234 we correct audio sync only if larger than this threshold */
fe74099a 2235 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
638c9d91 2236
01310af2
FB
2237 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2238 packet_queue_init(&is->audioq);
bb270c08 2239 SDL_PauseAudio(0);
01310af2 2240 break;
72415b2a 2241 case AVMEDIA_TYPE_VIDEO:
01310af2
FB
2242 is->video_stream = stream_index;
2243 is->video_st = ic->streams[stream_index];
2244
2245 packet_queue_init(&is->videoq);
2246 is->video_tid = SDL_CreateThread(video_thread, is);
2247 break;
72415b2a 2248 case AVMEDIA_TYPE_SUBTITLE:
72ce053b
IC
2249 is->subtitle_stream = stream_index;
2250 is->subtitle_st = ic->streams[stream_index];
2251 packet_queue_init(&is->subtitleq);
115329f1 2252
72ce053b
IC
2253 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2254 break;
01310af2
FB
2255 default:
2256 break;
2257 }
2258 return 0;
2259}
2260
2261static void stream_component_close(VideoState *is, int stream_index)
2262{
2263 AVFormatContext *ic = is->ic;
fe74099a 2264 AVCodecContext *avctx;
115329f1 2265
72ce053b
IC
2266 if (stream_index < 0 || stream_index >= ic->nb_streams)
2267 return;
fe74099a 2268 avctx = ic->streams[stream_index]->codec;
01310af2 2269
da7c65f0 2270 switch (avctx->codec_type) {
72415b2a 2271 case AVMEDIA_TYPE_AUDIO:
01310af2
FB
2272 packet_queue_abort(&is->audioq);
2273
2274 SDL_CloseAudio();
2275
2276 packet_queue_end(&is->audioq);
c74f1f47 2277 av_free_packet(&is->audio_pkt);
5a4476e2
PR
2278 if (is->reformat_ctx)
2279 av_audio_convert_free(is->reformat_ctx);
bc77fce6 2280 is->reformat_ctx = NULL;
f199f385
JR
2281 av_freep(&is->audio_buf1);
2282 is->audio_buf = NULL;
2283 av_freep(&is->frame);
cb2c4de3
JR
2284
2285 if (is->rdft) {
2286 av_rdft_end(is->rdft);
2287 av_freep(&is->rdft_data);
f9324d5a
JR
2288 is->rdft = NULL;
2289 is->rdft_bits = 0;
cb2c4de3 2290 }
01310af2 2291 break;
72415b2a 2292 case AVMEDIA_TYPE_VIDEO:
01310af2
FB
2293 packet_queue_abort(&is->videoq);
2294
2295 /* note: we also signal this mutex to make sure we deblock the
2296 video thread in all cases */
2297 SDL_LockMutex(is->pictq_mutex);
2298 SDL_CondSignal(is->pictq_cond);
2299 SDL_UnlockMutex(is->pictq_mutex);
2300
2301 SDL_WaitThread(is->video_tid, NULL);
2302
2303 packet_queue_end(&is->videoq);
2304 break;
72415b2a 2305 case AVMEDIA_TYPE_SUBTITLE:
72ce053b 2306 packet_queue_abort(&is->subtitleq);
115329f1 2307
72ce053b
IC
2308 /* note: we also signal this mutex to make sure we deblock the
2309 video thread in all cases */
2310 SDL_LockMutex(is->subpq_mutex);
2311 is->subtitle_stream_changed = 1;
115329f1 2312
72ce053b
IC
2313 SDL_CondSignal(is->subpq_cond);
2314 SDL_UnlockMutex(is->subpq_mutex);
2315
2316 SDL_WaitThread(is->subtitle_tid, NULL);
2317
2318 packet_queue_end(&is->subtitleq);
2319 break;
01310af2
FB
2320 default:
2321 break;
2322 }
2323
3f3fe38d 2324 ic->streams[stream_index]->discard = AVDISCARD_ALL;
fe74099a 2325 avcodec_close(avctx);
da7c65f0 2326 switch (avctx->codec_type) {
72415b2a 2327 case AVMEDIA_TYPE_AUDIO:
01310af2
FB
2328 is->audio_st = NULL;
2329 is->audio_stream = -1;
2330 break;
72415b2a 2331 case AVMEDIA_TYPE_VIDEO:
01310af2
FB
2332 is->video_st = NULL;
2333 is->video_stream = -1;
2334 break;
72415b2a 2335 case AVMEDIA_TYPE_SUBTITLE:
72ce053b
IC
2336 is->subtitle_st = NULL;
2337 is->subtitle_stream = -1;
2338 break;
01310af2
FB
2339 default:
2340 break;
2341 }
2342}
2343
416e3508
FB
2344/* since we have only one decoding thread, we can use a global
2345 variable instead of a thread local variable */
2346static VideoState *global_video_state;
2347
40972f7c 2348static int decode_interrupt_cb(void *ctx)
416e3508 2349{
d4b63054 2350 return global_video_state && global_video_state->abort_request;
416e3508 2351}
01310af2
FB
2352
2353/* this thread gets the stream from the disk or the network */
2354static int decode_thread(void *arg)
2355{
2356 VideoState *is = arg;
d0e142bb 2357 AVFormatContext *ic = NULL;
6625a3de 2358 int err, i, ret;
72415b2a 2359 int st_index[AVMEDIA_TYPE_NB];
01310af2 2360 AVPacket pkt1, *pkt = &pkt1;
da7c65f0 2361 int eof = 0;
d834d63b 2362 int pkt_in_play_range = 0;
d0e142bb 2363 AVDictionaryEntry *t;
3009f521
AK
2364 AVDictionary **opts;
2365 int orig_nb_streams;
6299a229 2366
6625a3de 2367 memset(st_index, -1, sizeof(st_index));
01310af2
FB
2368 is->video_stream = -1;
2369 is->audio_stream = -1;
72ce053b 2370 is->subtitle_stream = -1;
01310af2 2371
416e3508 2372 global_video_state = is;
416e3508 2373
40972f7c
MS
2374 ic = avformat_alloc_context();
2375 ic->interrupt_callback.callback = decode_interrupt_cb;
d0e142bb 2376 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
638c9d91
FB
2377 if (err < 0) {
2378 print_error(is->filename, err);
2379 ret = -1;
2380 goto fail;
2381 }
d0e142bb
AK
2382 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2383 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2384 ret = AVERROR_OPTION_NOT_FOUND;
2385 goto fail;
2386 }
01310af2 2387 is->ic = ic;
30bc6613 2388
da7c65f0 2389 if (genpts)
30bc6613
MN
2390 ic->flags |= AVFMT_FLAG_GENPTS;
2391
8ec19f84 2392 opts = setup_find_stream_info_opts(ic, codec_opts);
3009f521 2393 orig_nb_streams = ic->nb_streams;
bc778a0c 2394
3009f521 2395 err = avformat_find_stream_info(ic, opts);
24c07998
LA
2396 if (err < 0) {
2397 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2398 ret = -1;
2399 goto fail;
2400 }
3009f521
AK
2401 for (i = 0; i < orig_nb_streams; i++)
2402 av_dict_free(&opts[i]);
2403 av_freep(&opts);
2404
da7c65f0
AD
2405 if (ic->pb)
2406 ic->pb->eof_reached = 0; // FIXME hack, avplay maybe should not use url_feof() to test for the end
72ea344b 2407
da7c65f0
AD
2408 if (seek_by_bytes < 0)
2409 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
70a4764d 2410
72ea344b
FB
2411 /* if seeking requested, we execute it */
2412 if (start_time != AV_NOPTS_VALUE) {
2413 int64_t timestamp;
2414
2415 timestamp = start_time;
2416 /* add the stream start time */
2417 if (ic->start_time != AV_NOPTS_VALUE)
2418 timestamp += ic->start_time;
4ed29207 2419 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
72ea344b 2420 if (ret < 0) {
115329f1 2421 fprintf(stderr, "%s: could not seek to position %0.3f\n",
72ea344b
FB
2422 is->filename, (double)timestamp / AV_TIME_BASE);
2423 }
2424 }
72ea344b 2425
406f0f1b 2426 for (i = 0; i < ic->nb_streams; i++)
3f3fe38d 2427 ic->streams[i]->discard = AVDISCARD_ALL;
be732b70 2428 if (!video_disable)
406f0f1b
NG
2429 st_index[AVMEDIA_TYPE_VIDEO] =
2430 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2431 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
be732b70 2432 if (!audio_disable)
406f0f1b
NG
2433 st_index[AVMEDIA_TYPE_AUDIO] =
2434 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2435 wanted_stream[AVMEDIA_TYPE_AUDIO],
2436 st_index[AVMEDIA_TYPE_VIDEO],
2437 NULL, 0);
be732b70 2438 if (!video_disable)
406f0f1b
NG
2439 st_index[AVMEDIA_TYPE_SUBTITLE] =
2440 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2441 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2442 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2443 st_index[AVMEDIA_TYPE_AUDIO] :
2444 st_index[AVMEDIA_TYPE_VIDEO]),
2445 NULL, 0);
01310af2 2446 if (show_status) {
610219a5 2447 av_dump_format(ic, 0, is->filename, 0);
01310af2
FB
2448 }
2449
2450 /* open the streams */
72415b2a
SS
2451 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2452 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
01310af2
FB
2453 }
2454
da7c65f0 2455 ret = -1;
72415b2a 2456 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
da7c65f0 2457 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
077a8d61 2458 }
d38c9e7a 2459 is->refresh_tid = SDL_CreateThread(refresh_thread, is);
da7c65f0 2460 if (ret < 0) {
01310af2 2461 if (!display_disable)
bf8ae197 2462 is->show_audio = 2;
01310af2
FB
2463 }
2464
72415b2a
SS
2465 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2466 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
16a59a7b
BA
2467 }
2468
01310af2 2469 if (is->video_stream < 0 && is->audio_stream < 0) {
638c9d91
FB
2470 fprintf(stderr, "%s: could not open codecs\n", is->filename);
2471 ret = -1;
01310af2
FB
2472 goto fail;
2473 }
2474
da7c65f0 2475 for (;;) {
01310af2
FB
2476 if (is->abort_request)
2477 break;
416e3508
FB
2478 if (is->paused != is->last_paused) {
2479 is->last_paused = is->paused;
72ea344b 2480 if (is->paused)
da7c65f0 2481 is->read_pause_return = av_read_pause(ic);
72ea344b
FB
2482 else
2483 av_read_play(ic);
416e3508 2484 }
2f642393
AJ
2485#if CONFIG_RTSP_DEMUXER
2486 if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
416e3508
FB
2487 /* wait 10 ms to avoid trying to get another packet */
2488 /* XXX: horrible */
2489 SDL_Delay(10);
2490 continue;
2491 }
400738b1 2492#endif
72ea344b 2493 if (is->seek_req) {
da7c65f0
AD
2494 int64_t seek_target = is->seek_pos;
2495 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2496 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2497// FIXME the +-2 is due to rounding being not done in the correct direction in generation
4ed29207 2498// of the seek_pos/seek_rel variables
8e606cc8 2499
4ed29207 2500 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
72ea344b
FB
2501 if (ret < 0) {
2502 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
da7c65f0 2503 } else {
e6c0297f
MN
2504 if (is->audio_stream >= 0) {
2505 packet_queue_flush(&is->audioq);
39c6a118 2506 packet_queue_put(&is->audioq, &flush_pkt);
e6c0297f 2507 }
72ce053b
IC
2508 if (is->subtitle_stream >= 0) {
2509 packet_queue_flush(&is->subtitleq);
39c6a118 2510 packet_queue_put(&is->subtitleq, &flush_pkt);
72ce053b 2511 }
e6c0297f
MN
2512 if (is->video_stream >= 0) {
2513 packet_queue_flush(&is->videoq);
39c6a118 2514 packet_queue_put(&is->videoq, &flush_pkt);
e6c0297f 2515 }
72ea344b
FB
2516 }
2517 is->seek_req = 0;
da7c65f0 2518 eof = 0;
72ea344b 2519 }
416e3508 2520
01310af2 2521 /* if the queue are full, no need to read more */
79ee4683 2522 if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
da7c65f0
AD
2523 || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
2524 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0)
2525 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0))) {
01310af2
FB
2526 /* wait 10 ms */
2527 SDL_Delay(10);
2528 continue;
2529 }
da7c65f0
AD
2530 if (eof) {
2531 if (is->video_stream >= 0) {
26534fe8 2532 av_init_packet(pkt);
da7c65f0
AD
2533 pkt->data = NULL;
2534 pkt->size = 0;
2535 pkt->stream_index = is->video_stream;
26534fe8 2536 packet_queue_put(&is->videoq, pkt);
9dc41767 2537 }
59df4b82
JR
2538 if (is->audio_stream >= 0 &&
2539 is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
2540 av_init_packet(pkt);
2541 pkt->data = NULL;
2542 pkt->size = 0;
2543 pkt->stream_index = is->audio_stream;
2544 packet_queue_put(&is->audioq, pkt);
2545 }
b4083171 2546 SDL_Delay(10);
da7c65f0
AD
2547 if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
2548 if (loop != 1 && (!loop || --loop)) {
1922c0a7 2549 stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
da7c65f0
AD
2550 } else if (autoexit) {
2551 ret = AVERROR_EOF;
1922c0a7
RK
2552 goto fail;
2553 }
2d1653b0 2554 }
600a331c
MN
2555 continue;
2556 }
72ea344b 2557 ret = av_read_frame(ic, pkt);
01310af2 2558 if (ret < 0) {
648c7962 2559 if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached))
da7c65f0 2560 eof = 1;
648c7962 2561 if (ic->pb && ic->pb->error)
bb270c08 2562 break;
75bb7b0a
MN
2563 SDL_Delay(100); /* wait for user event */
2564 continue;
01310af2 2565 }
d834d63b
RK
2566 /* check if packet is in play range specified by user, then queue, otherwise discard */
2567 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2568 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2569 av_q2d(ic->streams[pkt->stream_index]->time_base) -
da7c65f0
AD
2570 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2571 <= ((double)duration / 1000000);
d834d63b 2572 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
01310af2 2573 packet_queue_put(&is->audioq, pkt);
d834d63b 2574 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
01310af2 2575 packet_queue_put(&is->videoq, pkt);
d834d63b 2576 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
72ce053b 2577 packet_queue_put(&is->subtitleq, pkt);
01310af2
FB
2578 } else {
2579 av_free_packet(pkt);
2580 }
2581 }
2582 /* wait until the end */
2583 while (!is->abort_request) {
2584 SDL_Delay(100);
2585 }
2586
638c9d91 2587 ret = 0;
01310af2 2588 fail:
416e3508
FB
2589 /* disable interrupting */
2590 global_video_state = NULL;
2591
01310af2
FB
2592 /* close each stream */
2593 if (is->audio_stream >= 0)
2594 stream_component_close(is, is->audio_stream);
2595 if (is->video_stream >= 0)
2596 stream_component_close(is, is->video_stream);
72ce053b
IC
2597 if (is->subtitle_stream >= 0)
2598 stream_component_close(is, is->subtitle_stream);
638c9d91 2599 if (is->ic) {
cd3716b9 2600 avformat_close_input(&is->ic);
638c9d91 2601 }
416e3508 2602
638c9d91
FB
2603 if (ret != 0) {
2604 SDL_Event event;
115329f1 2605
638c9d91
FB
2606 event.type = FF_QUIT_EVENT;
2607 event.user.data1 = is;
2608 SDL_PushEvent(&event);
2609 }
01310af2
FB
2610 return 0;
2611}
2612
638c9d91 2613static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
01310af2
FB
2614{
2615 VideoState *is;
2616
2617 is = av_mallocz(sizeof(VideoState));
2618 if (!is)
2619 return NULL;
f7d78f36 2620 av_strlcpy(is->filename, filename, sizeof(is->filename));
638c9d91 2621 is->iformat = iformat;
da7c65f0
AD
2622 is->ytop = 0;
2623 is->xleft = 0;
01310af2
FB
2624
2625 /* start video display */
2626 is->pictq_mutex = SDL_CreateMutex();
da7c65f0 2627 is->pictq_cond = SDL_CreateCond();
115329f1 2628
72ce053b 2629 is->subpq_mutex = SDL_CreateMutex();
da7c65f0 2630 is->subpq_cond = SDL_CreateCond();
115329f1 2631
638c9d91 2632 is->av_sync_type = av_sync_type;
da7c65f0 2633 is->parse_tid = SDL_CreateThread(decode_thread, is);
01310af2
FB
2634 if (!is->parse_tid) {
2635 av_free(is);
2636 return NULL;
2637 }
2638 return is;
2639}
2640
7b49ce2e 2641static void stream_cycle_channel(VideoState *is, int codec_type)
638c9d91
FB
2642{
2643 AVFormatContext *ic = is->ic;
2644 int start_index, stream_index;
2645 AVStream *st;
2646
72415b2a 2647 if (codec_type == AVMEDIA_TYPE_VIDEO)
638c9d91 2648 start_index = is->video_stream;
72415b2a 2649 else if (codec_type == AVMEDIA_TYPE_AUDIO)
638c9d91 2650 start_index = is->audio_stream;
72ce053b
IC
2651 else
2652 start_index = is->subtitle_stream;
72415b2a 2653 if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
638c9d91
FB
2654 return;
2655 stream_index = start_index;
da7c65f0 2656 for (;;) {
638c9d91 2657 if (++stream_index >= is->ic->nb_streams)
72ce053b 2658 {
72415b2a 2659 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
72ce053b
IC
2660 {
2661 stream_index = -1;
2662 goto the_end;
2663 } else
2664 stream_index = 0;
2665 }
638c9d91
FB
2666 if (stream_index == start_index)
2667 return;
2668 st = ic->streams[stream_index];
01f4895c 2669 if (st->codec->codec_type == codec_type) {
638c9d91 2670 /* check that parameters are OK */
da7c65f0 2671 switch (codec_type) {
72415b2a 2672 case AVMEDIA_TYPE_AUDIO:
01f4895c
MN
2673 if (st->codec->sample_rate != 0 &&
2674 st->codec->channels != 0)
638c9d91
FB
2675 goto the_end;
2676 break;
72415b2a
SS
2677 case AVMEDIA_TYPE_VIDEO:
2678 case AVMEDIA_TYPE_SUBTITLE:
638c9d91
FB
2679 goto the_end;
2680 default:
2681 break;
2682 }
2683 }
2684 }
2685 the_end:
2686 stream_component_close(is, start_index);
2687 stream_component_open(is, stream_index);
2688}
2689
2690
7b49ce2e 2691static void toggle_full_screen(void)
01310af2 2692{
01310af2 2693 is_full_screen = !is_full_screen;
fec5777e 2694#if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
5ea20630 2695 /* OS X needs to empty the picture_queue */
fec5777e
MB
2696 for (int i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
2697 cur_stream->pictq[i].reallocate = 1;
2698 }
2699#endif
fb84155b 2700 video_open(cur_stream);
01310af2
FB
2701}
2702
7b49ce2e 2703static void toggle_pause(void)
01310af2
FB
2704{
2705 if (cur_stream)
2706 stream_pause(cur_stream);
bba04f1e
WH
2707 step = 0;
2708}
2709
7b49ce2e 2710static void step_to_next_frame(void)
bba04f1e
WH
2711{
2712 if (cur_stream) {
19cc524a 2713 /* if the stream is paused unpause it, then step */
bba04f1e 2714 if (cur_stream->paused)
19cc524a 2715 stream_pause(cur_stream);
bba04f1e
WH
2716 }
2717 step = 1;
01310af2
FB
2718}
2719
7b49ce2e 2720static void toggle_audio_display(void)
01310af2
FB
2721{
2722 if (cur_stream) {
f5968788 2723 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
12eeda34 2724 cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
f5968788 2725 fill_rectangle(screen,
da7c65f0
AD
2726 cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2727 bgcolor);
f5968788 2728 SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
01310af2
FB
2729 }
2730}
2731
2732/* handle an event sent by the GUI */
7b49ce2e 2733static void event_loop(void)
01310af2
FB
2734{
2735 SDL_Event event;
a11d11aa 2736 double incr, pos, frac;
01310af2 2737
da7c65f0 2738 for (;;) {
d52ec002 2739 double x;
01310af2 2740 SDL_WaitEvent(&event);
da7c65f0 2741 switch (event.type) {
01310af2 2742 case SDL_KEYDOWN:
066ce8c9
AS
2743 if (exit_on_keydown) {
2744 do_exit();
2745 break;
2746 }
da7c65f0 2747 switch (event.key.keysym.sym) {
01310af2
FB
2748 case SDLK_ESCAPE:
2749 case SDLK_q:
2750 do_exit();
2751 break;
2752 case SDLK_f:
2753 toggle_full_screen();
2754 break;
2755 case SDLK_p:
2756 case SDLK_SPACE:
2757 toggle_pause();
2758 break;
da7c65f0 2759 case SDLK_s: // S: Step to next frame
bba04f1e
WH
2760 step_to_next_frame();
2761 break;
01310af2 2762 case SDLK_a:
115329f1 2763 if (cur_stream)
72415b2a 2764 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
638c9d91
FB
2765 break;
2766 case SDLK_v:
115329f1 2767 if (cur_stream)
72415b2a 2768 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
638c9d91 2769 break;
72ce053b 2770 case SDLK_t:
115329f1 2771 if (cur_stream)
72415b2a 2772 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
72ce053b 2773 break;
638c9d91 2774 case SDLK_w:
01310af2
FB
2775 toggle_audio_display();
2776 break;
72ea344b
FB
2777 case SDLK_LEFT:
2778 incr = -10.0;
2779 goto do_seek;
2780 case SDLK_RIGHT:
2781 incr = 10.0;
2782 goto do_seek;
2783 case SDLK_UP:
2784 incr = 60.0;
2785 goto do_seek;
2786 case SDLK_DOWN:
2787 incr = -60.0;
2788 do_seek:
2789 if (cur_stream) {
94b594c6 2790 if (seek_by_bytes) {
da7c65f0
AD
2791 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
2792 pos = cur_stream->video_current_pos;
2793 } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
2794 pos = cur_stream->audio_pkt.pos;
2795 } else
a2704c97 2796 pos = avio_tell(cur_stream->ic->pb);
94b594c6 2797 if (cur_stream->ic->bit_rate)
566cd2cb 2798 incr *= cur_stream->ic->bit_rate / 8.0;
94b594c6
SH
2799 else
2800 incr *= 180000.0;
2801 pos += incr;
2ef46053 2802 stream_seek(cur_stream, pos, incr, 1);
94b594c6
SH
2803 } else {
2804 pos = get_master_clock(cur_stream);
2805 pos += incr;
2ef46053 2806 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
94b594c6 2807 }
72ea344b
FB
2808 }
2809 break;
01310af2
FB
2810 default:
2811 break;
2812 }
2813 break;
a11d11aa 2814 case SDL_MOUSEBUTTONDOWN:
066ce8c9
AS
2815 if (exit_on_mousedown) {
2816 do_exit();
2817 break;
2818 }
d52ec002 2819 case SDL_MOUSEMOTION:
da7c65f0
AD
2820 if (event.type == SDL_MOUSEBUTTONDOWN) {
2821 x = event.button.x;
2822 } else {
2823 if (event.motion.state != SDL_PRESSED)
d52ec002 2824 break;
da7c65f0 2825 x = event.motion.x;
d52ec002 2826 }
bb270c08 2827 if (cur_stream) {
da7c65f0
AD
2828 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
2829 uint64_t size = avio_size(cur_stream->ic->pb);
d52ec002 2830 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
da7c65f0 2831 } else {
6371c81a
MN
2832 int64_t ts;
2833 int ns, hh, mm, ss;
2834 int tns, thh, tmm, tss;
da7c65f0
AD
2835 tns = cur_stream->ic->duration / 1000000LL;
2836 thh = tns / 3600;
2837 tmm = (tns % 3600) / 60;
2838 tss = (tns % 60);
2839 frac = x / cur_stream->width;
2840 ns = frac * tns;
2841 hh = ns / 3600;
2842 mm = (ns % 3600) / 60;
2843 ss = (ns % 60);
6371c81a
MN
2844 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2845 hh, mm, ss, thh, tmm, tss);
da7c65f0 2846 ts = frac * cur_stream->ic->duration;
6371c81a
MN
2847 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2848 ts += cur_stream->ic->start_time;
2849 stream_seek(cur_stream, ts, 0, 0);
2ef46053 2850 }
bb270c08
DB
2851 }
2852 break;
01310af2
FB
2853 case SDL_VIDEORESIZE:
2854 if (cur_stream) {
115329f1 2855 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
01310af2 2856 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
da7c65f0
AD
2857 screen_width = cur_stream->width = event.resize.w;
2858 screen_height = cur_stream->height = event.resize.h;
01310af2
FB
2859 }
2860 break;
2861 case SDL_QUIT:
638c9d91 2862 case FF_QUIT_EVENT:
01310af2
FB
2863 do_exit();
2864 break;
2865 case FF_ALLOC_EVENT:
fccb19e3 2866 video_open(event.user.data1);
01310af2
FB
2867 alloc_picture(event.user.data1);
2868 break;
2869 case FF_REFRESH_EVENT:
2870 video_refresh_timer(event.user.data1);
da7c65f0 2871 cur_stream->refresh = 0;
01310af2
FB
2872 break;
2873 default:
2874 break;
2875 }
2876 }
2877}
2878
26513856 2879static int opt_frame_size(const char *opt, const char *arg)
e4b89522 2880{
a4e540c4
SS
2881 av_log(NULL, AV_LOG_ERROR,
2882 "Option '%s' has been removed, use private format options instead\n", opt);
2883 return AVERROR(EINVAL);
e4b89522
LW
2884}
2885
a5b3b5f6 2886static int opt_width(const char *opt, const char *arg)
01310af2 2887{
a5b3b5f6
SS
2888 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2889 return 0;
01310af2
FB
2890}
2891
a5b3b5f6 2892static int opt_height(const char *opt, const char *arg)
01310af2 2893{
a5b3b5f6
SS
2894 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2895 return 0;
01310af2
FB
2896}
2897
26513856 2898static int opt_format(const char *opt, const char *arg)
01310af2
FB
2899{
2900 file_iformat = av_find_input_format(arg);
2901 if (!file_iformat) {
2902 fprintf(stderr, "Unknown input format: %s\n", arg);
26513856 2903 return AVERROR(EINVAL);
01310af2 2904 }
26513856 2905 return 0;
01310af2 2906}
61890b02 2907
26513856 2908static int opt_frame_pix_fmt(const char *opt, const char *arg)
e4b89522 2909{
0a858048
SS
2910 av_log(NULL, AV_LOG_ERROR,
2911 "Option '%s' has been removed, use private format options instead\n", opt);
2912 return AVERROR(EINVAL);
e4b89522
LW
2913}
2914
b81d6235 2915static int opt_sync(const char *opt, const char *arg)
638c9d91
FB
2916{
2917 if (!strcmp(arg, "audio"))
2918 av_sync_type = AV_SYNC_AUDIO_MASTER;
2919 else if (!strcmp(arg, "video"))
2920 av_sync_type = AV_SYNC_VIDEO_MASTER;
2921 else if (!strcmp(arg, "ext"))
2922 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
aab1b7e5 2923 else {
b81d6235 2924 fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
aab1b7e5
SS
2925 exit(1);
2926 }
b81d6235 2927 return 0;
638c9d91
FB
2928}
2929
e11bc2c6 2930static int opt_seek(const char *opt, const char *arg)
72ea344b 2931{
e11bc2c6
SS
2932 start_time = parse_time_or_die(opt, arg, 1);
2933 return 0;
72ea344b
FB
2934}
2935
d834d63b
RK
2936static int opt_duration(const char *opt, const char *arg)
2937{
2938 duration = parse_time_or_die(opt, arg, 1);
2939 return 0;
2940}
2941
a5b3b5f6 2942static int opt_debug(const char *opt, const char *arg)
e26a8335 2943{
a309073b 2944 av_log_set_level(99);
a5b3b5f6
SS
2945 debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2946 return 0;
e26a8335 2947}
115329f1 2948
a5b3b5f6 2949static int opt_vismv(const char *opt, const char *arg)
0c9bbaec 2950{
a5b3b5f6
SS
2951 debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2952 return 0;
0c9bbaec 2953}
c62c07d3 2954
a5b3b5f6 2955static int opt_thread_count(const char *opt, const char *arg)
c62c07d3 2956{
da7c65f0 2957 thread_count = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
b250f9c6 2958#if !HAVE_THREADS
c62c07d3
MN
2959 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2960#endif
a5b3b5f6 2961 return 0;
c62c07d3 2962}
115329f1 2963
358061f6 2964static const OptionDef options[] = {
992f8eae 2965#include "cmdutils_common_opts.h"
da7c65f0
AD
2966 { "x", HAS_ARG, { (void*)opt_width }, "force displayed width", "width" },
2967 { "y", HAS_ARG, { (void*)opt_height }, "force displayed height", "height" },
2968 { "s", HAS_ARG | OPT_VIDEO, { (void*)opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
2969 { "fs", OPT_BOOL, { (void*)&is_full_screen }, "force full screen" },
2970 { "an", OPT_BOOL, { (void*)&audio_disable }, "disable audio" },
2971 { "vn", OPT_BOOL, { (void*)&video_disable }, "disable video" },
2972 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
2973 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
2974 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
2975 { "ss", HAS_ARG, { (void*)&opt_seek }, "seek to a given position in seconds", "pos" },
2976 { "t", HAS_ARG, { (void*)&opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
2977 { "bytes", OPT_INT | HAS_ARG, { (void*)&seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
2978 { "nodisp", OPT_BOOL, { (void*)&display_disable }, "disable graphical display" },
2979 { "f", HAS_ARG, { (void*)opt_format }, "force format", "fmt" },
2980 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { (void*)opt_frame_pix_fmt }, "set pixel format", "format" },
2981 { "stats", OPT_BOOL | OPT_EXPERT, { (void*)&show_status }, "show status", "" },
2982 { "debug", HAS_ARG | OPT_EXPERT, { (void*)opt_debug }, "print specific debug info", "" },
2983 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&workaround_bugs }, "workaround bugs", "" },
2984 { "vismv", HAS_ARG | OPT_EXPERT, { (void*)opt_vismv }, "visualize motion vectors", "" },
2985 { "fast", OPT_BOOL | OPT_EXPERT, { (void*)&fast }, "non spec compliant optimizations", "" },
2986 { "genpts", OPT_BOOL | OPT_EXPERT, { (void*)&genpts }, "generate pts", "" },
2987 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2988 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&lowres }, "", "" },
2989 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_loop_filter }, "", "" },
2990 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_frame }, "", "" },
2991 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_idct }, "", "" },
2992 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&idct }, "set idct algo", "algo" },
2993 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_recognition }, "set error detection threshold (0-4)", "threshold" },
2994 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_concealment }, "set error concealment options", "bit_mask" },
2995 { "sync", HAS_ARG | OPT_EXPERT, { (void*)opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
2996 { "threads", HAS_ARG | OPT_EXPERT, { (void*)opt_thread_count }, "thread count", "count" },
2997 { "autoexit", OPT_BOOL | OPT_EXPERT, { (void*)&autoexit }, "exit at the end", "" },
2998 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_keydown }, "exit on key down", "" },
2999 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { (void*)&exit_on_mousedown }, "exit on mouse down", "" },
3000 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&loop }, "set number of times the playback shall be looped", "loop count" },
3001 { "framedrop", OPT_BOOL | OPT_EXPERT, { (void*)&framedrop }, "drop frames when cpu is too slow", "" },
3002 { "window_title", OPT_STRING | HAS_ARG, { (void*)&window_title }, "set window title", "window title" },
917d2bb3 3003#if CONFIG_AVFILTER
da7c65f0 3004 { "vf", OPT_STRING | HAS_ARG, { (void*)&vfilters }, "video filters", "filter list" },
917d2bb3 3005#endif
da7c65f0
AD
3006 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { (void*)&rdftspeed }, "rdft speed", "msecs" },
3007 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { (void*)opt_default }, "generic catch all option", "" },
3008 { "i", 0, { NULL }, "avconv compatibility dummy option", ""},
01310af2
FB
3009 { NULL, },
3010};
3011
0c2a18cb 3012static void show_usage(void)
01310af2 3013{
27daa420 3014 printf("Simple media player\n");
266463da 3015 printf("usage: %s [options] input_file\n", program_name);
01310af2 3016 printf("\n");
0c2a18cb
RP
3017}
3018
3019static void show_help(void)
3020{
f66eb58e 3021 av_log_set_callback(log_callback_help);
0c2a18cb 3022 show_usage();
02d504a7
FB
3023 show_help_options(options, "Main options:\n",
3024 OPT_EXPERT, 0);
3025 show_help_options(options, "\nAdvanced options:\n",
3026 OPT_EXPERT, OPT_EXPERT);
f66eb58e 3027 printf("\n");
7a6cd995
AK
3028 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3029 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
f66eb58e 3030#if !CONFIG_AVFILTER
7a6cd995 3031 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
f66eb58e 3032#endif
01310af2
FB
3033 printf("\nWhile playing:\n"
3034 "q, ESC quit\n"
3035 "f toggle full screen\n"
3036 "p, SPC pause\n"
638c9d91
FB
3037 "a cycle audio channel\n"
3038 "v cycle video channel\n"
72ce053b 3039 "t cycle subtitle channel\n"
638c9d91 3040 "w show audio waves\n"
79f8b328 3041 "s activate frame-step mode\n"
72ea344b
FB
3042 "left/right seek backward/forward 10 seconds\n"
3043 "down/up seek backward/forward 1 minute\n"
a11d11aa 3044 "mouse click seek to percentage in file corresponding to fraction of width\n"
01310af2 3045 );
01310af2
FB
3046}
3047
7cc8d638 3048static void opt_input_file(void *optctx, const char *filename)
01310af2 3049{
07a70b38
SS
3050 if (input_filename) {
3051 fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3052 filename, input_filename);
3053 exit(1);
3054 }
e8d83e1c 3055 if (!strcmp(filename, "-"))
9fcfc0b7 3056 filename = "pipe:";
01310af2
FB
3057 input_filename = filename;
3058}
3059
3060/* Called from the main */
3061int main(int argc, char **argv)
3062{
a5c33faa 3063 int flags;
115329f1 3064
6b6bca64 3065 av_log_set_flags(AV_LOG_SKIP_REPEATED);
182cbe43 3066 parse_loglevel(argc, argv, options);
6b6bca64 3067
01310af2 3068 /* register all codecs, demux and protocols */
c721d803 3069 avcodec_register_all();
9b157b0c 3070#if CONFIG_AVDEVICE
c721d803 3071 avdevice_register_all();
9b157b0c 3072#endif
917d2bb3
MN
3073#if CONFIG_AVFILTER
3074 avfilter_register_all();
3075#endif
01310af2 3076 av_register_all();
776f2bb9 3077 avformat_network_init();
01310af2 3078
a5c33faa 3079 init_opts();
e43d7a18 3080
ea9c581f 3081 show_banner();
4cfac5bc 3082
7cc8d638 3083 parse_options(NULL, argc, argv, options, opt_input_file);
01310af2 3084
aab1b7e5 3085 if (!input_filename) {
7f11e745 3086 show_usage();
7a7da6b4 3087 fprintf(stderr, "An input file must be specified\n");
266463da 3088 fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
aab1b7e5
SS
3089 exit(1);
3090 }
01310af2
FB
3091
3092 if (display_disable) {
3093 video_disable = 1;
3094 }
31319a8c 3095 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
c97f5402
DB
3096#if !defined(__MINGW32__) && !defined(__APPLE__)
3097 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
31319a8c 3098#endif
01310af2 3099 if (SDL_Init (flags)) {
05ab0b76 3100 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
01310af2
FB
3101 exit(1);
3102 }
3103
3104 if (!display_disable) {
b250f9c6 3105#if HAVE_SDL_VIDEO_SIZE
3ef17d62
MR
3106 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3107 fs_screen_width = vi->current_w;
3108 fs_screen_height = vi->current_h;
29f3b38a 3109#endif
01310af2
FB
3110 }
3111
3112 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
01310af2
FB
3113 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3114 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3115
39c6a118 3116 av_init_packet(&flush_pkt);
da7c65f0 3117 flush_pkt.data = "FLUSH";
39c6a118 3118
638c9d91 3119 cur_stream = stream_open(input_filename, file_iformat);
01310af2
FB
3120
3121 event_loop();
3122
3123 /* never returns */
3124
3125 return 0;
3126}