2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
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.
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.
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
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/colorspace.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avcodec.h"
52 # include "libavfilter/avfilter.h"
53 # include "libavfilter/buffersink.h"
54 # include "libavfilter/buffersrc.h"
58 #include <SDL_thread.h>
64 const char program_name[] = "ffplay";
65 const int program_birth_year = 2003;
67 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 /* SDL audio buffer size, in samples. Should be small to have precise
71 A/V sync as SDL does not have hardware buffer fullness info. */
72 #define SDL_AUDIO_BUFFER_SIZE 1024
74 /* no AV sync correction is done if below the minimum AV sync threshold */
75 #define AV_SYNC_THRESHOLD_MIN 0.04
76 /* AV sync correction is done if above the maximum AV sync threshold */
77 #define AV_SYNC_THRESHOLD_MAX 0.1
78 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
79 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
80 /* no AV correction is done if too big error */
81 #define AV_NOSYNC_THRESHOLD 10.0
83 /* maximum audio speed change to get correct sync */
84 #define SAMPLE_CORRECTION_PERCENT_MAX 10
86 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
87 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
88 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
89 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
91 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
92 #define AUDIO_DIFF_AVG_NB 20
94 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
95 #define REFRESH_RATE 0.01
97 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
98 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
99 #define SAMPLE_ARRAY_SIZE (8 * 65536)
101 #define CURSOR_HIDE_DELAY 1000000
103 static int64_t sws_flags = SWS_BICUBIC;
105 typedef struct MyAVPacketList {
107 struct MyAVPacketList *next;
111 typedef struct PacketQueue {
112 MyAVPacketList *first_pkt, *last_pkt;
121 #define VIDEO_PICTURE_QUEUE_SIZE 3
122 #define SUBPICTURE_QUEUE_SIZE 4
124 typedef struct VideoPicture {
125 double pts; // presentation timestamp for this picture
126 double duration; // estimated duration based on frame rate
127 int64_t pos; // byte position in file
129 int width, height; /* source height & width */
137 typedef struct SubPicture {
138 double pts; /* presentation time stamp for this picture */
143 typedef struct AudioParams {
146 int64_t channel_layout;
147 enum AVSampleFormat fmt;
152 typedef struct Clock {
153 double pts; /* clock base */
154 double pts_drift; /* clock base minus time at which we updated the clock */
157 int serial; /* clock is based on a packet with this serial */
159 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
163 AV_SYNC_AUDIO_MASTER, /* default choice */
164 AV_SYNC_VIDEO_MASTER,
165 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
168 typedef struct VideoState {
169 SDL_Thread *read_tid;
170 SDL_Thread *video_tid;
171 AVInputFormat *iformat;
177 int queue_attachments_req;
182 int read_pause_return;
197 int audio_clock_serial;
198 double audio_diff_cum; /* used for AV difference average computation */
199 double audio_diff_avg_coef;
200 double audio_diff_threshold;
201 int audio_diff_avg_count;
204 int audio_hw_buf_size;
205 uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
208 unsigned int audio_buf_size; /* in bytes */
209 unsigned int audio_buf1_size;
210 int audio_buf_index; /* in bytes */
211 int audio_write_buf_size;
212 int audio_buf_frames_pending;
213 AVPacket audio_pkt_temp;
215 int audio_pkt_temp_serial;
216 int audio_last_serial;
217 struct AudioParams audio_src;
219 struct AudioParams audio_filter_src;
221 struct AudioParams audio_tgt;
222 struct SwrContext *swr_ctx;
223 int frame_drops_early;
224 int frame_drops_late;
226 int64_t audio_frame_next_pts;
229 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
231 int16_t sample_array[SAMPLE_ARRAY_SIZE];
232 int sample_array_index;
236 FFTSample *rdft_data;
238 double last_vis_time;
240 SDL_Thread *subtitle_tid;
242 AVStream *subtitle_st;
243 PacketQueue subtitleq;
244 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
245 int subpq_size, subpq_rindex, subpq_windex;
246 SDL_mutex *subpq_mutex;
247 SDL_cond *subpq_cond;
250 double frame_last_returned_time;
251 double frame_last_filter_delay;
255 int64_t video_current_pos; // current displayed file pos
256 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
257 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
258 int pictq_size, pictq_rindex, pictq_windex;
259 SDL_mutex *pictq_mutex;
260 SDL_cond *pictq_cond;
262 struct SwsContext *img_convert_ctx;
264 SDL_Rect last_display_rect;
267 int width, height, xleft, ytop;
272 AVFilterContext *in_video_filter; // the first filter in the video chain
273 AVFilterContext *out_video_filter; // the last filter in the video chain
274 AVFilterContext *in_audio_filter; // the first filter in the audio chain
275 AVFilterContext *out_audio_filter; // the last filter in the audio chain
276 AVFilterGraph *agraph; // audio filter graph
279 int last_video_stream, last_audio_stream, last_subtitle_stream;
281 SDL_cond *continue_read_thread;
284 /* options specified by the user */
285 static AVInputFormat *file_iformat;
286 static const char *input_filename;
287 static const char *window_title;
288 static int fs_screen_width;
289 static int fs_screen_height;
290 static int default_width = 640;
291 static int default_height = 480;
292 static int screen_width = 0;
293 static int screen_height = 0;
294 static int audio_disable;
295 static int video_disable;
296 static int subtitle_disable;
297 static int wanted_stream[AVMEDIA_TYPE_NB] = {
298 [AVMEDIA_TYPE_AUDIO] = -1,
299 [AVMEDIA_TYPE_VIDEO] = -1,
300 [AVMEDIA_TYPE_SUBTITLE] = -1,
302 static int seek_by_bytes = -1;
303 static int display_disable;
304 static int show_status = 1;
305 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
306 static int64_t start_time = AV_NOPTS_VALUE;
307 static int64_t duration = AV_NOPTS_VALUE;
308 static int workaround_bugs = 1;
310 static int genpts = 0;
311 static int lowres = 0;
312 static int decoder_reorder_pts = -1;
314 static int exit_on_keydown;
315 static int exit_on_mousedown;
317 static int framedrop = -1;
318 static int infinite_buffer = -1;
319 static enum ShowMode show_mode = SHOW_MODE_NONE;
320 static const char *audio_codec_name;
321 static const char *subtitle_codec_name;
322 static const char *video_codec_name;
323 double rdftspeed = 0.02;
324 static int64_t cursor_last_shown;
325 static int cursor_hidden = 0;
327 static const char **vfilters_list = NULL;
328 static int nb_vfilters = 0;
329 static char *afilters = NULL;
331 static int autorotate = 1;
333 /* current context */
334 static int is_full_screen;
335 static int64_t audio_callback_time;
337 static AVPacket flush_pkt;
339 #define FF_ALLOC_EVENT (SDL_USEREVENT)
340 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
342 static SDL_Surface *screen;
345 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
347 GROW_ARRAY(vfilters_list, nb_vfilters);
348 vfilters_list[nb_vfilters - 1] = arg;
354 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
355 enum AVSampleFormat fmt2, int64_t channel_count2)
357 /* If channel count == 1, planar and non-planar formats are the same */
358 if (channel_count1 == 1 && channel_count2 == 1)
359 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
361 return channel_count1 != channel_count2 || fmt1 != fmt2;
365 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
367 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
368 return channel_layout;
373 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
375 MyAVPacketList *pkt1;
377 if (q->abort_request)
380 pkt1 = av_malloc(sizeof(MyAVPacketList));
385 if (pkt == &flush_pkt)
387 pkt1->serial = q->serial;
392 q->last_pkt->next = pkt1;
395 q->size += pkt1->pkt.size + sizeof(*pkt1);
396 /* XXX: should duplicate packet data in DV case */
397 SDL_CondSignal(q->cond);
401 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
405 /* duplicate the packet */
406 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
409 SDL_LockMutex(q->mutex);
410 ret = packet_queue_put_private(q, pkt);
411 SDL_UnlockMutex(q->mutex);
413 if (pkt != &flush_pkt && ret < 0)
419 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
421 AVPacket pkt1, *pkt = &pkt1;
425 pkt->stream_index = stream_index;
426 return packet_queue_put(q, pkt);
429 /* packet queue handling */
430 static void packet_queue_init(PacketQueue *q)
432 memset(q, 0, sizeof(PacketQueue));
433 q->mutex = SDL_CreateMutex();
434 q->cond = SDL_CreateCond();
435 q->abort_request = 1;
438 static void packet_queue_flush(PacketQueue *q)
440 MyAVPacketList *pkt, *pkt1;
442 SDL_LockMutex(q->mutex);
443 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
445 av_free_packet(&pkt->pkt);
452 SDL_UnlockMutex(q->mutex);
455 static void packet_queue_destroy(PacketQueue *q)
457 packet_queue_flush(q);
458 SDL_DestroyMutex(q->mutex);
459 SDL_DestroyCond(q->cond);
462 static void packet_queue_abort(PacketQueue *q)
464 SDL_LockMutex(q->mutex);
466 q->abort_request = 1;
468 SDL_CondSignal(q->cond);
470 SDL_UnlockMutex(q->mutex);
473 static void packet_queue_start(PacketQueue *q)
475 SDL_LockMutex(q->mutex);
476 q->abort_request = 0;
477 packet_queue_put_private(q, &flush_pkt);
478 SDL_UnlockMutex(q->mutex);
481 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
482 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
484 MyAVPacketList *pkt1;
487 SDL_LockMutex(q->mutex);
490 if (q->abort_request) {
497 q->first_pkt = pkt1->next;
501 q->size -= pkt1->pkt.size + sizeof(*pkt1);
504 *serial = pkt1->serial;
512 SDL_CondWait(q->cond, q->mutex);
515 SDL_UnlockMutex(q->mutex);
519 static inline void fill_rectangle(SDL_Surface *screen,
520 int x, int y, int w, int h, int color, int update)
527 SDL_FillRect(screen, &rect, color);
528 if (update && w > 0 && h > 0)
529 SDL_UpdateRect(screen, x, y, w, h);
532 /* draw only the border of a rectangle */
533 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
537 /* fill the background */
541 w2 = width - (x + w);
547 h2 = height - (y + h);
550 fill_rectangle(screen,
554 fill_rectangle(screen,
555 xleft + width - w2, ytop,
558 fill_rectangle(screen,
562 fill_rectangle(screen,
563 xleft + w1, ytop + height - h2,
568 #define ALPHA_BLEND(a, oldp, newp, s)\
569 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
571 #define RGBA_IN(r, g, b, a, s)\
573 unsigned int v = ((const uint32_t *)(s))[0];\
574 a = (v >> 24) & 0xff;\
575 r = (v >> 16) & 0xff;\
576 g = (v >> 8) & 0xff;\
580 #define YUVA_IN(y, u, v, a, s, pal)\
582 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
583 a = (val >> 24) & 0xff;\
584 y = (val >> 16) & 0xff;\
585 u = (val >> 8) & 0xff;\
589 #define YUVA_OUT(d, y, u, v, a)\
591 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
597 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
599 int wrap, wrap3, width2, skip2;
600 int y, u, v, a, u1, v1, a1, w, h;
601 uint8_t *lum, *cb, *cr;
604 int dstx, dsty, dstw, dsth;
606 dstw = av_clip(rect->w, 0, imgw);
607 dsth = av_clip(rect->h, 0, imgh);
608 dstx = av_clip(rect->x, 0, imgw - dstw);
609 dsty = av_clip(rect->y, 0, imgh - dsth);
610 lum = dst->data[0] + dsty * dst->linesize[0];
611 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
612 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
614 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
616 wrap = dst->linesize[0];
617 wrap3 = rect->pict.linesize[0];
618 p = rect->pict.data[0];
619 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
627 YUVA_IN(y, u, v, a, p, pal);
628 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
629 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
630 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
636 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
637 YUVA_IN(y, u, v, a, p, pal);
641 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
643 YUVA_IN(y, u, v, a, p + BPP, pal);
647 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
648 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
649 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
656 YUVA_IN(y, u, v, a, p, pal);
657 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
658 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
659 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
663 p += wrap3 - dstw * BPP;
664 lum += wrap - dstw - dstx;
665 cb += dst->linesize[1] - width2 - skip2;
666 cr += dst->linesize[2] - width2 - skip2;
668 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
674 YUVA_IN(y, u, v, a, p, pal);
678 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
681 YUVA_IN(y, u, v, a, p, pal);
685 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
686 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
687 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
693 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
694 YUVA_IN(y, u, v, a, p, pal);
698 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
700 YUVA_IN(y, u, v, a, p + BPP, pal);
704 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
708 YUVA_IN(y, u, v, a, p, pal);
712 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
714 YUVA_IN(y, u, v, a, p + BPP, pal);
718 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
720 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
721 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
725 p += -wrap3 + 2 * BPP;
729 YUVA_IN(y, u, v, a, p, pal);
733 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
736 YUVA_IN(y, u, v, a, p, pal);
740 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
741 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
742 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
748 p += wrap3 + (wrap3 - dstw * BPP);
749 lum += wrap + (wrap - dstw - dstx);
750 cb += dst->linesize[1] - width2 - skip2;
751 cr += dst->linesize[2] - width2 - skip2;
753 /* handle odd height */
760 YUVA_IN(y, u, v, a, p, pal);
761 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
762 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
763 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
769 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
770 YUVA_IN(y, u, v, a, p, pal);
774 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
776 YUVA_IN(y, u, v, a, p + BPP, pal);
780 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
781 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
782 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
789 YUVA_IN(y, u, v, a, p, pal);
790 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
791 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
792 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
797 static void free_picture(VideoPicture *vp)
800 SDL_FreeYUVOverlay(vp->bmp);
805 static void free_subpicture(SubPicture *sp)
807 avsubtitle_free(&sp->sub);
810 static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, VideoPicture *vp)
813 int width, height, x, y;
815 if (vp->sar.num == 0)
818 aspect_ratio = av_q2d(vp->sar);
820 if (aspect_ratio <= 0.0)
822 aspect_ratio *= (float)vp->width / (float)vp->height;
824 /* XXX: we suppose the screen has a 1.0 pixel ratio */
826 width = ((int)rint(height * aspect_ratio)) & ~1;
827 if (width > scr_width) {
829 height = ((int)rint(width / aspect_ratio)) & ~1;
831 x = (scr_width - width) / 2;
832 y = (scr_height - height) / 2;
833 rect->x = scr_xleft + x;
834 rect->y = scr_ytop + y;
835 rect->w = FFMAX(width, 1);
836 rect->h = FFMAX(height, 1);
839 static void video_image_display(VideoState *is)
847 vp = &is->pictq[is->pictq_rindex];
849 if (is->subtitle_st) {
850 if (is->subpq_size > 0) {
851 sp = &is->subpq[is->subpq_rindex];
853 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
854 SDL_LockYUVOverlay (vp->bmp);
856 pict.data[0] = vp->bmp->pixels[0];
857 pict.data[1] = vp->bmp->pixels[2];
858 pict.data[2] = vp->bmp->pixels[1];
860 pict.linesize[0] = vp->bmp->pitches[0];
861 pict.linesize[1] = vp->bmp->pitches[2];
862 pict.linesize[2] = vp->bmp->pitches[1];
864 for (i = 0; i < sp->sub.num_rects; i++)
865 blend_subrect(&pict, sp->sub.rects[i],
866 vp->bmp->w, vp->bmp->h);
868 SDL_UnlockYUVOverlay (vp->bmp);
873 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp);
875 SDL_DisplayYUVOverlay(vp->bmp, &rect);
877 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) {
878 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
879 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
880 is->last_display_rect = rect;
885 static inline int compute_mod(int a, int b)
887 return a < 0 ? a%b + b : a%b;
890 static void video_audio_display(VideoState *s)
892 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
893 int ch, channels, h, h2, bgcolor, fgcolor;
895 int rdft_bits, nb_freq;
897 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
899 nb_freq = 1 << (rdft_bits - 1);
901 /* compute display index : center on currently output samples */
902 channels = s->audio_tgt.channels;
903 nb_display_channels = channels;
905 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
907 delay = s->audio_write_buf_size;
910 /* to be more precise, we take into account the time spent since
911 the last buffer computation */
912 if (audio_callback_time) {
913 time_diff = av_gettime_relative() - audio_callback_time;
914 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
917 delay += 2 * data_used;
918 if (delay < data_used)
921 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
922 if (s->show_mode == SHOW_MODE_WAVES) {
924 for (i = 0; i < 1000; i += channels) {
925 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
926 int a = s->sample_array[idx];
927 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
928 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
929 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
931 if (h < score && (b ^ c) < 0) {
938 s->last_i_start = i_start;
940 i_start = s->last_i_start;
943 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
944 if (s->show_mode == SHOW_MODE_WAVES) {
945 fill_rectangle(screen,
946 s->xleft, s->ytop, s->width, s->height,
949 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
951 /* total height for one channel */
952 h = s->height / nb_display_channels;
953 /* graph height / 2 */
955 for (ch = 0; ch < nb_display_channels; ch++) {
957 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
958 for (x = 0; x < s->width; x++) {
959 y = (s->sample_array[i] * h2) >> 15;
966 fill_rectangle(screen,
967 s->xleft + x, ys, 1, y,
970 if (i >= SAMPLE_ARRAY_SIZE)
971 i -= SAMPLE_ARRAY_SIZE;
975 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
977 for (ch = 1; ch < nb_display_channels; ch++) {
978 y = s->ytop + ch * h;
979 fill_rectangle(screen,
980 s->xleft, y, s->width, 1,
983 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
985 nb_display_channels= FFMIN(nb_display_channels, 2);
986 if (rdft_bits != s->rdft_bits) {
987 av_rdft_end(s->rdft);
988 av_free(s->rdft_data);
989 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
990 s->rdft_bits = rdft_bits;
991 s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
995 for (ch = 0; ch < nb_display_channels; ch++) {
996 data[ch] = s->rdft_data + 2 * nb_freq * ch;
998 for (x = 0; x < 2 * nb_freq; x++) {
999 double w = (x-nb_freq) * (1.0 / nb_freq);
1000 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1002 if (i >= SAMPLE_ARRAY_SIZE)
1003 i -= SAMPLE_ARRAY_SIZE;
1005 av_rdft_calc(s->rdft, data[ch]);
1007 /* Least efficient way to do this, we should of course
1008 * directly access it but it is more than fast enough. */
1009 for (y = 0; y < s->height; y++) {
1010 double w = 1 / sqrt(nb_freq);
1011 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]));
1012 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1013 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1016 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1018 fill_rectangle(screen,
1019 s->xpos, s->height-y, 1, 1,
1023 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1026 if (s->xpos >= s->width)
1031 static void stream_close(VideoState *is)
1034 /* XXX: use a special url_shutdown call to abort parse cleanly */
1035 is->abort_request = 1;
1036 SDL_WaitThread(is->read_tid, NULL);
1037 packet_queue_destroy(&is->videoq);
1038 packet_queue_destroy(&is->audioq);
1039 packet_queue_destroy(&is->subtitleq);
1041 /* free all pictures */
1042 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
1043 free_picture(&is->pictq[i]);
1044 for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
1045 free_subpicture(&is->subpq[i]);
1046 SDL_DestroyMutex(is->pictq_mutex);
1047 SDL_DestroyCond(is->pictq_cond);
1048 SDL_DestroyMutex(is->subpq_mutex);
1049 SDL_DestroyCond(is->subpq_cond);
1050 SDL_DestroyCond(is->continue_read_thread);
1051 #if !CONFIG_AVFILTER
1052 sws_freeContext(is->img_convert_ctx);
1057 static void do_exit(VideoState *is)
1062 av_lockmgr_register(NULL);
1065 av_freep(&vfilters_list);
1067 avformat_network_deinit();
1071 av_log(NULL, AV_LOG_QUIET, "%s", "");
1075 static void sigterm_handler(int sig)
1080 static void set_default_window_size(VideoPicture *vp)
1083 calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
1084 default_width = rect.w;
1085 default_height = rect.h;
1088 static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
1090 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1093 if (is_full_screen) flags |= SDL_FULLSCREEN;
1094 else flags |= SDL_RESIZABLE;
1096 if (vp && vp->width)
1097 set_default_window_size(vp);
1099 if (is_full_screen && fs_screen_width) {
1100 w = fs_screen_width;
1101 h = fs_screen_height;
1102 } else if (!is_full_screen && screen_width) {
1109 w = FFMIN(16383, w);
1110 if (screen && is->width == screen->w && screen->w == w
1111 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1113 screen = SDL_SetVideoMode(w, h, 0, flags);
1115 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1119 window_title = input_filename;
1120 SDL_WM_SetCaption(window_title, window_title);
1122 is->width = screen->w;
1123 is->height = screen->h;
1128 /* display the current picture, if any */
1129 static void video_display(VideoState *is)
1132 video_open(is, 0, NULL);
1133 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1134 video_audio_display(is);
1135 else if (is->video_st)
1136 video_image_display(is);
1139 static double get_clock(Clock *c)
1141 if (*c->queue_serial != c->serial)
1146 double time = av_gettime_relative() / 1000000.0;
1147 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1151 static void set_clock_at(Clock *c, double pts, int serial, double time)
1154 c->last_updated = time;
1155 c->pts_drift = c->pts - time;
1159 static void set_clock(Clock *c, double pts, int serial)
1161 double time = av_gettime_relative() / 1000000.0;
1162 set_clock_at(c, pts, serial, time);
1165 static void set_clock_speed(Clock *c, double speed)
1167 set_clock(c, get_clock(c), c->serial);
1171 static void init_clock(Clock *c, int *queue_serial)
1175 c->queue_serial = queue_serial;
1176 set_clock(c, NAN, -1);
1179 static void sync_clock_to_slave(Clock *c, Clock *slave)
1181 double clock = get_clock(c);
1182 double slave_clock = get_clock(slave);
1183 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1184 set_clock(c, slave_clock, slave->serial);
1187 static int get_master_sync_type(VideoState *is) {
1188 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1190 return AV_SYNC_VIDEO_MASTER;
1192 return AV_SYNC_AUDIO_MASTER;
1193 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1195 return AV_SYNC_AUDIO_MASTER;
1197 return AV_SYNC_EXTERNAL_CLOCK;
1199 return AV_SYNC_EXTERNAL_CLOCK;
1203 /* get the current master clock value */
1204 static double get_master_clock(VideoState *is)
1208 switch (get_master_sync_type(is)) {
1209 case AV_SYNC_VIDEO_MASTER:
1210 val = get_clock(&is->vidclk);
1212 case AV_SYNC_AUDIO_MASTER:
1213 val = get_clock(&is->audclk);
1216 val = get_clock(&is->extclk);
1222 static void check_external_clock_speed(VideoState *is) {
1223 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1224 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1225 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1226 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1227 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1228 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1230 double speed = is->extclk.speed;
1232 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1236 /* seek in the stream */
1237 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1239 if (!is->seek_req) {
1242 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1244 is->seek_flags |= AVSEEK_FLAG_BYTE;
1246 SDL_CondSignal(is->continue_read_thread);
1250 /* pause or resume the video */
1251 static void stream_toggle_pause(VideoState *is)
1254 is->frame_timer += av_gettime_relative() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1255 if (is->read_pause_return != AVERROR(ENOSYS)) {
1256 is->vidclk.paused = 0;
1258 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1260 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1261 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1264 static void toggle_pause(VideoState *is)
1266 stream_toggle_pause(is);
1270 static void step_to_next_frame(VideoState *is)
1272 /* if the stream is paused unpause it, then step */
1274 stream_toggle_pause(is);
1278 static double compute_target_delay(double delay, VideoState *is)
1280 double sync_threshold, diff;
1282 /* update delay to follow master synchronisation source */
1283 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1284 /* if video is slave, we try to correct big delays by
1285 duplicating or deleting a frame */
1286 diff = get_clock(&is->vidclk) - get_master_clock(is);
1288 /* skip or repeat frame. We take into account the
1289 delay to compute the threshold. I still don't know
1290 if it is the best guess */
1291 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1292 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1293 if (diff <= -sync_threshold)
1294 delay = FFMAX(0, delay + diff);
1295 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1296 delay = delay + diff;
1297 else if (diff >= sync_threshold)
1302 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1308 static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp) {
1309 if (vp->serial == nextvp->serial) {
1310 double duration = nextvp->pts - vp->pts;
1311 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1312 return vp->duration;
1320 static void pictq_next_picture(VideoState *is) {
1321 /* update queue size and signal for next picture */
1322 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1323 is->pictq_rindex = 0;
1325 SDL_LockMutex(is->pictq_mutex);
1327 SDL_CondSignal(is->pictq_cond);
1328 SDL_UnlockMutex(is->pictq_mutex);
1331 static int pictq_prev_picture(VideoState *is) {
1332 VideoPicture *prevvp;
1334 /* update queue size and signal for the previous picture */
1335 prevvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
1336 if (prevvp->allocated && prevvp->serial == is->videoq.serial) {
1337 SDL_LockMutex(is->pictq_mutex);
1338 if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE) {
1339 if (--is->pictq_rindex == -1)
1340 is->pictq_rindex = VIDEO_PICTURE_QUEUE_SIZE - 1;
1344 SDL_CondSignal(is->pictq_cond);
1345 SDL_UnlockMutex(is->pictq_mutex);
1350 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1351 /* update current video pts */
1352 set_clock(&is->vidclk, pts, serial);
1353 sync_clock_to_slave(&is->extclk, &is->vidclk);
1354 is->video_current_pos = pos;
1357 /* called to display each frame */
1358 static void video_refresh(void *opaque, double *remaining_time)
1360 VideoState *is = opaque;
1363 SubPicture *sp, *sp2;
1365 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1366 check_external_clock_speed(is);
1368 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1369 time = av_gettime_relative() / 1000000.0;
1370 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1372 is->last_vis_time = time;
1374 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1379 if (is->force_refresh)
1380 redisplay = pictq_prev_picture(is);
1382 if (is->pictq_size == 0) {
1383 // nothing to do, no picture to display in the queue
1385 double last_duration, duration, delay;
1386 VideoPicture *vp, *lastvp;
1388 /* dequeue the picture */
1389 vp = &is->pictq[is->pictq_rindex];
1390 lastvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
1392 if (vp->serial != is->videoq.serial) {
1393 pictq_next_picture(is);
1394 is->video_current_pos = -1;
1399 if (lastvp->serial != vp->serial && !redisplay)
1400 is->frame_timer = av_gettime_relative() / 1000000.0;
1405 /* compute nominal last_duration */
1406 last_duration = vp_duration(is, lastvp, vp);
1410 delay = compute_target_delay(last_duration, is);
1412 time= av_gettime_relative()/1000000.0;
1413 if (time < is->frame_timer + delay && !redisplay) {
1414 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1418 is->frame_timer += delay;
1419 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1420 is->frame_timer = time;
1422 SDL_LockMutex(is->pictq_mutex);
1423 if (!redisplay && !isnan(vp->pts))
1424 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1425 SDL_UnlockMutex(is->pictq_mutex);
1427 if (is->pictq_size > 1) {
1428 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
1429 duration = vp_duration(is, vp, nextvp);
1430 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1432 is->frame_drops_late++;
1433 pictq_next_picture(is);
1439 if (is->subtitle_st) {
1440 while (is->subpq_size > 0) {
1441 sp = &is->subpq[is->subpq_rindex];
1443 if (is->subpq_size > 1)
1444 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1448 if (sp->serial != is->subtitleq.serial
1449 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1450 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1452 free_subpicture(sp);
1454 /* update queue size and signal for next picture */
1455 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1456 is->subpq_rindex = 0;
1458 SDL_LockMutex(is->subpq_mutex);
1460 SDL_CondSignal(is->subpq_cond);
1461 SDL_UnlockMutex(is->subpq_mutex);
1469 /* display picture */
1470 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1473 pictq_next_picture(is);
1475 if (is->step && !is->paused)
1476 stream_toggle_pause(is);
1479 is->force_refresh = 0;
1481 static int64_t last_time;
1483 int aqsize, vqsize, sqsize;
1486 cur_time = av_gettime_relative();
1487 if (!last_time || (cur_time - last_time) >= 30000) {
1492 aqsize = is->audioq.size;
1494 vqsize = is->videoq.size;
1495 if (is->subtitle_st)
1496 sqsize = is->subtitleq.size;
1498 if (is->audio_st && is->video_st)
1499 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1500 else if (is->video_st)
1501 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1502 else if (is->audio_st)
1503 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1504 av_log(NULL, AV_LOG_INFO,
1505 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1506 get_master_clock(is),
1507 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1509 is->frame_drops_early + is->frame_drops_late,
1513 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1514 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1516 last_time = cur_time;
1521 /* allocate a picture (needs to do that in main thread to avoid
1522 potential locking problems */
1523 static void alloc_picture(VideoState *is)
1528 vp = &is->pictq[is->pictq_windex];
1532 video_open(is, 0, vp);
1534 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1537 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1538 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1539 /* SDL allocates a buffer smaller than requested if the video
1540 * overlay hardware is unable to support the requested size. */
1541 av_log(NULL, AV_LOG_FATAL,
1542 "Error: the video system does not support an image\n"
1543 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1544 "to reduce the image size.\n", vp->width, vp->height );
1548 SDL_LockMutex(is->pictq_mutex);
1550 SDL_CondSignal(is->pictq_cond);
1551 SDL_UnlockMutex(is->pictq_mutex);
1554 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1555 int i, width, height;
1557 for (i = 0; i < 3; i++) {
1564 if (bmp->pitches[i] > width) {
1565 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1566 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1572 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1576 #if defined(DEBUG_SYNC) && 0
1577 printf("frame_type=%c pts=%0.3f\n",
1578 av_get_picture_type_char(src_frame->pict_type), pts);
1581 /* wait until we have space to put a new picture */
1582 SDL_LockMutex(is->pictq_mutex);
1584 /* keep the last already displayed picture in the queue */
1585 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 1 &&
1586 !is->videoq.abort_request) {
1587 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1589 SDL_UnlockMutex(is->pictq_mutex);
1591 if (is->videoq.abort_request)
1594 vp = &is->pictq[is->pictq_windex];
1596 vp->sar = src_frame->sample_aspect_ratio;
1598 /* alloc or resize hardware picture buffer */
1599 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1600 vp->width != src_frame->width ||
1601 vp->height != src_frame->height) {
1606 vp->width = src_frame->width;
1607 vp->height = src_frame->height;
1609 /* the allocation must be done in the main thread to avoid
1610 locking problems. */
1611 event.type = FF_ALLOC_EVENT;
1612 event.user.data1 = is;
1613 SDL_PushEvent(&event);
1615 /* wait until the picture is allocated */
1616 SDL_LockMutex(is->pictq_mutex);
1617 while (!vp->allocated && !is->videoq.abort_request) {
1618 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1620 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1621 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1622 while (!vp->allocated && !is->abort_request) {
1623 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1626 SDL_UnlockMutex(is->pictq_mutex);
1628 if (is->videoq.abort_request)
1632 /* if the frame is not skipped, then display it */
1634 AVPicture pict = { { 0 } };
1636 /* get a pointer on the bitmap */
1637 SDL_LockYUVOverlay (vp->bmp);
1639 pict.data[0] = vp->bmp->pixels[0];
1640 pict.data[1] = vp->bmp->pixels[2];
1641 pict.data[2] = vp->bmp->pixels[1];
1643 pict.linesize[0] = vp->bmp->pitches[0];
1644 pict.linesize[1] = vp->bmp->pitches[2];
1645 pict.linesize[2] = vp->bmp->pitches[1];
1648 // FIXME use direct rendering
1649 av_picture_copy(&pict, (AVPicture *)src_frame,
1650 src_frame->format, vp->width, vp->height);
1652 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1653 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1654 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1655 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1656 if (is->img_convert_ctx == NULL) {
1657 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1660 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1661 0, vp->height, pict.data, pict.linesize);
1663 /* workaround SDL PITCH_WORKAROUND */
1664 duplicate_right_border_pixels(vp->bmp);
1665 /* update the bitmap content */
1666 SDL_UnlockYUVOverlay(vp->bmp);
1669 vp->duration = duration;
1671 vp->serial = serial;
1673 /* now we can update the picture count */
1674 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1675 is->pictq_windex = 0;
1676 SDL_LockMutex(is->pictq_mutex);
1678 SDL_UnlockMutex(is->pictq_mutex);
1683 static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
1687 if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1690 if (pkt->data == flush_pkt.data) {
1691 avcodec_flush_buffers(is->video_st->codec);
1695 if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
1698 if (!got_picture && !pkt->data)
1699 is->video_finished = *serial;
1705 if (decoder_reorder_pts == -1) {
1706 frame->pts = av_frame_get_best_effort_timestamp(frame);
1707 } else if (decoder_reorder_pts) {
1708 frame->pts = frame->pkt_pts;
1710 frame->pts = frame->pkt_dts;
1713 if (frame->pts != AV_NOPTS_VALUE)
1714 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1716 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1718 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1719 if (frame->pts != AV_NOPTS_VALUE) {
1720 double diff = dpts - get_master_clock(is);
1721 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1722 diff - is->frame_last_filter_delay < 0 &&
1723 *serial == is->vidclk.serial &&
1724 is->videoq.nb_packets) {
1725 is->frame_drops_early++;
1726 av_frame_unref(frame);
1738 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1739 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1742 int nb_filters = graph->nb_filters;
1743 AVFilterInOut *outputs = NULL, *inputs = NULL;
1746 outputs = avfilter_inout_alloc();
1747 inputs = avfilter_inout_alloc();
1748 if (!outputs || !inputs) {
1749 ret = AVERROR(ENOMEM);
1753 outputs->name = av_strdup("in");
1754 outputs->filter_ctx = source_ctx;
1755 outputs->pad_idx = 0;
1756 outputs->next = NULL;
1758 inputs->name = av_strdup("out");
1759 inputs->filter_ctx = sink_ctx;
1760 inputs->pad_idx = 0;
1761 inputs->next = NULL;
1763 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1766 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1770 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1771 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1772 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1774 ret = avfilter_graph_config(graph, NULL);
1776 avfilter_inout_free(&outputs);
1777 avfilter_inout_free(&inputs);
1781 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1783 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1784 char sws_flags_str[128];
1785 char buffersrc_args[256];
1787 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1788 AVCodecContext *codec = is->video_st->codec;
1789 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1791 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1792 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1793 graph->scale_sws_opts = av_strdup(sws_flags_str);
1795 snprintf(buffersrc_args, sizeof(buffersrc_args),
1796 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1797 frame->width, frame->height, frame->format,
1798 is->video_st->time_base.num, is->video_st->time_base.den,
1799 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1800 if (fr.num && fr.den)
1801 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1803 if ((ret = avfilter_graph_create_filter(&filt_src,
1804 avfilter_get_by_name("buffer"),
1805 "ffplay_buffer", buffersrc_args, NULL,
1809 ret = avfilter_graph_create_filter(&filt_out,
1810 avfilter_get_by_name("buffersink"),
1811 "ffplay_buffersink", NULL, NULL, graph);
1815 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1818 last_filter = filt_out;
1820 /* Note: this macro adds a filter before the lastly added filter, so the
1821 * processing order of the filters is in reverse */
1822 #define INSERT_FILT(name, arg) do { \
1823 AVFilterContext *filt_ctx; \
1825 ret = avfilter_graph_create_filter(&filt_ctx, \
1826 avfilter_get_by_name(name), \
1827 "ffplay_" name, arg, NULL, graph); \
1831 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1835 last_filter = filt_ctx; \
1838 /* SDL YUV code is not handling odd width/height for some driver
1839 * combinations, therefore we crop the picture to an even width/height. */
1840 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1843 AVDictionaryEntry *rotate_tag = av_dict_get(is->video_st->metadata, "rotate", NULL, 0);
1844 if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
1845 if (!strcmp(rotate_tag->value, "90")) {
1846 INSERT_FILT("transpose", "clock");
1847 } else if (!strcmp(rotate_tag->value, "180")) {
1848 INSERT_FILT("hflip", NULL);
1849 INSERT_FILT("vflip", NULL);
1850 } else if (!strcmp(rotate_tag->value, "270")) {
1851 INSERT_FILT("transpose", "cclock");
1853 char rotate_buf[64];
1854 snprintf(rotate_buf, sizeof(rotate_buf), "%s*PI/180", rotate_tag->value);
1855 INSERT_FILT("rotate", rotate_buf);
1860 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1863 is->in_video_filter = filt_src;
1864 is->out_video_filter = filt_out;
1870 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1872 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1873 int sample_rates[2] = { 0, -1 };
1874 int64_t channel_layouts[2] = { 0, -1 };
1875 int channels[2] = { 0, -1 };
1876 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1877 char aresample_swr_opts[512] = "";
1878 AVDictionaryEntry *e = NULL;
1879 char asrc_args[256];
1882 avfilter_graph_free(&is->agraph);
1883 if (!(is->agraph = avfilter_graph_alloc()))
1884 return AVERROR(ENOMEM);
1886 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1887 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1888 if (strlen(aresample_swr_opts))
1889 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1890 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1892 ret = snprintf(asrc_args, sizeof(asrc_args),
1893 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1894 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1895 is->audio_filter_src.channels,
1896 1, is->audio_filter_src.freq);
1897 if (is->audio_filter_src.channel_layout)
1898 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1899 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1901 ret = avfilter_graph_create_filter(&filt_asrc,
1902 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1903 asrc_args, NULL, is->agraph);
1908 ret = avfilter_graph_create_filter(&filt_asink,
1909 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1910 NULL, NULL, is->agraph);
1914 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1916 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1919 if (force_output_format) {
1920 channel_layouts[0] = is->audio_tgt.channel_layout;
1921 channels [0] = is->audio_tgt.channels;
1922 sample_rates [0] = is->audio_tgt.freq;
1923 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1925 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1927 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1929 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1934 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1937 is->in_audio_filter = filt_asrc;
1938 is->out_audio_filter = filt_asink;
1942 avfilter_graph_free(&is->agraph);
1945 #endif /* CONFIG_AVFILTER */
1947 static int video_thread(void *arg)
1949 AVPacket pkt = { 0 };
1950 VideoState *is = arg;
1951 AVFrame *frame = av_frame_alloc();
1956 AVRational tb = is->video_st->time_base;
1957 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
1960 AVFilterGraph *graph = avfilter_graph_alloc();
1961 AVFilterContext *filt_out = NULL, *filt_in = NULL;
1964 enum AVPixelFormat last_format = -2;
1965 int last_serial = -1;
1966 int last_vfilter_idx = 0;
1970 while (is->paused && !is->videoq.abort_request)
1973 av_free_packet(&pkt);
1975 ret = get_video_frame(is, frame, &pkt, &serial);
1982 if ( last_w != frame->width
1983 || last_h != frame->height
1984 || last_format != frame->format
1985 || last_serial != serial
1986 || last_vfilter_idx != is->vfilter_idx) {
1987 av_log(NULL, AV_LOG_DEBUG,
1988 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1990 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
1991 frame->width, frame->height,
1992 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
1993 avfilter_graph_free(&graph);
1994 graph = avfilter_graph_alloc();
1995 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
1997 event.type = FF_QUIT_EVENT;
1998 event.user.data1 = is;
1999 SDL_PushEvent(&event);
2002 filt_in = is->in_video_filter;
2003 filt_out = is->out_video_filter;
2004 last_w = frame->width;
2005 last_h = frame->height;
2006 last_format = frame->format;
2007 last_serial = serial;
2008 last_vfilter_idx = is->vfilter_idx;
2009 frame_rate = filt_out->inputs[0]->frame_rate;
2012 ret = av_buffersrc_add_frame(filt_in, frame);
2017 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2019 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2021 if (ret == AVERROR_EOF)
2022 is->video_finished = serial;
2027 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2028 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2029 is->frame_last_filter_delay = 0;
2030 tb = filt_out->inputs[0]->time_base;
2032 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2033 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2034 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
2035 av_frame_unref(frame);
2045 avfilter_graph_free(&graph);
2047 av_free_packet(&pkt);
2048 av_frame_free(&frame);
2052 static int subtitle_thread(void *arg)
2054 VideoState *is = arg;
2056 AVPacket pkt1, *pkt = &pkt1;
2061 int r, g, b, y, u, v, a;
2064 while (is->paused && !is->subtitleq.abort_request) {
2067 if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
2070 if (pkt->data == flush_pkt.data) {
2071 avcodec_flush_buffers(is->subtitle_st->codec);
2074 SDL_LockMutex(is->subpq_mutex);
2075 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
2076 !is->subtitleq.abort_request) {
2077 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
2079 SDL_UnlockMutex(is->subpq_mutex);
2081 if (is->subtitleq.abort_request)
2084 sp = &is->subpq[is->subpq_windex];
2086 /* NOTE: ipts is the PTS of the _first_ picture beginning in
2087 this packet, if any */
2089 if (pkt->pts != AV_NOPTS_VALUE)
2090 pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2092 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
2093 &got_subtitle, pkt);
2094 if (got_subtitle && sp->sub.format == 0) {
2095 if (sp->sub.pts != AV_NOPTS_VALUE)
2096 pts = sp->sub.pts / (double)AV_TIME_BASE;
2098 sp->serial = serial;
2100 for (i = 0; i < sp->sub.num_rects; i++)
2102 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2104 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2105 y = RGB_TO_Y_CCIR(r, g, b);
2106 u = RGB_TO_U_CCIR(r, g, b, 0);
2107 v = RGB_TO_V_CCIR(r, g, b, 0);
2108 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2112 /* now we can update the picture count */
2113 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
2114 is->subpq_windex = 0;
2115 SDL_LockMutex(is->subpq_mutex);
2117 SDL_UnlockMutex(is->subpq_mutex);
2118 } else if (got_subtitle) {
2119 avsubtitle_free(&sp->sub);
2121 av_free_packet(pkt);
2126 /* copy samples for viewing in editor window */
2127 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2131 size = samples_size / sizeof(short);
2133 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2136 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2138 is->sample_array_index += len;
2139 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2140 is->sample_array_index = 0;
2145 /* return the wanted number of samples to get better sync if sync_type is video
2146 * or external master clock */
2147 static int synchronize_audio(VideoState *is, int nb_samples)
2149 int wanted_nb_samples = nb_samples;
2151 /* if not master, then we try to remove or add samples to correct the clock */
2152 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2153 double diff, avg_diff;
2154 int min_nb_samples, max_nb_samples;
2156 diff = get_clock(&is->audclk) - get_master_clock(is);
2158 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2159 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2160 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2161 /* not enough measures to have a correct estimate */
2162 is->audio_diff_avg_count++;
2164 /* estimate the A-V difference */
2165 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2167 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2168 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2169 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2170 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2171 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2173 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2174 diff, avg_diff, wanted_nb_samples - nb_samples,
2175 is->audio_clock, is->audio_diff_threshold);
2178 /* too big difference : may be initial PTS errors, so
2180 is->audio_diff_avg_count = 0;
2181 is->audio_diff_cum = 0;
2185 return wanted_nb_samples;
2189 * Decode one audio frame and return its uncompressed size.
2191 * The processed audio frame is decoded, converted if required, and
2192 * stored in is->audio_buf, with size in bytes given by the return
2195 static int audio_decode_frame(VideoState *is)
2197 AVPacket *pkt_temp = &is->audio_pkt_temp;
2198 AVPacket *pkt = &is->audio_pkt;
2199 AVCodecContext *dec = is->audio_st->codec;
2200 int len1, data_size, resampled_data_size;
2201 int64_t dec_channel_layout;
2203 av_unused double audio_clock0;
2204 int wanted_nb_samples;
2210 /* NOTE: the audio packet can contain several frames */
2211 while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
2213 if (!(is->frame = av_frame_alloc()))
2214 return AVERROR(ENOMEM);
2216 av_frame_unref(is->frame);
2219 if (is->audioq.serial != is->audio_pkt_temp_serial)
2225 if (!is->audio_buf_frames_pending) {
2226 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2228 /* if error, we skip the frame */
2234 pkt_temp->pts = AV_NOPTS_VALUE;
2235 pkt_temp->data += len1;
2236 pkt_temp->size -= len1;
2237 if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
2238 pkt_temp->stream_index = -1;
2239 if (!pkt_temp->data && !got_frame)
2240 is->audio_finished = is->audio_pkt_temp_serial;
2245 tb = (AVRational){1, is->frame->sample_rate};
2246 if (is->frame->pts != AV_NOPTS_VALUE)
2247 is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2248 else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
2249 is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
2250 else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
2252 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
2254 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
2257 if (is->frame->pts != AV_NOPTS_VALUE)
2258 is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
2261 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2264 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2265 is->frame->format, av_frame_get_channels(is->frame)) ||
2266 is->audio_filter_src.channel_layout != dec_channel_layout ||
2267 is->audio_filter_src.freq != is->frame->sample_rate ||
2268 is->audio_pkt_temp_serial != is->audio_last_serial;
2271 char buf1[1024], buf2[1024];
2272 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2273 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2274 av_log(NULL, AV_LOG_DEBUG,
2275 "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",
2276 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,
2277 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
2279 is->audio_filter_src.fmt = is->frame->format;
2280 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2281 is->audio_filter_src.channel_layout = dec_channel_layout;
2282 is->audio_filter_src.freq = is->frame->sample_rate;
2283 is->audio_last_serial = is->audio_pkt_temp_serial;
2285 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2289 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2294 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2295 if (ret == AVERROR(EAGAIN)) {
2296 is->audio_buf_frames_pending = 0;
2299 if (ret == AVERROR_EOF)
2300 is->audio_finished = is->audio_pkt_temp_serial;
2303 is->audio_buf_frames_pending = 1;
2304 tb = is->out_audio_filter->inputs[0]->time_base;
2307 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2308 is->frame->nb_samples,
2309 is->frame->format, 1);
2311 dec_channel_layout =
2312 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2313 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2314 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2316 if (is->frame->format != is->audio_src.fmt ||
2317 dec_channel_layout != is->audio_src.channel_layout ||
2318 is->frame->sample_rate != is->audio_src.freq ||
2319 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2320 swr_free(&is->swr_ctx);
2321 is->swr_ctx = swr_alloc_set_opts(NULL,
2322 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2323 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2325 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2326 av_log(NULL, AV_LOG_ERROR,
2327 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2328 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2329 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2332 is->audio_src.channel_layout = dec_channel_layout;
2333 is->audio_src.channels = av_frame_get_channels(is->frame);
2334 is->audio_src.freq = is->frame->sample_rate;
2335 is->audio_src.fmt = is->frame->format;
2339 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2340 uint8_t **out = &is->audio_buf1;
2341 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2342 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2345 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2348 if (wanted_nb_samples != is->frame->nb_samples) {
2349 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2350 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2351 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2355 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2356 if (!is->audio_buf1)
2357 return AVERROR(ENOMEM);
2358 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2360 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2363 if (len2 == out_count) {
2364 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2365 swr_init(is->swr_ctx);
2367 is->audio_buf = is->audio_buf1;
2368 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2370 is->audio_buf = is->frame->data[0];
2371 resampled_data_size = data_size;
2374 audio_clock0 = is->audio_clock;
2375 /* update the audio clock with the pts */
2376 if (is->frame->pts != AV_NOPTS_VALUE)
2377 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2379 is->audio_clock = NAN;
2380 is->audio_clock_serial = is->audio_pkt_temp_serial;
2383 static double last_clock;
2384 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2385 is->audio_clock - last_clock,
2386 is->audio_clock, audio_clock0);
2387 last_clock = is->audio_clock;
2390 return resampled_data_size;
2393 /* free the current packet */
2395 av_free_packet(pkt);
2396 memset(pkt_temp, 0, sizeof(*pkt_temp));
2397 pkt_temp->stream_index = -1;
2399 if (is->audioq.abort_request) {
2403 if (is->audioq.nb_packets == 0)
2404 SDL_CondSignal(is->continue_read_thread);
2406 /* read next packet */
2407 if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2410 if (pkt->data == flush_pkt.data) {
2411 avcodec_flush_buffers(dec);
2412 is->audio_buf_frames_pending = 0;
2413 is->audio_frame_next_pts = AV_NOPTS_VALUE;
2414 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
2415 is->audio_frame_next_pts = is->audio_st->start_time;
2422 /* prepare a new audio buffer */
2423 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2425 VideoState *is = opaque;
2426 int audio_size, len1;
2428 audio_callback_time = av_gettime_relative();
2431 if (is->audio_buf_index >= is->audio_buf_size) {
2432 audio_size = audio_decode_frame(is);
2433 if (audio_size < 0) {
2434 /* if error, just output silence */
2435 is->audio_buf = is->silence_buf;
2436 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2438 if (is->show_mode != SHOW_MODE_VIDEO)
2439 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2440 is->audio_buf_size = audio_size;
2442 is->audio_buf_index = 0;
2444 len1 = is->audio_buf_size - is->audio_buf_index;
2447 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2450 is->audio_buf_index += len1;
2452 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2453 /* Let's assume the audio driver that is used by SDL has two periods. */
2454 if (!isnan(is->audio_clock)) {
2455 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2456 sync_clock_to_slave(&is->extclk, &is->audclk);
2460 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2462 SDL_AudioSpec wanted_spec, spec;
2464 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2465 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2466 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2468 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2470 wanted_nb_channels = atoi(env);
2471 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2473 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2474 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2475 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2477 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2478 wanted_spec.channels = wanted_nb_channels;
2479 wanted_spec.freq = wanted_sample_rate;
2480 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2481 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2484 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2485 next_sample_rate_idx--;
2486 wanted_spec.format = AUDIO_S16SYS;
2487 wanted_spec.silence = 0;
2488 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2489 wanted_spec.callback = sdl_audio_callback;
2490 wanted_spec.userdata = opaque;
2491 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2492 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2493 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2494 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2495 if (!wanted_spec.channels) {
2496 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2497 wanted_spec.channels = wanted_nb_channels;
2498 if (!wanted_spec.freq) {
2499 av_log(NULL, AV_LOG_ERROR,
2500 "No more combinations to try, audio open failed\n");
2504 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2506 if (spec.format != AUDIO_S16SYS) {
2507 av_log(NULL, AV_LOG_ERROR,
2508 "SDL advised audio format %d is not supported!\n", spec.format);
2511 if (spec.channels != wanted_spec.channels) {
2512 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2513 if (!wanted_channel_layout) {
2514 av_log(NULL, AV_LOG_ERROR,
2515 "SDL advised channel count %d is not supported!\n", spec.channels);
2520 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2521 audio_hw_params->freq = spec.freq;
2522 audio_hw_params->channel_layout = wanted_channel_layout;
2523 audio_hw_params->channels = spec.channels;
2524 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2525 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2526 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2527 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2533 /* open a given stream. Return 0 if OK */
2534 static int stream_component_open(VideoState *is, int stream_index)
2536 AVFormatContext *ic = is->ic;
2537 AVCodecContext *avctx;
2539 const char *forced_codec_name = NULL;
2541 AVDictionaryEntry *t = NULL;
2542 int sample_rate, nb_channels;
2543 int64_t channel_layout;
2545 int stream_lowres = lowres;
2547 if (stream_index < 0 || stream_index >= ic->nb_streams)
2549 avctx = ic->streams[stream_index]->codec;
2551 codec = avcodec_find_decoder(avctx->codec_id);
2553 switch(avctx->codec_type){
2554 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2555 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2556 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2558 if (forced_codec_name)
2559 codec = avcodec_find_decoder_by_name(forced_codec_name);
2561 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2562 "No codec could be found with name '%s'\n", forced_codec_name);
2563 else av_log(NULL, AV_LOG_WARNING,
2564 "No codec could be found with id %d\n", avctx->codec_id);
2568 avctx->codec_id = codec->id;
2569 avctx->workaround_bugs = workaround_bugs;
2570 if(stream_lowres > av_codec_get_max_lowres(codec)){
2571 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2572 av_codec_get_max_lowres(codec));
2573 stream_lowres = av_codec_get_max_lowres(codec);
2575 av_codec_set_lowres(avctx, stream_lowres);
2577 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2578 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2579 if(codec->capabilities & CODEC_CAP_DR1)
2580 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2582 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2583 if (!av_dict_get(opts, "threads", NULL, 0))
2584 av_dict_set(&opts, "threads", "auto", 0);
2586 av_dict_set(&opts, "lowres", av_asprintf("%d", stream_lowres), AV_DICT_DONT_STRDUP_VAL);
2587 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2588 av_dict_set(&opts, "refcounted_frames", "1", 0);
2589 if (avcodec_open2(avctx, codec, &opts) < 0)
2591 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2592 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2593 return AVERROR_OPTION_NOT_FOUND;
2596 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2597 switch (avctx->codec_type) {
2598 case AVMEDIA_TYPE_AUDIO:
2603 is->audio_filter_src.freq = avctx->sample_rate;
2604 is->audio_filter_src.channels = avctx->channels;
2605 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2606 is->audio_filter_src.fmt = avctx->sample_fmt;
2607 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2609 link = is->out_audio_filter->inputs[0];
2610 sample_rate = link->sample_rate;
2611 nb_channels = link->channels;
2612 channel_layout = link->channel_layout;
2615 sample_rate = avctx->sample_rate;
2616 nb_channels = avctx->channels;
2617 channel_layout = avctx->channel_layout;
2620 /* prepare audio output */
2621 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2623 is->audio_hw_buf_size = ret;
2624 is->audio_src = is->audio_tgt;
2625 is->audio_buf_size = 0;
2626 is->audio_buf_index = 0;
2628 /* init averaging filter */
2629 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2630 is->audio_diff_avg_count = 0;
2631 /* since we do not have a precise anough audio fifo fullness,
2632 we correct audio sync only if larger than this threshold */
2633 is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec;
2635 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2636 memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2637 is->audio_pkt_temp.stream_index = -1;
2639 is->audio_stream = stream_index;
2640 is->audio_st = ic->streams[stream_index];
2642 packet_queue_start(&is->audioq);
2645 case AVMEDIA_TYPE_VIDEO:
2646 is->video_stream = stream_index;
2647 is->video_st = ic->streams[stream_index];
2649 packet_queue_start(&is->videoq);
2650 is->video_tid = SDL_CreateThread(video_thread, is);
2651 is->queue_attachments_req = 1;
2653 case AVMEDIA_TYPE_SUBTITLE:
2654 is->subtitle_stream = stream_index;
2655 is->subtitle_st = ic->streams[stream_index];
2656 packet_queue_start(&is->subtitleq);
2658 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2666 static void stream_component_close(VideoState *is, int stream_index)
2668 AVFormatContext *ic = is->ic;
2669 AVCodecContext *avctx;
2671 if (stream_index < 0 || stream_index >= ic->nb_streams)
2673 avctx = ic->streams[stream_index]->codec;
2675 switch (avctx->codec_type) {
2676 case AVMEDIA_TYPE_AUDIO:
2677 packet_queue_abort(&is->audioq);
2681 packet_queue_flush(&is->audioq);
2682 av_free_packet(&is->audio_pkt);
2683 swr_free(&is->swr_ctx);
2684 av_freep(&is->audio_buf1);
2685 is->audio_buf1_size = 0;
2686 is->audio_buf = NULL;
2687 av_frame_free(&is->frame);
2690 av_rdft_end(is->rdft);
2691 av_freep(&is->rdft_data);
2696 avfilter_graph_free(&is->agraph);
2699 case AVMEDIA_TYPE_VIDEO:
2700 packet_queue_abort(&is->videoq);
2702 /* note: we also signal this mutex to make sure we deblock the
2703 video thread in all cases */
2704 SDL_LockMutex(is->pictq_mutex);
2705 SDL_CondSignal(is->pictq_cond);
2706 SDL_UnlockMutex(is->pictq_mutex);
2708 SDL_WaitThread(is->video_tid, NULL);
2710 packet_queue_flush(&is->videoq);
2712 case AVMEDIA_TYPE_SUBTITLE:
2713 packet_queue_abort(&is->subtitleq);
2715 /* note: we also signal this mutex to make sure we deblock the
2716 video thread in all cases */
2717 SDL_LockMutex(is->subpq_mutex);
2718 SDL_CondSignal(is->subpq_cond);
2719 SDL_UnlockMutex(is->subpq_mutex);
2721 SDL_WaitThread(is->subtitle_tid, NULL);
2723 packet_queue_flush(&is->subtitleq);
2729 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2730 avcodec_close(avctx);
2731 switch (avctx->codec_type) {
2732 case AVMEDIA_TYPE_AUDIO:
2733 is->audio_st = NULL;
2734 is->audio_stream = -1;
2736 case AVMEDIA_TYPE_VIDEO:
2737 is->video_st = NULL;
2738 is->video_stream = -1;
2740 case AVMEDIA_TYPE_SUBTITLE:
2741 is->subtitle_st = NULL;
2742 is->subtitle_stream = -1;
2749 static int decode_interrupt_cb(void *ctx)
2751 VideoState *is = ctx;
2752 return is->abort_request;
2755 static int is_realtime(AVFormatContext *s)
2757 if( !strcmp(s->iformat->name, "rtp")
2758 || !strcmp(s->iformat->name, "rtsp")
2759 || !strcmp(s->iformat->name, "sdp")
2763 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2764 || !strncmp(s->filename, "udp:", 4)
2771 /* this thread gets the stream from the disk or the network */
2772 static int read_thread(void *arg)
2774 VideoState *is = arg;
2775 AVFormatContext *ic = NULL;
2777 int st_index[AVMEDIA_TYPE_NB];
2778 AVPacket pkt1, *pkt = &pkt1;
2780 int64_t stream_start_time;
2781 int pkt_in_play_range = 0;
2782 AVDictionaryEntry *t;
2783 AVDictionary **opts;
2784 int orig_nb_streams;
2785 SDL_mutex *wait_mutex = SDL_CreateMutex();
2787 memset(st_index, -1, sizeof(st_index));
2788 is->last_video_stream = is->video_stream = -1;
2789 is->last_audio_stream = is->audio_stream = -1;
2790 is->last_subtitle_stream = is->subtitle_stream = -1;
2792 ic = avformat_alloc_context();
2793 ic->interrupt_callback.callback = decode_interrupt_cb;
2794 ic->interrupt_callback.opaque = is;
2795 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2797 print_error(is->filename, err);
2801 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2802 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2803 ret = AVERROR_OPTION_NOT_FOUND;
2809 ic->flags |= AVFMT_FLAG_GENPTS;
2811 av_format_inject_global_side_data(ic);
2813 opts = setup_find_stream_info_opts(ic, codec_opts);
2814 orig_nb_streams = ic->nb_streams;
2816 err = avformat_find_stream_info(ic, opts);
2818 av_log(NULL, AV_LOG_WARNING,
2819 "%s: could not find codec parameters\n", is->filename);
2823 for (i = 0; i < orig_nb_streams; i++)
2824 av_dict_free(&opts[i]);
2828 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2830 if (seek_by_bytes < 0)
2831 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2833 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2835 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2836 window_title = av_asprintf("%s - %s", t->value, input_filename);
2838 /* if seeking requested, we execute it */
2839 if (start_time != AV_NOPTS_VALUE) {
2842 timestamp = start_time;
2843 /* add the stream start time */
2844 if (ic->start_time != AV_NOPTS_VALUE)
2845 timestamp += ic->start_time;
2846 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2848 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2849 is->filename, (double)timestamp / AV_TIME_BASE);
2853 is->realtime = is_realtime(ic);
2855 for (i = 0; i < ic->nb_streams; i++)
2856 ic->streams[i]->discard = AVDISCARD_ALL;
2858 st_index[AVMEDIA_TYPE_VIDEO] =
2859 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2860 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2862 st_index[AVMEDIA_TYPE_AUDIO] =
2863 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2864 wanted_stream[AVMEDIA_TYPE_AUDIO],
2865 st_index[AVMEDIA_TYPE_VIDEO],
2867 if (!video_disable && !subtitle_disable)
2868 st_index[AVMEDIA_TYPE_SUBTITLE] =
2869 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2870 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2871 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2872 st_index[AVMEDIA_TYPE_AUDIO] :
2873 st_index[AVMEDIA_TYPE_VIDEO]),
2876 av_dump_format(ic, 0, is->filename, 0);
2879 is->show_mode = show_mode;
2880 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2881 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2882 AVCodecContext *avctx = st->codec;
2883 VideoPicture vp = {0};
2884 vp.width = avctx->width;
2885 vp.height = avctx->height;
2886 vp.sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2888 set_default_window_size(&vp);
2891 /* open the streams */
2892 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2893 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2897 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2898 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2900 if (is->show_mode == SHOW_MODE_NONE)
2901 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2903 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2904 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2907 if (is->video_stream < 0 && is->audio_stream < 0) {
2908 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2914 if (infinite_buffer < 0 && is->realtime)
2915 infinite_buffer = 1;
2918 if (is->abort_request)
2920 if (is->paused != is->last_paused) {
2921 is->last_paused = is->paused;
2923 is->read_pause_return = av_read_pause(ic);
2927 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2929 (!strcmp(ic->iformat->name, "rtsp") ||
2930 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2931 /* wait 10 ms to avoid trying to get another packet */
2938 int64_t seek_target = is->seek_pos;
2939 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2940 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2941 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2942 // of the seek_pos/seek_rel variables
2944 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2946 av_log(NULL, AV_LOG_ERROR,
2947 "%s: error while seeking\n", is->ic->filename);
2949 if (is->audio_stream >= 0) {
2950 packet_queue_flush(&is->audioq);
2951 packet_queue_put(&is->audioq, &flush_pkt);
2953 if (is->subtitle_stream >= 0) {
2954 packet_queue_flush(&is->subtitleq);
2955 packet_queue_put(&is->subtitleq, &flush_pkt);
2957 if (is->video_stream >= 0) {
2958 packet_queue_flush(&is->videoq);
2959 packet_queue_put(&is->videoq, &flush_pkt);
2961 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2962 set_clock(&is->extclk, NAN, 0);
2964 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2968 is->queue_attachments_req = 1;
2971 step_to_next_frame(is);
2973 if (is->queue_attachments_req) {
2974 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2976 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2978 packet_queue_put(&is->videoq, ©);
2979 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2981 is->queue_attachments_req = 0;
2984 /* if the queue are full, no need to read more */
2985 if (infinite_buffer<1 &&
2986 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2987 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2988 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2989 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2990 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2992 SDL_LockMutex(wait_mutex);
2993 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2994 SDL_UnlockMutex(wait_mutex);
2998 (!is->audio_st || is->audio_finished == is->audioq.serial) &&
2999 (!is->video_st || (is->video_finished == is->videoq.serial && is->pictq_size == 0))) {
3000 if (loop != 1 && (!loop || --loop)) {
3001 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3002 } else if (autoexit) {
3008 if (is->video_stream >= 0)
3009 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3010 if (is->audio_stream >= 0)
3011 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3012 if (is->subtitle_stream >= 0)
3013 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3018 ret = av_read_frame(ic, pkt);
3020 if (ret == AVERROR_EOF || url_feof(ic->pb))
3022 if (ic->pb && ic->pb->error)
3024 SDL_LockMutex(wait_mutex);
3025 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3026 SDL_UnlockMutex(wait_mutex);
3029 /* check if packet is in play range specified by user, then queue, otherwise discard */
3030 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3031 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3032 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3033 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3034 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3035 <= ((double)duration / 1000000);
3036 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3037 packet_queue_put(&is->audioq, pkt);
3038 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3039 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3040 packet_queue_put(&is->videoq, pkt);
3041 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3042 packet_queue_put(&is->subtitleq, pkt);
3044 av_free_packet(pkt);
3047 /* wait until the end */
3048 while (!is->abort_request) {
3054 /* close each stream */
3055 if (is->audio_stream >= 0)
3056 stream_component_close(is, is->audio_stream);
3057 if (is->video_stream >= 0)
3058 stream_component_close(is, is->video_stream);
3059 if (is->subtitle_stream >= 0)
3060 stream_component_close(is, is->subtitle_stream);
3062 avformat_close_input(&is->ic);
3068 event.type = FF_QUIT_EVENT;
3069 event.user.data1 = is;
3070 SDL_PushEvent(&event);
3072 SDL_DestroyMutex(wait_mutex);
3076 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3080 is = av_mallocz(sizeof(VideoState));
3083 av_strlcpy(is->filename, filename, sizeof(is->filename));
3084 is->iformat = iformat;
3088 /* start video display */
3089 is->pictq_mutex = SDL_CreateMutex();
3090 is->pictq_cond = SDL_CreateCond();
3092 is->subpq_mutex = SDL_CreateMutex();
3093 is->subpq_cond = SDL_CreateCond();
3095 packet_queue_init(&is->videoq);
3096 packet_queue_init(&is->audioq);
3097 packet_queue_init(&is->subtitleq);
3099 is->continue_read_thread = SDL_CreateCond();
3101 init_clock(&is->vidclk, &is->videoq.serial);
3102 init_clock(&is->audclk, &is->audioq.serial);
3103 init_clock(&is->extclk, &is->extclk.serial);
3104 is->audio_clock_serial = -1;
3105 is->audio_last_serial = -1;
3106 is->av_sync_type = av_sync_type;
3107 is->read_tid = SDL_CreateThread(read_thread, is);
3108 if (!is->read_tid) {
3115 static void stream_cycle_channel(VideoState *is, int codec_type)
3117 AVFormatContext *ic = is->ic;
3118 int start_index, stream_index;
3121 AVProgram *p = NULL;
3122 int nb_streams = is->ic->nb_streams;
3124 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3125 start_index = is->last_video_stream;
3126 old_index = is->video_stream;
3127 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3128 start_index = is->last_audio_stream;
3129 old_index = is->audio_stream;
3131 start_index = is->last_subtitle_stream;
3132 old_index = is->subtitle_stream;
3134 stream_index = start_index;
3136 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3137 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3139 nb_streams = p->nb_stream_indexes;
3140 for (start_index = 0; start_index < nb_streams; start_index++)
3141 if (p->stream_index[start_index] == stream_index)
3143 if (start_index == nb_streams)
3145 stream_index = start_index;
3150 if (++stream_index >= nb_streams)
3152 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3155 is->last_subtitle_stream = -1;
3158 if (start_index == -1)
3162 if (stream_index == start_index)
3164 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3165 if (st->codec->codec_type == codec_type) {
3166 /* check that parameters are OK */
3167 switch (codec_type) {
3168 case AVMEDIA_TYPE_AUDIO:
3169 if (st->codec->sample_rate != 0 &&
3170 st->codec->channels != 0)
3173 case AVMEDIA_TYPE_VIDEO:
3174 case AVMEDIA_TYPE_SUBTITLE:
3182 if (p && stream_index != -1)
3183 stream_index = p->stream_index[stream_index];
3184 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3185 av_get_media_type_string(codec_type),
3189 stream_component_close(is, old_index);
3190 stream_component_open(is, stream_index);
3194 static void toggle_full_screen(VideoState *is)
3196 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3197 /* OS X needs to reallocate the SDL overlays */
3199 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3200 is->pictq[i].reallocate = 1;
3202 is_full_screen = !is_full_screen;
3203 video_open(is, 1, NULL);
3206 static void toggle_audio_display(VideoState *is)
3208 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3209 int next = is->show_mode;
3211 next = (next + 1) % SHOW_MODE_NB;
3212 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3213 if (is->show_mode != next) {
3214 fill_rectangle(screen,
3215 is->xleft, is->ytop, is->width, is->height,
3217 is->force_refresh = 1;
3218 is->show_mode = next;
3222 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3223 double remaining_time = 0.0;
3225 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3226 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3230 if (remaining_time > 0.0)
3231 av_usleep((int64_t)(remaining_time * 1000000.0));
3232 remaining_time = REFRESH_RATE;
3233 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3234 video_refresh(is, &remaining_time);
3239 static void seek_chapter(VideoState *is, int incr)
3241 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3244 if (!is->ic->nb_chapters)
3247 /* find the current chapter */
3248 for (i = 0; i < is->ic->nb_chapters; i++) {
3249 AVChapter *ch = is->ic->chapters[i];
3250 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3258 if (i >= is->ic->nb_chapters)
3261 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3262 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3263 AV_TIME_BASE_Q), 0, 0);
3266 /* handle an event sent by the GUI */
3267 static void event_loop(VideoState *cur_stream)
3270 double incr, pos, frac;
3274 refresh_loop_wait_event(cur_stream, &event);
3275 switch (event.type) {
3277 if (exit_on_keydown) {
3278 do_exit(cur_stream);
3281 switch (event.key.keysym.sym) {
3284 do_exit(cur_stream);
3287 toggle_full_screen(cur_stream);
3288 cur_stream->force_refresh = 1;
3292 toggle_pause(cur_stream);
3294 case SDLK_s: // S: Step to next frame
3295 step_to_next_frame(cur_stream);
3298 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3301 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3304 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3305 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3306 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3309 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3313 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3314 if (++cur_stream->vfilter_idx >= nb_vfilters)
3315 cur_stream->vfilter_idx = 0;
3317 cur_stream->vfilter_idx = 0;
3318 toggle_audio_display(cur_stream);
3321 toggle_audio_display(cur_stream);
3325 if (cur_stream->ic->nb_chapters <= 1) {
3329 seek_chapter(cur_stream, 1);
3332 if (cur_stream->ic->nb_chapters <= 1) {
3336 seek_chapter(cur_stream, -1);
3350 if (seek_by_bytes) {
3351 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
3352 pos = cur_stream->video_current_pos;
3353 } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
3354 pos = cur_stream->audio_pkt.pos;
3356 pos = avio_tell(cur_stream->ic->pb);
3357 if (cur_stream->ic->bit_rate)
3358 incr *= cur_stream->ic->bit_rate / 8.0;
3362 stream_seek(cur_stream, pos, incr, 1);
3364 pos = get_master_clock(cur_stream);
3366 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3368 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3369 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3370 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3377 case SDL_VIDEOEXPOSE:
3378 cur_stream->force_refresh = 1;
3380 case SDL_MOUSEBUTTONDOWN:
3381 if (exit_on_mousedown) {
3382 do_exit(cur_stream);
3385 case SDL_MOUSEMOTION:
3386 if (cursor_hidden) {
3390 cursor_last_shown = av_gettime_relative();
3391 if (event.type == SDL_MOUSEBUTTONDOWN) {
3394 if (event.motion.state != SDL_PRESSED)
3398 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3399 uint64_t size = avio_size(cur_stream->ic->pb);
3400 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3404 int tns, thh, tmm, tss;
3405 tns = cur_stream->ic->duration / 1000000LL;
3407 tmm = (tns % 3600) / 60;
3409 frac = x / cur_stream->width;
3412 mm = (ns % 3600) / 60;
3414 av_log(NULL, AV_LOG_INFO,
3415 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3416 hh, mm, ss, thh, tmm, tss);
3417 ts = frac * cur_stream->ic->duration;
3418 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3419 ts += cur_stream->ic->start_time;
3420 stream_seek(cur_stream, ts, 0, 0);
3423 case SDL_VIDEORESIZE:
3424 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3425 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3427 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3428 do_exit(cur_stream);
3430 screen_width = cur_stream->width = screen->w;
3431 screen_height = cur_stream->height = screen->h;
3432 cur_stream->force_refresh = 1;
3436 do_exit(cur_stream);
3438 case FF_ALLOC_EVENT:
3439 alloc_picture(event.user.data1);
3447 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3449 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3450 return opt_default(NULL, "video_size", arg);
3453 static int opt_width(void *optctx, const char *opt, const char *arg)
3455 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3459 static int opt_height(void *optctx, const char *opt, const char *arg)
3461 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3465 static int opt_format(void *optctx, const char *opt, const char *arg)
3467 file_iformat = av_find_input_format(arg);
3468 if (!file_iformat) {
3469 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3470 return AVERROR(EINVAL);
3475 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3477 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3478 return opt_default(NULL, "pixel_format", arg);
3481 static int opt_sync(void *optctx, const char *opt, const char *arg)
3483 if (!strcmp(arg, "audio"))
3484 av_sync_type = AV_SYNC_AUDIO_MASTER;
3485 else if (!strcmp(arg, "video"))
3486 av_sync_type = AV_SYNC_VIDEO_MASTER;
3487 else if (!strcmp(arg, "ext"))
3488 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3490 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3496 static int opt_seek(void *optctx, const char *opt, const char *arg)
3498 start_time = parse_time_or_die(opt, arg, 1);
3502 static int opt_duration(void *optctx, const char *opt, const char *arg)
3504 duration = parse_time_or_die(opt, arg, 1);
3508 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3510 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3511 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3512 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3513 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3517 static void opt_input_file(void *optctx, const char *filename)
3519 if (input_filename) {
3520 av_log(NULL, AV_LOG_FATAL,
3521 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3522 filename, input_filename);
3525 if (!strcmp(filename, "-"))
3527 input_filename = filename;
3530 static int opt_codec(void *optctx, const char *opt, const char *arg)
3532 const char *spec = strchr(opt, ':');
3534 av_log(NULL, AV_LOG_ERROR,
3535 "No media specifier was specified in '%s' in option '%s'\n",
3537 return AVERROR(EINVAL);
3541 case 'a' : audio_codec_name = arg; break;
3542 case 's' : subtitle_codec_name = arg; break;
3543 case 'v' : video_codec_name = arg; break;
3545 av_log(NULL, AV_LOG_ERROR,
3546 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3547 return AVERROR(EINVAL);
3554 static const OptionDef options[] = {
3555 #include "cmdutils_common_opts.h"
3556 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3557 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3558 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3559 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3560 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3561 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3562 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3563 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3564 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3565 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3566 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3567 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3568 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3569 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3570 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3571 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3572 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3573 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3574 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3575 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3576 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3577 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3578 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3579 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3580 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3581 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3582 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3583 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3584 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3585 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3587 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3588 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3590 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3591 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3592 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3593 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3594 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3595 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3596 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3597 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3598 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3602 static void show_usage(void)
3604 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3605 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3606 av_log(NULL, AV_LOG_INFO, "\n");
3609 void show_help_default(const char *opt, const char *arg)
3611 av_log_set_callback(log_callback_help);
3613 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3614 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3616 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3617 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3618 #if !CONFIG_AVFILTER
3619 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3621 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3623 printf("\nWhile playing:\n"
3625 "f toggle full screen\n"
3627 "a cycle audio channel in the current program\n"
3628 "v cycle video channel\n"
3629 "t cycle subtitle channel in the current program\n"
3631 "w cycle video filters or show modes\n"
3632 "s activate frame-step mode\n"
3633 "left/right seek backward/forward 10 seconds\n"
3634 "down/up seek backward/forward 1 minute\n"
3635 "page down/page up seek backward/forward 10 minutes\n"
3636 "mouse click seek to percentage in file corresponding to fraction of width\n"
3640 static int lockmgr(void **mtx, enum AVLockOp op)
3643 case AV_LOCK_CREATE:
3644 *mtx = SDL_CreateMutex();
3648 case AV_LOCK_OBTAIN:
3649 return !!SDL_LockMutex(*mtx);
3650 case AV_LOCK_RELEASE:
3651 return !!SDL_UnlockMutex(*mtx);
3652 case AV_LOCK_DESTROY:
3653 SDL_DestroyMutex(*mtx);
3659 /* Called from the main */
3660 int main(int argc, char **argv)
3664 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3666 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3667 parse_loglevel(argc, argv, options);
3669 /* register all codecs, demux and protocols */
3671 avdevice_register_all();
3674 avfilter_register_all();
3677 avformat_network_init();
3681 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3682 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3684 show_banner(argc, argv, options);
3686 parse_options(NULL, argc, argv, options, opt_input_file);
3688 if (!input_filename) {
3690 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3691 av_log(NULL, AV_LOG_FATAL,
3692 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3696 if (display_disable) {
3699 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3701 flags &= ~SDL_INIT_AUDIO;
3702 if (display_disable)
3703 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3704 #if !defined(_WIN32) && !defined(__APPLE__)
3705 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3707 if (SDL_Init (flags)) {
3708 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3709 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3713 if (!display_disable) {
3714 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3715 fs_screen_width = vi->current_w;
3716 fs_screen_height = vi->current_h;
3719 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3720 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3721 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3723 if (av_lockmgr_register(lockmgr)) {
3724 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3728 av_init_packet(&flush_pkt);
3729 flush_pkt.data = (uint8_t *)&flush_pkt;
3731 is = stream_open(input_filename, file_iformat);
3733 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");