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