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