fb99d9ad3e9dd8d03472ac9a2aea3d6810f00948
[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 if(screen && is->width == screen->w && screen->w == w
969 && is->height== screen->h && screen->h == h)
970 return 0;
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 printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1446 av_get_pict_type_char(src_frame->pict_type), pts, pts1);
1447 #endif
1448 return queue_picture(is, src_frame, pts, pos);
1449 }
1450
1451 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1452 {
1453 int len1, got_picture, i;
1454
1455 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1456 return -1;
1457
1458 if(pkt->data == flush_pkt.data){
1459 avcodec_flush_buffers(is->video_st->codec);
1460
1461 SDL_LockMutex(is->pictq_mutex);
1462 //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1463 for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1464 if(is->pictq[i].timer_id){
1465 SDL_RemoveTimer(is->pictq[i].timer_id);
1466 is->pictq[i].timer_id=0;
1467 schedule_refresh(is, 1);
1468 }
1469 }
1470 while (is->pictq_size && !is->videoq.abort_request) {
1471 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1472 }
1473 is->video_current_pos= -1;
1474 SDL_UnlockMutex(is->pictq_mutex);
1475
1476 is->last_dts_for_fault_detection=
1477 is->last_pts_for_fault_detection= INT64_MIN;
1478 is->frame_last_pts= AV_NOPTS_VALUE;
1479 is->frame_last_delay = 0;
1480 is->frame_timer = (double)av_gettime() / 1000000.0;
1481
1482 return 0;
1483 }
1484
1485 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1486 this packet, if any */
1487 is->video_st->codec->reordered_opaque= pkt->pts;
1488 len1 = avcodec_decode_video2(is->video_st->codec,
1489 frame, &got_picture,
1490 pkt);
1491
1492 if (got_picture) {
1493 if(pkt->dts != AV_NOPTS_VALUE){
1494 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1495 is->last_dts_for_fault_detection= pkt->dts;
1496 }
1497 if(frame->reordered_opaque != AV_NOPTS_VALUE){
1498 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1499 is->last_pts_for_fault_detection= frame->reordered_opaque;
1500 }
1501 }
1502
1503 if( ( decoder_reorder_pts==1
1504 || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1505 || pkt->dts == AV_NOPTS_VALUE)
1506 && frame->reordered_opaque != AV_NOPTS_VALUE)
1507 *pts= frame->reordered_opaque;
1508 else if(pkt->dts != AV_NOPTS_VALUE)
1509 *pts= pkt->dts;
1510 else
1511 *pts= 0;
1512
1513 // if (len1 < 0)
1514 // break;
1515 if (got_picture)
1516 return 1;
1517 return 0;
1518 }
1519
1520 #if CONFIG_AVFILTER
1521 typedef struct {
1522 VideoState *is;
1523 AVFrame *frame;
1524 } FilterPriv;
1525
1526 static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1527 {
1528 FilterPriv *priv = ctx->priv;
1529 if(!opaque) return -1;
1530
1531 priv->is = opaque;
1532 priv->frame = avcodec_alloc_frame();
1533
1534 return 0;
1535 }
1536
1537 static void input_uninit(AVFilterContext *ctx)
1538 {
1539 FilterPriv *priv = ctx->priv;
1540 av_free(priv->frame);
1541 }
1542
1543 static int input_request_frame(AVFilterLink *link)
1544 {
1545 FilterPriv *priv = link->src->priv;
1546 AVFilterPicRef *picref;
1547 int64_t pts = 0;
1548 AVPacket pkt;
1549 int ret;
1550
1551 while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1552 av_free_packet(&pkt);
1553 if (ret < 0)
1554 return -1;
1555
1556 /* FIXME: until I figure out how to hook everything up to the codec
1557 * right, we're just copying the entire frame. */
1558 picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1559 av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame,
1560 picref->pic->format, link->w, link->h);
1561 av_free_packet(&pkt);
1562
1563 picref->pts = pts;
1564 picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
1565 avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
1566 avfilter_draw_slice(link, 0, link->h, 1);
1567 avfilter_end_frame(link);
1568 avfilter_unref_pic(picref);
1569
1570 return 0;
1571 }
1572
1573 static int input_query_formats(AVFilterContext *ctx)
1574 {
1575 FilterPriv *priv = ctx->priv;
1576 enum PixelFormat pix_fmts[] = {
1577 priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1578 };
1579
1580 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1581 return 0;
1582 }
1583
1584 static int input_config_props(AVFilterLink *link)
1585 {
1586 FilterPriv *priv = link->src->priv;
1587 AVCodecContext *c = priv->is->video_st->codec;
1588
1589 link->w = c->width;
1590 link->h = c->height;
1591
1592 return 0;
1593 }
1594
1595 static AVFilter input_filter =
1596 {
1597 .name = "ffplay_input",
1598
1599 .priv_size = sizeof(FilterPriv),
1600
1601 .init = input_init,
1602 .uninit = input_uninit,
1603
1604 .query_formats = input_query_formats,
1605
1606 .inputs = (AVFilterPad[]) {{ .name = NULL }},
1607 .outputs = (AVFilterPad[]) {{ .name = "default",
1608 .type = CODEC_TYPE_VIDEO,
1609 .request_frame = input_request_frame,
1610 .config_props = input_config_props, },
1611 { .name = NULL }},
1612 };
1613
1614 static void output_end_frame(AVFilterLink *link)
1615 {
1616 }
1617
1618 static int output_query_formats(AVFilterContext *ctx)
1619 {
1620 enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
1621
1622 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1623 return 0;
1624 }
1625
1626 static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
1627 int64_t *pts)
1628 {
1629 AVFilterPicRef *pic;
1630
1631 if(avfilter_request_frame(ctx->inputs[0]))
1632 return -1;
1633 if(!(pic = ctx->inputs[0]->cur_pic))
1634 return -1;
1635 ctx->inputs[0]->cur_pic = NULL;
1636
1637 frame->opaque = pic;
1638 *pts = pic->pts;
1639
1640 memcpy(frame->data, pic->data, sizeof(frame->data));
1641 memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize));
1642
1643 return 1;
1644 }
1645
1646 static AVFilter output_filter =
1647 {
1648 .name = "ffplay_output",
1649
1650 .query_formats = output_query_formats,
1651
1652 .inputs = (AVFilterPad[]) {{ .name = "default",
1653 .type = CODEC_TYPE_VIDEO,
1654 .end_frame = output_end_frame,
1655 .min_perms = AV_PERM_READ, },
1656 { .name = NULL }},
1657 .outputs = (AVFilterPad[]) {{ .name = NULL }},
1658 };
1659 #endif /* CONFIG_AVFILTER */
1660
1661 static int video_thread(void *arg)
1662 {
1663 VideoState *is = arg;
1664 AVFrame *frame= avcodec_alloc_frame();
1665 int64_t pts_int;
1666 double pts;
1667 int ret;
1668
1669 #if CONFIG_AVFILTER
1670 AVFilterContext *filt_src = NULL, *filt_out = NULL;
1671 AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
1672 graph->scale_sws_opts = av_strdup("sws_flags=bilinear");
1673
1674 if(!(filt_src = avfilter_open(&input_filter, "src"))) goto the_end;
1675 if(!(filt_out = avfilter_open(&output_filter, "out"))) goto the_end;
1676
1677 if(avfilter_init_filter(filt_src, NULL, is)) goto the_end;
1678 if(avfilter_init_filter(filt_out, NULL, frame)) goto the_end;
1679
1680
1681 if(vfilters) {
1682 AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1683 AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
1684
1685 outputs->name = av_strdup("in");
1686 outputs->filter = filt_src;
1687 outputs->pad_idx = 0;
1688 outputs->next = NULL;
1689
1690 inputs->name = av_strdup("out");
1691 inputs->filter = filt_out;
1692 inputs->pad_idx = 0;
1693 inputs->next = NULL;
1694
1695 if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
1696 goto the_end;
1697 av_freep(&vfilters);
1698 } else {
1699 if(avfilter_link(filt_src, 0, filt_out, 0) < 0) goto the_end;
1700 }
1701 avfilter_graph_add_filter(graph, filt_src);
1702 avfilter_graph_add_filter(graph, filt_out);
1703
1704 if(avfilter_graph_check_validity(graph, NULL)) goto the_end;
1705 if(avfilter_graph_config_formats(graph, NULL)) goto the_end;
1706 if(avfilter_graph_config_links(graph, NULL)) goto the_end;
1707
1708 is->out_video_filter = filt_out;
1709 #endif
1710
1711 for(;;) {
1712 #if !CONFIG_AVFILTER
1713 AVPacket pkt;
1714 #endif
1715 while (is->paused && !is->videoq.abort_request)
1716 SDL_Delay(10);
1717 #if CONFIG_AVFILTER
1718 ret = get_filtered_video_frame(filt_out, frame, &pts_int);
1719 #else
1720 ret = get_video_frame(is, frame, &pts_int, &pkt);
1721 #endif
1722
1723 if (ret < 0) goto the_end;
1724
1725 if (!ret)
1726 continue;
1727
1728 pts = pts_int*av_q2d(is->video_st->time_base);
1729
1730 #if CONFIG_AVFILTER
1731 ret = output_picture2(is, frame, pts, -1); /* fixme: unknown pos */
1732 #else
1733 ret = output_picture2(is, frame, pts, pkt.pos);
1734 av_free_packet(&pkt);
1735 #endif
1736 if (ret < 0)
1737 goto the_end;
1738
1739 if (step)
1740 if (cur_stream)
1741 stream_pause(cur_stream);
1742 }
1743 the_end:
1744 #if CONFIG_AVFILTER
1745 avfilter_graph_destroy(graph);
1746 av_freep(&graph);
1747 #endif
1748 av_free(frame);
1749 return 0;
1750 }
1751
1752 static int subtitle_thread(void *arg)
1753 {
1754 VideoState *is = arg;
1755 SubPicture *sp;
1756 AVPacket pkt1, *pkt = &pkt1;
1757 int len1, got_subtitle;
1758 double pts;
1759 int i, j;
1760 int r, g, b, y, u, v, a;
1761
1762 for(;;) {
1763 while (is->paused && !is->subtitleq.abort_request) {
1764 SDL_Delay(10);
1765 }
1766 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1767 break;
1768
1769 if(pkt->data == flush_pkt.data){
1770 avcodec_flush_buffers(is->subtitle_st->codec);
1771 continue;
1772 }
1773 SDL_LockMutex(is->subpq_mutex);
1774 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1775 !is->subtitleq.abort_request) {
1776 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1777 }
1778 SDL_UnlockMutex(is->subpq_mutex);
1779
1780 if (is->subtitleq.abort_request)
1781 goto the_end;
1782
1783 sp = &is->subpq[is->subpq_windex];
1784
1785 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1786 this packet, if any */
1787 pts = 0;
1788 if (pkt->pts != AV_NOPTS_VALUE)
1789 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1790
1791 len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1792 &sp->sub, &got_subtitle,
1793 pkt);
1794 // if (len1 < 0)
1795 // break;
1796 if (got_subtitle && sp->sub.format == 0) {
1797 sp->pts = pts;
1798
1799 for (i = 0; i < sp->sub.num_rects; i++)
1800 {
1801 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1802 {
1803 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1804 y = RGB_TO_Y_CCIR(r, g, b);
1805 u = RGB_TO_U_CCIR(r, g, b, 0);
1806 v = RGB_TO_V_CCIR(r, g, b, 0);
1807 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1808 }
1809 }
1810
1811 /* now we can update the picture count */
1812 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1813 is->subpq_windex = 0;
1814 SDL_LockMutex(is->subpq_mutex);
1815 is->subpq_size++;
1816 SDL_UnlockMutex(is->subpq_mutex);
1817 }
1818 av_free_packet(pkt);
1819 // if (step)
1820 // if (cur_stream)
1821 // stream_pause(cur_stream);
1822 }
1823 the_end:
1824 return 0;
1825 }
1826
1827 /* copy samples for viewing in editor window */
1828 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1829 {
1830 int size, len, channels;
1831
1832 channels = is->audio_st->codec->channels;
1833
1834 size = samples_size / sizeof(short);
1835 while (size > 0) {
1836 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1837 if (len > size)
1838 len = size;
1839 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1840 samples += len;
1841 is->sample_array_index += len;
1842 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1843 is->sample_array_index = 0;
1844 size -= len;
1845 }
1846 }
1847
1848 /* return the new audio buffer size (samples can be added or deleted
1849 to get better sync if video or external master clock) */
1850 static int synchronize_audio(VideoState *is, short *samples,
1851 int samples_size1, double pts)
1852 {
1853 int n, samples_size;
1854 double ref_clock;
1855
1856 n = 2 * is->audio_st->codec->channels;
1857 samples_size = samples_size1;
1858
1859 /* if not master, then we try to remove or add samples to correct the clock */
1860 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1861 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1862 double diff, avg_diff;
1863 int wanted_size, min_size, max_size, nb_samples;
1864
1865 ref_clock = get_master_clock(is);
1866 diff = get_audio_clock(is) - ref_clock;
1867
1868 if (diff < AV_NOSYNC_THRESHOLD) {
1869 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1870 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1871 /* not enough measures to have a correct estimate */
1872 is->audio_diff_avg_count++;
1873 } else {
1874 /* estimate the A-V difference */
1875 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1876
1877 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1878 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1879 nb_samples = samples_size / n;
1880
1881 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1882 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1883 if (wanted_size < min_size)
1884 wanted_size = min_size;
1885 else if (wanted_size > max_size)
1886 wanted_size = max_size;
1887
1888 /* add or remove samples to correction the synchro */
1889 if (wanted_size < samples_size) {
1890 /* remove samples */
1891 samples_size = wanted_size;
1892 } else if (wanted_size > samples_size) {
1893 uint8_t *samples_end, *q;
1894 int nb;
1895
1896 /* add samples */
1897 nb = (samples_size - wanted_size);
1898 samples_end = (uint8_t *)samples + samples_size - n;
1899 q = samples_end + n;
1900 while (nb > 0) {
1901 memcpy(q, samples_end, n);
1902 q += n;
1903 nb -= n;
1904 }
1905 samples_size = wanted_size;
1906 }
1907 }
1908 #if 0
1909 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1910 diff, avg_diff, samples_size - samples_size1,
1911 is->audio_clock, is->video_clock, is->audio_diff_threshold);
1912 #endif
1913 }
1914 } else {
1915 /* too big difference : may be initial PTS errors, so
1916 reset A-V filter */
1917 is->audio_diff_avg_count = 0;
1918 is->audio_diff_cum = 0;
1919 }
1920 }
1921
1922 return samples_size;
1923 }
1924
1925 /* decode one audio frame and returns its uncompressed size */
1926 static int audio_decode_frame(VideoState *is, double *pts_ptr)
1927 {
1928 AVPacket *pkt_temp = &is->audio_pkt_temp;
1929 AVPacket *pkt = &is->audio_pkt;
1930 AVCodecContext *dec= is->audio_st->codec;
1931 int n, len1, data_size;
1932 double pts;
1933
1934 for(;;) {
1935 /* NOTE: the audio packet can contain several frames */
1936 while (pkt_temp->size > 0) {
1937 data_size = sizeof(is->audio_buf1);
1938 len1 = avcodec_decode_audio3(dec,
1939 (int16_t *)is->audio_buf1, &data_size,
1940 pkt_temp);
1941 if (len1 < 0) {
1942 /* if error, we skip the frame */
1943 pkt_temp->size = 0;
1944 break;
1945 }
1946
1947 pkt_temp->data += len1;
1948 pkt_temp->size -= len1;
1949 if (data_size <= 0)
1950 continue;
1951
1952 if (dec->sample_fmt != is->audio_src_fmt) {
1953 if (is->reformat_ctx)
1954 av_audio_convert_free(is->reformat_ctx);
1955 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1956 dec->sample_fmt, 1, NULL, 0);
1957 if (!is->reformat_ctx) {
1958 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1959 avcodec_get_sample_fmt_name(dec->sample_fmt),
1960 avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1961 break;
1962 }
1963 is->audio_src_fmt= dec->sample_fmt;
1964 }
1965
1966 if (is->reformat_ctx) {
1967 const void *ibuf[6]= {is->audio_buf1};
1968 void *obuf[6]= {is->audio_buf2};
1969 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1970 int ostride[6]= {2};
1971 int len= data_size/istride[0];
1972 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1973 printf("av_audio_convert() failed\n");
1974 break;
1975 }
1976 is->audio_buf= is->audio_buf2;
1977 /* FIXME: existing code assume that data_size equals framesize*channels*2
1978 remove this legacy cruft */
1979 data_size= len*2;
1980 }else{
1981 is->audio_buf= is->audio_buf1;
1982 }
1983
1984 /* if no pts, then compute it */
1985 pts = is->audio_clock;
1986 *pts_ptr = pts;
1987 n = 2 * dec->channels;
1988 is->audio_clock += (double)data_size /
1989 (double)(n * dec->sample_rate);
1990 #if defined(DEBUG_SYNC)
1991 {
1992 static double last_clock;
1993 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1994 is->audio_clock - last_clock,
1995 is->audio_clock, pts);
1996 last_clock = is->audio_clock;
1997 }
1998 #endif
1999 return data_size;
2000 }
2001
2002 /* free the current packet */
2003 if (pkt->data)
2004 av_free_packet(pkt);
2005
2006 if (is->paused || is->audioq.abort_request) {
2007 return -1;
2008 }
2009
2010 /* read next packet */
2011 if (packet_queue_get(&is->audioq, pkt, 1) < 0)
2012 return -1;
2013 if(pkt->data == flush_pkt.data){
2014 avcodec_flush_buffers(dec);
2015 continue;
2016 }
2017
2018 pkt_temp->data = pkt->data;
2019 pkt_temp->size = pkt->size;
2020
2021 /* if update the audio clock with the pts */
2022 if (pkt->pts != AV_NOPTS_VALUE) {
2023 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2024 }
2025 }
2026 }
2027
2028 /* get the current audio output buffer size, in samples. With SDL, we
2029 cannot have a precise information */
2030 static int audio_write_get_buf_size(VideoState *is)
2031 {
2032 return is->audio_buf_size - is->audio_buf_index;
2033 }
2034
2035
2036 /* prepare a new audio buffer */
2037 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2038 {
2039 VideoState *is = opaque;
2040 int audio_size, len1;
2041 double pts;
2042
2043 audio_callback_time = av_gettime();
2044
2045 while (len > 0) {
2046 if (is->audio_buf_index >= is->audio_buf_size) {
2047 audio_size = audio_decode_frame(is, &pts);
2048 if (audio_size < 0) {
2049 /* if error, just output silence */
2050 is->audio_buf = is->audio_buf1;
2051 is->audio_buf_size = 1024;
2052 memset(is->audio_buf, 0, is->audio_buf_size);
2053 } else {
2054 if (is->show_audio)
2055 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2056 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
2057 pts);
2058 is->audio_buf_size = audio_size;
2059 }
2060 is->audio_buf_index = 0;
2061 }
2062 len1 = is->audio_buf_size - is->audio_buf_index;
2063 if (len1 > len)
2064 len1 = len;
2065 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2066 len -= len1;
2067 stream += len1;
2068 is->audio_buf_index += len1;
2069 }
2070 }
2071
2072 /* open a given stream. Return 0 if OK */
2073 static int stream_component_open(VideoState *is, int stream_index)
2074 {
2075 AVFormatContext *ic = is->ic;
2076 AVCodecContext *avctx;
2077 AVCodec *codec;
2078 SDL_AudioSpec wanted_spec, spec;
2079
2080 if (stream_index < 0 || stream_index >= ic->nb_streams)
2081 return -1;
2082 avctx = ic->streams[stream_index]->codec;
2083
2084 /* prepare audio output */
2085 if (avctx->codec_type == CODEC_TYPE_AUDIO) {
2086 if (avctx->channels > 0) {
2087 avctx->request_channels = FFMIN(2, avctx->channels);
2088 } else {
2089 avctx->request_channels = 2;
2090 }
2091 }
2092
2093 codec = avcodec_find_decoder(avctx->codec_id);
2094 avctx->debug_mv = debug_mv;
2095 avctx->debug = debug;
2096 avctx->workaround_bugs = workaround_bugs;
2097 avctx->lowres = lowres;
2098 if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2099 avctx->idct_algo= idct;
2100 if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2101 avctx->skip_frame= skip_frame;
2102 avctx->skip_idct= skip_idct;
2103 avctx->skip_loop_filter= skip_loop_filter;
2104 avctx->error_recognition= error_recognition;
2105 avctx->error_concealment= error_concealment;
2106 avcodec_thread_init(avctx, thread_count);
2107
2108 set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0);
2109
2110 if (!codec ||
2111 avcodec_open(avctx, codec) < 0)
2112 return -1;
2113
2114 /* prepare audio output */
2115 if (avctx->codec_type == CODEC_TYPE_AUDIO) {
2116 wanted_spec.freq = avctx->sample_rate;
2117 wanted_spec.format = AUDIO_S16SYS;
2118 wanted_spec.channels = avctx->channels;
2119 wanted_spec.silence = 0;
2120 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2121 wanted_spec.callback = sdl_audio_callback;
2122 wanted_spec.userdata = is;
2123 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2124 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2125 return -1;
2126 }
2127 is->audio_hw_buf_size = spec.size;
2128 is->audio_src_fmt= SAMPLE_FMT_S16;
2129 }
2130
2131 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2132 switch(avctx->codec_type) {
2133 case CODEC_TYPE_AUDIO:
2134 is->audio_stream = stream_index;
2135 is->audio_st = ic->streams[stream_index];
2136 is->audio_buf_size = 0;
2137 is->audio_buf_index = 0;
2138
2139 /* init averaging filter */
2140 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2141 is->audio_diff_avg_count = 0;
2142 /* since we do not have a precise anough audio fifo fullness,
2143 we correct audio sync only if larger than this threshold */
2144 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
2145
2146 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2147 packet_queue_init(&is->audioq);
2148 SDL_PauseAudio(0);
2149 break;
2150 case CODEC_TYPE_VIDEO:
2151 is->video_stream = stream_index;
2152 is->video_st = ic->streams[stream_index];
2153
2154 // is->video_current_pts_time = av_gettime();
2155
2156 packet_queue_init(&is->videoq);
2157 is->video_tid = SDL_CreateThread(video_thread, is);
2158 break;
2159 case CODEC_TYPE_SUBTITLE:
2160 is->subtitle_stream = stream_index;
2161 is->subtitle_st = ic->streams[stream_index];
2162 packet_queue_init(&is->subtitleq);
2163
2164 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2165 break;
2166 default:
2167 break;
2168 }
2169 return 0;
2170 }
2171
2172 static void stream_component_close(VideoState *is, int stream_index)
2173 {
2174 AVFormatContext *ic = is->ic;
2175 AVCodecContext *avctx;
2176
2177 if (stream_index < 0 || stream_index >= ic->nb_streams)
2178 return;
2179 avctx = ic->streams[stream_index]->codec;
2180
2181 switch(avctx->codec_type) {
2182 case CODEC_TYPE_AUDIO:
2183 packet_queue_abort(&is->audioq);
2184
2185 SDL_CloseAudio();
2186
2187 packet_queue_end(&is->audioq);
2188 if (is->reformat_ctx)
2189 av_audio_convert_free(is->reformat_ctx);
2190 is->reformat_ctx = NULL;
2191 break;
2192 case CODEC_TYPE_VIDEO:
2193 packet_queue_abort(&is->videoq);
2194
2195 /* note: we also signal this mutex to make sure we deblock the
2196 video thread in all cases */
2197 SDL_LockMutex(is->pictq_mutex);
2198 SDL_CondSignal(is->pictq_cond);
2199 SDL_UnlockMutex(is->pictq_mutex);
2200
2201 SDL_WaitThread(is->video_tid, NULL);
2202
2203 packet_queue_end(&is->videoq);
2204 break;
2205 case CODEC_TYPE_SUBTITLE:
2206 packet_queue_abort(&is->subtitleq);
2207
2208 /* note: we also signal this mutex to make sure we deblock the
2209 video thread in all cases */
2210 SDL_LockMutex(is->subpq_mutex);
2211 is->subtitle_stream_changed = 1;
2212
2213 SDL_CondSignal(is->subpq_cond);
2214 SDL_UnlockMutex(is->subpq_mutex);
2215
2216 SDL_WaitThread(is->subtitle_tid, NULL);
2217
2218 packet_queue_end(&is->subtitleq);
2219 break;
2220 default:
2221 break;
2222 }
2223
2224 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2225 avcodec_close(avctx);
2226 switch(avctx->codec_type) {
2227 case CODEC_TYPE_AUDIO:
2228 is->audio_st = NULL;
2229 is->audio_stream = -1;
2230 break;
2231 case CODEC_TYPE_VIDEO:
2232 is->video_st = NULL;
2233 is->video_stream = -1;
2234 break;
2235 case CODEC_TYPE_SUBTITLE:
2236 is->subtitle_st = NULL;
2237 is->subtitle_stream = -1;
2238 break;
2239 default:
2240 break;
2241 }
2242 }
2243
2244 /* since we have only one decoding thread, we can use a global
2245 variable instead of a thread local variable */
2246 static VideoState *global_video_state;
2247
2248 static int decode_interrupt_cb(void)
2249 {
2250 return (global_video_state && global_video_state->abort_request);
2251 }
2252
2253 /* this thread gets the stream from the disk or the network */
2254 static int decode_thread(void *arg)
2255 {
2256 VideoState *is = arg;
2257 AVFormatContext *ic;
2258 int err, i, ret;
2259 int st_index[CODEC_TYPE_NB];
2260 int st_count[CODEC_TYPE_NB]={0};
2261 int st_best_packet_count[CODEC_TYPE_NB];
2262 AVPacket pkt1, *pkt = &pkt1;
2263 AVFormatParameters params, *ap = &params;
2264 int eof=0;
2265
2266 ic = avformat_alloc_context();
2267
2268 memset(st_index, -1, sizeof(st_index));
2269 memset(st_best_packet_count, -1, sizeof(st_best_packet_count));
2270 is->video_stream = -1;
2271 is->audio_stream = -1;
2272 is->subtitle_stream = -1;
2273
2274 global_video_state = is;
2275 url_set_interrupt_cb(decode_interrupt_cb);
2276
2277 memset(ap, 0, sizeof(*ap));
2278
2279 ap->prealloced_context = 1;
2280 ap->width = frame_width;
2281 ap->height= frame_height;
2282 ap->time_base= (AVRational){1, 25};
2283 ap->pix_fmt = frame_pix_fmt;
2284
2285 set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
2286
2287 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
2288 if (err < 0) {
2289 print_error(is->filename, err);
2290 ret = -1;
2291 goto fail;
2292 }
2293 is->ic = ic;
2294
2295 if(genpts)
2296 ic->flags |= AVFMT_FLAG_GENPTS;
2297
2298 err = av_find_stream_info(ic);
2299 if (err < 0) {
2300 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2301 ret = -1;
2302 goto fail;
2303 }
2304 if(ic->pb)
2305 ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
2306
2307 if(seek_by_bytes<0)
2308 seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2309
2310 /* if seeking requested, we execute it */
2311 if (start_time != AV_NOPTS_VALUE) {
2312 int64_t timestamp;
2313
2314 timestamp = start_time;
2315 /* add the stream start time */
2316 if (ic->start_time != AV_NOPTS_VALUE)
2317 timestamp += ic->start_time;
2318 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2319 if (ret < 0) {
2320 fprintf(stderr, "%s: could not seek to position %0.3f\n",
2321 is->filename, (double)timestamp / AV_TIME_BASE);
2322 }
2323 }
2324
2325 for(i = 0; i < ic->nb_streams; i++) {
2326 AVStream *st= ic->streams[i];
2327 AVCodecContext *avctx = st->codec;
2328 ic->streams[i]->discard = AVDISCARD_ALL;
2329 if(avctx->codec_type >= (unsigned)CODEC_TYPE_NB)
2330 continue;
2331 if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0)
2332 continue;
2333
2334 if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames)
2335 continue;
2336 st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames;
2337
2338 switch(avctx->codec_type) {
2339 case CODEC_TYPE_AUDIO:
2340 if (!audio_disable)
2341 st_index[CODEC_TYPE_AUDIO] = i;
2342 break;
2343 case CODEC_TYPE_VIDEO:
2344 case CODEC_TYPE_SUBTITLE:
2345 if (!video_disable)
2346 st_index[avctx->codec_type] = i;
2347 break;
2348 default:
2349 break;
2350 }
2351 }
2352 if (show_status) {
2353 dump_format(ic, 0, is->filename, 0);
2354 }
2355
2356 /* open the streams */
2357 if (st_index[CODEC_TYPE_AUDIO] >= 0) {
2358 stream_component_open(is, st_index[CODEC_TYPE_AUDIO]);
2359 }
2360
2361 ret=-1;
2362 if (st_index[CODEC_TYPE_VIDEO] >= 0) {
2363 ret= stream_component_open(is, st_index[CODEC_TYPE_VIDEO]);
2364 }
2365 if(ret<0) {
2366 /* add the refresh timer to draw the picture */
2367 schedule_refresh(is, 40);
2368
2369 if (!display_disable)
2370 is->show_audio = 2;
2371 }
2372
2373 if (st_index[CODEC_TYPE_SUBTITLE] >= 0) {
2374 stream_component_open(is, st_index[CODEC_TYPE_SUBTITLE]);
2375 }
2376
2377 if (is->video_stream < 0 && is->audio_stream < 0) {
2378 fprintf(stderr, "%s: could not open codecs\n", is->filename);
2379 ret = -1;
2380 goto fail;
2381 }
2382
2383 for(;;) {
2384 if (is->abort_request)
2385 break;
2386 if (is->paused != is->last_paused) {
2387 is->last_paused = is->paused;
2388 if (is->paused)
2389 is->read_pause_return= av_read_pause(ic);
2390 else
2391 av_read_play(ic);
2392 }
2393 #if CONFIG_RTSP_DEMUXER
2394 if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2395 /* wait 10 ms to avoid trying to get another packet */
2396 /* XXX: horrible */
2397 SDL_Delay(10);
2398 continue;
2399 }
2400 #endif
2401 if (is->seek_req) {
2402 int64_t seek_target= is->seek_pos;
2403 int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2404 int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2405 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2406 // of the seek_pos/seek_rel variables
2407
2408 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2409 if (ret < 0) {
2410 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2411 }else{
2412 if (is->audio_stream >= 0) {
2413 packet_queue_flush(&is->audioq);
2414 packet_queue_put(&is->audioq, &flush_pkt);
2415 }
2416 if (is->subtitle_stream >= 0) {
2417 packet_queue_flush(&is->subtitleq);
2418 packet_queue_put(&is->subtitleq, &flush_pkt);
2419 }
2420 if (is->video_stream >= 0) {
2421 packet_queue_flush(&is->videoq);
2422 packet_queue_put(&is->videoq, &flush_pkt);
2423 }
2424 }
2425 is->seek_req = 0;
2426 eof= 0;
2427 }
2428
2429 /* if the queue are full, no need to read more */
2430 if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2431 || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2432 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0)
2433 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2434 /* wait 10 ms */
2435 SDL_Delay(10);
2436 continue;
2437 }
2438 if(url_feof(ic->pb) || eof) {
2439 if(is->video_stream >= 0){
2440 av_init_packet(pkt);
2441 pkt->data=NULL;
2442 pkt->size=0;
2443 pkt->stream_index= is->video_stream;
2444 packet_queue_put(&is->videoq, pkt);
2445 }
2446 SDL_Delay(10);
2447 if(autoexit && is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
2448 ret=AVERROR_EOF;
2449 goto fail;
2450 }
2451 continue;
2452 }
2453 ret = av_read_frame(ic, pkt);
2454 if (ret < 0) {
2455 if (ret == AVERROR_EOF)
2456 eof=1;
2457 if (url_ferror(ic->pb))
2458 break;
2459 SDL_Delay(100); /* wait for user event */
2460 continue;
2461 }
2462 if (pkt->stream_index == is->audio_stream) {
2463 packet_queue_put(&is->audioq, pkt);
2464 } else if (pkt->stream_index == is->video_stream) {
2465 packet_queue_put(&is->videoq, pkt);
2466 } else if (pkt->stream_index == is->subtitle_stream) {
2467 packet_queue_put(&is->subtitleq, pkt);
2468 } else {
2469 av_free_packet(pkt);
2470 }
2471 }
2472 /* wait until the end */
2473 while (!is->abort_request) {
2474 SDL_Delay(100);
2475 }
2476
2477 ret = 0;
2478 fail:
2479 /* disable interrupting */
2480 global_video_state = NULL;
2481
2482 /* close each stream */
2483 if (is->audio_stream >= 0)
2484 stream_component_close(is, is->audio_stream);
2485 if (is->video_stream >= 0)
2486 stream_component_close(is, is->video_stream);
2487 if (is->subtitle_stream >= 0)
2488 stream_component_close(is, is->subtitle_stream);
2489 if (is->ic) {
2490 av_close_input_file(is->ic);
2491 is->ic = NULL; /* safety */
2492 }
2493 url_set_interrupt_cb(NULL);
2494
2495 if (ret != 0) {
2496 SDL_Event event;
2497
2498 event.type = FF_QUIT_EVENT;
2499 event.user.data1 = is;
2500 SDL_PushEvent(&event);
2501 }
2502 return 0;
2503 }
2504
2505 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2506 {
2507 VideoState *is;
2508
2509 is = av_mallocz(sizeof(VideoState));
2510 if (!is)
2511 return NULL;
2512 av_strlcpy(is->filename, filename, sizeof(is->filename));
2513 is->iformat = iformat;
2514 is->ytop = 0;
2515 is->xleft = 0;
2516
2517 /* start video display */
2518 is->pictq_mutex = SDL_CreateMutex();
2519 is->pictq_cond = SDL_CreateCond();
2520
2521 is->subpq_mutex = SDL_CreateMutex();
2522 is->subpq_cond = SDL_CreateCond();
2523
2524 is->av_sync_type = av_sync_type;
2525 is->parse_tid = SDL_CreateThread(decode_thread, is);
2526 if (!is->parse_tid) {
2527 av_free(is);
2528 return NULL;
2529 }
2530 return is;
2531 }
2532
2533 static void stream_close(VideoState *is)
2534 {
2535 VideoPicture *vp;
2536 int i;
2537 /* XXX: use a special url_shutdown call to abort parse cleanly */
2538 is->abort_request = 1;
2539 SDL_WaitThread(is->parse_tid, NULL);
2540
2541 /* free all pictures */
2542 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2543 vp = &is->pictq[i];
2544 #if CONFIG_AVFILTER
2545 if (vp->picref) {
2546 avfilter_unref_pic(vp->picref);
2547 vp->picref = NULL;
2548 }
2549 #endif
2550 if (vp->bmp) {
2551 SDL_FreeYUVOverlay(vp->bmp);
2552 vp->bmp = NULL;
2553 }
2554 }
2555 SDL_DestroyMutex(is->pictq_mutex);
2556 SDL_DestroyCond(is->pictq_cond);
2557 SDL_DestroyMutex(is->subpq_mutex);
2558 SDL_DestroyCond(is->subpq_cond);
2559 #if !CONFIG_AVFILTER
2560 if (is->img_convert_ctx)
2561 sws_freeContext(is->img_convert_ctx);
2562 #endif
2563 av_free(is);
2564 }
2565
2566 static void stream_cycle_channel(VideoState *is, int codec_type)
2567 {
2568 AVFormatContext *ic = is->ic;
2569 int start_index, stream_index;
2570 AVStream *st;
2571
2572 if (codec_type == CODEC_TYPE_VIDEO)
2573 start_index = is->video_stream;
2574 else if (codec_type == CODEC_TYPE_AUDIO)
2575 start_index = is->audio_stream;
2576 else
2577 start_index = is->subtitle_stream;
2578 if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2579 return;
2580 stream_index = start_index;
2581 for(;;) {
2582 if (++stream_index >= is->ic->nb_streams)
2583 {
2584 if (codec_type == CODEC_TYPE_SUBTITLE)
2585 {
2586 stream_index = -1;
2587 goto the_end;
2588 } else
2589 stream_index = 0;
2590 }
2591 if (stream_index == start_index)
2592 return;
2593 st = ic->streams[stream_index];
2594 if (st->codec->codec_type == codec_type) {
2595 /* check that parameters are OK */
2596 switch(codec_type) {
2597 case CODEC_TYPE_AUDIO:
2598 if (st->codec->sample_rate != 0 &&
2599 st->codec->channels != 0)
2600 goto the_end;
2601 break;
2602 case CODEC_TYPE_VIDEO:
2603 case CODEC_TYPE_SUBTITLE:
2604 goto the_end;
2605 default:
2606 break;
2607 }
2608 }
2609 }
2610 the_end:
2611 stream_component_close(is, start_index);
2612 stream_component_open(is, stream_index);
2613 }
2614
2615
2616 static void toggle_full_screen(void)
2617 {
2618 is_full_screen = !is_full_screen;
2619 if (!fs_screen_width) {
2620 /* use default SDL method */
2621 // SDL_WM_ToggleFullScreen(screen);
2622 }
2623 video_open(cur_stream);
2624 }
2625
2626 static void toggle_pause(void)
2627 {
2628 if (cur_stream)
2629 stream_pause(cur_stream);
2630 step = 0;
2631 }
2632
2633 static void step_to_next_frame(void)
2634 {
2635 if (cur_stream) {
2636 /* if the stream is paused unpause it, then step */
2637 if (cur_stream->paused)
2638 stream_pause(cur_stream);
2639 }
2640 step = 1;
2641 }
2642
2643 static void do_exit(void)
2644 {
2645 int i;
2646 if (cur_stream) {
2647 stream_close(cur_stream);
2648 cur_stream = NULL;
2649 }
2650 for (i = 0; i < CODEC_TYPE_NB; i++)
2651 av_free(avcodec_opts[i]);
2652 av_free(avformat_opts);
2653 av_free(sws_opts);
2654 #if CONFIG_AVFILTER
2655 avfilter_uninit();
2656 #endif
2657 if (show_status)
2658 printf("\n");
2659 SDL_Quit();
2660 exit(0);
2661 }
2662
2663 static void toggle_audio_display(void)
2664 {
2665 if (cur_stream) {
2666 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2667 cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
2668 fill_rectangle(screen,
2669 cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2670 bgcolor);
2671 SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
2672 }
2673 }
2674
2675 /* handle an event sent by the GUI */
2676 static void event_loop(void)
2677 {
2678 SDL_Event event;
2679 double incr, pos, frac;
2680
2681 for(;;) {
2682 double x;
2683 SDL_WaitEvent(&event);
2684 switch(event.type) {
2685 case SDL_KEYDOWN:
2686 switch(event.key.keysym.sym) {
2687 case SDLK_ESCAPE:
2688 case SDLK_q:
2689 do_exit();
2690 break;
2691 case SDLK_f:
2692 toggle_full_screen();
2693 break;
2694 case SDLK_p:
2695 case SDLK_SPACE:
2696 toggle_pause();
2697 break;
2698 case SDLK_s: //S: Step to next frame
2699 step_to_next_frame();
2700 break;
2701 case SDLK_a:
2702 if (cur_stream)
2703 stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2704 break;
2705 case SDLK_v:
2706 if (cur_stream)
2707 stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2708 break;
2709 case SDLK_t:
2710 if (cur_stream)
2711 stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2712 break;
2713 case SDLK_w:
2714 toggle_audio_display();
2715 break;
2716 case SDLK_LEFT:
2717 incr = -10.0;
2718 goto do_seek;
2719 case SDLK_RIGHT:
2720 incr = 10.0;
2721 goto do_seek;
2722 case SDLK_UP:
2723 incr = 60.0;
2724 goto do_seek;
2725 case SDLK_DOWN:
2726 incr = -60.0;
2727 do_seek:
2728 if (cur_stream) {
2729 if (seek_by_bytes) {
2730 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2731 pos= cur_stream->video_current_pos;
2732 }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2733 pos= cur_stream->audio_pkt.pos;
2734 }else
2735 pos = url_ftell(cur_stream->ic->pb);
2736 if (cur_stream->ic->bit_rate)
2737 incr *= cur_stream->ic->bit_rate / 8.0;
2738 else
2739 incr *= 180000.0;
2740 pos += incr;
2741 stream_seek(cur_stream, pos, incr, 1);
2742 } else {
2743 pos = get_master_clock(cur_stream);
2744 pos += incr;
2745 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2746 }
2747 }
2748 break;
2749 default:
2750 break;
2751 }
2752 break;
2753 case SDL_MOUSEBUTTONDOWN:
2754 case SDL_MOUSEMOTION:
2755 if(event.type ==SDL_MOUSEBUTTONDOWN){
2756 x= event.button.x;
2757 }else{
2758 if(event.motion.state != SDL_PRESSED)
2759 break;
2760 x= event.motion.x;
2761 }
2762 if (cur_stream) {
2763 if(seek_by_bytes || cur_stream->ic->duration<=0){
2764 uint64_t size= url_fsize(cur_stream->ic->pb);
2765 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2766 }else{
2767 int64_t ts;
2768 int ns, hh, mm, ss;
2769 int tns, thh, tmm, tss;
2770 tns = cur_stream->ic->duration/1000000LL;
2771 thh = tns/3600;
2772 tmm = (tns%3600)/60;
2773 tss = (tns%60);
2774 frac = x/cur_stream->width;
2775 ns = frac*tns;
2776 hh = ns/3600;
2777 mm = (ns%3600)/60;
2778 ss = (ns%60);
2779 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2780 hh, mm, ss, thh, tmm, tss);
2781 ts = frac*cur_stream->ic->duration;
2782 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2783 ts += cur_stream->ic->start_time;
2784 stream_seek(cur_stream, ts, 0, 0);
2785 }
2786 }
2787 break;
2788 case SDL_VIDEORESIZE:
2789 if (cur_stream) {
2790 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2791 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2792 screen_width = cur_stream->width = event.resize.w;
2793 screen_height= cur_stream->height= event.resize.h;
2794 }
2795 break;
2796 case SDL_QUIT:
2797 case FF_QUIT_EVENT:
2798 do_exit();
2799 break;
2800 case FF_ALLOC_EVENT:
2801 video_open(event.user.data1);
2802 alloc_picture(event.user.data1);
2803 break;
2804 case FF_REFRESH_EVENT:
2805 video_refresh_timer(event.user.data1);
2806 break;
2807 default:
2808 break;
2809 }
2810 }
2811 }
2812
2813 static void opt_frame_size(const char *arg)
2814 {
2815 if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2816 fprintf(stderr, "Incorrect frame size\n");
2817 exit(1);
2818 }
2819 if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2820 fprintf(stderr, "Frame size must be a multiple of 2\n");
2821 exit(1);
2822 }
2823 }
2824
2825 static int opt_width(const char *opt, const char *arg)
2826 {
2827 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2828 return 0;
2829 }
2830
2831 static int opt_height(const char *opt, const char *arg)
2832 {
2833 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2834 return 0;
2835 }
2836
2837 static void opt_format(const char *arg)
2838 {
2839 file_iformat = av_find_input_format(arg);
2840 if (!file_iformat) {
2841 fprintf(stderr, "Unknown input format: %s\n", arg);
2842 exit(1);
2843 }
2844 }
2845
2846 static void opt_frame_pix_fmt(const char *arg)
2847 {
2848 frame_pix_fmt = av_get_pix_fmt(arg);
2849 }
2850
2851 static int opt_sync(const char *opt, const char *arg)
2852 {
2853 if (!strcmp(arg, "audio"))
2854 av_sync_type = AV_SYNC_AUDIO_MASTER;
2855 else if (!strcmp(arg, "video"))
2856 av_sync_type = AV_SYNC_VIDEO_MASTER;
2857 else if (!strcmp(arg, "ext"))
2858 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2859 else {
2860 fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2861 exit(1);
2862 }
2863 return 0;
2864 }
2865
2866 static int opt_seek(const char *opt, const char *arg)
2867 {
2868 start_time = parse_time_or_die(opt, arg, 1);
2869 return 0;
2870 }
2871
2872 static int opt_debug(const char *opt, const char *arg)
2873 {
2874 av_log_set_level(99);
2875 debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2876 return 0;
2877 }
2878
2879 static int opt_vismv(const char *opt, const char *arg)
2880 {
2881 debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2882 return 0;
2883 }
2884
2885 static int opt_thread_count(const char *opt, const char *arg)
2886 {
2887 thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2888 #if !HAVE_THREADS
2889 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2890 #endif
2891 return 0;
2892 }
2893
2894 static const OptionDef options[] = {
2895 #include "cmdutils_common_opts.h"
2896 { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2897 { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2898 { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2899 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2900 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2901 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2902 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
2903 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
2904 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
2905 { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2906 { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
2907 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2908 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2909 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2910 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2911 { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2912 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2913 { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2914 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2915 { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2916 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2917 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2918 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2919 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2920 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2921 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
2922 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" },
2923 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
2924 { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2925 { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2926 { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
2927 #if CONFIG_AVFILTER
2928 { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
2929 #endif
2930 { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2931 { NULL, },
2932 };
2933
2934 static void show_usage(void)
2935 {
2936 printf("Simple media player\n");
2937 printf("usage: ffplay [options] input_file\n");
2938 printf("\n");
2939 }
2940
2941 static void show_help(void)
2942 {
2943 show_usage();
2944 show_help_options(options, "Main options:\n",
2945 OPT_EXPERT, 0);
2946 show_help_options(options, "\nAdvanced options:\n",
2947 OPT_EXPERT, OPT_EXPERT);
2948 printf("\nWhile playing:\n"
2949 "q, ESC quit\n"
2950 "f toggle full screen\n"
2951 "p, SPC pause\n"
2952 "a cycle audio channel\n"
2953 "v cycle video channel\n"
2954 "t cycle subtitle channel\n"
2955 "w show audio waves\n"
2956 "left/right seek backward/forward 10 seconds\n"
2957 "down/up seek backward/forward 1 minute\n"
2958 "mouse click seek to percentage in file corresponding to fraction of width\n"
2959 );
2960 }
2961
2962 static void opt_input_file(const char *filename)
2963 {
2964 if (input_filename) {
2965 fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
2966 filename, input_filename);
2967 exit(1);
2968 }
2969 if (!strcmp(filename, "-"))
2970 filename = "pipe:";
2971 input_filename = filename;
2972 }
2973
2974 /* Called from the main */
2975 int main(int argc, char **argv)
2976 {
2977 int flags, i;
2978
2979 /* register all codecs, demux and protocols */
2980 avcodec_register_all();
2981 avdevice_register_all();
2982 #if CONFIG_AVFILTER
2983 avfilter_register_all();
2984 #endif
2985 av_register_all();
2986
2987 for(i=0; i<CODEC_TYPE_NB; i++){
2988 avcodec_opts[i]= avcodec_alloc_context2(i);
2989 }
2990 avformat_opts = avformat_alloc_context();
2991 #if !CONFIG_AVFILTER
2992 sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2993 #endif
2994
2995 show_banner();
2996
2997 parse_options(argc, argv, options, opt_input_file);
2998
2999 if (!input_filename) {
3000 show_usage();
3001 fprintf(stderr, "An input file must be specified\n");
3002 fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
3003 exit(1);
3004 }
3005
3006 if (display_disable) {
3007 video_disable = 1;
3008 }
3009 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3010 #if !defined(__MINGW32__) && !defined(__APPLE__)
3011 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3012 #endif
3013 if (SDL_Init (flags)) {
3014 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3015 exit(1);
3016 }
3017
3018 if (!display_disable) {
3019 #if HAVE_SDL_VIDEO_SIZE
3020 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3021 fs_screen_width = vi->current_w;
3022 fs_screen_height = vi->current_h;
3023 #endif
3024 }
3025
3026 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3027 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3028 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3029
3030 av_init_packet(&flush_pkt);
3031 flush_pkt.data= "FLUSH";
3032
3033 cur_stream = stream_open(input_filename, file_iformat);
3034
3035 event_loop();
3036
3037 /* never returns */
3038
3039 return 0;
3040 }