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