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