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