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