fate: drop pointless _audio and _video suffixes from xan tests
[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 int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
879 int w,h;
880
881 if(is_full_screen) flags |= SDL_FULLSCREEN;
882 else flags |= SDL_RESIZABLE;
883
884 if (is_full_screen && fs_screen_width) {
885 w = fs_screen_width;
886 h = fs_screen_height;
887 } else if(!is_full_screen && screen_width){
888 w = screen_width;
889 h = screen_height;
890 #if CONFIG_AVFILTER
891 }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
892 w = is->out_video_filter->inputs[0]->w;
893 h = is->out_video_filter->inputs[0]->h;
894 #else
895 }else if (is->video_st && is->video_st->codec->width){
896 w = is->video_st->codec->width;
897 h = is->video_st->codec->height;
898 #endif
899 } else {
900 w = 640;
901 h = 480;
902 }
903 if(screen && is->width == screen->w && screen->w == w
904 && is->height== screen->h && screen->h == h)
905 return 0;
906
907 #if defined(__APPLE__) && !SDL_VERSION_ATLEAST(1, 2, 14)
908 /* setting bits_per_pixel = 0 or 32 causes blank video on OS X and older SDL */
909 screen = SDL_SetVideoMode(w, h, 24, flags);
910 #else
911 screen = SDL_SetVideoMode(w, h, 0, flags);
912 #endif
913 if (!screen) {
914 fprintf(stderr, "SDL: could not set video mode - exiting\n");
915 return -1;
916 }
917 if (!window_title)
918 window_title = input_filename;
919 SDL_WM_SetCaption(window_title, window_title);
920
921 is->width = screen->w;
922 is->height = screen->h;
923
924 return 0;
925 }
926
927 /* display the current picture, if any */
928 static void video_display(VideoState *is)
929 {
930 if(!screen)
931 video_open(cur_stream);
932 if (is->audio_st && is->show_audio)
933 video_audio_display(is);
934 else if (is->video_st)
935 video_image_display(is);
936 }
937
938 static int refresh_thread(void *opaque)
939 {
940 VideoState *is= opaque;
941 while(!is->abort_request){
942 SDL_Event event;
943 event.type = FF_REFRESH_EVENT;
944 event.user.data1 = opaque;
945 if(!is->refresh){
946 is->refresh=1;
947 SDL_PushEvent(&event);
948 }
949 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
950 }
951 return 0;
952 }
953
954 /* get the current audio clock value */
955 static double get_audio_clock(VideoState *is)
956 {
957 double pts;
958 int hw_buf_size, bytes_per_sec;
959 pts = is->audio_clock;
960 hw_buf_size = audio_write_get_buf_size(is);
961 bytes_per_sec = 0;
962 if (is->audio_st) {
963 bytes_per_sec = is->audio_st->codec->sample_rate *
964 2 * is->audio_st->codec->channels;
965 }
966 if (bytes_per_sec)
967 pts -= (double)hw_buf_size / bytes_per_sec;
968 return pts;
969 }
970
971 /* get the current video clock value */
972 static double get_video_clock(VideoState *is)
973 {
974 if (is->paused) {
975 return is->video_current_pts;
976 } else {
977 return is->video_current_pts_drift + av_gettime() / 1000000.0;
978 }
979 }
980
981 /* get the current external clock value */
982 static double get_external_clock(VideoState *is)
983 {
984 int64_t ti;
985 ti = av_gettime();
986 return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
987 }
988
989 /* get the current master clock value */
990 static double get_master_clock(VideoState *is)
991 {
992 double val;
993
994 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
995 if (is->video_st)
996 val = get_video_clock(is);
997 else
998 val = get_audio_clock(is);
999 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1000 if (is->audio_st)
1001 val = get_audio_clock(is);
1002 else
1003 val = get_video_clock(is);
1004 } else {
1005 val = get_external_clock(is);
1006 }
1007 return val;
1008 }
1009
1010 /* seek in the stream */
1011 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1012 {
1013 if (!is->seek_req) {
1014 is->seek_pos = pos;
1015 is->seek_rel = rel;
1016 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1017 if (seek_by_bytes)
1018 is->seek_flags |= AVSEEK_FLAG_BYTE;
1019 is->seek_req = 1;
1020 }
1021 }
1022
1023 /* pause or resume the video */
1024 static void stream_pause(VideoState *is)
1025 {
1026 if (is->paused) {
1027 is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1028 if(is->read_pause_return != AVERROR(ENOSYS)){
1029 is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1030 }
1031 is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1032 }
1033 is->paused = !is->paused;
1034 }
1035
1036 static double compute_target_time(double frame_current_pts, VideoState *is)
1037 {
1038 double delay, sync_threshold, diff;
1039
1040 /* compute nominal delay */
1041 delay = frame_current_pts - is->frame_last_pts;
1042 if (delay <= 0 || delay >= 10.0) {
1043 /* if incorrect delay, use previous one */
1044 delay = is->frame_last_delay;
1045 } else {
1046 is->frame_last_delay = delay;
1047 }
1048 is->frame_last_pts = frame_current_pts;
1049
1050 /* update delay to follow master synchronisation source */
1051 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1052 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1053 /* if video is slave, we try to correct big delays by
1054 duplicating or deleting a frame */
1055 diff = get_video_clock(is) - get_master_clock(is);
1056
1057 /* skip or repeat frame. We take into account the
1058 delay to compute the threshold. I still don't know
1059 if it is the best guess */
1060 sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1061 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1062 if (diff <= -sync_threshold)
1063 delay = 0;
1064 else if (diff >= sync_threshold)
1065 delay = 2 * delay;
1066 }
1067 }
1068 is->frame_timer += delay;
1069
1070 av_dlog(NULL, "video: delay=%0.3f pts=%0.3f A-V=%f\n",
1071 delay, frame_current_pts, -diff);
1072
1073 return is->frame_timer;
1074 }
1075
1076 /* called to display each frame */
1077 static void video_refresh_timer(void *opaque)
1078 {
1079 VideoState *is = opaque;
1080 VideoPicture *vp;
1081
1082 SubPicture *sp, *sp2;
1083
1084 if (is->video_st) {
1085 retry:
1086 if (is->pictq_size == 0) {
1087 //nothing to do, no picture to display in the que
1088 } else {
1089 double time= av_gettime()/1000000.0;
1090 double next_target;
1091 /* dequeue the picture */
1092 vp = &is->pictq[is->pictq_rindex];
1093
1094 if(time < vp->target_clock)
1095 return;
1096 /* update current video pts */
1097 is->video_current_pts = vp->pts;
1098 is->video_current_pts_drift = is->video_current_pts - time;
1099 is->video_current_pos = vp->pos;
1100 if(is->pictq_size > 1){
1101 VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
1102 assert(nextvp->target_clock >= vp->target_clock);
1103 next_target= nextvp->target_clock;
1104 }else{
1105 next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
1106 }
1107 if(framedrop && time > next_target){
1108 is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
1109 if(is->pictq_size > 1 || time > next_target + 0.5){
1110 /* update queue size and signal for next picture */
1111 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1112 is->pictq_rindex = 0;
1113
1114 SDL_LockMutex(is->pictq_mutex);
1115 is->pictq_size--;
1116 SDL_CondSignal(is->pictq_cond);
1117 SDL_UnlockMutex(is->pictq_mutex);
1118 goto retry;
1119 }
1120 }
1121
1122 if(is->subtitle_st) {
1123 if (is->subtitle_stream_changed) {
1124 SDL_LockMutex(is->subpq_mutex);
1125
1126 while (is->subpq_size) {
1127 free_subpicture(&is->subpq[is->subpq_rindex]);
1128
1129 /* update queue size and signal for next picture */
1130 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1131 is->subpq_rindex = 0;
1132
1133 is->subpq_size--;
1134 }
1135 is->subtitle_stream_changed = 0;
1136
1137 SDL_CondSignal(is->subpq_cond);
1138 SDL_UnlockMutex(is->subpq_mutex);
1139 } else {
1140 if (is->subpq_size > 0) {
1141 sp = &is->subpq[is->subpq_rindex];
1142
1143 if (is->subpq_size > 1)
1144 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1145 else
1146 sp2 = NULL;
1147
1148 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1149 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1150 {
1151 free_subpicture(sp);
1152
1153 /* update queue size and signal for next picture */
1154 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1155 is->subpq_rindex = 0;
1156
1157 SDL_LockMutex(is->subpq_mutex);
1158 is->subpq_size--;
1159 SDL_CondSignal(is->subpq_cond);
1160 SDL_UnlockMutex(is->subpq_mutex);
1161 }
1162 }
1163 }
1164 }
1165
1166 /* display picture */
1167 if (!display_disable)
1168 video_display(is);
1169
1170 /* update queue size and signal for next picture */
1171 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1172 is->pictq_rindex = 0;
1173
1174 SDL_LockMutex(is->pictq_mutex);
1175 is->pictq_size--;
1176 SDL_CondSignal(is->pictq_cond);
1177 SDL_UnlockMutex(is->pictq_mutex);
1178 }
1179 } else if (is->audio_st) {
1180 /* draw the next audio frame */
1181
1182 /* if only audio stream, then display the audio bars (better
1183 than nothing, just to test the implementation */
1184
1185 /* display picture */
1186 if (!display_disable)
1187 video_display(is);
1188 }
1189 if (show_status) {
1190 static int64_t last_time;
1191 int64_t cur_time;
1192 int aqsize, vqsize, sqsize;
1193 double av_diff;
1194
1195 cur_time = av_gettime();
1196 if (!last_time || (cur_time - last_time) >= 30000) {
1197 aqsize = 0;
1198 vqsize = 0;
1199 sqsize = 0;
1200 if (is->audio_st)
1201 aqsize = is->audioq.size;
1202 if (is->video_st)
1203 vqsize = is->videoq.size;
1204 if (is->subtitle_st)
1205 sqsize = is->subtitleq.size;
1206 av_diff = 0;
1207 if (is->audio_st && is->video_st)
1208 av_diff = get_audio_clock(is) - get_video_clock(is);
1209 printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1210 get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
1211 fflush(stdout);
1212 last_time = cur_time;
1213 }
1214 }
1215 }
1216
1217 static void stream_close(VideoState *is)
1218 {
1219 VideoPicture *vp;
1220 int i;
1221 /* XXX: use a special url_shutdown call to abort parse cleanly */
1222 is->abort_request = 1;
1223 SDL_WaitThread(is->parse_tid, NULL);
1224 SDL_WaitThread(is->refresh_tid, NULL);
1225
1226 /* free all pictures */
1227 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
1228 vp = &is->pictq[i];
1229 #if CONFIG_AVFILTER
1230 if (vp->picref) {
1231 avfilter_unref_buffer(vp->picref);
1232 vp->picref = NULL;
1233 }
1234 #endif
1235 if (vp->bmp) {
1236 SDL_FreeYUVOverlay(vp->bmp);
1237 vp->bmp = NULL;
1238 }
1239 }
1240 SDL_DestroyMutex(is->pictq_mutex);
1241 SDL_DestroyCond(is->pictq_cond);
1242 SDL_DestroyMutex(is->subpq_mutex);
1243 SDL_DestroyCond(is->subpq_cond);
1244 #if !CONFIG_AVFILTER
1245 if (is->img_convert_ctx)
1246 sws_freeContext(is->img_convert_ctx);
1247 #endif
1248 av_free(is);
1249 }
1250
1251 static void do_exit(void)
1252 {
1253 if (cur_stream) {
1254 stream_close(cur_stream);
1255 cur_stream = NULL;
1256 }
1257 uninit_opts();
1258 #if CONFIG_AVFILTER
1259 avfilter_uninit();
1260 #endif
1261 avformat_network_deinit();
1262 if (show_status)
1263 printf("\n");
1264 SDL_Quit();
1265 av_log(NULL, AV_LOG_QUIET, "");
1266 exit(0);
1267 }
1268
1269 /* allocate a picture (needs to do that in main thread to avoid
1270 potential locking problems */
1271 static void alloc_picture(void *opaque)
1272 {
1273 VideoState *is = opaque;
1274 VideoPicture *vp;
1275
1276 vp = &is->pictq[is->pictq_windex];
1277
1278 if (vp->bmp)
1279 SDL_FreeYUVOverlay(vp->bmp);
1280
1281 #if CONFIG_AVFILTER
1282 if (vp->picref)
1283 avfilter_unref_buffer(vp->picref);
1284 vp->picref = NULL;
1285
1286 vp->width = is->out_video_filter->inputs[0]->w;
1287 vp->height = is->out_video_filter->inputs[0]->h;
1288 vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1289 #else
1290 vp->width = is->video_st->codec->width;
1291 vp->height = is->video_st->codec->height;
1292 vp->pix_fmt = is->video_st->codec->pix_fmt;
1293 #endif
1294
1295 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1296 SDL_YV12_OVERLAY,
1297 screen);
1298 if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1299 /* SDL allocates a buffer smaller than requested if the video
1300 * overlay hardware is unable to support the requested size. */
1301 fprintf(stderr, "Error: the video system does not support an image\n"
1302 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1303 "to reduce the image size.\n", vp->width, vp->height );
1304 do_exit();
1305 }
1306
1307 SDL_LockMutex(is->pictq_mutex);
1308 vp->allocated = 1;
1309 SDL_CondSignal(is->pictq_cond);
1310 SDL_UnlockMutex(is->pictq_mutex);
1311 }
1312
1313 /**
1314 *
1315 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1316 */
1317 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
1318 {
1319 VideoPicture *vp;
1320 #if CONFIG_AVFILTER
1321 AVPicture pict_src;
1322 #else
1323 int dst_pix_fmt = PIX_FMT_YUV420P;
1324 #endif
1325 /* wait until we have space to put a new picture */
1326 SDL_LockMutex(is->pictq_mutex);
1327
1328 if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
1329 is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
1330
1331 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1332 !is->videoq.abort_request) {
1333 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1334 }
1335 SDL_UnlockMutex(is->pictq_mutex);
1336
1337 if (is->videoq.abort_request)
1338 return -1;
1339
1340 vp = &is->pictq[is->pictq_windex];
1341
1342 /* alloc or resize hardware picture buffer */
1343 if (!vp->bmp || vp->reallocate ||
1344 #if CONFIG_AVFILTER
1345 vp->width != is->out_video_filter->inputs[0]->w ||
1346 vp->height != is->out_video_filter->inputs[0]->h) {
1347 #else
1348 vp->width != is->video_st->codec->width ||
1349 vp->height != is->video_st->codec->height) {
1350 #endif
1351 SDL_Event event;
1352
1353 vp->allocated = 0;
1354 vp->reallocate = 0;
1355
1356 /* the allocation must be done in the main thread to avoid
1357 locking problems */
1358 event.type = FF_ALLOC_EVENT;
1359 event.user.data1 = is;
1360 SDL_PushEvent(&event);
1361
1362 /* wait until the picture is allocated */
1363 SDL_LockMutex(is->pictq_mutex);
1364 while (!vp->allocated && !is->videoq.abort_request) {
1365 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1366 }
1367 SDL_UnlockMutex(is->pictq_mutex);
1368
1369 if (is->videoq.abort_request)
1370 return -1;
1371 }
1372
1373 /* if the frame is not skipped, then display it */
1374 if (vp->bmp) {
1375 AVPicture pict;
1376 #if CONFIG_AVFILTER
1377 if(vp->picref)
1378 avfilter_unref_buffer(vp->picref);
1379 vp->picref = src_frame->opaque;
1380 #endif
1381
1382 /* get a pointer on the bitmap */
1383 SDL_LockYUVOverlay (vp->bmp);
1384
1385 memset(&pict,0,sizeof(AVPicture));
1386 pict.data[0] = vp->bmp->pixels[0];
1387 pict.data[1] = vp->bmp->pixels[2];
1388 pict.data[2] = vp->bmp->pixels[1];
1389
1390 pict.linesize[0] = vp->bmp->pitches[0];
1391 pict.linesize[1] = vp->bmp->pitches[2];
1392 pict.linesize[2] = vp->bmp->pitches[1];
1393
1394 #if CONFIG_AVFILTER
1395 pict_src.data[0] = src_frame->data[0];
1396 pict_src.data[1] = src_frame->data[1];
1397 pict_src.data[2] = src_frame->data[2];
1398
1399 pict_src.linesize[0] = src_frame->linesize[0];
1400 pict_src.linesize[1] = src_frame->linesize[1];
1401 pict_src.linesize[2] = src_frame->linesize[2];
1402
1403 //FIXME use direct rendering
1404 av_picture_copy(&pict, &pict_src,
1405 vp->pix_fmt, vp->width, vp->height);
1406 #else
1407 sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1408 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1409 vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
1410 dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1411 if (is->img_convert_ctx == NULL) {
1412 fprintf(stderr, "Cannot initialize the conversion context\n");
1413 exit(1);
1414 }
1415 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1416 0, vp->height, pict.data, pict.linesize);
1417 #endif
1418 /* update the bitmap content */
1419 SDL_UnlockYUVOverlay(vp->bmp);
1420
1421 vp->pts = pts;
1422 vp->pos = pos;
1423
1424 /* now we can update the picture count */
1425 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1426 is->pictq_windex = 0;
1427 SDL_LockMutex(is->pictq_mutex);
1428 vp->target_clock= compute_target_time(vp->pts, is);
1429
1430 is->pictq_size++;
1431 SDL_UnlockMutex(is->pictq_mutex);
1432 }
1433 return 0;
1434 }
1435
1436 /**
1437 * compute the exact PTS for the picture if it is omitted in the stream
1438 * @param pts1 the dts of the pkt / pts of the frame
1439 */
1440 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1441 {
1442 double frame_delay, pts;
1443
1444 pts = pts1;
1445
1446 if (pts != 0) {
1447 /* update video clock with pts, if present */
1448 is->video_clock = pts;
1449 } else {
1450 pts = is->video_clock;
1451 }
1452 /* update video clock for next frame */
1453 frame_delay = av_q2d(is->video_st->codec->time_base);
1454 /* for MPEG2, the frame can be repeated, so we update the
1455 clock accordingly */
1456 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1457 is->video_clock += frame_delay;
1458
1459 return queue_picture(is, src_frame, pts, pos);
1460 }
1461
1462 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1463 {
1464 int got_picture, i;
1465
1466 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1467 return -1;
1468
1469 if (pkt->data == flush_pkt.data) {
1470 avcodec_flush_buffers(is->video_st->codec);
1471
1472 SDL_LockMutex(is->pictq_mutex);
1473 //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1474 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1475 is->pictq[i].target_clock= 0;
1476 }
1477 while (is->pictq_size && !is->videoq.abort_request) {
1478 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1479 }
1480 is->video_current_pos = -1;
1481 SDL_UnlockMutex(is->pictq_mutex);
1482
1483 init_pts_correction(&is->pts_ctx);
1484 is->frame_last_pts = AV_NOPTS_VALUE;
1485 is->frame_last_delay = 0;
1486 is->frame_timer = (double)av_gettime() / 1000000.0;
1487 is->skip_frames = 1;
1488 is->skip_frames_index = 0;
1489 return 0;
1490 }
1491
1492 avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt);
1493
1494 if (got_picture) {
1495 if (decoder_reorder_pts == -1) {
1496 *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
1497 } else if (decoder_reorder_pts) {
1498 *pts = frame->pkt_pts;
1499 } else {
1500 *pts = frame->pkt_dts;
1501 }
1502
1503 if (*pts == AV_NOPTS_VALUE) {
1504 *pts = 0;
1505 }
1506
1507 is->skip_frames_index += 1;
1508 if(is->skip_frames_index >= is->skip_frames){
1509 is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1510 return 1;
1511 }
1512
1513 }
1514 return 0;
1515 }
1516
1517 #if CONFIG_AVFILTER
1518 typedef struct {
1519 VideoState *is;
1520 AVFrame *frame;
1521 int use_dr1;
1522 } FilterPriv;
1523
1524 static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
1525 {
1526 AVFilterContext *ctx = codec->opaque;
1527 AVFilterBufferRef *ref;
1528 int perms = AV_PERM_WRITE;
1529 int i, w, h, stride[4];
1530 unsigned edge;
1531 int pixel_size;
1532
1533 if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
1534 perms |= AV_PERM_NEG_LINESIZES;
1535
1536 if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
1537 if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
1538 if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
1539 if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
1540 }
1541 if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
1542
1543 w = codec->width;
1544 h = codec->height;
1545 avcodec_align_dimensions2(codec, &w, &h, stride);
1546 edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
1547 w += edge << 1;
1548 h += edge << 1;
1549
1550 if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
1551 return -1;
1552
1553 pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1+1;
1554 ref->video->w = codec->width;
1555 ref->video->h = codec->height;
1556 for(i = 0; i < 4; i ++) {
1557 unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
1558 unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
1559
1560 if (ref->data[i]) {
1561 ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
1562 }
1563 pic->data[i] = ref->data[i];
1564 pic->linesize[i] = ref->linesize[i];
1565 }
1566 pic->opaque = ref;
1567 pic->type = FF_BUFFER_TYPE_USER;
1568 pic->reordered_opaque = codec->reordered_opaque;
1569 if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
1570 else pic->pkt_pts = AV_NOPTS_VALUE;
1571 return 0;
1572 }
1573
1574 static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1575 {
1576 memset(pic->data, 0, sizeof(pic->data));
1577 avfilter_unref_buffer(pic->opaque);
1578 }
1579
1580 static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1581 {
1582 AVFilterBufferRef *ref = pic->opaque;
1583
1584 if (pic->data[0] == NULL) {
1585 pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1586 return codec->get_buffer(codec, pic);
1587 }
1588
1589 if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
1590 (codec->pix_fmt != ref->format)) {
1591 av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1592 return -1;
1593 }
1594
1595 pic->reordered_opaque = codec->reordered_opaque;
1596 if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
1597 else pic->pkt_pts = AV_NOPTS_VALUE;
1598 return 0;
1599 }
1600
1601 static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1602 {
1603 FilterPriv *priv = ctx->priv;
1604 AVCodecContext *codec;
1605 if(!opaque) return -1;
1606
1607 priv->is = opaque;
1608 codec = priv->is->video_st->codec;
1609 codec->opaque = ctx;
1610 if(codec->codec->capabilities & CODEC_CAP_DR1) {
1611 priv->use_dr1 = 1;
1612 codec->get_buffer = input_get_buffer;
1613 codec->release_buffer = input_release_buffer;
1614 codec->reget_buffer = input_reget_buffer;
1615 codec->thread_safe_callbacks = 1;
1616 }
1617
1618 priv->frame = avcodec_alloc_frame();
1619
1620 return 0;
1621 }
1622
1623 static void input_uninit(AVFilterContext *ctx)
1624 {
1625 FilterPriv *priv = ctx->priv;
1626 av_free(priv->frame);
1627 }
1628
1629 static int input_request_frame(AVFilterLink *link)
1630 {
1631 FilterPriv *priv = link->src->priv;
1632 AVFilterBufferRef *picref;
1633 int64_t pts = 0;
1634 AVPacket pkt;
1635 int ret;
1636
1637 while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1638 av_free_packet(&pkt);
1639 if (ret < 0)
1640 return -1;
1641
1642 if(priv->use_dr1) {
1643 picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
1644 } else {
1645 picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1646 av_image_copy(picref->data, picref->linesize,
1647 priv->frame->data, priv->frame->linesize,
1648 picref->format, link->w, link->h);
1649 }
1650 av_free_packet(&pkt);
1651
1652 avfilter_copy_frame_props(picref, priv->frame);
1653 picref->pts = pts;
1654
1655 avfilter_start_frame(link, picref);
1656 avfilter_draw_slice(link, 0, link->h, 1);
1657 avfilter_end_frame(link);
1658
1659 return 0;
1660 }
1661
1662 static int input_query_formats(AVFilterContext *ctx)
1663 {
1664 FilterPriv *priv = ctx->priv;
1665 enum PixelFormat pix_fmts[] = {
1666 priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1667 };
1668
1669 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1670 return 0;
1671 }
1672
1673 static int input_config_props(AVFilterLink *link)
1674 {
1675 FilterPriv *priv = link->src->priv;
1676 AVCodecContext *c = priv->is->video_st->codec;
1677
1678 link->w = c->width;
1679 link->h = c->height;
1680 link->time_base = priv->is->video_st->time_base;
1681
1682 return 0;
1683 }
1684
1685 static AVFilter input_filter =
1686 {
1687 .name = "avplay_input",
1688
1689 .priv_size = sizeof(FilterPriv),
1690
1691 .init = input_init,
1692 .uninit = input_uninit,
1693
1694 .query_formats = input_query_formats,
1695
1696 .inputs = (AVFilterPad[]) {{ .name = NULL }},
1697 .outputs = (AVFilterPad[]) {{ .name = "default",
1698 .type = AVMEDIA_TYPE_VIDEO,
1699 .request_frame = input_request_frame,
1700 .config_props = input_config_props, },
1701 { .name = NULL }},
1702 };
1703
1704 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
1705 {
1706 char sws_flags_str[128];
1707 int ret;
1708 FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
1709 AVFilterContext *filt_src = NULL, *filt_out = NULL;
1710 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1711 graph->scale_sws_opts = av_strdup(sws_flags_str);
1712
1713 if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
1714 NULL, is, graph)) < 0)
1715 return ret;
1716 if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
1717 NULL, &ffsink_ctx, graph)) < 0)
1718 return ret;
1719
1720 if(vfilters) {
1721 AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1722 AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
1723
1724 outputs->name = av_strdup("in");
1725 outputs->filter_ctx = filt_src;
1726 outputs->pad_idx = 0;
1727 outputs->next = NULL;
1728
1729 inputs->name = av_strdup("out");
1730 inputs->filter_ctx = filt_out;
1731 inputs->pad_idx = 0;
1732 inputs->next = NULL;
1733
1734 if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
1735 return ret;
1736 av_freep(&vfilters);
1737 } else {
1738 if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
1739 return ret;
1740 }
1741
1742 if ((ret = avfilter_graph_config(graph, NULL)) < 0)
1743 return ret;
1744
1745 is->out_video_filter = filt_out;
1746
1747 return ret;
1748 }
1749
1750 #endif /* CONFIG_AVFILTER */
1751
1752 static int video_thread(void *arg)
1753 {
1754 VideoState *is = arg;
1755 AVFrame *frame= avcodec_alloc_frame();
1756 int64_t pts_int;
1757 double pts;
1758 int ret;
1759
1760 #if CONFIG_AVFILTER
1761 AVFilterGraph *graph = avfilter_graph_alloc();
1762 AVFilterContext *filt_out = NULL;
1763 int64_t pos;
1764 int last_w = is->video_st->codec->width;
1765 int last_h = is->video_st->codec->height;
1766
1767 if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1768 goto the_end;
1769 filt_out = is->out_video_filter;
1770 #endif
1771
1772 for(;;) {
1773 #if !CONFIG_AVFILTER
1774 AVPacket pkt;
1775 #else
1776 AVFilterBufferRef *picref;
1777 AVRational tb;
1778 #endif
1779 while (is->paused && !is->videoq.abort_request)
1780 SDL_Delay(10);
1781 #if CONFIG_AVFILTER
1782 if ( last_w != is->video_st->codec->width
1783 || last_h != is->video_st->codec->height) {
1784 av_dlog(NULL, "Changing size %dx%d -> %dx%d\n", last_w, last_h,
1785 is->video_st->codec->width, is->video_st->codec->height);
1786 avfilter_graph_free(&graph);
1787 graph = avfilter_graph_alloc();
1788 if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1789 goto the_end;
1790 filt_out = is->out_video_filter;
1791 last_w = is->video_st->codec->width;
1792 last_h = is->video_st->codec->height;
1793 }
1794 ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
1795 if (picref) {
1796 pts_int = picref->pts;
1797 pos = picref->pos;
1798 frame->opaque = picref;
1799 }
1800
1801 if (av_cmp_q(tb, is->video_st->time_base)) {
1802 av_unused int64_t pts1 = pts_int;
1803 pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
1804 av_dlog(NULL, "video_thread(): "
1805 "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
1806 tb.num, tb.den, pts1,
1807 is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1808 }
1809 #else
1810 ret = get_video_frame(is, frame, &pts_int, &pkt);
1811 #endif
1812
1813 if (ret < 0) goto the_end;
1814
1815 if (!ret)
1816 continue;
1817
1818 pts = pts_int*av_q2d(is->video_st->time_base);
1819
1820 #if CONFIG_AVFILTER
1821 ret = output_picture2(is, frame, pts, pos);
1822 #else
1823 ret = output_picture2(is, frame, pts, pkt.pos);
1824 av_free_packet(&pkt);
1825 #endif
1826 if (ret < 0)
1827 goto the_end;
1828
1829 if (step)
1830 if (cur_stream)
1831 stream_pause(cur_stream);
1832 }
1833 the_end:
1834 #if CONFIG_AVFILTER
1835 avfilter_graph_free(&graph);
1836 #endif
1837 av_free(frame);
1838 return 0;
1839 }
1840
1841 static int subtitle_thread(void *arg)
1842 {
1843 VideoState *is = arg;
1844 SubPicture *sp;
1845 AVPacket pkt1, *pkt = &pkt1;
1846 int got_subtitle;
1847 double pts;
1848 int i, j;
1849 int r, g, b, y, u, v, a;
1850
1851 for(;;) {
1852 while (is->paused && !is->subtitleq.abort_request) {
1853 SDL_Delay(10);
1854 }
1855 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1856 break;
1857
1858 if(pkt->data == flush_pkt.data){
1859 avcodec_flush_buffers(is->subtitle_st->codec);
1860 continue;
1861 }
1862 SDL_LockMutex(is->subpq_mutex);
1863 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1864 !is->subtitleq.abort_request) {
1865 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1866 }
1867 SDL_UnlockMutex(is->subpq_mutex);
1868
1869 if (is->subtitleq.abort_request)
1870 return 0;
1871
1872 sp = &is->subpq[is->subpq_windex];
1873
1874 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1875 this packet, if any */
1876 pts = 0;
1877 if (pkt->pts != AV_NOPTS_VALUE)
1878 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1879
1880 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
1881 &got_subtitle, pkt);
1882
1883 if (got_subtitle && sp->sub.format == 0) {
1884 sp->pts = pts;
1885
1886 for (i = 0; i < sp->sub.num_rects; i++)
1887 {
1888 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1889 {
1890 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1891 y = RGB_TO_Y_CCIR(r, g, b);
1892 u = RGB_TO_U_CCIR(r, g, b, 0);
1893 v = RGB_TO_V_CCIR(r, g, b, 0);
1894 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1895 }
1896 }
1897
1898 /* now we can update the picture count */
1899 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1900 is->subpq_windex = 0;
1901 SDL_LockMutex(is->subpq_mutex);
1902 is->subpq_size++;
1903 SDL_UnlockMutex(is->subpq_mutex);
1904 }
1905 av_free_packet(pkt);
1906 }
1907 return 0;
1908 }
1909
1910 /* copy samples for viewing in editor window */
1911 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1912 {
1913 int size, len;
1914
1915 size = samples_size / sizeof(short);
1916 while (size > 0) {
1917 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1918 if (len > size)
1919 len = size;
1920 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1921 samples += len;
1922 is->sample_array_index += len;
1923 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1924 is->sample_array_index = 0;
1925 size -= len;
1926 }
1927 }
1928
1929 /* return the new audio buffer size (samples can be added or deleted
1930 to get better sync if video or external master clock) */
1931 static int synchronize_audio(VideoState *is, short *samples,
1932 int samples_size1, double pts)
1933 {
1934 int n, samples_size;
1935 double ref_clock;
1936
1937 n = 2 * is->audio_st->codec->channels;
1938 samples_size = samples_size1;
1939
1940 /* if not master, then we try to remove or add samples to correct the clock */
1941 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1942 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1943 double diff, avg_diff;
1944 int wanted_size, min_size, max_size, nb_samples;
1945
1946 ref_clock = get_master_clock(is);
1947 diff = get_audio_clock(is) - ref_clock;
1948
1949 if (diff < AV_NOSYNC_THRESHOLD) {
1950 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1951 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1952 /* not enough measures to have a correct estimate */
1953 is->audio_diff_avg_count++;
1954 } else {
1955 /* estimate the A-V difference */
1956 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1957
1958 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1959 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1960 nb_samples = samples_size / n;
1961
1962 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1963 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1964 if (wanted_size < min_size)
1965 wanted_size = min_size;
1966 else if (wanted_size > max_size)
1967 wanted_size = max_size;
1968
1969 /* add or remove samples to correction the synchro */
1970 if (wanted_size < samples_size) {
1971 /* remove samples */
1972 samples_size = wanted_size;
1973 } else if (wanted_size > samples_size) {
1974 uint8_t *samples_end, *q;
1975 int nb;
1976
1977 /* add samples */
1978 nb = (samples_size - wanted_size);
1979 samples_end = (uint8_t *)samples + samples_size - n;
1980 q = samples_end + n;
1981 while (nb > 0) {
1982 memcpy(q, samples_end, n);
1983 q += n;
1984 nb -= n;
1985 }
1986 samples_size = wanted_size;
1987 }
1988 }
1989 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1990 diff, avg_diff, samples_size - samples_size1,
1991 is->audio_clock, is->video_clock, is->audio_diff_threshold);
1992 }
1993 } else {
1994 /* too big difference : may be initial PTS errors, so
1995 reset A-V filter */
1996 is->audio_diff_avg_count = 0;
1997 is->audio_diff_cum = 0;
1998 }
1999 }
2000
2001 return samples_size;
2002 }
2003
2004 /* decode one audio frame and returns its uncompressed size */
2005 static int audio_decode_frame(VideoState *is, double *pts_ptr)
2006 {
2007 AVPacket *pkt_temp = &is->audio_pkt_temp;
2008 AVPacket *pkt = &is->audio_pkt;
2009 AVCodecContext *dec= is->audio_st->codec;
2010 int n, len1, data_size, got_frame;
2011 double pts;
2012 int new_packet = 0;
2013 int flush_complete = 0;
2014
2015 for(;;) {
2016 /* NOTE: the audio packet can contain several frames */
2017 while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
2018 if (!is->frame) {
2019 if (!(is->frame = avcodec_alloc_frame()))
2020 return AVERROR(ENOMEM);
2021 } else
2022 avcodec_get_frame_defaults(is->frame);
2023
2024 if (flush_complete)
2025 break;
2026 new_packet = 0;
2027 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2028 if (len1 < 0) {
2029 /* if error, we skip the frame */
2030 pkt_temp->size = 0;
2031 break;
2032 }
2033
2034 pkt_temp->data += len1;
2035 pkt_temp->size -= len1;
2036
2037 if (!got_frame) {
2038 /* stop sending empty packets if the decoder is finished */
2039 if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2040 flush_complete = 1;
2041 continue;
2042 }
2043 data_size = av_samples_get_buffer_size(NULL, dec->channels,
2044 is->frame->nb_samples,
2045 dec->sample_fmt, 1);
2046
2047 if (dec->sample_fmt != is->audio_src_fmt) {
2048 if (is->reformat_ctx)
2049 av_audio_convert_free(is->reformat_ctx);
2050 is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
2051 dec->sample_fmt, 1, NULL, 0);
2052 if (!is->reformat_ctx) {
2053 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
2054 av_get_sample_fmt_name(dec->sample_fmt),
2055 av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
2056 break;
2057 }
2058 is->audio_src_fmt= dec->sample_fmt;
2059 }
2060
2061 if (is->reformat_ctx) {
2062 const void *ibuf[6]= { is->frame->data[0] };
2063 void *obuf[6];
2064 int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)};
2065 int ostride[6]= {2};
2066 int len= data_size/istride[0];
2067 obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32));
2068 if (!obuf[0]) {
2069 return AVERROR(ENOMEM);
2070 }
2071 is->audio_buf1 = obuf[0];
2072 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
2073 printf("av_audio_convert() failed\n");
2074 break;
2075 }
2076 is->audio_buf = is->audio_buf1;
2077 /* FIXME: existing code assume that data_size equals framesize*channels*2
2078 remove this legacy cruft */
2079 data_size= len*2;
2080 }else{
2081 is->audio_buf = is->frame->data[0];
2082 }
2083
2084 /* if no pts, then compute it */
2085 pts = is->audio_clock;
2086 *pts_ptr = pts;
2087 n = 2 * dec->channels;
2088 is->audio_clock += (double)data_size /
2089 (double)(n * dec->sample_rate);
2090 #ifdef DEBUG
2091 {
2092 static double last_clock;
2093 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2094 is->audio_clock - last_clock,
2095 is->audio_clock, pts);
2096 last_clock = is->audio_clock;
2097 }
2098 #endif
2099 return data_size;
2100 }
2101
2102 /* free the current packet */
2103 if (pkt->data)
2104 av_free_packet(pkt);
2105 memset(pkt_temp, 0, sizeof(*pkt_temp));
2106
2107 if (is->paused || is->audioq.abort_request) {
2108 return -1;
2109 }
2110
2111 /* read next packet */
2112 if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
2113 return -1;
2114
2115 if (pkt->data == flush_pkt.data)
2116 avcodec_flush_buffers(dec);
2117
2118 *pkt_temp = *pkt;
2119
2120 /* if update the audio clock with the pts */
2121 if (pkt->pts != AV_NOPTS_VALUE) {
2122 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2123 }
2124 }
2125 }
2126
2127 /* prepare a new audio buffer */
2128 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2129 {
2130 VideoState *is = opaque;
2131 int audio_size, len1;
2132 double pts;
2133
2134 audio_callback_time = av_gettime();
2135
2136 while (len > 0) {
2137 if (is->audio_buf_index >= is->audio_buf_size) {
2138 audio_size = audio_decode_frame(is, &pts);
2139 if (audio_size < 0) {
2140 /* if error, just output silence */
2141 is->audio_buf = is->silence_buf;
2142 is->audio_buf_size = sizeof(is->silence_buf);
2143 } else {
2144 if (is->show_audio)
2145 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2146 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
2147 pts);
2148 is->audio_buf_size = audio_size;
2149 }
2150 is->audio_buf_index = 0;
2151 }
2152 len1 = is->audio_buf_size - is->audio_buf_index;
2153 if (len1 > len)
2154 len1 = len;
2155 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2156 len -= len1;
2157 stream += len1;
2158 is->audio_buf_index += len1;
2159 }
2160 }
2161
2162 /* open a given stream. Return 0 if OK */
2163 static int stream_component_open(VideoState *is, int stream_index)
2164 {
2165 AVFormatContext *ic = is->ic;
2166 AVCodecContext *avctx;
2167 AVCodec *codec;
2168 SDL_AudioSpec wanted_spec, spec;
2169 AVDictionary *opts;
2170 AVDictionaryEntry *t = NULL;
2171
2172 if (stream_index < 0 || stream_index >= ic->nb_streams)
2173 return -1;
2174 avctx = ic->streams[stream_index]->codec;
2175
2176 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index]);
2177
2178 codec = avcodec_find_decoder(avctx->codec_id);
2179 avctx->debug_mv = debug_mv;
2180 avctx->debug = debug;
2181 avctx->workaround_bugs = workaround_bugs;
2182 avctx->lowres = lowres;
2183 if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2184 avctx->idct_algo= idct;
2185 if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2186 avctx->skip_frame= skip_frame;
2187 avctx->skip_idct= skip_idct;
2188 avctx->skip_loop_filter= skip_loop_filter;
2189 avctx->error_recognition= error_recognition;
2190 avctx->error_concealment= error_concealment;
2191 avctx->thread_count= thread_count;
2192
2193 if (!codec ||
2194 avcodec_open2(avctx, codec, &opts) < 0)
2195 return -1;
2196 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2197 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2198 return AVERROR_OPTION_NOT_FOUND;
2199 }
2200
2201 /* prepare audio output */
2202 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2203 wanted_spec.freq = avctx->sample_rate;
2204 wanted_spec.format = AUDIO_S16SYS;
2205 wanted_spec.channels = avctx->channels;
2206 wanted_spec.silence = 0;
2207 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2208 wanted_spec.callback = sdl_audio_callback;
2209 wanted_spec.userdata = is;
2210 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2211 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2212 return -1;
2213 }
2214 is->audio_hw_buf_size = spec.size;
2215 is->audio_src_fmt= AV_SAMPLE_FMT_S16;
2216 }
2217
2218 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2219 switch(avctx->codec_type) {
2220 case AVMEDIA_TYPE_AUDIO:
2221 is->audio_stream = stream_index;
2222 is->audio_st = ic->streams[stream_index];
2223 is->audio_buf_size = 0;
2224 is->audio_buf_index = 0;
2225
2226 /* init averaging filter */
2227 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2228 is->audio_diff_avg_count = 0;
2229 /* since we do not have a precise anough audio fifo fullness,
2230 we correct audio sync only if larger than this threshold */
2231 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
2232
2233 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2234 packet_queue_init(&is->audioq);
2235 SDL_PauseAudio(0);
2236 break;
2237 case AVMEDIA_TYPE_VIDEO:
2238 is->video_stream = stream_index;
2239 is->video_st = ic->streams[stream_index];
2240
2241 packet_queue_init(&is->videoq);
2242 is->video_tid = SDL_CreateThread(video_thread, is);
2243 break;
2244 case AVMEDIA_TYPE_SUBTITLE:
2245 is->subtitle_stream = stream_index;
2246 is->subtitle_st = ic->streams[stream_index];
2247 packet_queue_init(&is->subtitleq);
2248
2249 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2250 break;
2251 default:
2252 break;
2253 }
2254 return 0;
2255 }
2256
2257 static void stream_component_close(VideoState *is, int stream_index)
2258 {
2259 AVFormatContext *ic = is->ic;
2260 AVCodecContext *avctx;
2261
2262 if (stream_index < 0 || stream_index >= ic->nb_streams)
2263 return;
2264 avctx = ic->streams[stream_index]->codec;
2265
2266 switch(avctx->codec_type) {
2267 case AVMEDIA_TYPE_AUDIO:
2268 packet_queue_abort(&is->audioq);
2269
2270 SDL_CloseAudio();
2271
2272 packet_queue_end(&is->audioq);
2273 av_free_packet(&is->audio_pkt);
2274 if (is->reformat_ctx)
2275 av_audio_convert_free(is->reformat_ctx);
2276 is->reformat_ctx = NULL;
2277 av_freep(&is->audio_buf1);
2278 is->audio_buf = NULL;
2279 av_freep(&is->frame);
2280
2281 if (is->rdft) {
2282 av_rdft_end(is->rdft);
2283 av_freep(&is->rdft_data);
2284 is->rdft = NULL;
2285 is->rdft_bits = 0;
2286 }
2287 break;
2288 case AVMEDIA_TYPE_VIDEO:
2289 packet_queue_abort(&is->videoq);
2290
2291 /* note: we also signal this mutex to make sure we deblock the
2292 video thread in all cases */
2293 SDL_LockMutex(is->pictq_mutex);
2294 SDL_CondSignal(is->pictq_cond);
2295 SDL_UnlockMutex(is->pictq_mutex);
2296
2297 SDL_WaitThread(is->video_tid, NULL);
2298
2299 packet_queue_end(&is->videoq);
2300 break;
2301 case AVMEDIA_TYPE_SUBTITLE:
2302 packet_queue_abort(&is->subtitleq);
2303
2304 /* note: we also signal this mutex to make sure we deblock the
2305 video thread in all cases */
2306 SDL_LockMutex(is->subpq_mutex);
2307 is->subtitle_stream_changed = 1;
2308
2309 SDL_CondSignal(is->subpq_cond);
2310 SDL_UnlockMutex(is->subpq_mutex);
2311
2312 SDL_WaitThread(is->subtitle_tid, NULL);
2313
2314 packet_queue_end(&is->subtitleq);
2315 break;
2316 default:
2317 break;
2318 }
2319
2320 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2321 avcodec_close(avctx);
2322 switch(avctx->codec_type) {
2323 case AVMEDIA_TYPE_AUDIO:
2324 is->audio_st = NULL;
2325 is->audio_stream = -1;
2326 break;
2327 case AVMEDIA_TYPE_VIDEO:
2328 is->video_st = NULL;
2329 is->video_stream = -1;
2330 break;
2331 case AVMEDIA_TYPE_SUBTITLE:
2332 is->subtitle_st = NULL;
2333 is->subtitle_stream = -1;
2334 break;
2335 default:
2336 break;
2337 }
2338 }
2339
2340 /* since we have only one decoding thread, we can use a global
2341 variable instead of a thread local variable */
2342 static VideoState *global_video_state;
2343
2344 static int decode_interrupt_cb(void *ctx)
2345 {
2346 return (global_video_state && global_video_state->abort_request);
2347 }
2348
2349 /* this thread gets the stream from the disk or the network */
2350 static int decode_thread(void *arg)
2351 {
2352 VideoState *is = arg;
2353 AVFormatContext *ic = NULL;
2354 int err, i, ret;
2355 int st_index[AVMEDIA_TYPE_NB];
2356 AVPacket pkt1, *pkt = &pkt1;
2357 int eof=0;
2358 int pkt_in_play_range = 0;
2359 AVDictionaryEntry *t;
2360 AVDictionary **opts;
2361 int orig_nb_streams;
2362
2363 memset(st_index, -1, sizeof(st_index));
2364 is->video_stream = -1;
2365 is->audio_stream = -1;
2366 is->subtitle_stream = -1;
2367
2368 global_video_state = is;
2369
2370 ic = avformat_alloc_context();
2371 ic->interrupt_callback.callback = decode_interrupt_cb;
2372 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2373 if (err < 0) {
2374 print_error(is->filename, err);
2375 ret = -1;
2376 goto fail;
2377 }
2378 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2379 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2380 ret = AVERROR_OPTION_NOT_FOUND;
2381 goto fail;
2382 }
2383 is->ic = ic;
2384
2385 if(genpts)
2386 ic->flags |= AVFMT_FLAG_GENPTS;
2387
2388 opts = setup_find_stream_info_opts(ic, codec_opts);
2389 orig_nb_streams = ic->nb_streams;
2390
2391 err = avformat_find_stream_info(ic, opts);
2392 if (err < 0) {
2393 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2394 ret = -1;
2395 goto fail;
2396 }
2397 for (i = 0; i < orig_nb_streams; i++)
2398 av_dict_free(&opts[i]);
2399 av_freep(&opts);
2400
2401 if(ic->pb)
2402 ic->pb->eof_reached= 0; //FIXME hack, avplay maybe should not use url_feof() to test for the end
2403
2404 if(seek_by_bytes<0)
2405 seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2406
2407 /* if seeking requested, we execute it */
2408 if (start_time != AV_NOPTS_VALUE) {
2409 int64_t timestamp;
2410
2411 timestamp = start_time;
2412 /* add the stream start time */
2413 if (ic->start_time != AV_NOPTS_VALUE)
2414 timestamp += ic->start_time;
2415 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2416 if (ret < 0) {
2417 fprintf(stderr, "%s: could not seek to position %0.3f\n",
2418 is->filename, (double)timestamp / AV_TIME_BASE);
2419 }
2420 }
2421
2422 for (i = 0; i < ic->nb_streams; i++)
2423 ic->streams[i]->discard = AVDISCARD_ALL;
2424 if (!video_disable)
2425 st_index[AVMEDIA_TYPE_VIDEO] =
2426 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2427 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2428 if (!audio_disable)
2429 st_index[AVMEDIA_TYPE_AUDIO] =
2430 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2431 wanted_stream[AVMEDIA_TYPE_AUDIO],
2432 st_index[AVMEDIA_TYPE_VIDEO],
2433 NULL, 0);
2434 if (!video_disable)
2435 st_index[AVMEDIA_TYPE_SUBTITLE] =
2436 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2437 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2438 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2439 st_index[AVMEDIA_TYPE_AUDIO] :
2440 st_index[AVMEDIA_TYPE_VIDEO]),
2441 NULL, 0);
2442 if (show_status) {
2443 av_dump_format(ic, 0, is->filename, 0);
2444 }
2445
2446 /* open the streams */
2447 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2448 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2449 }
2450
2451 ret=-1;
2452 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2453 ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2454 }
2455 is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2456 if(ret<0) {
2457 if (!display_disable)
2458 is->show_audio = 2;
2459 }
2460
2461 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2462 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2463 }
2464
2465 if (is->video_stream < 0 && is->audio_stream < 0) {
2466 fprintf(stderr, "%s: could not open codecs\n", is->filename);
2467 ret = -1;
2468 goto fail;
2469 }
2470
2471 for(;;) {
2472 if (is->abort_request)
2473 break;
2474 if (is->paused != is->last_paused) {
2475 is->last_paused = is->paused;
2476 if (is->paused)
2477 is->read_pause_return= av_read_pause(ic);
2478 else
2479 av_read_play(ic);
2480 }
2481 #if CONFIG_RTSP_DEMUXER
2482 if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2483 /* wait 10 ms to avoid trying to get another packet */
2484 /* XXX: horrible */
2485 SDL_Delay(10);
2486 continue;
2487 }
2488 #endif
2489 if (is->seek_req) {
2490 int64_t seek_target= is->seek_pos;
2491 int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2492 int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2493 //FIXME the +-2 is due to rounding being not done in the correct direction in generation
2494 // of the seek_pos/seek_rel variables
2495
2496 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2497 if (ret < 0) {
2498 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2499 }else{
2500 if (is->audio_stream >= 0) {
2501 packet_queue_flush(&is->audioq);
2502 packet_queue_put(&is->audioq, &flush_pkt);
2503 }
2504 if (is->subtitle_stream >= 0) {
2505 packet_queue_flush(&is->subtitleq);
2506 packet_queue_put(&is->subtitleq, &flush_pkt);
2507 }
2508 if (is->video_stream >= 0) {
2509 packet_queue_flush(&is->videoq);
2510 packet_queue_put(&is->videoq, &flush_pkt);
2511 }
2512 }
2513 is->seek_req = 0;
2514 eof= 0;
2515 }
2516
2517 /* if the queue are full, no need to read more */
2518 if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2519 || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2520 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0)
2521 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2522 /* wait 10 ms */
2523 SDL_Delay(10);
2524 continue;
2525 }
2526 if(eof) {
2527 if(is->video_stream >= 0){
2528 av_init_packet(pkt);
2529 pkt->data=NULL;
2530 pkt->size=0;
2531 pkt->stream_index= is->video_stream;
2532 packet_queue_put(&is->videoq, pkt);
2533 }
2534 if (is->audio_stream >= 0 &&
2535 is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
2536 av_init_packet(pkt);
2537 pkt->data = NULL;
2538 pkt->size = 0;
2539 pkt->stream_index = is->audio_stream;
2540 packet_queue_put(&is->audioq, pkt);
2541 }
2542 SDL_Delay(10);
2543 if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
2544 if(loop!=1 && (!loop || --loop)){
2545 stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2546 }else if(autoexit){
2547 ret=AVERROR_EOF;
2548 goto fail;
2549 }
2550 }
2551 continue;
2552 }
2553 ret = av_read_frame(ic, pkt);
2554 if (ret < 0) {
2555 if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached))
2556 eof=1;
2557 if (ic->pb && ic->pb->error)
2558 break;
2559 SDL_Delay(100); /* wait for user event */
2560 continue;
2561 }
2562 /* check if packet is in play range specified by user, then queue, otherwise discard */
2563 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2564 (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2565 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2566 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000
2567 <= ((double)duration/1000000);
2568 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2569 packet_queue_put(&is->audioq, pkt);
2570 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
2571 packet_queue_put(&is->videoq, pkt);
2572 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2573 packet_queue_put(&is->subtitleq, pkt);
2574 } else {
2575 av_free_packet(pkt);
2576 }
2577 }
2578 /* wait until the end */
2579 while (!is->abort_request) {
2580 SDL_Delay(100);
2581 }
2582
2583 ret = 0;
2584 fail:
2585 /* disable interrupting */
2586 global_video_state = NULL;
2587
2588 /* close each stream */
2589 if (is->audio_stream >= 0)
2590 stream_component_close(is, is->audio_stream);
2591 if (is->video_stream >= 0)
2592 stream_component_close(is, is->video_stream);
2593 if (is->subtitle_stream >= 0)
2594 stream_component_close(is, is->subtitle_stream);
2595 if (is->ic) {
2596 avformat_close_input(&is->ic);
2597 }
2598 avio_set_interrupt_cb(NULL);
2599
2600 if (ret != 0) {
2601 SDL_Event event;
2602
2603 event.type = FF_QUIT_EVENT;
2604 event.user.data1 = is;
2605 SDL_PushEvent(&event);
2606 }
2607 return 0;
2608 }
2609
2610 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2611 {
2612 VideoState *is;
2613
2614 is = av_mallocz(sizeof(VideoState));
2615 if (!is)
2616 return NULL;
2617 av_strlcpy(is->filename, filename, sizeof(is->filename));
2618 is->iformat = iformat;
2619 is->ytop = 0;
2620 is->xleft = 0;
2621
2622 /* start video display */
2623 is->pictq_mutex = SDL_CreateMutex();
2624 is->pictq_cond = SDL_CreateCond();
2625
2626 is->subpq_mutex = SDL_CreateMutex();
2627 is->subpq_cond = SDL_CreateCond();
2628
2629 is->av_sync_type = av_sync_type;
2630 is->parse_tid = SDL_CreateThread(decode_thread, is);
2631 if (!is->parse_tid) {
2632 av_free(is);
2633 return NULL;
2634 }
2635 return is;
2636 }
2637
2638 static void stream_cycle_channel(VideoState *is, int codec_type)
2639 {
2640 AVFormatContext *ic = is->ic;
2641 int start_index, stream_index;
2642 AVStream *st;
2643
2644 if (codec_type == AVMEDIA_TYPE_VIDEO)
2645 start_index = is->video_stream;
2646 else if (codec_type == AVMEDIA_TYPE_AUDIO)
2647 start_index = is->audio_stream;
2648 else
2649 start_index = is->subtitle_stream;
2650 if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
2651 return;
2652 stream_index = start_index;
2653 for(;;) {
2654 if (++stream_index >= is->ic->nb_streams)
2655 {
2656 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
2657 {
2658 stream_index = -1;
2659 goto the_end;
2660 } else
2661 stream_index = 0;
2662 }
2663 if (stream_index == start_index)
2664 return;
2665 st = ic->streams[stream_index];
2666 if (st->codec->codec_type == codec_type) {
2667 /* check that parameters are OK */
2668 switch(codec_type) {
2669 case AVMEDIA_TYPE_AUDIO:
2670 if (st->codec->sample_rate != 0 &&
2671 st->codec->channels != 0)
2672 goto the_end;
2673 break;
2674 case AVMEDIA_TYPE_VIDEO:
2675 case AVMEDIA_TYPE_SUBTITLE:
2676 goto the_end;
2677 default:
2678 break;
2679 }
2680 }
2681 }
2682 the_end:
2683 stream_component_close(is, start_index);
2684 stream_component_open(is, stream_index);
2685 }
2686
2687
2688 static void toggle_full_screen(void)
2689 {
2690 is_full_screen = !is_full_screen;
2691 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
2692 /* OSX needs to empty the picture_queue */
2693 for (int i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
2694 cur_stream->pictq[i].reallocate = 1;
2695 }
2696 #endif
2697 video_open(cur_stream);
2698 }
2699
2700 static void toggle_pause(void)
2701 {
2702 if (cur_stream)
2703 stream_pause(cur_stream);
2704 step = 0;
2705 }
2706
2707 static void step_to_next_frame(void)
2708 {
2709 if (cur_stream) {
2710 /* if the stream is paused unpause it, then step */
2711 if (cur_stream->paused)
2712 stream_pause(cur_stream);
2713 }
2714 step = 1;
2715 }
2716
2717 static void toggle_audio_display(void)
2718 {
2719 if (cur_stream) {
2720 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2721 cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
2722 fill_rectangle(screen,
2723 cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2724 bgcolor);
2725 SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
2726 }
2727 }
2728
2729 /* handle an event sent by the GUI */
2730 static void event_loop(void)
2731 {
2732 SDL_Event event;
2733 double incr, pos, frac;
2734
2735 for(;;) {
2736 double x;
2737 SDL_WaitEvent(&event);
2738 switch(event.type) {
2739 case SDL_KEYDOWN:
2740 if (exit_on_keydown) {
2741 do_exit();
2742 break;
2743 }
2744 switch(event.key.keysym.sym) {
2745 case SDLK_ESCAPE:
2746 case SDLK_q:
2747 do_exit();
2748 break;
2749 case SDLK_f:
2750 toggle_full_screen();
2751 break;
2752 case SDLK_p:
2753 case SDLK_SPACE:
2754 toggle_pause();
2755 break;
2756 case SDLK_s: //S: Step to next frame
2757 step_to_next_frame();
2758 break;
2759 case SDLK_a:
2760 if (cur_stream)
2761 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
2762 break;
2763 case SDLK_v:
2764 if (cur_stream)
2765 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
2766 break;
2767 case SDLK_t:
2768 if (cur_stream)
2769 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
2770 break;
2771 case SDLK_w:
2772 toggle_audio_display();
2773 break;
2774 case SDLK_LEFT:
2775 incr = -10.0;
2776 goto do_seek;
2777 case SDLK_RIGHT:
2778 incr = 10.0;
2779 goto do_seek;
2780 case SDLK_UP:
2781 incr = 60.0;
2782 goto do_seek;
2783 case SDLK_DOWN:
2784 incr = -60.0;
2785 do_seek:
2786 if (cur_stream) {
2787 if (seek_by_bytes) {
2788 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2789 pos= cur_stream->video_current_pos;
2790 }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2791 pos= cur_stream->audio_pkt.pos;
2792 }else
2793 pos = avio_tell(cur_stream->ic->pb);
2794 if (cur_stream->ic->bit_rate)
2795 incr *= cur_stream->ic->bit_rate / 8.0;
2796 else
2797 incr *= 180000.0;
2798 pos += incr;
2799 stream_seek(cur_stream, pos, incr, 1);
2800 } else {
2801 pos = get_master_clock(cur_stream);
2802 pos += incr;
2803 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2804 }
2805 }
2806 break;
2807 default:
2808 break;
2809 }
2810 break;
2811 case SDL_MOUSEBUTTONDOWN:
2812 if (exit_on_mousedown) {
2813 do_exit();
2814 break;
2815 }
2816 case SDL_MOUSEMOTION:
2817 if(event.type ==SDL_MOUSEBUTTONDOWN){
2818 x= event.button.x;
2819 }else{
2820 if(event.motion.state != SDL_PRESSED)
2821 break;
2822 x= event.motion.x;
2823 }
2824 if (cur_stream) {
2825 if(seek_by_bytes || cur_stream->ic->duration<=0){
2826 uint64_t size= avio_size(cur_stream->ic->pb);
2827 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2828 }else{
2829 int64_t ts;
2830 int ns, hh, mm, ss;
2831 int tns, thh, tmm, tss;
2832 tns = cur_stream->ic->duration/1000000LL;
2833 thh = tns/3600;
2834 tmm = (tns%3600)/60;
2835 tss = (tns%60);
2836 frac = x/cur_stream->width;
2837 ns = frac*tns;
2838 hh = ns/3600;
2839 mm = (ns%3600)/60;
2840 ss = (ns%60);
2841 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2842 hh, mm, ss, thh, tmm, tss);
2843 ts = frac*cur_stream->ic->duration;
2844 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2845 ts += cur_stream->ic->start_time;
2846 stream_seek(cur_stream, ts, 0, 0);
2847 }
2848 }
2849 break;
2850 case SDL_VIDEORESIZE:
2851 if (cur_stream) {
2852 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2853 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2854 screen_width = cur_stream->width = event.resize.w;
2855 screen_height= cur_stream->height= event.resize.h;
2856 }
2857 break;
2858 case SDL_QUIT:
2859 case FF_QUIT_EVENT:
2860 do_exit();
2861 break;
2862 case FF_ALLOC_EVENT:
2863 video_open(event.user.data1);
2864 alloc_picture(event.user.data1);
2865 break;
2866 case FF_REFRESH_EVENT:
2867 video_refresh_timer(event.user.data1);
2868 cur_stream->refresh=0;
2869 break;
2870 default:
2871 break;
2872 }
2873 }
2874 }
2875
2876 static int opt_frame_size(const char *opt, const char *arg)
2877 {
2878 av_log(NULL, AV_LOG_ERROR,
2879 "Option '%s' has been removed, use private format options instead\n", opt);
2880 return AVERROR(EINVAL);
2881 }
2882
2883 static int opt_width(const char *opt, const char *arg)
2884 {
2885 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2886 return 0;
2887 }
2888
2889 static int opt_height(const char *opt, const char *arg)
2890 {
2891 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2892 return 0;
2893 }
2894
2895 static int opt_format(const char *opt, const char *arg)
2896 {
2897 file_iformat = av_find_input_format(arg);
2898 if (!file_iformat) {
2899 fprintf(stderr, "Unknown input format: %s\n", arg);
2900 return AVERROR(EINVAL);
2901 }
2902 return 0;
2903 }
2904
2905 static int opt_frame_pix_fmt(const char *opt, const char *arg)
2906 {
2907 av_log(NULL, AV_LOG_ERROR,
2908 "Option '%s' has been removed, use private format options instead\n", opt);
2909 return AVERROR(EINVAL);
2910 }
2911
2912 static int opt_sync(const char *opt, const char *arg)
2913 {
2914 if (!strcmp(arg, "audio"))
2915 av_sync_type = AV_SYNC_AUDIO_MASTER;
2916 else if (!strcmp(arg, "video"))
2917 av_sync_type = AV_SYNC_VIDEO_MASTER;
2918 else if (!strcmp(arg, "ext"))
2919 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2920 else {
2921 fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2922 exit(1);
2923 }
2924 return 0;
2925 }
2926
2927 static int opt_seek(const char *opt, const char *arg)
2928 {
2929 start_time = parse_time_or_die(opt, arg, 1);
2930 return 0;
2931 }
2932
2933 static int opt_duration(const char *opt, const char *arg)
2934 {
2935 duration = parse_time_or_die(opt, arg, 1);
2936 return 0;
2937 }
2938
2939 static int opt_debug(const char *opt, const char *arg)
2940 {
2941 av_log_set_level(99);
2942 debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2943 return 0;
2944 }
2945
2946 static int opt_vismv(const char *opt, const char *arg)
2947 {
2948 debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2949 return 0;
2950 }
2951
2952 static int opt_thread_count(const char *opt, const char *arg)
2953 {
2954 thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2955 #if !HAVE_THREADS
2956 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2957 #endif
2958 return 0;
2959 }
2960
2961 static const OptionDef options[] = {
2962 #include "cmdutils_common_opts.h"
2963 { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2964 { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2965 { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2966 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2967 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2968 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2969 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
2970 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
2971 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
2972 { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2973 { "t", HAS_ARG, {(void*)&opt_duration}, "play \"duration\" seconds of audio/video", "duration" },
2974 { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
2975 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2976 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2977 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2978 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2979 { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2980 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2981 { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2982 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2983 { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2984 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2985 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2986 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2987 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2988 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2989 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
2990 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" },
2991 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
2992 { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2993 { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2994 { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
2995 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_keydown}, "exit on key down", "" },
2996 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_mousedown}, "exit on mouse down", "" },
2997 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
2998 { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
2999 { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
3000 #if CONFIG_AVFILTER
3001 { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
3002 #endif
3003 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
3004 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
3005 { "i", 0, {NULL}, "avconv compatibility dummy option", ""},
3006 { NULL, },
3007 };
3008
3009 static void show_usage(void)
3010 {
3011 printf("Simple media player\n");
3012 printf("usage: %s [options] input_file\n", program_name);
3013 printf("\n");
3014 }
3015
3016 static void show_help(void)
3017 {
3018 av_log_set_callback(log_callback_help);
3019 show_usage();
3020 show_help_options(options, "Main options:\n",
3021 OPT_EXPERT, 0);
3022 show_help_options(options, "\nAdvanced options:\n",
3023 OPT_EXPERT, OPT_EXPERT);
3024 printf("\n");
3025 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3026 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3027 #if !CONFIG_AVFILTER
3028 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3029 #endif
3030 printf("\nWhile playing:\n"
3031 "q, ESC quit\n"
3032 "f toggle full screen\n"
3033 "p, SPC pause\n"
3034 "a cycle audio channel\n"
3035 "v cycle video channel\n"
3036 "t cycle subtitle channel\n"
3037 "w show audio waves\n"
3038 "s activate frame-step mode\n"
3039 "left/right seek backward/forward 10 seconds\n"
3040 "down/up seek backward/forward 1 minute\n"
3041 "mouse click seek to percentage in file corresponding to fraction of width\n"
3042 );
3043 }
3044
3045 static void opt_input_file(void *optctx, const char *filename)
3046 {
3047 if (input_filename) {
3048 fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3049 filename, input_filename);
3050 exit(1);
3051 }
3052 if (!strcmp(filename, "-"))
3053 filename = "pipe:";
3054 input_filename = filename;
3055 }
3056
3057 /* Called from the main */
3058 int main(int argc, char **argv)
3059 {
3060 int flags;
3061
3062 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3063 parse_loglevel(argc, argv, options);
3064
3065 /* register all codecs, demux and protocols */
3066 avcodec_register_all();
3067 #if CONFIG_AVDEVICE
3068 avdevice_register_all();
3069 #endif
3070 #if CONFIG_AVFILTER
3071 avfilter_register_all();
3072 #endif
3073 av_register_all();
3074 avformat_network_init();
3075
3076 init_opts();
3077
3078 show_banner();
3079
3080 parse_options(NULL, argc, argv, options, opt_input_file);
3081
3082 if (!input_filename) {
3083 show_usage();
3084 fprintf(stderr, "An input file must be specified\n");
3085 fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3086 exit(1);
3087 }
3088
3089 if (display_disable) {
3090 video_disable = 1;
3091 }
3092 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3093 #if !defined(__MINGW32__) && !defined(__APPLE__)
3094 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3095 #endif
3096 if (SDL_Init (flags)) {
3097 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3098 exit(1);
3099 }
3100
3101 if (!display_disable) {
3102 #if HAVE_SDL_VIDEO_SIZE
3103 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3104 fs_screen_width = vi->current_w;
3105 fs_screen_height = vi->current_h;
3106 #endif
3107 }
3108
3109 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3110 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3111 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3112
3113 av_init_packet(&flush_pkt);
3114 flush_pkt.data= "FLUSH";
3115
3116 cur_stream = stream_open(input_filename, file_iformat);
3117
3118 event_loop();
3119
3120 /* never returns */
3121
3122 return 0;
3123 }