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