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