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