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