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