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