FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ffplay.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * simple media player based on the FFmpeg libraries
24  */
25 
26 #include "config.h"
27 #include <inttypes.h>
28 #include <math.h>
29 #include <limits.h>
30 #include <signal.h>
31 #include "libavutil/avstring.h"
32 #include "libavutil/colorspace.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/dict.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/samplefmt.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/time.h"
41 #include "libavformat/avformat.h"
42 #include "libavdevice/avdevice.h"
43 #include "libswscale/swscale.h"
44 #include "libavutil/opt.h"
45 #include "libavcodec/avfft.h"
47 
48 #if CONFIG_AVFILTER
49 # include "libavfilter/avcodec.h"
50 # include "libavfilter/avfilter.h"
51 # include "libavfilter/buffersink.h"
52 # include "libavfilter/buffersrc.h"
53 #endif
54 
55 #include <SDL.h>
56 #include <SDL_thread.h>
57 
58 #include "cmdutils.h"
59 
60 #include <assert.h>
61 
62 const char program_name[] = "ffplay";
63 const int program_birth_year = 2003;
64 
65 #define MAX_QUEUE_SIZE (15 * 1024 * 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 /* maximum audio speed change to get correct sync */
78 #define SAMPLE_CORRECTION_PERCENT_MAX 10
79 
80 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
81 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
82 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
83 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
84 
85 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
86 #define AUDIO_DIFF_AVG_NB 20
87 
88 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
89 #define REFRESH_RATE 0.01
90 
91 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
92 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
93 #define SAMPLE_ARRAY_SIZE (8 * 65536)
94 
95 #define CURSOR_HIDE_DELAY 1000000
96 
97 static int64_t sws_flags = SWS_BICUBIC;
98 
99 typedef struct MyAVPacketList {
102  int serial;
104 
105 typedef struct PacketQueue {
108  int size;
110  int serial;
111  SDL_mutex *mutex;
112  SDL_cond *cond;
113 } PacketQueue;
114 
115 #define VIDEO_PICTURE_QUEUE_SIZE 4
116 #define SUBPICTURE_QUEUE_SIZE 4
117 
118 typedef struct VideoPicture {
119  double pts; // presentation timestamp for this picture
120  int64_t pos; // byte position in file
121  SDL_Overlay *bmp;
122  int width, height; /* source height & width */
125  int serial;
126 
128 } VideoPicture;
129 
130 typedef struct SubPicture {
131  double pts; /* presentation time stamp for this picture */
133 } SubPicture;
134 
135 typedef struct AudioParams {
136  int freq;
137  int channels;
138  int64_t channel_layout;
140 } AudioParams;
141 
142 enum {
143  AV_SYNC_AUDIO_MASTER, /* default choice */
145  AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
146 };
147 
148 typedef struct VideoState {
149  SDL_Thread *read_tid;
150  SDL_Thread *video_tid;
155  int paused;
158  int seek_req;
160  int64_t seek_pos;
161  int64_t seek_rel;
164  int realtime;
165 
167 
169  double external_clock; ///< external clock base
170  double external_clock_drift; ///< external clock base - time (av_gettime) at which we updated external_clock
171  int64_t external_clock_time; ///< last reference time
172  double external_clock_speed; ///< speed of the external clock
173 
174  double audio_clock;
176  double audio_diff_cum; /* used for AV difference average computation */
186  unsigned int audio_buf_size; /* in bytes */
187  unsigned int audio_buf1_size;
188  int audio_buf_index; /* in bytes */
196 #if CONFIG_AVFILTER
197  struct AudioParams audio_filter_src;
198 #endif
206 
207  enum ShowMode {
209  } show_mode;
216  int xpos;
218 
219  SDL_Thread *subtitle_tid;
226  SDL_mutex *subpq_mutex;
227  SDL_cond *subpq_cond;
228 
229  double frame_timer;
240  double video_current_pts; // current displayed pts
241  double video_current_pts_drift; // video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
242  int64_t video_current_pos; // current displayed file pos
243  double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
247  SDL_mutex *pictq_mutex;
248  SDL_cond *pictq_cond;
249 #if !CONFIG_AVFILTER
251 #endif
253 
254  char filename[1024];
256  int step;
257 
258 #if CONFIG_AVFILTER
259  AVFilterContext *in_video_filter; // the first filter in the video chain
260  AVFilterContext *out_video_filter; // the last filter in the video chain
261  AVFilterContext *in_audio_filter; // the first filter in the audio chain
262  AVFilterContext *out_audio_filter; // the last filter in the audio chain
263  AVFilterGraph *agraph; // audio filter graph
264 #endif
265 
267 
269 } VideoState;
270 
271 /* options specified by the user */
273 static const char *input_filename;
274 static const char *window_title;
275 static int fs_screen_width;
276 static int fs_screen_height;
277 static int default_width = 640;
278 static int default_height = 480;
279 static int screen_width = 0;
280 static int screen_height = 0;
281 static int audio_disable;
282 static int video_disable;
283 static int subtitle_disable;
285  [AVMEDIA_TYPE_AUDIO] = -1,
286  [AVMEDIA_TYPE_VIDEO] = -1,
287  [AVMEDIA_TYPE_SUBTITLE] = -1,
288 };
289 static int seek_by_bytes = -1;
290 static int display_disable;
291 static int show_status = 1;
293 static int64_t start_time = AV_NOPTS_VALUE;
294 static int64_t duration = AV_NOPTS_VALUE;
295 static int workaround_bugs = 1;
296 static int fast = 0;
297 static int genpts = 0;
298 static int lowres = 0;
299 static int idct = FF_IDCT_AUTO;
300 static int error_concealment = 3;
301 static int decoder_reorder_pts = -1;
302 static int autoexit;
303 static int exit_on_keydown;
304 static int exit_on_mousedown;
305 static int loop = 1;
306 static int framedrop = -1;
307 static int infinite_buffer = -1;
308 static enum ShowMode show_mode = SHOW_MODE_NONE;
309 static const char *audio_codec_name;
310 static const char *subtitle_codec_name;
311 static const char *video_codec_name;
312 double rdftspeed = 0.02;
313 static int64_t cursor_last_shown;
314 static int cursor_hidden = 0;
315 #if CONFIG_AVFILTER
316 static char *vfilters = NULL;
317 static char *afilters = NULL;
318 #endif
319 
320 /* current context */
321 static int is_full_screen;
322 static int64_t audio_callback_time;
323 
325 
326 #define FF_ALLOC_EVENT (SDL_USEREVENT)
327 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
328 
329 static SDL_Surface *screen;
330 
331 static inline
332 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
333  enum AVSampleFormat fmt2, int64_t channel_count2)
334 {
335  /* If channel count == 1, planar and non-planar formats are the same */
336  if (channel_count1 == 1 && channel_count2 == 1)
338  else
339  return channel_count1 != channel_count2 || fmt1 != fmt2;
340 }
341 
342 static inline
343 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
344 {
345  if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
346  return channel_layout;
347  else
348  return 0;
349 }
350 
351 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
352 
354 {
355  MyAVPacketList *pkt1;
356 
357  if (q->abort_request)
358  return -1;
359 
360  pkt1 = av_malloc(sizeof(MyAVPacketList));
361  if (!pkt1)
362  return -1;
363  pkt1->pkt = *pkt;
364  pkt1->next = NULL;
365  if (pkt == &flush_pkt)
366  q->serial++;
367  pkt1->serial = q->serial;
368 
369  if (!q->last_pkt)
370  q->first_pkt = pkt1;
371  else
372  q->last_pkt->next = pkt1;
373  q->last_pkt = pkt1;
374  q->nb_packets++;
375  q->size += pkt1->pkt.size + sizeof(*pkt1);
376  /* XXX: should duplicate packet data in DV case */
377  SDL_CondSignal(q->cond);
378  return 0;
379 }
380 
382 {
383  int ret;
384 
385  /* duplicate the packet */
386  if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
387  return -1;
388 
389  SDL_LockMutex(q->mutex);
390  ret = packet_queue_put_private(q, pkt);
391  SDL_UnlockMutex(q->mutex);
392 
393  if (pkt != &flush_pkt && ret < 0)
394  av_free_packet(pkt);
395 
396  return ret;
397 }
398 
399 /* packet queue handling */
401 {
402  memset(q, 0, sizeof(PacketQueue));
403  q->mutex = SDL_CreateMutex();
404  q->cond = SDL_CreateCond();
405  q->abort_request = 1;
406 }
407 
409 {
410  MyAVPacketList *pkt, *pkt1;
411 
412  SDL_LockMutex(q->mutex);
413  for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
414  pkt1 = pkt->next;
415  av_free_packet(&pkt->pkt);
416  av_freep(&pkt);
417  }
418  q->last_pkt = NULL;
419  q->first_pkt = NULL;
420  q->nb_packets = 0;
421  q->size = 0;
422  SDL_UnlockMutex(q->mutex);
423 }
424 
426 {
428  SDL_DestroyMutex(q->mutex);
429  SDL_DestroyCond(q->cond);
430 }
431 
433 {
434  SDL_LockMutex(q->mutex);
435 
436  q->abort_request = 1;
437 
438  SDL_CondSignal(q->cond);
439 
440  SDL_UnlockMutex(q->mutex);
441 }
442 
444 {
445  SDL_LockMutex(q->mutex);
446  q->abort_request = 0;
447  packet_queue_put_private(q, &flush_pkt);
448  SDL_UnlockMutex(q->mutex);
449 }
450 
451 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
452 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
453 {
454  MyAVPacketList *pkt1;
455  int ret;
456 
457  SDL_LockMutex(q->mutex);
458 
459  for (;;) {
460  if (q->abort_request) {
461  ret = -1;
462  break;
463  }
464 
465  pkt1 = q->first_pkt;
466  if (pkt1) {
467  q->first_pkt = pkt1->next;
468  if (!q->first_pkt)
469  q->last_pkt = NULL;
470  q->nb_packets--;
471  q->size -= pkt1->pkt.size + sizeof(*pkt1);
472  *pkt = pkt1->pkt;
473  if (serial)
474  *serial = pkt1->serial;
475  av_free(pkt1);
476  ret = 1;
477  break;
478  } else if (!block) {
479  ret = 0;
480  break;
481  } else {
482  SDL_CondWait(q->cond, q->mutex);
483  }
484  }
485  SDL_UnlockMutex(q->mutex);
486  return ret;
487 }
488 
489 static inline void fill_rectangle(SDL_Surface *screen,
490  int x, int y, int w, int h, int color, int update)
491 {
492  SDL_Rect rect;
493  rect.x = x;
494  rect.y = y;
495  rect.w = w;
496  rect.h = h;
497  SDL_FillRect(screen, &rect, color);
498  if (update && w > 0 && h > 0)
499  SDL_UpdateRect(screen, x, y, w, h);
500 }
501 
502 /* draw only the border of a rectangle */
503 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
504 {
505  int w1, w2, h1, h2;
506 
507  /* fill the background */
508  w1 = x;
509  if (w1 < 0)
510  w1 = 0;
511  w2 = width - (x + w);
512  if (w2 < 0)
513  w2 = 0;
514  h1 = y;
515  if (h1 < 0)
516  h1 = 0;
517  h2 = height - (y + h);
518  if (h2 < 0)
519  h2 = 0;
521  xleft, ytop,
522  w1, height,
523  color, update);
525  xleft + width - w2, ytop,
526  w2, height,
527  color, update);
529  xleft + w1, ytop,
530  width - w1 - w2, h1,
531  color, update);
533  xleft + w1, ytop + height - h2,
534  width - w1 - w2, h2,
535  color, update);
536 }
537 
538 #define ALPHA_BLEND(a, oldp, newp, s)\
539 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
540 
541 #define RGBA_IN(r, g, b, a, s)\
542 {\
543  unsigned int v = ((const uint32_t *)(s))[0];\
544  a = (v >> 24) & 0xff;\
545  r = (v >> 16) & 0xff;\
546  g = (v >> 8) & 0xff;\
547  b = v & 0xff;\
548 }
549 
550 #define YUVA_IN(y, u, v, a, s, pal)\
551 {\
552  unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
553  a = (val >> 24) & 0xff;\
554  y = (val >> 16) & 0xff;\
555  u = (val >> 8) & 0xff;\
556  v = val & 0xff;\
557 }
558 
559 #define YUVA_OUT(d, y, u, v, a)\
560 {\
561  ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
562 }
563 
564 
565 #define BPP 1
566 
567 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
568 {
569  int wrap, wrap3, width2, skip2;
570  int y, u, v, a, u1, v1, a1, w, h;
571  uint8_t *lum, *cb, *cr;
572  const uint8_t *p;
573  const uint32_t *pal;
574  int dstx, dsty, dstw, dsth;
575 
576  dstw = av_clip(rect->w, 0, imgw);
577  dsth = av_clip(rect->h, 0, imgh);
578  dstx = av_clip(rect->x, 0, imgw - dstw);
579  dsty = av_clip(rect->y, 0, imgh - dsth);
580  lum = dst->data[0] + dsty * dst->linesize[0];
581  cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
582  cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
583 
584  width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
585  skip2 = dstx >> 1;
586  wrap = dst->linesize[0];
587  wrap3 = rect->pict.linesize[0];
588  p = rect->pict.data[0];
589  pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
590 
591  if (dsty & 1) {
592  lum += dstx;
593  cb += skip2;
594  cr += skip2;
595 
596  if (dstx & 1) {
597  YUVA_IN(y, u, v, a, p, pal);
598  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
599  cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
600  cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
601  cb++;
602  cr++;
603  lum++;
604  p += BPP;
605  }
606  for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
607  YUVA_IN(y, u, v, a, p, pal);
608  u1 = u;
609  v1 = v;
610  a1 = a;
611  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
612 
613  YUVA_IN(y, u, v, a, p + BPP, pal);
614  u1 += u;
615  v1 += v;
616  a1 += a;
617  lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
618  cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
619  cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
620  cb++;
621  cr++;
622  p += 2 * BPP;
623  lum += 2;
624  }
625  if (w) {
626  YUVA_IN(y, u, v, a, p, pal);
627  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
628  cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
629  cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
630  p++;
631  lum++;
632  }
633  p += wrap3 - dstw * BPP;
634  lum += wrap - dstw - dstx;
635  cb += dst->linesize[1] - width2 - skip2;
636  cr += dst->linesize[2] - width2 - skip2;
637  }
638  for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
639  lum += dstx;
640  cb += skip2;
641  cr += skip2;
642 
643  if (dstx & 1) {
644  YUVA_IN(y, u, v, a, p, pal);
645  u1 = u;
646  v1 = v;
647  a1 = a;
648  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
649  p += wrap3;
650  lum += wrap;
651  YUVA_IN(y, u, v, a, p, pal);
652  u1 += u;
653  v1 += v;
654  a1 += a;
655  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
656  cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
657  cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
658  cb++;
659  cr++;
660  p += -wrap3 + BPP;
661  lum += -wrap + 1;
662  }
663  for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
664  YUVA_IN(y, u, v, a, p, pal);
665  u1 = u;
666  v1 = v;
667  a1 = a;
668  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
669 
670  YUVA_IN(y, u, v, a, p + BPP, pal);
671  u1 += u;
672  v1 += v;
673  a1 += a;
674  lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
675  p += wrap3;
676  lum += wrap;
677 
678  YUVA_IN(y, u, v, a, p, pal);
679  u1 += u;
680  v1 += v;
681  a1 += a;
682  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
683 
684  YUVA_IN(y, u, v, a, p + BPP, pal);
685  u1 += u;
686  v1 += v;
687  a1 += a;
688  lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
689 
690  cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
691  cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
692 
693  cb++;
694  cr++;
695  p += -wrap3 + 2 * BPP;
696  lum += -wrap + 2;
697  }
698  if (w) {
699  YUVA_IN(y, u, v, a, p, pal);
700  u1 = u;
701  v1 = v;
702  a1 = a;
703  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
704  p += wrap3;
705  lum += wrap;
706  YUVA_IN(y, u, v, a, p, pal);
707  u1 += u;
708  v1 += v;
709  a1 += a;
710  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
711  cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
712  cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
713  cb++;
714  cr++;
715  p += -wrap3 + BPP;
716  lum += -wrap + 1;
717  }
718  p += wrap3 + (wrap3 - dstw * BPP);
719  lum += wrap + (wrap - dstw - dstx);
720  cb += dst->linesize[1] - width2 - skip2;
721  cr += dst->linesize[2] - width2 - skip2;
722  }
723  /* handle odd height */
724  if (h) {
725  lum += dstx;
726  cb += skip2;
727  cr += skip2;
728 
729  if (dstx & 1) {
730  YUVA_IN(y, u, v, a, p, pal);
731  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
732  cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
733  cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
734  cb++;
735  cr++;
736  lum++;
737  p += BPP;
738  }
739  for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
740  YUVA_IN(y, u, v, a, p, pal);
741  u1 = u;
742  v1 = v;
743  a1 = a;
744  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
745 
746  YUVA_IN(y, u, v, a, p + BPP, pal);
747  u1 += u;
748  v1 += v;
749  a1 += a;
750  lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
751  cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
752  cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
753  cb++;
754  cr++;
755  p += 2 * BPP;
756  lum += 2;
757  }
758  if (w) {
759  YUVA_IN(y, u, v, a, p, pal);
760  lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
761  cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
762  cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
763  }
764  }
765 }
766 
768 {
769  avsubtitle_free(&sp->sub);
770 }
771 
772 static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, VideoPicture *vp)
773 {
774  float aspect_ratio;
775  int width, height, x, y;
776 
777  if (vp->sar.num == 0)
778  aspect_ratio = 0;
779  else
780  aspect_ratio = av_q2d(vp->sar);
781 
782  if (aspect_ratio <= 0.0)
783  aspect_ratio = 1.0;
784  aspect_ratio *= (float)vp->width / (float)vp->height;
785 
786  /* XXX: we suppose the screen has a 1.0 pixel ratio */
787  height = scr_height;
788  width = ((int)rint(height * aspect_ratio)) & ~1;
789  if (width > scr_width) {
790  width = scr_width;
791  height = ((int)rint(width / aspect_ratio)) & ~1;
792  }
793  x = (scr_width - width) / 2;
794  y = (scr_height - height) / 2;
795  rect->x = scr_xleft + x;
796  rect->y = scr_ytop + y;
797  rect->w = FFMAX(width, 1);
798  rect->h = FFMAX(height, 1);
799 }
800 
802 {
803  VideoPicture *vp;
804  SubPicture *sp;
805  AVPicture pict;
806  SDL_Rect rect;
807  int i;
808 
809  vp = &is->pictq[is->pictq_rindex];
810  if (vp->bmp) {
811  if (is->subtitle_st) {
812  if (is->subpq_size > 0) {
813  sp = &is->subpq[is->subpq_rindex];
814 
815  if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
816  SDL_LockYUVOverlay (vp->bmp);
817 
818  pict.data[0] = vp->bmp->pixels[0];
819  pict.data[1] = vp->bmp->pixels[2];
820  pict.data[2] = vp->bmp->pixels[1];
821 
822  pict.linesize[0] = vp->bmp->pitches[0];
823  pict.linesize[1] = vp->bmp->pitches[2];
824  pict.linesize[2] = vp->bmp->pitches[1];
825 
826  for (i = 0; i < sp->sub.num_rects; i++)
827  blend_subrect(&pict, sp->sub.rects[i],
828  vp->bmp->w, vp->bmp->h);
829 
830  SDL_UnlockYUVOverlay (vp->bmp);
831  }
832  }
833  }
834 
835  calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp);
836 
837  SDL_DisplayYUVOverlay(vp->bmp, &rect);
838 
839  if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
840  int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
841  fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
842  is->last_display_rect = rect;
843  }
844  }
845 }
846 
847 static inline int compute_mod(int a, int b)
848 {
849  return a < 0 ? a%b + b : a%b;
850 }
851 
853 {
854  int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
855  int ch, channels, h, h2, bgcolor, fgcolor;
856  int64_t time_diff;
857  int rdft_bits, nb_freq;
858 
859  for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
860  ;
861  nb_freq = 1 << (rdft_bits - 1);
862 
863  /* compute display index : center on currently output samples */
864  channels = s->audio_tgt.channels;
865  nb_display_channels = channels;
866  if (!s->paused) {
867  int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
868  n = 2 * channels;
869  delay = s->audio_write_buf_size;
870  delay /= n;
871 
872  /* to be more precise, we take into account the time spent since
873  the last buffer computation */
874  if (audio_callback_time) {
875  time_diff = av_gettime() - audio_callback_time;
876  delay -= (time_diff * s->audio_tgt.freq) / 1000000;
877  }
878 
879  delay += 2 * data_used;
880  if (delay < data_used)
881  delay = data_used;
882 
883  i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
884  if (s->show_mode == SHOW_MODE_WAVES) {
885  h = INT_MIN;
886  for (i = 0; i < 1000; i += channels) {
887  int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
888  int a = s->sample_array[idx];
889  int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
890  int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
891  int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
892  int score = a - d;
893  if (h < score && (b ^ c) < 0) {
894  h = score;
895  i_start = idx;
896  }
897  }
898  }
899 
900  s->last_i_start = i_start;
901  } else {
902  i_start = s->last_i_start;
903  }
904 
905  bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
906  if (s->show_mode == SHOW_MODE_WAVES) {
908  s->xleft, s->ytop, s->width, s->height,
909  bgcolor, 0);
910 
911  fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
912 
913  /* total height for one channel */
914  h = s->height / nb_display_channels;
915  /* graph height / 2 */
916  h2 = (h * 9) / 20;
917  for (ch = 0; ch < nb_display_channels; ch++) {
918  i = i_start + ch;
919  y1 = s->ytop + ch * h + (h / 2); /* position of center line */
920  for (x = 0; x < s->width; x++) {
921  y = (s->sample_array[i] * h2) >> 15;
922  if (y < 0) {
923  y = -y;
924  ys = y1 - y;
925  } else {
926  ys = y1;
927  }
929  s->xleft + x, ys, 1, y,
930  fgcolor, 0);
931  i += channels;
932  if (i >= SAMPLE_ARRAY_SIZE)
933  i -= SAMPLE_ARRAY_SIZE;
934  }
935  }
936 
937  fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
938 
939  for (ch = 1; ch < nb_display_channels; ch++) {
940  y = s->ytop + ch * h;
942  s->xleft, y, s->width, 1,
943  fgcolor, 0);
944  }
945  SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
946  } else {
947  nb_display_channels= FFMIN(nb_display_channels, 2);
948  if (rdft_bits != s->rdft_bits) {
949  av_rdft_end(s->rdft);
950  av_free(s->rdft_data);
951  s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
952  s->rdft_bits = rdft_bits;
953  s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
954  }
955  {
956  FFTSample *data[2];
957  for (ch = 0; ch < nb_display_channels; ch++) {
958  data[ch] = s->rdft_data + 2 * nb_freq * ch;
959  i = i_start + ch;
960  for (x = 0; x < 2 * nb_freq; x++) {
961  double w = (x-nb_freq) * (1.0 / nb_freq);
962  data[ch][x] = s->sample_array[i] * (1.0 - w * w);
963  i += channels;
964  if (i >= SAMPLE_ARRAY_SIZE)
965  i -= SAMPLE_ARRAY_SIZE;
966  }
967  av_rdft_calc(s->rdft, data[ch]);
968  }
969  // least efficient way to do this, we should of course directly access it but its more than fast enough
970  for (y = 0; y < s->height; y++) {
971  double w = 1 / sqrt(nb_freq);
972  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]));
973  int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
974  + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
975  a = FFMIN(a, 255);
976  b = FFMIN(b, 255);
977  fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
978 
980  s->xpos, s->height-y, 1, 1,
981  fgcolor, 0);
982  }
983  }
984  SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
985  if (!s->paused)
986  s->xpos++;
987  if (s->xpos >= s->width)
988  s->xpos= s->xleft;
989  }
990 }
991 
992 static void stream_close(VideoState *is)
993 {
994  VideoPicture *vp;
995  int i;
996  /* XXX: use a special url_shutdown call to abort parse cleanly */
997  is->abort_request = 1;
998  SDL_WaitThread(is->read_tid, NULL);
1002 
1003  /* free all pictures */
1004  for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1005  vp = &is->pictq[i];
1006  if (vp->bmp) {
1007  SDL_FreeYUVOverlay(vp->bmp);
1008  vp->bmp = NULL;
1009  }
1010  }
1011  SDL_DestroyMutex(is->pictq_mutex);
1012  SDL_DestroyCond(is->pictq_cond);
1013  SDL_DestroyMutex(is->subpq_mutex);
1014  SDL_DestroyCond(is->subpq_cond);
1015  SDL_DestroyCond(is->continue_read_thread);
1016 #if !CONFIG_AVFILTER
1018 #endif
1019  av_free(is);
1020 }
1021 
1022 static void do_exit(VideoState *is)
1023 {
1024  if (is) {
1025  stream_close(is);
1026  }
1028  uninit_opts();
1029 #if CONFIG_AVFILTER
1030  av_freep(&vfilters);
1031 #endif
1033  if (show_status)
1034  printf("\n");
1035  SDL_Quit();
1036  av_log(NULL, AV_LOG_QUIET, "%s", "");
1037  exit(0);
1038 }
1039 
1040 static void sigterm_handler(int sig)
1041 {
1042  exit(123);
1043 }
1044 
1045 static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
1046 {
1047  int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1048  int w,h;
1049  SDL_Rect rect;
1050 
1051  if (is_full_screen) flags |= SDL_FULLSCREEN;
1052  else flags |= SDL_RESIZABLE;
1053 
1054  if (vp && vp->width) {
1055  calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
1056  default_width = rect.w;
1057  default_height = rect.h;
1058  }
1059 
1061  w = fs_screen_width;
1062  h = fs_screen_height;
1063  } else if (!is_full_screen && screen_width) {
1064  w = screen_width;
1065  h = screen_height;
1066  } else {
1067  w = default_width;
1068  h = default_height;
1069  }
1070  if (screen && is->width == screen->w && screen->w == w
1071  && is->height== screen->h && screen->h == h && !force_set_video_mode)
1072  return 0;
1073  screen = SDL_SetVideoMode(w, h, 0, flags);
1074  if (!screen) {
1075  fprintf(stderr, "SDL: could not set video mode - exiting\n");
1076  do_exit(is);
1077  }
1078  if (!window_title)
1080  SDL_WM_SetCaption(window_title, window_title);
1081 
1082  is->width = screen->w;
1083  is->height = screen->h;
1084 
1085  return 0;
1086 }
1087 
1088 /* display the current picture, if any */
1089 static void video_display(VideoState *is)
1090 {
1091  if (!screen)
1092  video_open(is, 0, NULL);
1093  if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1094  video_audio_display(is);
1095  else if (is->video_st)
1096  video_image_display(is);
1097 }
1098 
1099 /* get the current audio clock value */
1100 static double get_audio_clock(VideoState *is)
1101 {
1102  if (is->audio_clock_serial != is->audioq.serial)
1103  return NAN;
1104  if (is->paused) {
1105  return is->audio_current_pts;
1106  } else {
1107  return is->audio_current_pts_drift + av_gettime() / 1000000.0;
1108  }
1109 }
1110 
1111 /* get the current video clock value */
1112 static double get_video_clock(VideoState *is)
1113 {
1114  if (is->video_clock_serial != is->videoq.serial)
1115  return NAN;
1116  if (is->paused) {
1117  return is->video_current_pts;
1118  } else {
1119  return is->video_current_pts_drift + av_gettime() / 1000000.0;
1120  }
1121 }
1122 
1123 /* get the current external clock value */
1124 static double get_external_clock(VideoState *is)
1125 {
1126  if (is->paused) {
1127  return is->external_clock;
1128  } else {
1129  double time = av_gettime() / 1000000.0;
1130  return is->external_clock_drift + time - (time - is->external_clock_time / 1000000.0) * (1.0 - is->external_clock_speed);
1131  }
1132 }
1133 
1135  if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1136  if (is->video_st)
1137  return AV_SYNC_VIDEO_MASTER;
1138  else
1139  return AV_SYNC_AUDIO_MASTER;
1140  } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1141  if (is->audio_st)
1142  return AV_SYNC_AUDIO_MASTER;
1143  else
1144  return AV_SYNC_EXTERNAL_CLOCK;
1145  } else {
1146  return AV_SYNC_EXTERNAL_CLOCK;
1147  }
1148 }
1149 
1150 /* get the current master clock value */
1151 static double get_master_clock(VideoState *is)
1152 {
1153  double val;
1154 
1155  switch (get_master_sync_type(is)) {
1156  case AV_SYNC_VIDEO_MASTER:
1157  val = get_video_clock(is);
1158  break;
1159  case AV_SYNC_AUDIO_MASTER:
1160  val = get_audio_clock(is);
1161  break;
1162  default:
1163  val = get_external_clock(is);
1164  break;
1165  }
1166  return val;
1167 }
1168 
1169 static void update_external_clock_pts(VideoState *is, double pts)
1170 {
1172  is->external_clock = pts;
1173  is->external_clock_drift = pts - is->external_clock_time / 1000000.0;
1174 }
1175 
1176 static void check_external_clock_sync(VideoState *is, double pts) {
1177  double ext_clock = get_external_clock(is);
1178  if (isnan(ext_clock) || fabs(ext_clock - pts) > AV_NOSYNC_THRESHOLD) {
1179  update_external_clock_pts(is, pts);
1180  }
1181 }
1182 
1183 static void update_external_clock_speed(VideoState *is, double speed) {
1185  is->external_clock_speed = speed;
1186 }
1187 
1189  if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1190  is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1192  } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1193  (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1195  } else {
1196  double speed = is->external_clock_speed;
1197  if (speed != 1.0)
1198  update_external_clock_speed(is, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1199  }
1200 }
1201 
1202 /* seek in the stream */
1203 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1204 {
1205  if (!is->seek_req) {
1206  is->seek_pos = pos;
1207  is->seek_rel = rel;
1208  is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1209  if (seek_by_bytes)
1211  is->seek_req = 1;
1212  SDL_CondSignal(is->continue_read_thread);
1213  }
1214 }
1215 
1216 /* pause or resume the video */
1218 {
1219  if (is->paused) {
1220  is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1221  if (is->read_pause_return != AVERROR(ENOSYS)) {
1222  is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1223  }
1224  is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1225  }
1227  is->paused = !is->paused;
1228 }
1229 
1230 static void toggle_pause(VideoState *is)
1231 {
1232  stream_toggle_pause(is);
1233  is->step = 0;
1234 }
1235 
1237 {
1238  /* if the stream is paused unpause it, then step */
1239  if (is->paused)
1240  stream_toggle_pause(is);
1241  is->step = 1;
1242 }
1243 
1244 static double compute_target_delay(double delay, VideoState *is)
1245 {
1246  double sync_threshold, diff;
1247 
1248  /* update delay to follow master synchronisation source */
1250  /* if video is slave, we try to correct big delays by
1251  duplicating or deleting a frame */
1252  diff = get_video_clock(is) - get_master_clock(is);
1253 
1254  /* skip or repeat frame. We take into account the
1255  delay to compute the threshold. I still don't know
1256  if it is the best guess */
1257  sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1258  if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
1259  if (diff <= -sync_threshold)
1260  delay = 0;
1261  else if (diff >= sync_threshold)
1262  delay = 2 * delay;
1263  }
1264  }
1265 
1266  av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1267  delay, -diff);
1268 
1269  return delay;
1270 }
1271 
1272 static void pictq_next_picture(VideoState *is) {
1273  /* update queue size and signal for next picture */
1275  is->pictq_rindex = 0;
1276 
1277  SDL_LockMutex(is->pictq_mutex);
1278  is->pictq_size--;
1279  SDL_CondSignal(is->pictq_cond);
1280  SDL_UnlockMutex(is->pictq_mutex);
1281 }
1282 
1284  VideoPicture *prevvp;
1285  int ret = 0;
1286  /* update queue size and signal for the previous picture */
1288  if (prevvp->allocated && prevvp->serial == is->videoq.serial) {
1289  SDL_LockMutex(is->pictq_mutex);
1290  if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE - 1) {
1291  if (--is->pictq_rindex == -1)
1293  is->pictq_size++;
1294  ret = 1;
1295  }
1296  SDL_CondSignal(is->pictq_cond);
1297  SDL_UnlockMutex(is->pictq_mutex);
1298  }
1299  return ret;
1300 }
1301 
1302 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1303  double time = av_gettime() / 1000000.0;
1304  /* update current video pts */
1305  is->video_current_pts = pts;
1306  is->video_current_pts_drift = is->video_current_pts - time;
1307  is->video_current_pos = pos;
1308  is->frame_last_pts = pts;
1309  is->video_clock_serial = serial;
1310  if (is->videoq.serial == serial)
1312 }
1313 
1314 /* called to display each frame */
1315 static void video_refresh(void *opaque, double *remaining_time)
1316 {
1317  VideoState *is = opaque;
1318  VideoPicture *vp;
1319  double time;
1320 
1321  SubPicture *sp, *sp2;
1322 
1323  if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1325 
1326  if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1327  time = av_gettime() / 1000000.0;
1328  if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1329  video_display(is);
1330  is->last_vis_time = time;
1331  }
1332  *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1333  }
1334 
1335  if (is->video_st) {
1336  int redisplay = 0;
1337  if (is->force_refresh)
1338  redisplay = pictq_prev_picture(is);
1339 retry:
1340  if (is->pictq_size == 0) {
1341  SDL_LockMutex(is->pictq_mutex);
1345  }
1346  SDL_UnlockMutex(is->pictq_mutex);
1347  // nothing to do, no picture to display in the queue
1348  } else {
1349  double last_duration, duration, delay;
1350  /* dequeue the picture */
1351  vp = &is->pictq[is->pictq_rindex];
1352 
1353  if (vp->serial != is->videoq.serial) {
1354  pictq_next_picture(is);
1355  redisplay = 0;
1356  goto retry;
1357  }
1358 
1359  if (is->paused)
1360  goto display;
1361 
1362  /* compute nominal last_duration */
1363  last_duration = vp->pts - is->frame_last_pts;
1364  if (!isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {
1365  /* if duration of the last frame was sane, update last_duration in video state */
1366  is->frame_last_duration = last_duration;
1367  }
1368  delay = compute_target_delay(is->frame_last_duration, is);
1369 
1370  time= av_gettime()/1000000.0;
1371  if (time < is->frame_timer + delay) {
1372  *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1373  return;
1374  }
1375 
1376  if (delay > 0)
1377  is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
1378 
1379  SDL_LockMutex(is->pictq_mutex);
1380  if (!isnan(vp->pts))
1381  update_video_pts(is, vp->pts, vp->pos, vp->serial);
1382  SDL_UnlockMutex(is->pictq_mutex);
1383 
1384  if (is->pictq_size > 1) {
1385  VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
1386  duration = nextvp->pts - vp->pts;
1387  if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1388  if (!redisplay)
1389  is->frame_drops_late++;
1390  pictq_next_picture(is);
1391  redisplay = 0;
1392  goto retry;
1393  }
1394  }
1395 
1396  if (is->subtitle_st) {
1397  if (is->subtitle_stream_changed) {
1398  SDL_LockMutex(is->subpq_mutex);
1399 
1400  while (is->subpq_size) {
1401  free_subpicture(&is->subpq[is->subpq_rindex]);
1402 
1403  /* update queue size and signal for next picture */
1404  if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1405  is->subpq_rindex = 0;
1406 
1407  is->subpq_size--;
1408  }
1409  is->subtitle_stream_changed = 0;
1410 
1411  SDL_CondSignal(is->subpq_cond);
1412  SDL_UnlockMutex(is->subpq_mutex);
1413  } else {
1414  if (is->subpq_size > 0) {
1415  sp = &is->subpq[is->subpq_rindex];
1416 
1417  if (is->subpq_size > 1)
1418  sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1419  else
1420  sp2 = NULL;
1421 
1422  if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1423  || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1424  {
1425  free_subpicture(sp);
1426 
1427  /* update queue size and signal for next picture */
1428  if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1429  is->subpq_rindex = 0;
1430 
1431  SDL_LockMutex(is->subpq_mutex);
1432  is->subpq_size--;
1433  SDL_CondSignal(is->subpq_cond);
1434  SDL_UnlockMutex(is->subpq_mutex);
1435  }
1436  }
1437  }
1438  }
1439 
1440 display:
1441  /* display picture */
1442  if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1443  video_display(is);
1444 
1445  pictq_next_picture(is);
1446 
1447  if (is->step && !is->paused)
1448  stream_toggle_pause(is);
1449  }
1450  }
1451  is->force_refresh = 0;
1452  if (show_status) {
1453  static int64_t last_time;
1454  int64_t cur_time;
1455  int aqsize, vqsize, sqsize;
1456  double av_diff;
1457 
1458  cur_time = av_gettime();
1459  if (!last_time || (cur_time - last_time) >= 30000) {
1460  aqsize = 0;
1461  vqsize = 0;
1462  sqsize = 0;
1463  if (is->audio_st)
1464  aqsize = is->audioq.size;
1465  if (is->video_st)
1466  vqsize = is->videoq.size;
1467  if (is->subtitle_st)
1468  sqsize = is->subtitleq.size;
1469  av_diff = 0;
1470  if (is->audio_st && is->video_st)
1471  av_diff = get_audio_clock(is) - get_video_clock(is);
1472  printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1473  get_master_clock(is),
1474  av_diff,
1476  aqsize / 1024,
1477  vqsize / 1024,
1478  sqsize,
1481  fflush(stdout);
1482  last_time = cur_time;
1483  }
1484  }
1485 }
1486 
1487 /* allocate a picture (needs to do that in main thread to avoid
1488  potential locking problems */
1489 static void alloc_picture(VideoState *is)
1490 {
1491  VideoPicture *vp;
1492 
1493  vp = &is->pictq[is->pictq_windex];
1494 
1495  if (vp->bmp)
1496  SDL_FreeYUVOverlay(vp->bmp);
1497 
1498  video_open(is, 0, vp);
1499 
1500  vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1501  SDL_YV12_OVERLAY,
1502  screen);
1503  if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1504  /* SDL allocates a buffer smaller than requested if the video
1505  * overlay hardware is unable to support the requested size. */
1506  fprintf(stderr, "Error: the video system does not support an image\n"
1507  "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1508  "to reduce the image size.\n", vp->width, vp->height );
1509  do_exit(is);
1510  }
1511 
1512  SDL_LockMutex(is->pictq_mutex);
1513  vp->allocated = 1;
1514  SDL_CondSignal(is->pictq_cond);
1515  SDL_UnlockMutex(is->pictq_mutex);
1516 }
1517 
1518 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1519  int i, width, height;
1520  Uint8 *p, *maxp;
1521  for (i = 0; i < 3; i++) {
1522  width = bmp->w;
1523  height = bmp->h;
1524  if (i > 0) {
1525  width >>= 1;
1526  height >>= 1;
1527  }
1528  if (bmp->pitches[i] > width) {
1529  maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1530  for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1531  *(p+1) = *p;
1532  }
1533  }
1534 }
1535 
1536 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos, int serial)
1537 {
1538  VideoPicture *vp;
1539 
1540 #if defined(DEBUG_SYNC) && 0
1541  printf("frame_type=%c pts=%0.3f\n",
1542  av_get_picture_type_char(src_frame->pict_type), pts);
1543 #endif
1544 
1545  /* wait until we have space to put a new picture */
1546  SDL_LockMutex(is->pictq_mutex);
1547 
1548  /* keep the last already displayed picture in the queue */
1549  while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 2 &&
1550  !is->videoq.abort_request) {
1551  SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1552  }
1553  SDL_UnlockMutex(is->pictq_mutex);
1554 
1555  if (is->videoq.abort_request)
1556  return -1;
1557 
1558  vp = &is->pictq[is->pictq_windex];
1559 
1560  vp->sar = src_frame->sample_aspect_ratio;
1561 
1562  /* alloc or resize hardware picture buffer */
1563  if (!vp->bmp || vp->reallocate || !vp->allocated ||
1564  vp->width != src_frame->width ||
1565  vp->height != src_frame->height) {
1566  SDL_Event event;
1567 
1568  vp->allocated = 0;
1569  vp->reallocate = 0;
1570  vp->width = src_frame->width;
1571  vp->height = src_frame->height;
1572 
1573  /* the allocation must be done in the main thread to avoid
1574  locking problems. */
1575  event.type = FF_ALLOC_EVENT;
1576  event.user.data1 = is;
1577  SDL_PushEvent(&event);
1578 
1579  /* wait until the picture is allocated */
1580  SDL_LockMutex(is->pictq_mutex);
1581  while (!vp->allocated && !is->videoq.abort_request) {
1582  SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1583  }
1584  /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1585  if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1586  while (!vp->allocated) {
1587  SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1588  }
1589  }
1590  SDL_UnlockMutex(is->pictq_mutex);
1591 
1592  if (is->videoq.abort_request)
1593  return -1;
1594  }
1595 
1596  /* if the frame is not skipped, then display it */
1597  if (vp->bmp) {
1598  AVPicture pict = { { 0 } };
1599 
1600  /* get a pointer on the bitmap */
1601  SDL_LockYUVOverlay (vp->bmp);
1602 
1603  pict.data[0] = vp->bmp->pixels[0];
1604  pict.data[1] = vp->bmp->pixels[2];
1605  pict.data[2] = vp->bmp->pixels[1];
1606 
1607  pict.linesize[0] = vp->bmp->pitches[0];
1608  pict.linesize[1] = vp->bmp->pitches[2];
1609  pict.linesize[2] = vp->bmp->pitches[1];
1610 
1611 #if CONFIG_AVFILTER
1612  // FIXME use direct rendering
1613  av_picture_copy(&pict, (AVPicture *)src_frame,
1614  src_frame->format, vp->width, vp->height);
1615 #else
1616  av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1618  vp->width, vp->height, src_frame->format, vp->width, vp->height,
1620  if (is->img_convert_ctx == NULL) {
1621  fprintf(stderr, "Cannot initialize the conversion context\n");
1622  exit(1);
1623  }
1624  sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1625  0, vp->height, pict.data, pict.linesize);
1626 #endif
1627  /* workaround SDL PITCH_WORKAROUND */
1629  /* update the bitmap content */
1630  SDL_UnlockYUVOverlay(vp->bmp);
1631 
1632  vp->pts = pts;
1633  vp->pos = pos;
1634  vp->serial = serial;
1635 
1636  /* now we can update the picture count */
1638  is->pictq_windex = 0;
1639  SDL_LockMutex(is->pictq_mutex);
1640  is->pictq_size++;
1641  SDL_UnlockMutex(is->pictq_mutex);
1642  }
1643  return 0;
1644 }
1645 
1646 static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
1647 {
1648  int got_picture;
1649 
1650  if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1651  return -1;
1652 
1653  if (pkt->data == flush_pkt.data) {
1655 
1656  SDL_LockMutex(is->pictq_mutex);
1657  // Make sure there are no long delay timers (ideally we should just flush the queue but that's harder)
1658  while (is->pictq_size && !is->videoq.abort_request) {
1659  SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1660  }
1661  is->video_current_pos = -1;
1663  is->frame_last_duration = 0;
1664  is->frame_timer = (double)av_gettime() / 1000000.0;
1666  SDL_UnlockMutex(is->pictq_mutex);
1667  return 0;
1668  }
1669 
1670  if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
1671  return 0;
1672 
1673  if (got_picture) {
1674  int ret = 1;
1675  double dpts = NAN;
1676 
1677  if (decoder_reorder_pts == -1) {
1678  frame->pts = av_frame_get_best_effort_timestamp(frame);
1679  } else if (decoder_reorder_pts) {
1680  frame->pts = frame->pkt_pts;
1681  } else {
1682  frame->pts = frame->pkt_dts;
1683  }
1684 
1685  if (frame->pts != AV_NOPTS_VALUE)
1686  dpts = av_q2d(is->video_st->time_base) * frame->pts;
1687 
1688  frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1689 
1691  SDL_LockMutex(is->pictq_mutex);
1692  if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) {
1693  double clockdiff = get_video_clock(is) - get_master_clock(is);
1694  double ptsdiff = dpts - is->frame_last_pts;
1695  if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
1696  !isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
1697  clockdiff + ptsdiff - is->frame_last_filter_delay < 0 &&
1698  is->videoq.nb_packets) {
1699  is->frame_last_dropped_pos = pkt->pos;
1700  is->frame_last_dropped_pts = dpts;
1701  is->frame_last_dropped_serial = *serial;
1702  is->frame_drops_early++;
1703  av_frame_unref(frame);
1704  ret = 0;
1705  }
1706  }
1707  SDL_UnlockMutex(is->pictq_mutex);
1708  }
1709 
1710  return ret;
1711  }
1712  return 0;
1713 }
1714 
1715 #if CONFIG_AVFILTER
1716 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1717  AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1718 {
1719  int ret;
1721 
1722  if (filtergraph) {
1723  outputs = avfilter_inout_alloc();
1724  inputs = avfilter_inout_alloc();
1725  if (!outputs || !inputs) {
1726  ret = AVERROR(ENOMEM);
1727  goto fail;
1728  }
1729 
1730  outputs->name = av_strdup("in");
1731  outputs->filter_ctx = source_ctx;
1732  outputs->pad_idx = 0;
1733  outputs->next = NULL;
1734 
1735  inputs->name = av_strdup("out");
1736  inputs->filter_ctx = sink_ctx;
1737  inputs->pad_idx = 0;
1738  inputs->next = NULL;
1739 
1740  if ((ret = avfilter_graph_parse(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1741  goto fail;
1742  } else {
1743  if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1744  goto fail;
1745  }
1746 
1747  ret = avfilter_graph_config(graph, NULL);
1748 fail:
1749  avfilter_inout_free(&outputs);
1750  avfilter_inout_free(&inputs);
1751  return ret;
1752 }
1753 
1754 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1755 {
1756  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1757  char sws_flags_str[128];
1758  char buffersrc_args[256];
1759  int ret;
1760  AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_crop;
1761  AVCodecContext *codec = is->video_st->codec;
1762  AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1763 
1764  av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1765  snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1766  graph->scale_sws_opts = av_strdup(sws_flags_str);
1767 
1768  snprintf(buffersrc_args, sizeof(buffersrc_args),
1769  "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1770  frame->width, frame->height, frame->format,
1772  codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1773  if (fr.num && fr.den)
1774  av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1775 
1776  if ((ret = avfilter_graph_create_filter(&filt_src,
1777  avfilter_get_by_name("buffer"),
1778  "ffplay_buffer", buffersrc_args, NULL,
1779  graph)) < 0)
1780  goto fail;
1781 
1782  ret = avfilter_graph_create_filter(&filt_out,
1783  avfilter_get_by_name("buffersink"),
1784  "ffplay_buffersink", NULL, NULL, graph);
1785  if (ret < 0)
1786  goto fail;
1787 
1788  if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1789  goto fail;
1790 
1791  /* SDL YUV code is not handling odd width/height for some driver
1792  * combinations, therefore we crop the picture to an even width/height. */
1793  if ((ret = avfilter_graph_create_filter(&filt_crop,
1794  avfilter_get_by_name("crop"),
1795  "ffplay_crop", "floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
1796  goto fail;
1797  if ((ret = avfilter_link(filt_crop, 0, filt_out, 0)) < 0)
1798  goto fail;
1799 
1800  if ((ret = configure_filtergraph(graph, vfilters, filt_src, filt_crop)) < 0)
1801  goto fail;
1802 
1803  is->in_video_filter = filt_src;
1804  is->out_video_filter = filt_out;
1805 
1806 fail:
1807  return ret;
1808 }
1809 
1810 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1811 {
1813  int sample_rates[2] = { 0, -1 };
1814  int64_t channel_layouts[2] = { 0, -1 };
1815  int channels[2] = { 0, -1 };
1816  AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1817  char asrc_args[256];
1818  int ret;
1819 
1820  avfilter_graph_free(&is->agraph);
1821  if (!(is->agraph = avfilter_graph_alloc()))
1822  return AVERROR(ENOMEM);
1823 
1824  ret = snprintf(asrc_args, sizeof(asrc_args),
1825  "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1826  is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1827  is->audio_filter_src.channels,
1828  1, is->audio_filter_src.freq);
1829  if (is->audio_filter_src.channel_layout)
1830  snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1831  ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1832 
1833  ret = avfilter_graph_create_filter(&filt_asrc,
1834  avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1835  asrc_args, NULL, is->agraph);
1836  if (ret < 0)
1837  goto end;
1838 
1839 
1840  ret = avfilter_graph_create_filter(&filt_asink,
1841  avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1842  NULL, NULL, is->agraph);
1843  if (ret < 0)
1844  goto end;
1845 
1846  if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1847  goto end;
1848  if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1849  goto end;
1850 
1851  if (force_output_format) {
1852  channel_layouts[0] = is->audio_tgt.channel_layout;
1853  channels [0] = is->audio_tgt.channels;
1854  sample_rates [0] = is->audio_tgt.freq;
1855  if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1856  goto end;
1857  if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1858  goto end;
1859  if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1860  goto end;
1861  if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1862  goto end;
1863  }
1864 
1865 
1866  if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1867  goto end;
1868 
1869  is->in_audio_filter = filt_asrc;
1870  is->out_audio_filter = filt_asink;
1871 
1872 end:
1873  if (ret < 0)
1874  avfilter_graph_free(&is->agraph);
1875  return ret;
1876 }
1877 #endif /* CONFIG_AVFILTER */
1878 
1879 static int video_thread(void *arg)
1880 {
1881  AVPacket pkt = { 0 };
1882  VideoState *is = arg;
1883  AVFrame *frame = av_frame_alloc();
1884  double pts;
1885  int ret;
1886  int serial = 0;
1887 
1888 #if CONFIG_AVFILTER
1890  AVFilterContext *filt_out = NULL, *filt_in = NULL;
1891  int last_w = 0;
1892  int last_h = 0;
1893  enum AVPixelFormat last_format = -2;
1894  int last_serial = -1;
1895 #endif
1896 
1897  for (;;) {
1898  while (is->paused && !is->videoq.abort_request)
1899  SDL_Delay(10);
1900 
1902  av_free_packet(&pkt);
1903 
1904  ret = get_video_frame(is, frame, &pkt, &serial);
1905  if (ret < 0)
1906  goto the_end;
1907  if (!ret)
1908  continue;
1909 
1910 #if CONFIG_AVFILTER
1911  if ( last_w != frame->width
1912  || last_h != frame->height
1913  || last_format != frame->format
1914  || last_serial != serial) {
1916  "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1917  last_w, last_h,
1918  (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
1919  frame->width, frame->height,
1920  (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
1921  avfilter_graph_free(&graph);
1922  graph = avfilter_graph_alloc();
1923  if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) {
1924  SDL_Event event;
1925  event.type = FF_QUIT_EVENT;
1926  event.user.data1 = is;
1927  SDL_PushEvent(&event);
1928  av_free_packet(&pkt);
1929  goto the_end;
1930  }
1931  filt_in = is->in_video_filter;
1932  filt_out = is->out_video_filter;
1933  last_w = frame->width;
1934  last_h = frame->height;
1935  last_format = frame->format;
1936  last_serial = serial;
1937  }
1938 
1939  ret = av_buffersrc_add_frame(filt_in, frame);
1940  if (ret < 0)
1941  goto the_end;
1942  av_frame_unref(frame);
1944  av_free_packet(&pkt);
1945 
1946  while (ret >= 0) {
1947  is->frame_last_returned_time = av_gettime() / 1000000.0;
1948 
1949  ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
1950  if (ret < 0) {
1951  ret = 0;
1952  break;
1953  }
1954 
1956  if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
1957  is->frame_last_filter_delay = 0;
1958 
1959  pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(filt_out->inputs[0]->time_base);
1960  ret = queue_picture(is, frame, pts, av_frame_get_pkt_pos(frame), serial);
1961  av_frame_unref(frame);
1962  }
1963 #else
1964  pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(is->video_st->time_base);
1965  ret = queue_picture(is, frame, pts, pkt.pos, serial);
1966  av_frame_unref(frame);
1967 #endif
1968 
1969  if (ret < 0)
1970  goto the_end;
1971  }
1972  the_end:
1974 #if CONFIG_AVFILTER
1975  avfilter_graph_free(&graph);
1976 #endif
1977  av_free_packet(&pkt);
1978  av_frame_free(&frame);
1979  return 0;
1980 }
1981 
1982 static int subtitle_thread(void *arg)
1983 {
1984  VideoState *is = arg;
1985  SubPicture *sp;
1986  AVPacket pkt1, *pkt = &pkt1;
1987  int got_subtitle;
1988  double pts;
1989  int i, j;
1990  int r, g, b, y, u, v, a;
1991 
1992  for (;;) {
1993  while (is->paused && !is->subtitleq.abort_request) {
1994  SDL_Delay(10);
1995  }
1996  if (packet_queue_get(&is->subtitleq, pkt, 1, NULL) < 0)
1997  break;
1998 
1999  if (pkt->data == flush_pkt.data) {
2001  continue;
2002  }
2003  SDL_LockMutex(is->subpq_mutex);
2004  while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
2005  !is->subtitleq.abort_request) {
2006  SDL_CondWait(is->subpq_cond, is->subpq_mutex);
2007  }
2008  SDL_UnlockMutex(is->subpq_mutex);
2009 
2010  if (is->subtitleq.abort_request)
2011  return 0;
2012 
2013  sp = &is->subpq[is->subpq_windex];
2014 
2015  /* NOTE: ipts is the PTS of the _first_ picture beginning in
2016  this packet, if any */
2017  pts = 0;
2018  if (pkt->pts != AV_NOPTS_VALUE)
2019  pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2020 
2022  &got_subtitle, pkt);
2023  if (got_subtitle && sp->sub.format == 0) {
2024  if (sp->sub.pts != AV_NOPTS_VALUE)
2025  pts = sp->sub.pts / (double)AV_TIME_BASE;
2026  sp->pts = pts;
2027 
2028  for (i = 0; i < sp->sub.num_rects; i++)
2029  {
2030  for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2031  {
2032  RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2033  y = RGB_TO_Y_CCIR(r, g, b);
2034  u = RGB_TO_U_CCIR(r, g, b, 0);
2035  v = RGB_TO_V_CCIR(r, g, b, 0);
2036  YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2037  }
2038  }
2039 
2040  /* now we can update the picture count */
2041  if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
2042  is->subpq_windex = 0;
2043  SDL_LockMutex(is->subpq_mutex);
2044  is->subpq_size++;
2045  SDL_UnlockMutex(is->subpq_mutex);
2046  }
2047  av_free_packet(pkt);
2048  }
2049  return 0;
2050 }
2051 
2052 /* copy samples for viewing in editor window */
2053 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2054 {
2055  int size, len;
2056 
2057  size = samples_size / sizeof(short);
2058  while (size > 0) {
2060  if (len > size)
2061  len = size;
2062  memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2063  samples += len;
2064  is->sample_array_index += len;
2066  is->sample_array_index = 0;
2067  size -= len;
2068  }
2069 }
2070 
2071 /* return the wanted number of samples to get better sync if sync_type is video
2072  * or external master clock */
2074 {
2075  int wanted_nb_samples = nb_samples;
2076 
2077  /* if not master, then we try to remove or add samples to correct the clock */
2079  double diff, avg_diff;
2080  int min_nb_samples, max_nb_samples;
2081 
2082  diff = get_audio_clock(is) - get_master_clock(is);
2083 
2084  if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2085  is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2087  /* not enough measures to have a correct estimate */
2088  is->audio_diff_avg_count++;
2089  } else {
2090  /* estimate the A-V difference */
2091  avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2092 
2093  if (fabs(avg_diff) >= is->audio_diff_threshold) {
2094  wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2095  min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2096  max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2097  wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2098  }
2099  av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2100  diff, avg_diff, wanted_nb_samples - nb_samples,
2102  }
2103  } else {
2104  /* too big difference : may be initial PTS errors, so
2105  reset A-V filter */
2106  is->audio_diff_avg_count = 0;
2107  is->audio_diff_cum = 0;
2108  }
2109  }
2110 
2111  return wanted_nb_samples;
2112 }
2113 
2114 /**
2115  * Decode one audio frame and return its uncompressed size.
2116  *
2117  * The processed audio frame is decoded, converted if required, and
2118  * stored in is->audio_buf, with size in bytes given by the return
2119  * value.
2120  */
2122 {
2123  AVPacket *pkt_temp = &is->audio_pkt_temp;
2124  AVPacket *pkt = &is->audio_pkt;
2125  AVCodecContext *dec = is->audio_st->codec;
2126  int len1, data_size, resampled_data_size;
2127  int64_t dec_channel_layout;
2128  int got_frame;
2129  av_unused double audio_clock0;
2130  int new_packet = 0;
2131  int flush_complete = 0;
2132  int wanted_nb_samples;
2133  AVRational tb;
2134  int ret;
2135  int reconfigure;
2136 
2137  for (;;) {
2138  /* NOTE: the audio packet can contain several frames */
2139  while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet) || is->audio_buf_frames_pending) {
2140  if (!is->frame) {
2141  if (!(is->frame = avcodec_alloc_frame()))
2142  return AVERROR(ENOMEM);
2143  } else {
2144  av_frame_unref(is->frame);
2146  }
2147 
2148  if (is->audioq.serial != is->audio_pkt_temp_serial)
2149  break;
2150 
2151  if (is->paused)
2152  return -1;
2153 
2154  if (!is->audio_buf_frames_pending) {
2155  if (flush_complete)
2156  break;
2157  new_packet = 0;
2158  len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2159  if (len1 < 0) {
2160  /* if error, we skip the frame */
2161  pkt_temp->size = 0;
2162  break;
2163  }
2164 
2165  pkt_temp->data += len1;
2166  pkt_temp->size -= len1;
2167 
2168  if (!got_frame) {
2169  /* stop sending empty packets if the decoder is finished */
2170  if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
2171  flush_complete = 1;
2172  continue;
2173  }
2174 
2175  tb = (AVRational){1, is->frame->sample_rate};
2176  if (is->frame->pts != AV_NOPTS_VALUE)
2177  is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2178  if (is->frame->pts == AV_NOPTS_VALUE && pkt_temp->pts != AV_NOPTS_VALUE)
2179  is->frame->pts = av_rescale_q(pkt_temp->pts, is->audio_st->time_base, tb);
2180  if (pkt_temp->pts != AV_NOPTS_VALUE)
2181  pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
2182 
2183 #if CONFIG_AVFILTER
2184  dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2185 
2186  reconfigure =
2187  cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2188  is->frame->format, av_frame_get_channels(is->frame)) ||
2189  is->audio_filter_src.channel_layout != dec_channel_layout ||
2190  is->audio_filter_src.freq != is->frame->sample_rate ||
2192 
2193  if (reconfigure) {
2194  char buf1[1024], buf2[1024];
2195  av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2196  av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2198  "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
2199  is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, is->audio_last_serial,
2201 
2202  is->audio_filter_src.fmt = is->frame->format;
2203  is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2204  is->audio_filter_src.channel_layout = dec_channel_layout;
2205  is->audio_filter_src.freq = is->frame->sample_rate;
2207 
2208  if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2209  return ret;
2210  }
2211 
2212  if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2213  return ret;
2214  av_frame_unref(is->frame);
2215 #endif
2216  }
2217 #if CONFIG_AVFILTER
2218  if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2219  if (ret == AVERROR(EAGAIN)) {
2220  is->audio_buf_frames_pending = 0;
2221  continue;
2222  }
2223  return ret;
2224  }
2225  is->audio_buf_frames_pending = 1;
2226  tb = is->out_audio_filter->inputs[0]->time_base;
2227 #endif
2228 
2230  is->frame->nb_samples,
2231  is->frame->format, 1);
2232 
2233  dec_channel_layout =
2236  wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2237 
2238  if (is->frame->format != is->audio_src.fmt ||
2239  dec_channel_layout != is->audio_src.channel_layout ||
2240  is->frame->sample_rate != is->audio_src.freq ||
2241  (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2242  swr_free(&is->swr_ctx);
2245  dec_channel_layout, is->frame->format, is->frame->sample_rate,
2246  0, NULL);
2247  if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2248  fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2251  break;
2252  }
2253  is->audio_src.channel_layout = dec_channel_layout;
2255  is->audio_src.freq = is->frame->sample_rate;
2256  is->audio_src.fmt = is->frame->format;
2257  }
2258 
2259  if (is->swr_ctx) {
2260  const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2261  uint8_t **out = &is->audio_buf1;
2262  int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2263  int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2264  int len2;
2265  if (out_size < 0) {
2266  fprintf(stderr, "av_samples_get_buffer_size() failed\n");
2267  break;
2268  }
2269  if (wanted_nb_samples != is->frame->nb_samples) {
2270  if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2271  wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2272  fprintf(stderr, "swr_set_compensation() failed\n");
2273  break;
2274  }
2275  }
2276  av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2277  if (!is->audio_buf1)
2278  return AVERROR(ENOMEM);
2279  len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2280  if (len2 < 0) {
2281  fprintf(stderr, "swr_convert() failed\n");
2282  break;
2283  }
2284  if (len2 == out_count) {
2285  fprintf(stderr, "warning: audio buffer is probably too small\n");
2286  swr_init(is->swr_ctx);
2287  }
2288  is->audio_buf = is->audio_buf1;
2289  resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2290  } else {
2291  is->audio_buf = is->frame->data[0];
2292  resampled_data_size = data_size;
2293  }
2294 
2295  audio_clock0 = is->audio_clock;
2296  /* update the audio clock with the pts */
2297  if (is->frame->pts != AV_NOPTS_VALUE) {
2298  is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2300  }
2301 #ifdef DEBUG
2302  {
2303  static double last_clock;
2304  printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2305  is->audio_clock - last_clock,
2306  is->audio_clock, audio_clock0);
2307  last_clock = is->audio_clock;
2308  }
2309 #endif
2310  return resampled_data_size;
2311  }
2312 
2313  /* free the current packet */
2314  if (pkt->data)
2315  av_free_packet(pkt);
2316  memset(pkt_temp, 0, sizeof(*pkt_temp));
2317 
2318  if (is->audioq.abort_request) {
2319  return -1;
2320  }
2321 
2322  if (is->audioq.nb_packets == 0)
2323  SDL_CondSignal(is->continue_read_thread);
2324 
2325  /* read next packet */
2326  if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2327  return -1;
2328 
2329  if (pkt->data == flush_pkt.data) {
2330  avcodec_flush_buffers(dec);
2331  flush_complete = 0;
2332  is->audio_buf_frames_pending = 0;
2333  }
2334 
2335  *pkt_temp = *pkt;
2336  }
2337 }
2338 
2339 /* prepare a new audio buffer */
2340 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2341 {
2342  VideoState *is = opaque;
2343  int audio_size, len1;
2344  int bytes_per_sec;
2346 
2348 
2349  while (len > 0) {
2350  if (is->audio_buf_index >= is->audio_buf_size) {
2351  audio_size = audio_decode_frame(is);
2352  if (audio_size < 0) {
2353  /* if error, just output silence */
2354  is->audio_buf = is->silence_buf;
2355  is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
2356  } else {
2357  if (is->show_mode != SHOW_MODE_VIDEO)
2358  update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2359  is->audio_buf_size = audio_size;
2360  }
2361  is->audio_buf_index = 0;
2362  }
2363  len1 = is->audio_buf_size - is->audio_buf_index;
2364  if (len1 > len)
2365  len1 = len;
2366  memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2367  len -= len1;
2368  stream += len1;
2369  is->audio_buf_index += len1;
2370  }
2371  bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2373  /* Let's assume the audio driver that is used by SDL has two periods. */
2374  is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
2376  if (is->audioq.serial == is->audio_clock_serial)
2378 }
2379 
2380 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2381 {
2382  SDL_AudioSpec wanted_spec, spec;
2383  const char *env;
2384  const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2385 
2386  env = SDL_getenv("SDL_AUDIO_CHANNELS");
2387  if (env) {
2388  wanted_nb_channels = atoi(env);
2389  wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2390  }
2391  if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2392  wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2393  wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2394  }
2395  wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2396  wanted_spec.freq = wanted_sample_rate;
2397  if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2398  fprintf(stderr, "Invalid sample rate or channel count!\n");
2399  return -1;
2400  }
2401  wanted_spec.format = AUDIO_S16SYS;
2402  wanted_spec.silence = 0;
2403  wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2404  wanted_spec.callback = sdl_audio_callback;
2405  wanted_spec.userdata = opaque;
2406  while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2407  fprintf(stderr, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
2408  wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2409  if (!wanted_spec.channels) {
2410  fprintf(stderr, "No more channel combinations to try, audio open failed\n");
2411  return -1;
2412  }
2413  wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2414  }
2415  if (spec.format != AUDIO_S16SYS) {
2416  fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
2417  return -1;
2418  }
2419  if (spec.channels != wanted_spec.channels) {
2420  wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2421  if (!wanted_channel_layout) {
2422  fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
2423  return -1;
2424  }
2425  }
2426 
2427  audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2428  audio_hw_params->freq = spec.freq;
2429  audio_hw_params->channel_layout = wanted_channel_layout;
2430  audio_hw_params->channels = spec.channels;
2431  return spec.size;
2432 }
2433 
2434 /* open a given stream. Return 0 if OK */
2435 static int stream_component_open(VideoState *is, int stream_index)
2436 {
2437  AVFormatContext *ic = is->ic;
2438  AVCodecContext *avctx;
2439  AVCodec *codec;
2440  const char *forced_codec_name = NULL;
2441  AVDictionary *opts;
2443  int sample_rate, nb_channels;
2444  int64_t channel_layout;
2445  int ret;
2446 
2447  if (stream_index < 0 || stream_index >= ic->nb_streams)
2448  return -1;
2449  avctx = ic->streams[stream_index]->codec;
2450 
2451  codec = avcodec_find_decoder(avctx->codec_id);
2452 
2453  switch(avctx->codec_type){
2454  case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2455  case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2456  case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2457  }
2458  if (forced_codec_name)
2459  codec = avcodec_find_decoder_by_name(forced_codec_name);
2460  if (!codec) {
2461  if (forced_codec_name) fprintf(stderr, "No codec could be found with name '%s'\n", forced_codec_name);
2462  else fprintf(stderr, "No codec could be found with id %d\n", avctx->codec_id);
2463  return -1;
2464  }
2465 
2466  avctx->codec_id = codec->id;
2468  avctx->lowres = lowres;
2469  if(avctx->lowres > codec->max_lowres){
2470  av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2471  codec->max_lowres);
2472  avctx->lowres= codec->max_lowres;
2473  }
2474  avctx->idct_algo = idct;
2476 
2477  if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2478  if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2479  if(codec->capabilities & CODEC_CAP_DR1)
2480  avctx->flags |= CODEC_FLAG_EMU_EDGE;
2481 
2482  opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2483  if (!av_dict_get(opts, "threads", NULL, 0))
2484  av_dict_set(&opts, "threads", "auto", 0);
2485  if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2486  av_dict_set(&opts, "refcounted_frames", "1", 0);
2487  if (avcodec_open2(avctx, codec, &opts) < 0)
2488  return -1;
2489  if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2490  av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2491  return AVERROR_OPTION_NOT_FOUND;
2492  }
2493 
2494  ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2495  switch (avctx->codec_type) {
2496  case AVMEDIA_TYPE_AUDIO:
2497 #if CONFIG_AVFILTER
2498  {
2499  AVFilterLink *link;
2500 
2501  is->audio_filter_src.freq = avctx->sample_rate;
2502  is->audio_filter_src.channels = avctx->channels;
2503  is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2504  is->audio_filter_src.fmt = avctx->sample_fmt;
2505  if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2506  return ret;
2507  link = is->out_audio_filter->inputs[0];
2508  sample_rate = link->sample_rate;
2509  nb_channels = link->channels;
2510  channel_layout = link->channel_layout;
2511  }
2512 #else
2513  sample_rate = avctx->sample_rate;
2514  nb_channels = avctx->channels;
2515  channel_layout = avctx->channel_layout;
2516 #endif
2517 
2518  /* prepare audio output */
2519  if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2520  return ret;
2521  is->audio_hw_buf_size = ret;
2522  is->audio_src = is->audio_tgt;
2523  is->audio_buf_size = 0;
2524  is->audio_buf_index = 0;
2525 
2526  /* init averaging filter */
2527  is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2528  is->audio_diff_avg_count = 0;
2529  /* since we do not have a precise anough audio fifo fullness,
2530  we correct audio sync only if larger than this threshold */
2532 
2533  memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2534  memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2535 
2536  is->audio_stream = stream_index;
2537  is->audio_st = ic->streams[stream_index];
2538 
2539  packet_queue_start(&is->audioq);
2540  SDL_PauseAudio(0);
2541  break;
2542  case AVMEDIA_TYPE_VIDEO:
2543  is->video_stream = stream_index;
2544  is->video_st = ic->streams[stream_index];
2545 
2546  packet_queue_start(&is->videoq);
2547  is->video_tid = SDL_CreateThread(video_thread, is);
2548  is->queue_attachments_req = 1;
2549  break;
2550  case AVMEDIA_TYPE_SUBTITLE:
2551  is->subtitle_stream = stream_index;
2552  is->subtitle_st = ic->streams[stream_index];
2554 
2555  is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2556  break;
2557  default:
2558  break;
2559  }
2560  return 0;
2561 }
2562 
2563 static void stream_component_close(VideoState *is, int stream_index)
2564 {
2565  AVFormatContext *ic = is->ic;
2566  AVCodecContext *avctx;
2567 
2568  if (stream_index < 0 || stream_index >= ic->nb_streams)
2569  return;
2570  avctx = ic->streams[stream_index]->codec;
2571 
2572  switch (avctx->codec_type) {
2573  case AVMEDIA_TYPE_AUDIO:
2574  packet_queue_abort(&is->audioq);
2575 
2576  SDL_CloseAudio();
2577 
2578  packet_queue_flush(&is->audioq);
2579  av_free_packet(&is->audio_pkt);
2580  swr_free(&is->swr_ctx);
2581  av_freep(&is->audio_buf1);
2582  is->audio_buf1_size = 0;
2583  is->audio_buf = NULL;
2584  av_frame_free(&is->frame);
2585 
2586  if (is->rdft) {
2587  av_rdft_end(is->rdft);
2588  av_freep(&is->rdft_data);
2589  is->rdft = NULL;
2590  is->rdft_bits = 0;
2591  }
2592 #if CONFIG_AVFILTER
2593  avfilter_graph_free(&is->agraph);
2594 #endif
2595  break;
2596  case AVMEDIA_TYPE_VIDEO:
2597  packet_queue_abort(&is->videoq);
2598 
2599  /* note: we also signal this mutex to make sure we deblock the
2600  video thread in all cases */
2601  SDL_LockMutex(is->pictq_mutex);
2602  SDL_CondSignal(is->pictq_cond);
2603  SDL_UnlockMutex(is->pictq_mutex);
2604 
2605  SDL_WaitThread(is->video_tid, NULL);
2606 
2607  packet_queue_flush(&is->videoq);
2608  break;
2609  case AVMEDIA_TYPE_SUBTITLE:
2611 
2612  /* note: we also signal this mutex to make sure we deblock the
2613  video thread in all cases */
2614  SDL_LockMutex(is->subpq_mutex);
2615  is->subtitle_stream_changed = 1;
2616 
2617  SDL_CondSignal(is->subpq_cond);
2618  SDL_UnlockMutex(is->subpq_mutex);
2619 
2620  SDL_WaitThread(is->subtitle_tid, NULL);
2621 
2623  break;
2624  default:
2625  break;
2626  }
2627 
2628  ic->streams[stream_index]->discard = AVDISCARD_ALL;
2629  avcodec_close(avctx);
2630  switch (avctx->codec_type) {
2631  case AVMEDIA_TYPE_AUDIO:
2632  is->audio_st = NULL;
2633  is->audio_stream = -1;
2634  break;
2635  case AVMEDIA_TYPE_VIDEO:
2636  is->video_st = NULL;
2637  is->video_stream = -1;
2638  break;
2639  case AVMEDIA_TYPE_SUBTITLE:
2640  is->subtitle_st = NULL;
2641  is->subtitle_stream = -1;
2642  break;
2643  default:
2644  break;
2645  }
2646 }
2647 
2648 static int decode_interrupt_cb(void *ctx)
2649 {
2650  VideoState *is = ctx;
2651  return is->abort_request;
2652 }
2653 
2655 {
2656  if( !strcmp(s->iformat->name, "rtp")
2657  || !strcmp(s->iformat->name, "rtsp")
2658  || !strcmp(s->iformat->name, "sdp")
2659  )
2660  return 1;
2661 
2662  if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2663  || !strncmp(s->filename, "udp:", 4)
2664  )
2665  )
2666  return 1;
2667  return 0;
2668 }
2669 
2670 /* this thread gets the stream from the disk or the network */
2671 static int read_thread(void *arg)
2672 {
2673  VideoState *is = arg;
2674  AVFormatContext *ic = NULL;
2675  int err, i, ret;
2676  int st_index[AVMEDIA_TYPE_NB];
2677  AVPacket pkt1, *pkt = &pkt1;
2678  int eof = 0;
2679  int pkt_in_play_range = 0;
2681  AVDictionary **opts;
2682  int orig_nb_streams;
2683  SDL_mutex *wait_mutex = SDL_CreateMutex();
2684 
2685  memset(st_index, -1, sizeof(st_index));
2686  is->last_video_stream = is->video_stream = -1;
2687  is->last_audio_stream = is->audio_stream = -1;
2688  is->last_subtitle_stream = is->subtitle_stream = -1;
2689 
2690  ic = avformat_alloc_context();
2692  ic->interrupt_callback.opaque = is;
2693  err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2694  if (err < 0) {
2695  print_error(is->filename, err);
2696  ret = -1;
2697  goto fail;
2698  }
2700  av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2702  goto fail;
2703  }
2704  is->ic = ic;
2705 
2706  if (genpts)
2707  ic->flags |= AVFMT_FLAG_GENPTS;
2708 
2710  orig_nb_streams = ic->nb_streams;
2711 
2712  err = avformat_find_stream_info(ic, opts);
2713  if (err < 0) {
2714  fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2715  ret = -1;
2716  goto fail;
2717  }
2718  for (i = 0; i < orig_nb_streams; i++)
2719  av_dict_free(&opts[i]);
2720  av_freep(&opts);
2721 
2722  if (ic->pb)
2723  ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2724 
2725  if (seek_by_bytes < 0)
2726  seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2727 
2728  is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2729 
2730  if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2731  window_title = av_asprintf("%s - %s", t->value, input_filename);
2732 
2733  /* if seeking requested, we execute it */
2734  if (start_time != AV_NOPTS_VALUE) {
2735  int64_t timestamp;
2736 
2737  timestamp = start_time;
2738  /* add the stream start time */
2739  if (ic->start_time != AV_NOPTS_VALUE)
2740  timestamp += ic->start_time;
2741  ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2742  if (ret < 0) {
2743  fprintf(stderr, "%s: could not seek to position %0.3f\n",
2744  is->filename, (double)timestamp / AV_TIME_BASE);
2745  }
2746  }
2747 
2748  is->realtime = is_realtime(ic);
2749 
2750  for (i = 0; i < ic->nb_streams; i++)
2751  ic->streams[i]->discard = AVDISCARD_ALL;
2752  if (!video_disable)
2753  st_index[AVMEDIA_TYPE_VIDEO] =
2756  if (!audio_disable)
2757  st_index[AVMEDIA_TYPE_AUDIO] =
2760  st_index[AVMEDIA_TYPE_VIDEO],
2761  NULL, 0);
2763  st_index[AVMEDIA_TYPE_SUBTITLE] =
2766  (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2767  st_index[AVMEDIA_TYPE_AUDIO] :
2768  st_index[AVMEDIA_TYPE_VIDEO]),
2769  NULL, 0);
2770  if (show_status) {
2771  av_dump_format(ic, 0, is->filename, 0);
2772  }
2773 
2774  is->show_mode = show_mode;
2775 
2776  /* open the streams */
2777  if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2778  stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2779  }
2780 
2781  ret = -1;
2782  if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2783  ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2784  }
2785  if (is->show_mode == SHOW_MODE_NONE)
2786  is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2787 
2788  if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2789  stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2790  }
2791 
2792  if (is->video_stream < 0 && is->audio_stream < 0) {
2793  fprintf(stderr, "%s: could not open codecs\n", is->filename);
2794  ret = -1;
2795  goto fail;
2796  }
2797 
2798  if (infinite_buffer < 0 && is->realtime)
2799  infinite_buffer = 1;
2800 
2801  for (;;) {
2802  if (is->abort_request)
2803  break;
2804  if (is->paused != is->last_paused) {
2805  is->last_paused = is->paused;
2806  if (is->paused)
2807  is->read_pause_return = av_read_pause(ic);
2808  else
2809  av_read_play(ic);
2810  }
2811 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2812  if (is->paused &&
2813  (!strcmp(ic->iformat->name, "rtsp") ||
2814  (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2815  /* wait 10 ms to avoid trying to get another packet */
2816  /* XXX: horrible */
2817  SDL_Delay(10);
2818  continue;
2819  }
2820 #endif
2821  if (is->seek_req) {
2822  int64_t seek_target = is->seek_pos;
2823  int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2824  int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2825 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2826 // of the seek_pos/seek_rel variables
2827 
2828  ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2829  if (ret < 0) {
2830  fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2831  } else {
2832  if (is->audio_stream >= 0) {
2833  packet_queue_flush(&is->audioq);
2834  packet_queue_put(&is->audioq, &flush_pkt);
2835  }
2836  if (is->subtitle_stream >= 0) {
2838  packet_queue_put(&is->subtitleq, &flush_pkt);
2839  }
2840  if (is->video_stream >= 0) {
2841  packet_queue_flush(&is->videoq);
2842  packet_queue_put(&is->videoq, &flush_pkt);
2843  }
2844  if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2846  } else {
2847  update_external_clock_pts(is, seek_target / (double)AV_TIME_BASE);
2848  }
2849  }
2850  is->seek_req = 0;
2851  is->queue_attachments_req = 1;
2852  eof = 0;
2853  if (is->paused)
2854  step_to_next_frame(is);
2855  }
2856  if (is->queue_attachments_req) {
2858  AVPacket copy;
2859  if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)
2860  goto fail;
2861  packet_queue_put(&is->videoq, &copy);
2862  }
2863  is->queue_attachments_req = 0;
2864  }
2865 
2866  /* if the queue are full, no need to read more */
2867  if (infinite_buffer<1 &&
2868  (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2869  || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2870  && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2872  && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2873  /* wait 10 ms */
2874  SDL_LockMutex(wait_mutex);
2875  SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2876  SDL_UnlockMutex(wait_mutex);
2877  continue;
2878  }
2879  if (eof) {
2880  if (is->video_stream >= 0) {
2881  av_init_packet(pkt);
2882  pkt->data = NULL;
2883  pkt->size = 0;
2884  pkt->stream_index = is->video_stream;
2885  packet_queue_put(&is->videoq, pkt);
2886  }
2887  if (is->audio_stream >= 0 &&
2889  av_init_packet(pkt);
2890  pkt->data = NULL;
2891  pkt->size = 0;
2892  pkt->stream_index = is->audio_stream;
2893  packet_queue_put(&is->audioq, pkt);
2894  }
2895  SDL_Delay(10);
2896  if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
2897  if (loop != 1 && (!loop || --loop)) {
2898  stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2899  } else if (autoexit) {
2900  ret = AVERROR_EOF;
2901  goto fail;
2902  }
2903  }
2904  eof=0;
2905  continue;
2906  }
2907  ret = av_read_frame(ic, pkt);
2908  if (ret < 0) {
2909  if (ret == AVERROR_EOF || url_feof(ic->pb))
2910  eof = 1;
2911  if (ic->pb && ic->pb->error)
2912  break;
2913  SDL_LockMutex(wait_mutex);
2914  SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2915  SDL_UnlockMutex(wait_mutex);
2916  continue;
2917  }
2918  /* check if packet is in play range specified by user, then queue, otherwise discard */
2919  pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2920  (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2921  av_q2d(ic->streams[pkt->stream_index]->time_base) -
2922  (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2923  <= ((double)duration / 1000000);
2924  if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2925  packet_queue_put(&is->audioq, pkt);
2926  } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2928  packet_queue_put(&is->videoq, pkt);
2929  } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2930  packet_queue_put(&is->subtitleq, pkt);
2931  } else {
2932  av_free_packet(pkt);
2933  }
2934  }
2935  /* wait until the end */
2936  while (!is->abort_request) {
2937  SDL_Delay(100);
2938  }
2939 
2940  ret = 0;
2941  fail:
2942  /* close each stream */
2943  if (is->audio_stream >= 0)
2945  if (is->video_stream >= 0)
2947  if (is->subtitle_stream >= 0)
2949  if (is->ic) {
2950  avformat_close_input(&is->ic);
2951  }
2952 
2953  if (ret != 0) {
2954  SDL_Event event;
2955 
2956  event.type = FF_QUIT_EVENT;
2957  event.user.data1 = is;
2958  SDL_PushEvent(&event);
2959  }
2960  SDL_DestroyMutex(wait_mutex);
2961  return 0;
2962 }
2963 
2964 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2965 {
2966  VideoState *is;
2967 
2968  is = av_mallocz(sizeof(VideoState));
2969  if (!is)
2970  return NULL;
2971  av_strlcpy(is->filename, filename, sizeof(is->filename));
2972  is->iformat = iformat;
2973  is->ytop = 0;
2974  is->xleft = 0;
2975 
2976  /* start video display */
2977  is->pictq_mutex = SDL_CreateMutex();
2978  is->pictq_cond = SDL_CreateCond();
2979 
2980  is->subpq_mutex = SDL_CreateMutex();
2981  is->subpq_cond = SDL_CreateCond();
2982 
2983  packet_queue_init(&is->videoq);
2984  packet_queue_init(&is->audioq);
2986 
2987  is->continue_read_thread = SDL_CreateCond();
2988 
2990  update_external_clock_speed(is, 1.0);
2991  is->audio_current_pts_drift = -av_gettime() / 1000000.0;
2993  is->audio_clock_serial = -1;
2994  is->video_clock_serial = -1;
2995  is->audio_last_serial = -1;
2996  is->av_sync_type = av_sync_type;
2997  is->read_tid = SDL_CreateThread(read_thread, is);
2998  if (!is->read_tid) {
2999  av_free(is);
3000  return NULL;
3001  }
3002  return is;
3003 }
3004 
3006 {
3007  AVFormatContext *ic = is->ic;
3008  int start_index, stream_index;
3009  int old_index;
3010  AVStream *st;
3011 
3012  if (codec_type == AVMEDIA_TYPE_VIDEO) {
3013  start_index = is->last_video_stream;
3014  old_index = is->video_stream;
3015  } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3016  start_index = is->last_audio_stream;
3017  old_index = is->audio_stream;
3018  } else {
3019  start_index = is->last_subtitle_stream;
3020  old_index = is->subtitle_stream;
3021  }
3022  stream_index = start_index;
3023  for (;;) {
3024  if (++stream_index >= is->ic->nb_streams)
3025  {
3026  if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3027  {
3028  stream_index = -1;
3029  is->last_subtitle_stream = -1;
3030  goto the_end;
3031  }
3032  if (start_index == -1)
3033  return;
3034  stream_index = 0;
3035  }
3036  if (stream_index == start_index)
3037  return;
3038  st = ic->streams[stream_index];
3039  if (st->codec->codec_type == codec_type) {
3040  /* check that parameters are OK */
3041  switch (codec_type) {
3042  case AVMEDIA_TYPE_AUDIO:
3043  if (st->codec->sample_rate != 0 &&
3044  st->codec->channels != 0)
3045  goto the_end;
3046  break;
3047  case AVMEDIA_TYPE_VIDEO:
3048  case AVMEDIA_TYPE_SUBTITLE:
3049  goto the_end;
3050  default:
3051  break;
3052  }
3053  }
3054  }
3055  the_end:
3056  stream_component_close(is, old_index);
3057  stream_component_open(is, stream_index);
3058 }
3059 
3060 
3062 {
3063 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3064  /* OS X needs to reallocate the SDL overlays */
3065  int i;
3066  for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3067  is->pictq[i].reallocate = 1;
3068 #endif
3070  video_open(is, 1, NULL);
3071 }
3072 
3074 {
3075  int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3076  int next = is->show_mode;
3077  do {
3078  next = (next + 1) % SHOW_MODE_NB;
3079  } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3080  if (is->show_mode != next) {
3082  is->xleft, is->ytop, is->width, is->height,
3083  bgcolor, 1);
3084  is->force_refresh = 1;
3085  is->show_mode = next;
3086  }
3087 }
3088 
3089 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3090  double remaining_time = 0.0;
3091  SDL_PumpEvents();
3092  while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3094  SDL_ShowCursor(0);
3095  cursor_hidden = 1;
3096  }
3097  if (remaining_time > 0.0)
3098  av_usleep((int64_t)(remaining_time * 1000000.0));
3099  remaining_time = REFRESH_RATE;
3100  if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3101  video_refresh(is, &remaining_time);
3102  SDL_PumpEvents();
3103  }
3104 }
3105 
3106 /* handle an event sent by the GUI */
3107 static void event_loop(VideoState *cur_stream)
3108 {
3109  SDL_Event event;
3110  double incr, pos, frac;
3111 
3112  for (;;) {
3113  double x;
3114  refresh_loop_wait_event(cur_stream, &event);
3115  switch (event.type) {
3116  case SDL_KEYDOWN:
3117  if (exit_on_keydown) {
3118  do_exit(cur_stream);
3119  break;
3120  }
3121  switch (event.key.keysym.sym) {
3122  case SDLK_ESCAPE:
3123  case SDLK_q:
3124  do_exit(cur_stream);
3125  break;
3126  case SDLK_f:
3127  toggle_full_screen(cur_stream);
3128  cur_stream->force_refresh = 1;
3129  break;
3130  case SDLK_p:
3131  case SDLK_SPACE:
3132  toggle_pause(cur_stream);
3133  break;
3134  case SDLK_s: // S: Step to next frame
3135  step_to_next_frame(cur_stream);
3136  break;
3137  case SDLK_a:
3139  break;
3140  case SDLK_v:
3142  break;
3143  case SDLK_t:
3145  break;
3146  case SDLK_w:
3147  toggle_audio_display(cur_stream);
3148  break;
3149  case SDLK_PAGEUP:
3150  incr = 600.0;
3151  goto do_seek;
3152  case SDLK_PAGEDOWN:
3153  incr = -600.0;
3154  goto do_seek;
3155  case SDLK_LEFT:
3156  incr = -10.0;
3157  goto do_seek;
3158  case SDLK_RIGHT:
3159  incr = 10.0;
3160  goto do_seek;
3161  case SDLK_UP:
3162  incr = 60.0;
3163  goto do_seek;
3164  case SDLK_DOWN:
3165  incr = -60.0;
3166  do_seek:
3167  if (seek_by_bytes) {
3168  if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
3169  pos = cur_stream->video_current_pos;
3170  } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
3171  pos = cur_stream->audio_pkt.pos;
3172  } else
3173  pos = avio_tell(cur_stream->ic->pb);
3174  if (cur_stream->ic->bit_rate)
3175  incr *= cur_stream->ic->bit_rate / 8.0;
3176  else
3177  incr *= 180000.0;
3178  pos += incr;
3179  stream_seek(cur_stream, pos, incr, 1);
3180  } else {
3181  pos = get_master_clock(cur_stream);
3182  if (isnan(pos))
3183  pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3184  pos += incr;
3185  if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3186  pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3187  stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3188  }
3189  break;
3190  default:
3191  break;
3192  }
3193  break;
3194  case SDL_VIDEOEXPOSE:
3195  cur_stream->force_refresh = 1;
3196  break;
3197  case SDL_MOUSEBUTTONDOWN:
3198  if (exit_on_mousedown) {
3199  do_exit(cur_stream);
3200  break;
3201  }
3202  case SDL_MOUSEMOTION:
3203  if (cursor_hidden) {
3204  SDL_ShowCursor(1);
3205  cursor_hidden = 0;
3206  }
3208  if (event.type == SDL_MOUSEBUTTONDOWN) {
3209  x = event.button.x;
3210  } else {
3211  if (event.motion.state != SDL_PRESSED)
3212  break;
3213  x = event.motion.x;
3214  }
3215  if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3216  uint64_t size = avio_size(cur_stream->ic->pb);
3217  stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3218  } else {
3219  int64_t ts;
3220  int ns, hh, mm, ss;
3221  int tns, thh, tmm, tss;
3222  tns = cur_stream->ic->duration / 1000000LL;
3223  thh = tns / 3600;
3224  tmm = (tns % 3600) / 60;
3225  tss = (tns % 60);
3226  frac = x / cur_stream->width;
3227  ns = frac * tns;
3228  hh = ns / 3600;
3229  mm = (ns % 3600) / 60;
3230  ss = (ns % 60);
3231  fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3232  hh, mm, ss, thh, tmm, tss);
3233  ts = frac * cur_stream->ic->duration;
3234  if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3235  ts += cur_stream->ic->start_time;
3236  stream_seek(cur_stream, ts, 0, 0);
3237  }
3238  break;
3239  case SDL_VIDEORESIZE:
3240  screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
3241  SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3242  screen_width = cur_stream->width = event.resize.w;
3243  screen_height = cur_stream->height = event.resize.h;
3244  cur_stream->force_refresh = 1;
3245  break;
3246  case SDL_QUIT:
3247  case FF_QUIT_EVENT:
3248  do_exit(cur_stream);
3249  break;
3250  case FF_ALLOC_EVENT:
3251  alloc_picture(event.user.data1);
3252  break;
3253  default:
3254  break;
3255  }
3256  }
3257 }
3258 
3259 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3260 {
3261  av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3262  return opt_default(NULL, "video_size", arg);
3263 }
3264 
3265 static int opt_width(void *optctx, const char *opt, const char *arg)
3266 {
3267  screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3268  return 0;
3269 }
3270 
3271 static int opt_height(void *optctx, const char *opt, const char *arg)
3272 {
3273  screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3274  return 0;
3275 }
3276 
3277 static int opt_format(void *optctx, const char *opt, const char *arg)
3278 {
3279  file_iformat = av_find_input_format(arg);
3280  if (!file_iformat) {
3281  fprintf(stderr, "Unknown input format: %s\n", arg);
3282  return AVERROR(EINVAL);
3283  }
3284  return 0;
3285 }
3286 
3287 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3288 {
3289  av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3290  return opt_default(NULL, "pixel_format", arg);
3291 }
3292 
3293 static int opt_sync(void *optctx, const char *opt, const char *arg)
3294 {
3295  if (!strcmp(arg, "audio"))
3297  else if (!strcmp(arg, "video"))
3299  else if (!strcmp(arg, "ext"))
3301  else {
3302  fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
3303  exit(1);
3304  }
3305  return 0;
3306 }
3307 
3308 static int opt_seek(void *optctx, const char *opt, const char *arg)
3309 {
3310  start_time = parse_time_or_die(opt, arg, 1);
3311  return 0;
3312 }
3313 
3314 static int opt_duration(void *optctx, const char *opt, const char *arg)
3315 {
3316  duration = parse_time_or_die(opt, arg, 1);
3317  return 0;
3318 }
3319 
3320 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3321 {
3322  show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3323  !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3324  !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3325  parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3326  return 0;
3327 }
3328 
3329 static void opt_input_file(void *optctx, const char *filename)
3330 {
3331  if (input_filename) {
3332  fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3333  filename, input_filename);
3334  exit(1);
3335  }
3336  if (!strcmp(filename, "-"))
3337  filename = "pipe:";
3338  input_filename = filename;
3339 }
3340 
3341 static int opt_codec(void *optctx, const char *opt, const char *arg)
3342 {
3343  const char *spec = strchr(opt, ':');
3344  if (!spec) {
3345  fprintf(stderr, "No media specifier was specified in '%s' in option '%s'\n",
3346  arg, opt);
3347  return AVERROR(EINVAL);
3348  }
3349  spec++;
3350  switch (spec[0]) {
3351  case 'a' : audio_codec_name = arg; break;
3352  case 's' : subtitle_codec_name = arg; break;
3353  case 'v' : video_codec_name = arg; break;
3354  default:
3355  fprintf(stderr, "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3356  return AVERROR(EINVAL);
3357  }
3358  return 0;
3359 }
3360 
3361 static int dummy;
3362 
3363 static const OptionDef options[] = {
3364 #include "cmdutils_common_opts.h"
3365  { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3366  { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3367  { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3368  { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3369  { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3370  { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3371  { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3372  { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3373  { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3374  { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3375  { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3376  { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3377  { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3378  { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3379  { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3380  { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3381  { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3382  { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3383  { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3384  { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3385  { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3386  { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3387  { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo", "algo" },
3388  { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options", "bit_mask" },
3389  { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3390  { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3391  { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3392  { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3393  { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3394  { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3395  { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3396  { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3397 #if CONFIG_AVFILTER
3398  { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "set video filters", "filter_graph" },
3399  { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3400 #endif
3401  { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3402  { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3403  { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3404  { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3405  { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3406  { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3407  { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3408  { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3409  { NULL, },
3410 };
3411 
3412 static void show_usage(void)
3413 {
3414  av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3415  av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3416  av_log(NULL, AV_LOG_INFO, "\n");
3417 }
3418 
3419 void show_help_default(const char *opt, const char *arg)
3420 {
3422  show_usage();
3423  show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3424  show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3425  printf("\n");
3428 #if !CONFIG_AVFILTER
3430 #else
3432 #endif
3433  printf("\nWhile playing:\n"
3434  "q, ESC quit\n"
3435  "f toggle full screen\n"
3436  "p, SPC pause\n"
3437  "a cycle audio channel\n"
3438  "v cycle video channel\n"
3439  "t cycle subtitle channel\n"
3440  "w show audio waves\n"
3441  "s activate frame-step mode\n"
3442  "left/right seek backward/forward 10 seconds\n"
3443  "down/up seek backward/forward 1 minute\n"
3444  "page down/page up seek backward/forward 10 minutes\n"
3445  "mouse click seek to percentage in file corresponding to fraction of width\n"
3446  );
3447 }
3448 
3449 static int lockmgr(void **mtx, enum AVLockOp op)
3450 {
3451  switch(op) {
3452  case AV_LOCK_CREATE:
3453  *mtx = SDL_CreateMutex();
3454  if(!*mtx)
3455  return 1;
3456  return 0;
3457  case AV_LOCK_OBTAIN:
3458  return !!SDL_LockMutex(*mtx);
3459  case AV_LOCK_RELEASE:
3460  return !!SDL_UnlockMutex(*mtx);
3461  case AV_LOCK_DESTROY:
3462  SDL_DestroyMutex(*mtx);
3463  return 0;
3464  }
3465  return 1;
3466 }
3467 
3468 /* Called from the main */
3469 int main(int argc, char **argv)
3470 {
3471  int flags;
3472  VideoState *is;
3473  char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3474 
3476  parse_loglevel(argc, argv, options);
3477 
3478  /* register all codecs, demux and protocols */
3480 #if CONFIG_AVDEVICE
3482 #endif
3483 #if CONFIG_AVFILTER
3485 #endif
3486  av_register_all();
3488 
3489  init_opts();
3490 
3491  signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3492  signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3493 
3494  show_banner(argc, argv, options);
3495 
3496  parse_options(NULL, argc, argv, options, opt_input_file);
3497 
3498  if (!input_filename) {
3499  show_usage();
3500  fprintf(stderr, "An input file must be specified\n");
3501  fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3502  exit(1);
3503  }
3504 
3505  if (display_disable) {
3506  video_disable = 1;
3507  }
3508  flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3509  if (audio_disable)
3510  flags &= ~SDL_INIT_AUDIO;
3511  if (display_disable)
3512  SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3513 #if !defined(__MINGW32__) && !defined(__APPLE__)
3514  flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3515 #endif
3516  if (SDL_Init (flags)) {
3517  fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3518  fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
3519  exit(1);
3520  }
3521 
3522  if (!display_disable) {
3523  const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3524  fs_screen_width = vi->current_w;
3525  fs_screen_height = vi->current_h;
3526  }
3527 
3528  SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3529  SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3530  SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3531 
3533  fprintf(stderr, "Could not initialize lock manager!\n");
3534  do_exit(NULL);
3535  }
3536 
3537  av_init_packet(&flush_pkt);
3538  flush_pkt.data = (uint8_t *)&flush_pkt;
3539 
3540  is = stream_open(input_filename, file_iformat);
3541  if (!is) {
3542  fprintf(stderr, "Failed to initialize VideoState!\n");
3543  do_exit(NULL);
3544  }
3545 
3546  event_loop(is);
3547 
3548  /* never returns */
3549 
3550  return 0;
3551 }