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