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