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 error_concealment = 3;
313 static int decoder_reorder_pts = -1;
315 static int exit_on_keydown;
316 static int exit_on_mousedown;
318 static int framedrop = -1;
319 static int infinite_buffer = -1;
320 static enum ShowMode show_mode = SHOW_MODE_NONE;
321 static const char *audio_codec_name;
322 static const char *subtitle_codec_name;
323 static const char *video_codec_name;
324 double rdftspeed = 0.02;
325 static int64_t cursor_last_shown;
326 static int cursor_hidden = 0;
328 static const char **vfilters_list = NULL;
329 static int nb_vfilters = 0;
330 static char *afilters = NULL;
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, *filt_crop;
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 /* SDL YUV code is not handling odd width/height for some driver
1819 * combinations, therefore we crop the picture to an even width/height. */
1820 if ((ret = avfilter_graph_create_filter(&filt_crop,
1821 avfilter_get_by_name("crop"),
1822 "ffplay_crop", "floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
1824 if ((ret = avfilter_link(filt_crop, 0, filt_out, 0)) < 0)
1827 if ((ret = configure_filtergraph(graph, vfilters, filt_src, filt_crop)) < 0)
1830 is->in_video_filter = filt_src;
1831 is->out_video_filter = filt_out;
1837 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1839 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1840 int sample_rates[2] = { 0, -1 };
1841 int64_t channel_layouts[2] = { 0, -1 };
1842 int channels[2] = { 0, -1 };
1843 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1844 char aresample_swr_opts[512] = "";
1845 AVDictionaryEntry *e = NULL;
1846 char asrc_args[256];
1849 avfilter_graph_free(&is->agraph);
1850 if (!(is->agraph = avfilter_graph_alloc()))
1851 return AVERROR(ENOMEM);
1853 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1854 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1855 if (strlen(aresample_swr_opts))
1856 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1857 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1859 ret = snprintf(asrc_args, sizeof(asrc_args),
1860 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1861 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1862 is->audio_filter_src.channels,
1863 1, is->audio_filter_src.freq);
1864 if (is->audio_filter_src.channel_layout)
1865 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1866 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1868 ret = avfilter_graph_create_filter(&filt_asrc,
1869 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1870 asrc_args, NULL, is->agraph);
1875 ret = avfilter_graph_create_filter(&filt_asink,
1876 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1877 NULL, NULL, is->agraph);
1881 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1883 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1886 if (force_output_format) {
1887 channel_layouts[0] = is->audio_tgt.channel_layout;
1888 channels [0] = is->audio_tgt.channels;
1889 sample_rates [0] = is->audio_tgt.freq;
1890 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1892 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1894 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1896 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1901 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1904 is->in_audio_filter = filt_asrc;
1905 is->out_audio_filter = filt_asink;
1909 avfilter_graph_free(&is->agraph);
1912 #endif /* CONFIG_AVFILTER */
1914 static int video_thread(void *arg)
1916 AVPacket pkt = { 0 };
1917 VideoState *is = arg;
1918 AVFrame *frame = av_frame_alloc();
1923 AVRational tb = is->video_st->time_base;
1924 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
1927 AVFilterGraph *graph = avfilter_graph_alloc();
1928 AVFilterContext *filt_out = NULL, *filt_in = NULL;
1931 enum AVPixelFormat last_format = -2;
1932 int last_serial = -1;
1933 int last_vfilter_idx = 0;
1937 while (is->paused && !is->videoq.abort_request)
1940 av_free_packet(&pkt);
1942 ret = get_video_frame(is, frame, &pkt, &serial);
1949 if ( last_w != frame->width
1950 || last_h != frame->height
1951 || last_format != frame->format
1952 || last_serial != serial
1953 || last_vfilter_idx != is->vfilter_idx) {
1954 av_log(NULL, AV_LOG_DEBUG,
1955 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1957 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
1958 frame->width, frame->height,
1959 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
1960 avfilter_graph_free(&graph);
1961 graph = avfilter_graph_alloc();
1962 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
1964 event.type = FF_QUIT_EVENT;
1965 event.user.data1 = is;
1966 SDL_PushEvent(&event);
1969 filt_in = is->in_video_filter;
1970 filt_out = is->out_video_filter;
1971 last_w = frame->width;
1972 last_h = frame->height;
1973 last_format = frame->format;
1974 last_serial = serial;
1975 last_vfilter_idx = is->vfilter_idx;
1976 frame_rate = filt_out->inputs[0]->frame_rate;
1979 ret = av_buffersrc_add_frame(filt_in, frame);
1984 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
1986 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
1988 if (ret == AVERROR_EOF)
1989 is->video_finished = serial;
1994 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
1995 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
1996 is->frame_last_filter_delay = 0;
1997 tb = filt_out->inputs[0]->time_base;
1999 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2000 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2001 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
2002 av_frame_unref(frame);
2012 avfilter_graph_free(&graph);
2014 av_free_packet(&pkt);
2015 av_frame_free(&frame);
2019 static int subtitle_thread(void *arg)
2021 VideoState *is = arg;
2023 AVPacket pkt1, *pkt = &pkt1;
2028 int r, g, b, y, u, v, a;
2031 while (is->paused && !is->subtitleq.abort_request) {
2034 if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
2037 if (pkt->data == flush_pkt.data) {
2038 avcodec_flush_buffers(is->subtitle_st->codec);
2041 SDL_LockMutex(is->subpq_mutex);
2042 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
2043 !is->subtitleq.abort_request) {
2044 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
2046 SDL_UnlockMutex(is->subpq_mutex);
2048 if (is->subtitleq.abort_request)
2051 sp = &is->subpq[is->subpq_windex];
2053 /* NOTE: ipts is the PTS of the _first_ picture beginning in
2054 this packet, if any */
2056 if (pkt->pts != AV_NOPTS_VALUE)
2057 pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2059 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
2060 &got_subtitle, pkt);
2061 if (got_subtitle && sp->sub.format == 0) {
2062 if (sp->sub.pts != AV_NOPTS_VALUE)
2063 pts = sp->sub.pts / (double)AV_TIME_BASE;
2065 sp->serial = serial;
2067 for (i = 0; i < sp->sub.num_rects; i++)
2069 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2071 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2072 y = RGB_TO_Y_CCIR(r, g, b);
2073 u = RGB_TO_U_CCIR(r, g, b, 0);
2074 v = RGB_TO_V_CCIR(r, g, b, 0);
2075 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2079 /* now we can update the picture count */
2080 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
2081 is->subpq_windex = 0;
2082 SDL_LockMutex(is->subpq_mutex);
2084 SDL_UnlockMutex(is->subpq_mutex);
2085 } else if (got_subtitle) {
2086 avsubtitle_free(&sp->sub);
2088 av_free_packet(pkt);
2093 /* copy samples for viewing in editor window */
2094 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2098 size = samples_size / sizeof(short);
2100 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2103 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2105 is->sample_array_index += len;
2106 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2107 is->sample_array_index = 0;
2112 /* return the wanted number of samples to get better sync if sync_type is video
2113 * or external master clock */
2114 static int synchronize_audio(VideoState *is, int nb_samples)
2116 int wanted_nb_samples = nb_samples;
2118 /* if not master, then we try to remove or add samples to correct the clock */
2119 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2120 double diff, avg_diff;
2121 int min_nb_samples, max_nb_samples;
2123 diff = get_clock(&is->audclk) - get_master_clock(is);
2125 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2126 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2127 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2128 /* not enough measures to have a correct estimate */
2129 is->audio_diff_avg_count++;
2131 /* estimate the A-V difference */
2132 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2134 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2135 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2136 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2137 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2138 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2140 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2141 diff, avg_diff, wanted_nb_samples - nb_samples,
2142 is->audio_clock, is->audio_diff_threshold);
2145 /* too big difference : may be initial PTS errors, so
2147 is->audio_diff_avg_count = 0;
2148 is->audio_diff_cum = 0;
2152 return wanted_nb_samples;
2156 * Decode one audio frame and return its uncompressed size.
2158 * The processed audio frame is decoded, converted if required, and
2159 * stored in is->audio_buf, with size in bytes given by the return
2162 static int audio_decode_frame(VideoState *is)
2164 AVPacket *pkt_temp = &is->audio_pkt_temp;
2165 AVPacket *pkt = &is->audio_pkt;
2166 AVCodecContext *dec = is->audio_st->codec;
2167 int len1, data_size, resampled_data_size;
2168 int64_t dec_channel_layout;
2170 av_unused double audio_clock0;
2171 int wanted_nb_samples;
2177 /* NOTE: the audio packet can contain several frames */
2178 while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
2180 if (!(is->frame = av_frame_alloc()))
2181 return AVERROR(ENOMEM);
2183 av_frame_unref(is->frame);
2186 if (is->audioq.serial != is->audio_pkt_temp_serial)
2192 if (!is->audio_buf_frames_pending) {
2193 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2195 /* if error, we skip the frame */
2201 pkt_temp->pts = AV_NOPTS_VALUE;
2202 pkt_temp->data += len1;
2203 pkt_temp->size -= len1;
2204 if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
2205 pkt_temp->stream_index = -1;
2206 if (!pkt_temp->data && !got_frame)
2207 is->audio_finished = is->audio_pkt_temp_serial;
2212 tb = (AVRational){1, is->frame->sample_rate};
2213 if (is->frame->pts != AV_NOPTS_VALUE)
2214 is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2215 else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
2216 is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
2217 else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
2219 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
2221 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
2224 if (is->frame->pts != AV_NOPTS_VALUE)
2225 is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
2228 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2231 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2232 is->frame->format, av_frame_get_channels(is->frame)) ||
2233 is->audio_filter_src.channel_layout != dec_channel_layout ||
2234 is->audio_filter_src.freq != is->frame->sample_rate ||
2235 is->audio_pkt_temp_serial != is->audio_last_serial;
2238 char buf1[1024], buf2[1024];
2239 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2240 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2241 av_log(NULL, AV_LOG_DEBUG,
2242 "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",
2243 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,
2244 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
2246 is->audio_filter_src.fmt = is->frame->format;
2247 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2248 is->audio_filter_src.channel_layout = dec_channel_layout;
2249 is->audio_filter_src.freq = is->frame->sample_rate;
2250 is->audio_last_serial = is->audio_pkt_temp_serial;
2252 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2256 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2261 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2262 if (ret == AVERROR(EAGAIN)) {
2263 is->audio_buf_frames_pending = 0;
2266 if (ret == AVERROR_EOF)
2267 is->audio_finished = is->audio_pkt_temp_serial;
2270 is->audio_buf_frames_pending = 1;
2271 tb = is->out_audio_filter->inputs[0]->time_base;
2274 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2275 is->frame->nb_samples,
2276 is->frame->format, 1);
2278 dec_channel_layout =
2279 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2280 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2281 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2283 if (is->frame->format != is->audio_src.fmt ||
2284 dec_channel_layout != is->audio_src.channel_layout ||
2285 is->frame->sample_rate != is->audio_src.freq ||
2286 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2287 swr_free(&is->swr_ctx);
2288 is->swr_ctx = swr_alloc_set_opts(NULL,
2289 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2290 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2292 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2293 av_log(NULL, AV_LOG_ERROR,
2294 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2295 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2296 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2299 is->audio_src.channel_layout = dec_channel_layout;
2300 is->audio_src.channels = av_frame_get_channels(is->frame);
2301 is->audio_src.freq = is->frame->sample_rate;
2302 is->audio_src.fmt = is->frame->format;
2306 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2307 uint8_t **out = &is->audio_buf1;
2308 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2309 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2312 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2315 if (wanted_nb_samples != is->frame->nb_samples) {
2316 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2317 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2318 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2322 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2323 if (!is->audio_buf1)
2324 return AVERROR(ENOMEM);
2325 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2327 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2330 if (len2 == out_count) {
2331 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2332 swr_init(is->swr_ctx);
2334 is->audio_buf = is->audio_buf1;
2335 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2337 is->audio_buf = is->frame->data[0];
2338 resampled_data_size = data_size;
2341 audio_clock0 = is->audio_clock;
2342 /* update the audio clock with the pts */
2343 if (is->frame->pts != AV_NOPTS_VALUE)
2344 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2346 is->audio_clock = NAN;
2347 is->audio_clock_serial = is->audio_pkt_temp_serial;
2350 static double last_clock;
2351 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2352 is->audio_clock - last_clock,
2353 is->audio_clock, audio_clock0);
2354 last_clock = is->audio_clock;
2357 return resampled_data_size;
2360 /* free the current packet */
2362 av_free_packet(pkt);
2363 memset(pkt_temp, 0, sizeof(*pkt_temp));
2364 pkt_temp->stream_index = -1;
2366 if (is->audioq.abort_request) {
2370 if (is->audioq.nb_packets == 0)
2371 SDL_CondSignal(is->continue_read_thread);
2373 /* read next packet */
2374 if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2377 if (pkt->data == flush_pkt.data) {
2378 avcodec_flush_buffers(dec);
2379 is->audio_buf_frames_pending = 0;
2380 is->audio_frame_next_pts = AV_NOPTS_VALUE;
2381 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
2382 is->audio_frame_next_pts = is->audio_st->start_time;
2389 /* prepare a new audio buffer */
2390 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2392 VideoState *is = opaque;
2393 int audio_size, len1;
2395 audio_callback_time = av_gettime_relative();
2398 if (is->audio_buf_index >= is->audio_buf_size) {
2399 audio_size = audio_decode_frame(is);
2400 if (audio_size < 0) {
2401 /* if error, just output silence */
2402 is->audio_buf = is->silence_buf;
2403 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2405 if (is->show_mode != SHOW_MODE_VIDEO)
2406 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2407 is->audio_buf_size = audio_size;
2409 is->audio_buf_index = 0;
2411 len1 = is->audio_buf_size - is->audio_buf_index;
2414 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2417 is->audio_buf_index += len1;
2419 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2420 /* Let's assume the audio driver that is used by SDL has two periods. */
2421 if (!isnan(is->audio_clock)) {
2422 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);
2423 sync_clock_to_slave(&is->extclk, &is->audclk);
2427 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2429 SDL_AudioSpec wanted_spec, spec;
2431 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2432 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2433 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2435 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2437 wanted_nb_channels = atoi(env);
2438 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2440 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2441 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2442 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2444 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2445 wanted_spec.channels = wanted_nb_channels;
2446 wanted_spec.freq = wanted_sample_rate;
2447 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2448 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2451 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2452 next_sample_rate_idx--;
2453 wanted_spec.format = AUDIO_S16SYS;
2454 wanted_spec.silence = 0;
2455 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2456 wanted_spec.callback = sdl_audio_callback;
2457 wanted_spec.userdata = opaque;
2458 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2459 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2460 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2461 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2462 if (!wanted_spec.channels) {
2463 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2464 wanted_spec.channels = wanted_nb_channels;
2465 if (!wanted_spec.freq) {
2466 av_log(NULL, AV_LOG_ERROR,
2467 "No more combinations to try, audio open failed\n");
2471 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2473 if (spec.format != AUDIO_S16SYS) {
2474 av_log(NULL, AV_LOG_ERROR,
2475 "SDL advised audio format %d is not supported!\n", spec.format);
2478 if (spec.channels != wanted_spec.channels) {
2479 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2480 if (!wanted_channel_layout) {
2481 av_log(NULL, AV_LOG_ERROR,
2482 "SDL advised channel count %d is not supported!\n", spec.channels);
2487 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2488 audio_hw_params->freq = spec.freq;
2489 audio_hw_params->channel_layout = wanted_channel_layout;
2490 audio_hw_params->channels = spec.channels;
2491 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2492 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);
2493 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2494 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2500 /* open a given stream. Return 0 if OK */
2501 static int stream_component_open(VideoState *is, int stream_index)
2503 AVFormatContext *ic = is->ic;
2504 AVCodecContext *avctx;
2506 const char *forced_codec_name = NULL;
2508 AVDictionaryEntry *t = NULL;
2509 int sample_rate, nb_channels;
2510 int64_t channel_layout;
2512 int stream_lowres = lowres;
2514 if (stream_index < 0 || stream_index >= ic->nb_streams)
2516 avctx = ic->streams[stream_index]->codec;
2518 codec = avcodec_find_decoder(avctx->codec_id);
2520 switch(avctx->codec_type){
2521 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2522 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2523 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2525 if (forced_codec_name)
2526 codec = avcodec_find_decoder_by_name(forced_codec_name);
2528 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2529 "No codec could be found with name '%s'\n", forced_codec_name);
2530 else av_log(NULL, AV_LOG_WARNING,
2531 "No codec could be found with id %d\n", avctx->codec_id);
2535 avctx->codec_id = codec->id;
2536 avctx->workaround_bugs = workaround_bugs;
2537 if(stream_lowres > av_codec_get_max_lowres(codec)){
2538 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2539 av_codec_get_max_lowres(codec));
2540 stream_lowres = av_codec_get_max_lowres(codec);
2542 av_codec_set_lowres(avctx, stream_lowres);
2543 avctx->error_concealment = error_concealment;
2545 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2546 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2547 if(codec->capabilities & CODEC_CAP_DR1)
2548 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2550 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2551 if (!av_dict_get(opts, "threads", NULL, 0))
2552 av_dict_set(&opts, "threads", "auto", 0);
2554 av_dict_set(&opts, "lowres", av_asprintf("%d", stream_lowres), AV_DICT_DONT_STRDUP_VAL);
2555 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2556 av_dict_set(&opts, "refcounted_frames", "1", 0);
2557 if (avcodec_open2(avctx, codec, &opts) < 0)
2559 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2560 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2561 return AVERROR_OPTION_NOT_FOUND;
2564 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2565 switch (avctx->codec_type) {
2566 case AVMEDIA_TYPE_AUDIO:
2571 is->audio_filter_src.freq = avctx->sample_rate;
2572 is->audio_filter_src.channels = avctx->channels;
2573 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2574 is->audio_filter_src.fmt = avctx->sample_fmt;
2575 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2577 link = is->out_audio_filter->inputs[0];
2578 sample_rate = link->sample_rate;
2579 nb_channels = link->channels;
2580 channel_layout = link->channel_layout;
2583 sample_rate = avctx->sample_rate;
2584 nb_channels = avctx->channels;
2585 channel_layout = avctx->channel_layout;
2588 /* prepare audio output */
2589 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2591 is->audio_hw_buf_size = ret;
2592 is->audio_src = is->audio_tgt;
2593 is->audio_buf_size = 0;
2594 is->audio_buf_index = 0;
2596 /* init averaging filter */
2597 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2598 is->audio_diff_avg_count = 0;
2599 /* since we do not have a precise anough audio fifo fullness,
2600 we correct audio sync only if larger than this threshold */
2601 is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec;
2603 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2604 memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2605 is->audio_pkt_temp.stream_index = -1;
2607 is->audio_stream = stream_index;
2608 is->audio_st = ic->streams[stream_index];
2610 packet_queue_start(&is->audioq);
2613 case AVMEDIA_TYPE_VIDEO:
2614 is->video_stream = stream_index;
2615 is->video_st = ic->streams[stream_index];
2617 packet_queue_start(&is->videoq);
2618 is->video_tid = SDL_CreateThread(video_thread, is);
2619 is->queue_attachments_req = 1;
2621 case AVMEDIA_TYPE_SUBTITLE:
2622 is->subtitle_stream = stream_index;
2623 is->subtitle_st = ic->streams[stream_index];
2624 packet_queue_start(&is->subtitleq);
2626 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2634 static void stream_component_close(VideoState *is, int stream_index)
2636 AVFormatContext *ic = is->ic;
2637 AVCodecContext *avctx;
2639 if (stream_index < 0 || stream_index >= ic->nb_streams)
2641 avctx = ic->streams[stream_index]->codec;
2643 switch (avctx->codec_type) {
2644 case AVMEDIA_TYPE_AUDIO:
2645 packet_queue_abort(&is->audioq);
2649 packet_queue_flush(&is->audioq);
2650 av_free_packet(&is->audio_pkt);
2651 swr_free(&is->swr_ctx);
2652 av_freep(&is->audio_buf1);
2653 is->audio_buf1_size = 0;
2654 is->audio_buf = NULL;
2655 av_frame_free(&is->frame);
2658 av_rdft_end(is->rdft);
2659 av_freep(&is->rdft_data);
2664 avfilter_graph_free(&is->agraph);
2667 case AVMEDIA_TYPE_VIDEO:
2668 packet_queue_abort(&is->videoq);
2670 /* note: we also signal this mutex to make sure we deblock the
2671 video thread in all cases */
2672 SDL_LockMutex(is->pictq_mutex);
2673 SDL_CondSignal(is->pictq_cond);
2674 SDL_UnlockMutex(is->pictq_mutex);
2676 SDL_WaitThread(is->video_tid, NULL);
2678 packet_queue_flush(&is->videoq);
2680 case AVMEDIA_TYPE_SUBTITLE:
2681 packet_queue_abort(&is->subtitleq);
2683 /* note: we also signal this mutex to make sure we deblock the
2684 video thread in all cases */
2685 SDL_LockMutex(is->subpq_mutex);
2686 SDL_CondSignal(is->subpq_cond);
2687 SDL_UnlockMutex(is->subpq_mutex);
2689 SDL_WaitThread(is->subtitle_tid, NULL);
2691 packet_queue_flush(&is->subtitleq);
2697 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2698 avcodec_close(avctx);
2699 switch (avctx->codec_type) {
2700 case AVMEDIA_TYPE_AUDIO:
2701 is->audio_st = NULL;
2702 is->audio_stream = -1;
2704 case AVMEDIA_TYPE_VIDEO:
2705 is->video_st = NULL;
2706 is->video_stream = -1;
2708 case AVMEDIA_TYPE_SUBTITLE:
2709 is->subtitle_st = NULL;
2710 is->subtitle_stream = -1;
2717 static int decode_interrupt_cb(void *ctx)
2719 VideoState *is = ctx;
2720 return is->abort_request;
2723 static int is_realtime(AVFormatContext *s)
2725 if( !strcmp(s->iformat->name, "rtp")
2726 || !strcmp(s->iformat->name, "rtsp")
2727 || !strcmp(s->iformat->name, "sdp")
2731 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2732 || !strncmp(s->filename, "udp:", 4)
2739 /* this thread gets the stream from the disk or the network */
2740 static int read_thread(void *arg)
2742 VideoState *is = arg;
2743 AVFormatContext *ic = NULL;
2745 int st_index[AVMEDIA_TYPE_NB];
2746 AVPacket pkt1, *pkt = &pkt1;
2748 int64_t stream_start_time;
2749 int pkt_in_play_range = 0;
2750 AVDictionaryEntry *t;
2751 AVDictionary **opts;
2752 int orig_nb_streams;
2753 SDL_mutex *wait_mutex = SDL_CreateMutex();
2755 memset(st_index, -1, sizeof(st_index));
2756 is->last_video_stream = is->video_stream = -1;
2757 is->last_audio_stream = is->audio_stream = -1;
2758 is->last_subtitle_stream = is->subtitle_stream = -1;
2760 ic = avformat_alloc_context();
2761 ic->interrupt_callback.callback = decode_interrupt_cb;
2762 ic->interrupt_callback.opaque = is;
2763 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2765 print_error(is->filename, err);
2769 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2770 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2771 ret = AVERROR_OPTION_NOT_FOUND;
2777 ic->flags |= AVFMT_FLAG_GENPTS;
2779 av_format_inject_global_side_data(ic);
2781 opts = setup_find_stream_info_opts(ic, codec_opts);
2782 orig_nb_streams = ic->nb_streams;
2784 err = avformat_find_stream_info(ic, opts);
2786 av_log(NULL, AV_LOG_WARNING,
2787 "%s: could not find codec parameters\n", is->filename);
2791 for (i = 0; i < orig_nb_streams; i++)
2792 av_dict_free(&opts[i]);
2796 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2798 if (seek_by_bytes < 0)
2799 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2801 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2803 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2804 window_title = av_asprintf("%s - %s", t->value, input_filename);
2806 /* if seeking requested, we execute it */
2807 if (start_time != AV_NOPTS_VALUE) {
2810 timestamp = start_time;
2811 /* add the stream start time */
2812 if (ic->start_time != AV_NOPTS_VALUE)
2813 timestamp += ic->start_time;
2814 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2816 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2817 is->filename, (double)timestamp / AV_TIME_BASE);
2821 is->realtime = is_realtime(ic);
2823 for (i = 0; i < ic->nb_streams; i++)
2824 ic->streams[i]->discard = AVDISCARD_ALL;
2826 st_index[AVMEDIA_TYPE_VIDEO] =
2827 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2828 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2830 st_index[AVMEDIA_TYPE_AUDIO] =
2831 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2832 wanted_stream[AVMEDIA_TYPE_AUDIO],
2833 st_index[AVMEDIA_TYPE_VIDEO],
2835 if (!video_disable && !subtitle_disable)
2836 st_index[AVMEDIA_TYPE_SUBTITLE] =
2837 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2838 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2839 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2840 st_index[AVMEDIA_TYPE_AUDIO] :
2841 st_index[AVMEDIA_TYPE_VIDEO]),
2844 av_dump_format(ic, 0, is->filename, 0);
2847 is->show_mode = show_mode;
2848 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2849 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2850 AVCodecContext *avctx = st->codec;
2851 VideoPicture vp = {0};
2852 vp.width = avctx->width;
2853 vp.height = avctx->height;
2854 vp.sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2856 set_default_window_size(&vp);
2859 /* open the streams */
2860 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2861 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2865 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2866 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2868 if (is->show_mode == SHOW_MODE_NONE)
2869 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2871 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2872 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2875 if (is->video_stream < 0 && is->audio_stream < 0) {
2876 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2882 if (infinite_buffer < 0 && is->realtime)
2883 infinite_buffer = 1;
2886 if (is->abort_request)
2888 if (is->paused != is->last_paused) {
2889 is->last_paused = is->paused;
2891 is->read_pause_return = av_read_pause(ic);
2895 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2897 (!strcmp(ic->iformat->name, "rtsp") ||
2898 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2899 /* wait 10 ms to avoid trying to get another packet */
2906 int64_t seek_target = is->seek_pos;
2907 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2908 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2909 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2910 // of the seek_pos/seek_rel variables
2912 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2914 av_log(NULL, AV_LOG_ERROR,
2915 "%s: error while seeking\n", is->ic->filename);
2917 if (is->audio_stream >= 0) {
2918 packet_queue_flush(&is->audioq);
2919 packet_queue_put(&is->audioq, &flush_pkt);
2921 if (is->subtitle_stream >= 0) {
2922 packet_queue_flush(&is->subtitleq);
2923 packet_queue_put(&is->subtitleq, &flush_pkt);
2925 if (is->video_stream >= 0) {
2926 packet_queue_flush(&is->videoq);
2927 packet_queue_put(&is->videoq, &flush_pkt);
2929 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2930 set_clock(&is->extclk, NAN, 0);
2932 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2936 is->queue_attachments_req = 1;
2939 step_to_next_frame(is);
2941 if (is->queue_attachments_req) {
2942 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2944 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2946 packet_queue_put(&is->videoq, ©);
2947 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2949 is->queue_attachments_req = 0;
2952 /* if the queue are full, no need to read more */
2953 if (infinite_buffer<1 &&
2954 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2955 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2956 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2957 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2958 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2960 SDL_LockMutex(wait_mutex);
2961 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2962 SDL_UnlockMutex(wait_mutex);
2966 (!is->audio_st || is->audio_finished == is->audioq.serial) &&
2967 (!is->video_st || (is->video_finished == is->videoq.serial && is->pictq_size == 0))) {
2968 if (loop != 1 && (!loop || --loop)) {
2969 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2970 } else if (autoexit) {
2976 if (is->video_stream >= 0)
2977 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2978 if (is->audio_stream >= 0)
2979 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2980 if (is->subtitle_stream >= 0)
2981 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2986 ret = av_read_frame(ic, pkt);
2988 if (ret == AVERROR_EOF || url_feof(ic->pb))
2990 if (ic->pb && ic->pb->error)
2992 SDL_LockMutex(wait_mutex);
2993 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2994 SDL_UnlockMutex(wait_mutex);
2997 /* check if packet is in play range specified by user, then queue, otherwise discard */
2998 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2999 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3000 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3001 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3002 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3003 <= ((double)duration / 1000000);
3004 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3005 packet_queue_put(&is->audioq, pkt);
3006 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3007 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3008 packet_queue_put(&is->videoq, pkt);
3009 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3010 packet_queue_put(&is->subtitleq, pkt);
3012 av_free_packet(pkt);
3015 /* wait until the end */
3016 while (!is->abort_request) {
3022 /* close each stream */
3023 if (is->audio_stream >= 0)
3024 stream_component_close(is, is->audio_stream);
3025 if (is->video_stream >= 0)
3026 stream_component_close(is, is->video_stream);
3027 if (is->subtitle_stream >= 0)
3028 stream_component_close(is, is->subtitle_stream);
3030 avformat_close_input(&is->ic);
3036 event.type = FF_QUIT_EVENT;
3037 event.user.data1 = is;
3038 SDL_PushEvent(&event);
3040 SDL_DestroyMutex(wait_mutex);
3044 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3048 is = av_mallocz(sizeof(VideoState));
3051 av_strlcpy(is->filename, filename, sizeof(is->filename));
3052 is->iformat = iformat;
3056 /* start video display */
3057 is->pictq_mutex = SDL_CreateMutex();
3058 is->pictq_cond = SDL_CreateCond();
3060 is->subpq_mutex = SDL_CreateMutex();
3061 is->subpq_cond = SDL_CreateCond();
3063 packet_queue_init(&is->videoq);
3064 packet_queue_init(&is->audioq);
3065 packet_queue_init(&is->subtitleq);
3067 is->continue_read_thread = SDL_CreateCond();
3069 init_clock(&is->vidclk, &is->videoq.serial);
3070 init_clock(&is->audclk, &is->audioq.serial);
3071 init_clock(&is->extclk, &is->extclk.serial);
3072 is->audio_clock_serial = -1;
3073 is->audio_last_serial = -1;
3074 is->av_sync_type = av_sync_type;
3075 is->read_tid = SDL_CreateThread(read_thread, is);
3076 if (!is->read_tid) {
3083 static void stream_cycle_channel(VideoState *is, int codec_type)
3085 AVFormatContext *ic = is->ic;
3086 int start_index, stream_index;
3089 AVProgram *p = NULL;
3090 int nb_streams = is->ic->nb_streams;
3092 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3093 start_index = is->last_video_stream;
3094 old_index = is->video_stream;
3095 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3096 start_index = is->last_audio_stream;
3097 old_index = is->audio_stream;
3099 start_index = is->last_subtitle_stream;
3100 old_index = is->subtitle_stream;
3102 stream_index = start_index;
3104 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3105 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3107 nb_streams = p->nb_stream_indexes;
3108 for (start_index = 0; start_index < nb_streams; start_index++)
3109 if (p->stream_index[start_index] == stream_index)
3111 if (start_index == nb_streams)
3113 stream_index = start_index;
3118 if (++stream_index >= nb_streams)
3120 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3123 is->last_subtitle_stream = -1;
3126 if (start_index == -1)
3130 if (stream_index == start_index)
3132 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3133 if (st->codec->codec_type == codec_type) {
3134 /* check that parameters are OK */
3135 switch (codec_type) {
3136 case AVMEDIA_TYPE_AUDIO:
3137 if (st->codec->sample_rate != 0 &&
3138 st->codec->channels != 0)
3141 case AVMEDIA_TYPE_VIDEO:
3142 case AVMEDIA_TYPE_SUBTITLE:
3150 if (p && stream_index != -1)
3151 stream_index = p->stream_index[stream_index];
3152 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3153 av_get_media_type_string(codec_type),
3157 stream_component_close(is, old_index);
3158 stream_component_open(is, stream_index);
3162 static void toggle_full_screen(VideoState *is)
3164 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3165 /* OS X needs to reallocate the SDL overlays */
3167 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3168 is->pictq[i].reallocate = 1;
3170 is_full_screen = !is_full_screen;
3171 video_open(is, 1, NULL);
3174 static void toggle_audio_display(VideoState *is)
3176 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3177 int next = is->show_mode;
3179 next = (next + 1) % SHOW_MODE_NB;
3180 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3181 if (is->show_mode != next) {
3182 fill_rectangle(screen,
3183 is->xleft, is->ytop, is->width, is->height,
3185 is->force_refresh = 1;
3186 is->show_mode = next;
3190 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3191 double remaining_time = 0.0;
3193 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3194 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3198 if (remaining_time > 0.0)
3199 av_usleep((int64_t)(remaining_time * 1000000.0));
3200 remaining_time = REFRESH_RATE;
3201 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3202 video_refresh(is, &remaining_time);
3207 static void seek_chapter(VideoState *is, int incr)
3209 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3212 if (!is->ic->nb_chapters)
3215 /* find the current chapter */
3216 for (i = 0; i < is->ic->nb_chapters; i++) {
3217 AVChapter *ch = is->ic->chapters[i];
3218 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3226 if (i >= is->ic->nb_chapters)
3229 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3230 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3231 AV_TIME_BASE_Q), 0, 0);
3234 /* handle an event sent by the GUI */
3235 static void event_loop(VideoState *cur_stream)
3238 double incr, pos, frac;
3242 refresh_loop_wait_event(cur_stream, &event);
3243 switch (event.type) {
3245 if (exit_on_keydown) {
3246 do_exit(cur_stream);
3249 switch (event.key.keysym.sym) {
3252 do_exit(cur_stream);
3255 toggle_full_screen(cur_stream);
3256 cur_stream->force_refresh = 1;
3260 toggle_pause(cur_stream);
3262 case SDLK_s: // S: Step to next frame
3263 step_to_next_frame(cur_stream);
3266 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3269 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3272 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3273 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3274 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3277 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3281 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3282 if (++cur_stream->vfilter_idx >= nb_vfilters)
3283 cur_stream->vfilter_idx = 0;
3285 cur_stream->vfilter_idx = 0;
3286 toggle_audio_display(cur_stream);
3289 toggle_audio_display(cur_stream);
3293 if (cur_stream->ic->nb_chapters <= 1) {
3297 seek_chapter(cur_stream, 1);
3300 if (cur_stream->ic->nb_chapters <= 1) {
3304 seek_chapter(cur_stream, -1);
3318 if (seek_by_bytes) {
3319 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
3320 pos = cur_stream->video_current_pos;
3321 } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
3322 pos = cur_stream->audio_pkt.pos;
3324 pos = avio_tell(cur_stream->ic->pb);
3325 if (cur_stream->ic->bit_rate)
3326 incr *= cur_stream->ic->bit_rate / 8.0;
3330 stream_seek(cur_stream, pos, incr, 1);
3332 pos = get_master_clock(cur_stream);
3334 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3336 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3337 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3338 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3345 case SDL_VIDEOEXPOSE:
3346 cur_stream->force_refresh = 1;
3348 case SDL_MOUSEBUTTONDOWN:
3349 if (exit_on_mousedown) {
3350 do_exit(cur_stream);
3353 case SDL_MOUSEMOTION:
3354 if (cursor_hidden) {
3358 cursor_last_shown = av_gettime_relative();
3359 if (event.type == SDL_MOUSEBUTTONDOWN) {
3362 if (event.motion.state != SDL_PRESSED)
3366 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3367 uint64_t size = avio_size(cur_stream->ic->pb);
3368 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3372 int tns, thh, tmm, tss;
3373 tns = cur_stream->ic->duration / 1000000LL;
3375 tmm = (tns % 3600) / 60;
3377 frac = x / cur_stream->width;
3380 mm = (ns % 3600) / 60;
3382 av_log(NULL, AV_LOG_INFO,
3383 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3384 hh, mm, ss, thh, tmm, tss);
3385 ts = frac * cur_stream->ic->duration;
3386 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3387 ts += cur_stream->ic->start_time;
3388 stream_seek(cur_stream, ts, 0, 0);
3391 case SDL_VIDEORESIZE:
3392 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3393 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3395 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3396 do_exit(cur_stream);
3398 screen_width = cur_stream->width = screen->w;
3399 screen_height = cur_stream->height = screen->h;
3400 cur_stream->force_refresh = 1;
3404 do_exit(cur_stream);
3406 case FF_ALLOC_EVENT:
3407 alloc_picture(event.user.data1);
3415 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3417 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3418 return opt_default(NULL, "video_size", arg);
3421 static int opt_width(void *optctx, const char *opt, const char *arg)
3423 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3427 static int opt_height(void *optctx, const char *opt, const char *arg)
3429 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3433 static int opt_format(void *optctx, const char *opt, const char *arg)
3435 file_iformat = av_find_input_format(arg);
3436 if (!file_iformat) {
3437 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3438 return AVERROR(EINVAL);
3443 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3445 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3446 return opt_default(NULL, "pixel_format", arg);
3449 static int opt_sync(void *optctx, const char *opt, const char *arg)
3451 if (!strcmp(arg, "audio"))
3452 av_sync_type = AV_SYNC_AUDIO_MASTER;
3453 else if (!strcmp(arg, "video"))
3454 av_sync_type = AV_SYNC_VIDEO_MASTER;
3455 else if (!strcmp(arg, "ext"))
3456 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3458 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3464 static int opt_seek(void *optctx, const char *opt, const char *arg)
3466 start_time = parse_time_or_die(opt, arg, 1);
3470 static int opt_duration(void *optctx, const char *opt, const char *arg)
3472 duration = parse_time_or_die(opt, arg, 1);
3476 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3478 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3479 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3480 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3481 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3485 static void opt_input_file(void *optctx, const char *filename)
3487 if (input_filename) {
3488 av_log(NULL, AV_LOG_FATAL,
3489 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3490 filename, input_filename);
3493 if (!strcmp(filename, "-"))
3495 input_filename = filename;
3498 static int opt_codec(void *optctx, const char *opt, const char *arg)
3500 const char *spec = strchr(opt, ':');
3502 av_log(NULL, AV_LOG_ERROR,
3503 "No media specifier was specified in '%s' in option '%s'\n",
3505 return AVERROR(EINVAL);
3509 case 'a' : audio_codec_name = arg; break;
3510 case 's' : subtitle_codec_name = arg; break;
3511 case 'v' : video_codec_name = arg; break;
3513 av_log(NULL, AV_LOG_ERROR,
3514 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3515 return AVERROR(EINVAL);
3522 static const OptionDef options[] = {
3523 #include "cmdutils_common_opts.h"
3524 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3525 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3526 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3527 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3528 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3529 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3530 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3531 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3532 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3533 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3534 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3535 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3536 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3537 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3538 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3539 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3540 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3541 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3542 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3543 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3544 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3545 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3546 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options", "bit_mask" },
3547 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3548 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3549 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3550 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3551 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3552 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3553 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3554 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3556 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3557 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3559 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3560 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3561 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3562 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3563 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3564 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3565 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3566 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3570 static void show_usage(void)
3572 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3573 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3574 av_log(NULL, AV_LOG_INFO, "\n");
3577 void show_help_default(const char *opt, const char *arg)
3579 av_log_set_callback(log_callback_help);
3581 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3582 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3584 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3585 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3586 #if !CONFIG_AVFILTER
3587 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3589 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3591 printf("\nWhile playing:\n"
3593 "f toggle full screen\n"
3595 "a cycle audio channel in the current program\n"
3596 "v cycle video channel\n"
3597 "t cycle subtitle channel in the current program\n"
3599 "w cycle video filters or show modes\n"
3600 "s activate frame-step mode\n"
3601 "left/right seek backward/forward 10 seconds\n"
3602 "down/up seek backward/forward 1 minute\n"
3603 "page down/page up seek backward/forward 10 minutes\n"
3604 "mouse click seek to percentage in file corresponding to fraction of width\n"
3608 static int lockmgr(void **mtx, enum AVLockOp op)
3611 case AV_LOCK_CREATE:
3612 *mtx = SDL_CreateMutex();
3616 case AV_LOCK_OBTAIN:
3617 return !!SDL_LockMutex(*mtx);
3618 case AV_LOCK_RELEASE:
3619 return !!SDL_UnlockMutex(*mtx);
3620 case AV_LOCK_DESTROY:
3621 SDL_DestroyMutex(*mtx);
3627 /* Called from the main */
3628 int main(int argc, char **argv)
3632 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3634 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3635 parse_loglevel(argc, argv, options);
3637 /* register all codecs, demux and protocols */
3639 avdevice_register_all();
3642 avfilter_register_all();
3645 avformat_network_init();
3649 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3650 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3652 show_banner(argc, argv, options);
3654 parse_options(NULL, argc, argv, options, opt_input_file);
3656 if (!input_filename) {
3658 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3659 av_log(NULL, AV_LOG_FATAL,
3660 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3664 if (display_disable) {
3667 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3669 flags &= ~SDL_INIT_AUDIO;
3670 if (display_disable)
3671 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3672 #if !defined(_WIN32) && !defined(__APPLE__)
3673 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3675 if (SDL_Init (flags)) {
3676 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3677 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3681 if (!display_disable) {
3682 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3683 fs_screen_width = vi->current_w;
3684 fs_screen_height = vi->current_h;
3687 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3688 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3689 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3691 if (av_lockmgr_register(lockmgr)) {
3692 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3696 av_init_packet(&flush_pkt);
3697 flush_pkt.data = (uint8_t *)&flush_pkt;
3699 is = stream_open(input_filename, file_iformat);
3701 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");