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