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