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