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
31 #include "libavutil/avstring.h"
32 #include "libavutil/colorspace.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/dict.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/samplefmt.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/time.h"
41 #include "libavformat/avformat.h"
42 #include "libavdevice/avdevice.h"
43 #include "libswscale/swscale.h"
44 #include "libavutil/opt.h"
45 #include "libavcodec/avfft.h"
46 #include "libswresample/swresample.h"
49 # include "libavfilter/avcodec.h"
50 # include "libavfilter/avfilter.h"
51 # include "libavfilter/buffersink.h"
52 # include "libavfilter/buffersrc.h"
56 #include <SDL_thread.h>
62 const char program_name[] = "ffplay";
63 const int program_birth_year = 2003;
65 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 /* SDL audio buffer size, in samples. Should be small to have precise
69 A/V sync as SDL does not have hardware buffer fullness info. */
70 #define SDL_AUDIO_BUFFER_SIZE 1024
72 /* no AV sync correction is done if below the minimum AV sync threshold */
73 #define AV_SYNC_THRESHOLD_MIN 0.01
74 /* AV sync correction is done if above the maximum AV sync threshold */
75 #define AV_SYNC_THRESHOLD_MAX 0.1
76 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
77 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
78 /* no AV correction is done if too big error */
79 #define AV_NOSYNC_THRESHOLD 10.0
81 /* maximum audio speed change to get correct sync */
82 #define SAMPLE_CORRECTION_PERCENT_MAX 10
84 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
85 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
86 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
87 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
89 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
90 #define AUDIO_DIFF_AVG_NB 20
92 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
93 #define REFRESH_RATE 0.01
95 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
96 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
97 #define SAMPLE_ARRAY_SIZE (8 * 65536)
99 #define CURSOR_HIDE_DELAY 1000000
101 static int64_t sws_flags = SWS_BICUBIC;
103 typedef struct MyAVPacketList {
105 struct MyAVPacketList *next;
109 typedef struct PacketQueue {
110 MyAVPacketList *first_pkt, *last_pkt;
119 #define VIDEO_PICTURE_QUEUE_SIZE 3
120 #define SUBPICTURE_QUEUE_SIZE 4
122 typedef struct VideoPicture {
123 double pts; // presentation timestamp for this picture
124 double duration; // estimated duration based on frame rate
125 int64_t pos; // byte position in file
127 int width, height; /* source height & width */
135 typedef struct SubPicture {
136 double pts; /* presentation time stamp for this picture */
141 typedef struct AudioParams {
144 int64_t channel_layout;
145 enum AVSampleFormat fmt;
148 typedef struct Clock {
149 double pts; /* clock base */
150 double pts_drift; /* clock base minus time at which we updated the clock */
153 int serial; /* clock is based on a packet with this serial */
155 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
159 AV_SYNC_AUDIO_MASTER, /* default choice */
160 AV_SYNC_VIDEO_MASTER,
161 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
164 typedef struct VideoState {
165 SDL_Thread *read_tid;
166 SDL_Thread *video_tid;
167 AVInputFormat *iformat;
173 int queue_attachments_req;
178 int read_pause_return;
193 int audio_clock_serial;
194 double audio_diff_cum; /* used for AV difference average computation */
195 double audio_diff_avg_coef;
196 double audio_diff_threshold;
197 int audio_diff_avg_count;
200 int audio_hw_buf_size;
201 uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
204 unsigned int audio_buf_size; /* in bytes */
205 unsigned int audio_buf1_size;
206 int audio_buf_index; /* in bytes */
207 int audio_write_buf_size;
208 int audio_buf_frames_pending;
209 AVPacket audio_pkt_temp;
211 int audio_pkt_temp_serial;
212 int audio_last_serial;
213 struct AudioParams audio_src;
215 struct AudioParams audio_filter_src;
217 struct AudioParams audio_tgt;
218 struct SwrContext *swr_ctx;
219 int frame_drops_early;
220 int frame_drops_late;
222 int64_t audio_frame_next_pts;
225 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
227 int16_t sample_array[SAMPLE_ARRAY_SIZE];
228 int sample_array_index;
232 FFTSample *rdft_data;
234 double last_vis_time;
236 SDL_Thread *subtitle_tid;
238 AVStream *subtitle_st;
239 PacketQueue subtitleq;
240 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
241 int subpq_size, subpq_rindex, subpq_windex;
242 SDL_mutex *subpq_mutex;
243 SDL_cond *subpq_cond;
246 double frame_last_pts;
247 double frame_last_duration;
248 double frame_last_dropped_pts;
249 double frame_last_returned_time;
250 double frame_last_filter_delay;
251 int64_t frame_last_dropped_pos;
252 int frame_last_dropped_serial;
256 int64_t video_current_pos; // current displayed file pos
257 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
258 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
259 int pictq_size, pictq_rindex, pictq_windex;
260 SDL_mutex *pictq_mutex;
261 SDL_cond *pictq_cond;
263 struct SwsContext *img_convert_ctx;
265 SDL_Rect last_display_rect;
268 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 char *vfilters = NULL;
329 static char *afilters = NULL;
332 /* current context */
333 static int is_full_screen;
334 static int64_t audio_callback_time;
336 static AVPacket flush_pkt;
338 #define FF_ALLOC_EVENT (SDL_USEREVENT)
339 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
341 static SDL_Surface *screen;
344 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
345 enum AVSampleFormat fmt2, int64_t channel_count2)
347 /* If channel count == 1, planar and non-planar formats are the same */
348 if (channel_count1 == 1 && channel_count2 == 1)
349 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
351 return channel_count1 != channel_count2 || fmt1 != fmt2;
355 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
357 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
358 return channel_layout;
363 static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
365 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
367 MyAVPacketList *pkt1;
369 if (q->abort_request)
372 pkt1 = av_malloc(sizeof(MyAVPacketList));
377 if (pkt == &flush_pkt)
379 pkt1->serial = q->serial;
384 q->last_pkt->next = pkt1;
387 q->size += pkt1->pkt.size + sizeof(*pkt1);
388 /* XXX: should duplicate packet data in DV case */
389 SDL_CondSignal(q->cond);
393 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
397 /* duplicate the packet */
398 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
401 SDL_LockMutex(q->mutex);
402 ret = packet_queue_put_private(q, pkt);
403 SDL_UnlockMutex(q->mutex);
405 if (pkt != &flush_pkt && ret < 0)
411 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
413 AVPacket pkt1, *pkt = &pkt1;
417 pkt->stream_index = stream_index;
418 return packet_queue_put(q, pkt);
421 /* packet queue handling */
422 static void packet_queue_init(PacketQueue *q)
424 memset(q, 0, sizeof(PacketQueue));
425 q->mutex = SDL_CreateMutex();
426 q->cond = SDL_CreateCond();
427 q->abort_request = 1;
430 static void packet_queue_flush(PacketQueue *q)
432 MyAVPacketList *pkt, *pkt1;
434 SDL_LockMutex(q->mutex);
435 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
437 av_free_packet(&pkt->pkt);
444 SDL_UnlockMutex(q->mutex);
447 static void packet_queue_destroy(PacketQueue *q)
449 packet_queue_flush(q);
450 SDL_DestroyMutex(q->mutex);
451 SDL_DestroyCond(q->cond);
454 static void packet_queue_abort(PacketQueue *q)
456 SDL_LockMutex(q->mutex);
458 q->abort_request = 1;
460 SDL_CondSignal(q->cond);
462 SDL_UnlockMutex(q->mutex);
465 static void packet_queue_start(PacketQueue *q)
467 SDL_LockMutex(q->mutex);
468 q->abort_request = 0;
469 packet_queue_put_private(q, &flush_pkt);
470 SDL_UnlockMutex(q->mutex);
473 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
474 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
476 MyAVPacketList *pkt1;
479 SDL_LockMutex(q->mutex);
482 if (q->abort_request) {
489 q->first_pkt = pkt1->next;
493 q->size -= pkt1->pkt.size + sizeof(*pkt1);
496 *serial = pkt1->serial;
504 SDL_CondWait(q->cond, q->mutex);
507 SDL_UnlockMutex(q->mutex);
511 static inline void fill_rectangle(SDL_Surface *screen,
512 int x, int y, int w, int h, int color, int update)
519 SDL_FillRect(screen, &rect, color);
520 if (update && w > 0 && h > 0)
521 SDL_UpdateRect(screen, x, y, w, h);
524 /* draw only the border of a rectangle */
525 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
529 /* fill the background */
533 w2 = width - (x + w);
539 h2 = height - (y + h);
542 fill_rectangle(screen,
546 fill_rectangle(screen,
547 xleft + width - w2, ytop,
550 fill_rectangle(screen,
554 fill_rectangle(screen,
555 xleft + w1, ytop + height - h2,
560 #define ALPHA_BLEND(a, oldp, newp, s)\
561 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
563 #define RGBA_IN(r, g, b, a, s)\
565 unsigned int v = ((const uint32_t *)(s))[0];\
566 a = (v >> 24) & 0xff;\
567 r = (v >> 16) & 0xff;\
568 g = (v >> 8) & 0xff;\
572 #define YUVA_IN(y, u, v, a, s, pal)\
574 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
575 a = (val >> 24) & 0xff;\
576 y = (val >> 16) & 0xff;\
577 u = (val >> 8) & 0xff;\
581 #define YUVA_OUT(d, y, u, v, a)\
583 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
589 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
591 int wrap, wrap3, width2, skip2;
592 int y, u, v, a, u1, v1, a1, w, h;
593 uint8_t *lum, *cb, *cr;
596 int dstx, dsty, dstw, dsth;
598 dstw = av_clip(rect->w, 0, imgw);
599 dsth = av_clip(rect->h, 0, imgh);
600 dstx = av_clip(rect->x, 0, imgw - dstw);
601 dsty = av_clip(rect->y, 0, imgh - dsth);
602 lum = dst->data[0] + dsty * dst->linesize[0];
603 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
604 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
606 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
608 wrap = dst->linesize[0];
609 wrap3 = rect->pict.linesize[0];
610 p = rect->pict.data[0];
611 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
619 YUVA_IN(y, u, v, a, p, pal);
620 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
621 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
622 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
628 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
629 YUVA_IN(y, u, v, a, p, pal);
633 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
635 YUVA_IN(y, u, v, a, p + BPP, pal);
639 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
640 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
641 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
648 YUVA_IN(y, u, v, a, p, pal);
649 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
650 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
651 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
655 p += wrap3 - dstw * BPP;
656 lum += wrap - dstw - dstx;
657 cb += dst->linesize[1] - width2 - skip2;
658 cr += dst->linesize[2] - width2 - skip2;
660 for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
666 YUVA_IN(y, u, v, a, p, pal);
670 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
673 YUVA_IN(y, u, v, a, p, pal);
677 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
678 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
679 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
685 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
686 YUVA_IN(y, u, v, a, p, pal);
690 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
692 YUVA_IN(y, u, v, a, p + BPP, pal);
696 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
700 YUVA_IN(y, u, v, a, p, pal);
704 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
706 YUVA_IN(y, u, v, a, p + BPP, pal);
710 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
712 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
713 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
717 p += -wrap3 + 2 * BPP;
721 YUVA_IN(y, u, v, a, p, pal);
725 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
728 YUVA_IN(y, u, v, a, p, pal);
732 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
733 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
734 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
740 p += wrap3 + (wrap3 - dstw * BPP);
741 lum += wrap + (wrap - dstw - dstx);
742 cb += dst->linesize[1] - width2 - skip2;
743 cr += dst->linesize[2] - width2 - skip2;
745 /* handle odd height */
752 YUVA_IN(y, u, v, a, p, pal);
753 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
754 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
755 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
761 for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
762 YUVA_IN(y, u, v, a, p, pal);
766 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
768 YUVA_IN(y, u, v, a, p + BPP, pal);
772 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
773 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
774 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
781 YUVA_IN(y, u, v, a, p, pal);
782 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
783 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
784 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
789 static void free_picture(VideoPicture *vp)
792 SDL_FreeYUVOverlay(vp->bmp);
797 static void free_subpicture(SubPicture *sp)
799 avsubtitle_free(&sp->sub);
802 static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, VideoPicture *vp)
805 int width, height, x, y;
807 if (vp->sar.num == 0)
810 aspect_ratio = av_q2d(vp->sar);
812 if (aspect_ratio <= 0.0)
814 aspect_ratio *= (float)vp->width / (float)vp->height;
816 /* XXX: we suppose the screen has a 1.0 pixel ratio */
818 width = ((int)rint(height * aspect_ratio)) & ~1;
819 if (width > scr_width) {
821 height = ((int)rint(width / aspect_ratio)) & ~1;
823 x = (scr_width - width) / 2;
824 y = (scr_height - height) / 2;
825 rect->x = scr_xleft + x;
826 rect->y = scr_ytop + y;
827 rect->w = FFMAX(width, 1);
828 rect->h = FFMAX(height, 1);
831 static void video_image_display(VideoState *is)
839 vp = &is->pictq[is->pictq_rindex];
841 if (is->subtitle_st) {
842 if (is->subpq_size > 0) {
843 sp = &is->subpq[is->subpq_rindex];
845 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
846 SDL_LockYUVOverlay (vp->bmp);
848 pict.data[0] = vp->bmp->pixels[0];
849 pict.data[1] = vp->bmp->pixels[2];
850 pict.data[2] = vp->bmp->pixels[1];
852 pict.linesize[0] = vp->bmp->pitches[0];
853 pict.linesize[1] = vp->bmp->pitches[2];
854 pict.linesize[2] = vp->bmp->pitches[1];
856 for (i = 0; i < sp->sub.num_rects; i++)
857 blend_subrect(&pict, sp->sub.rects[i],
858 vp->bmp->w, vp->bmp->h);
860 SDL_UnlockYUVOverlay (vp->bmp);
865 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp);
867 SDL_DisplayYUVOverlay(vp->bmp, &rect);
869 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) {
870 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
871 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
872 is->last_display_rect = rect;
877 static inline int compute_mod(int a, int b)
879 return a < 0 ? a%b + b : a%b;
882 static void video_audio_display(VideoState *s)
884 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
885 int ch, channels, h, h2, bgcolor, fgcolor;
887 int rdft_bits, nb_freq;
889 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
891 nb_freq = 1 << (rdft_bits - 1);
893 /* compute display index : center on currently output samples */
894 channels = s->audio_tgt.channels;
895 nb_display_channels = channels;
897 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
899 delay = s->audio_write_buf_size;
902 /* to be more precise, we take into account the time spent since
903 the last buffer computation */
904 if (audio_callback_time) {
905 time_diff = av_gettime() - audio_callback_time;
906 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
909 delay += 2 * data_used;
910 if (delay < data_used)
913 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
914 if (s->show_mode == SHOW_MODE_WAVES) {
916 for (i = 0; i < 1000; i += channels) {
917 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
918 int a = s->sample_array[idx];
919 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
920 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
921 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
923 if (h < score && (b ^ c) < 0) {
930 s->last_i_start = i_start;
932 i_start = s->last_i_start;
935 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
936 if (s->show_mode == SHOW_MODE_WAVES) {
937 fill_rectangle(screen,
938 s->xleft, s->ytop, s->width, s->height,
941 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
943 /* total height for one channel */
944 h = s->height / nb_display_channels;
945 /* graph height / 2 */
947 for (ch = 0; ch < nb_display_channels; ch++) {
949 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
950 for (x = 0; x < s->width; x++) {
951 y = (s->sample_array[i] * h2) >> 15;
958 fill_rectangle(screen,
959 s->xleft + x, ys, 1, y,
962 if (i >= SAMPLE_ARRAY_SIZE)
963 i -= SAMPLE_ARRAY_SIZE;
967 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
969 for (ch = 1; ch < nb_display_channels; ch++) {
970 y = s->ytop + ch * h;
971 fill_rectangle(screen,
972 s->xleft, y, s->width, 1,
975 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
977 nb_display_channels= FFMIN(nb_display_channels, 2);
978 if (rdft_bits != s->rdft_bits) {
979 av_rdft_end(s->rdft);
980 av_free(s->rdft_data);
981 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
982 s->rdft_bits = rdft_bits;
983 s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
987 for (ch = 0; ch < nb_display_channels; ch++) {
988 data[ch] = s->rdft_data + 2 * nb_freq * ch;
990 for (x = 0; x < 2 * nb_freq; x++) {
991 double w = (x-nb_freq) * (1.0 / nb_freq);
992 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
994 if (i >= SAMPLE_ARRAY_SIZE)
995 i -= SAMPLE_ARRAY_SIZE;
997 av_rdft_calc(s->rdft, data[ch]);
999 /* Least efficient way to do this, we should of course
1000 * directly access it but it is more than fast enough. */
1001 for (y = 0; y < s->height; y++) {
1002 double w = 1 / sqrt(nb_freq);
1003 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]));
1004 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1005 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1008 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1010 fill_rectangle(screen,
1011 s->xpos, s->height-y, 1, 1,
1015 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1018 if (s->xpos >= s->width)
1023 static void stream_close(VideoState *is)
1026 /* XXX: use a special url_shutdown call to abort parse cleanly */
1027 is->abort_request = 1;
1028 SDL_WaitThread(is->read_tid, NULL);
1029 packet_queue_destroy(&is->videoq);
1030 packet_queue_destroy(&is->audioq);
1031 packet_queue_destroy(&is->subtitleq);
1033 /* free all pictures */
1034 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
1035 free_picture(&is->pictq[i]);
1036 for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
1037 free_subpicture(&is->subpq[i]);
1038 SDL_DestroyMutex(is->pictq_mutex);
1039 SDL_DestroyCond(is->pictq_cond);
1040 SDL_DestroyMutex(is->subpq_mutex);
1041 SDL_DestroyCond(is->subpq_cond);
1042 SDL_DestroyCond(is->continue_read_thread);
1043 #if !CONFIG_AVFILTER
1044 sws_freeContext(is->img_convert_ctx);
1049 static void do_exit(VideoState *is)
1054 av_lockmgr_register(NULL);
1057 av_freep(&vfilters);
1059 avformat_network_deinit();
1063 av_log(NULL, AV_LOG_QUIET, "%s", "");
1067 static void sigterm_handler(int sig)
1072 static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
1074 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1078 if (is_full_screen) flags |= SDL_FULLSCREEN;
1079 else flags |= SDL_RESIZABLE;
1081 if (vp && vp->width) {
1082 calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
1083 default_width = rect.w;
1084 default_height = rect.h;
1087 if (is_full_screen && fs_screen_width) {
1088 w = fs_screen_width;
1089 h = fs_screen_height;
1090 } else if (!is_full_screen && screen_width) {
1097 w = FFMIN(16383, w);
1098 if (screen && is->width == screen->w && screen->w == w
1099 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1101 screen = SDL_SetVideoMode(w, h, 0, flags);
1103 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1107 window_title = input_filename;
1108 SDL_WM_SetCaption(window_title, window_title);
1110 is->width = screen->w;
1111 is->height = screen->h;
1116 /* display the current picture, if any */
1117 static void video_display(VideoState *is)
1120 video_open(is, 0, NULL);
1121 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1122 video_audio_display(is);
1123 else if (is->video_st)
1124 video_image_display(is);
1127 static double get_clock(Clock *c)
1129 if (*c->queue_serial != c->serial)
1134 double time = av_gettime() / 1000000.0;
1135 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1139 static void set_clock_at(Clock *c, double pts, int serial, double time)
1142 c->last_updated = time;
1143 c->pts_drift = c->pts - time;
1147 static void set_clock(Clock *c, double pts, int serial)
1149 double time = av_gettime() / 1000000.0;
1150 set_clock_at(c, pts, serial, time);
1153 static void set_clock_speed(Clock *c, double speed)
1155 set_clock(c, get_clock(c), c->serial);
1159 static void init_clock(Clock *c, int *queue_serial)
1163 c->queue_serial = queue_serial;
1164 set_clock(c, NAN, -1);
1167 static void sync_clock_to_slave(Clock *c, Clock *slave)
1169 double clock = get_clock(c);
1170 double slave_clock = get_clock(slave);
1171 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1172 set_clock(c, slave_clock, slave->serial);
1175 static int get_master_sync_type(VideoState *is) {
1176 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1178 return AV_SYNC_VIDEO_MASTER;
1180 return AV_SYNC_AUDIO_MASTER;
1181 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1183 return AV_SYNC_AUDIO_MASTER;
1185 return AV_SYNC_EXTERNAL_CLOCK;
1187 return AV_SYNC_EXTERNAL_CLOCK;
1191 /* get the current master clock value */
1192 static double get_master_clock(VideoState *is)
1196 switch (get_master_sync_type(is)) {
1197 case AV_SYNC_VIDEO_MASTER:
1198 val = get_clock(&is->vidclk);
1200 case AV_SYNC_AUDIO_MASTER:
1201 val = get_clock(&is->audclk);
1204 val = get_clock(&is->extclk);
1210 static void check_external_clock_speed(VideoState *is) {
1211 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1212 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1213 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1214 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1215 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1216 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1218 double speed = is->extclk.speed;
1220 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1224 /* seek in the stream */
1225 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1227 if (!is->seek_req) {
1230 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1232 is->seek_flags |= AVSEEK_FLAG_BYTE;
1234 SDL_CondSignal(is->continue_read_thread);
1238 /* pause or resume the video */
1239 static void stream_toggle_pause(VideoState *is)
1242 is->frame_timer += av_gettime() / 1000000.0 + is->vidclk.pts_drift - is->vidclk.pts;
1243 if (is->read_pause_return != AVERROR(ENOSYS)) {
1244 is->vidclk.paused = 0;
1246 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1248 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1249 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1252 static void toggle_pause(VideoState *is)
1254 stream_toggle_pause(is);
1258 static void step_to_next_frame(VideoState *is)
1260 /* if the stream is paused unpause it, then step */
1262 stream_toggle_pause(is);
1266 static double compute_target_delay(double delay, VideoState *is)
1268 double sync_threshold, diff;
1270 /* update delay to follow master synchronisation source */
1271 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1272 /* if video is slave, we try to correct big delays by
1273 duplicating or deleting a frame */
1274 diff = get_clock(&is->vidclk) - get_master_clock(is);
1276 /* skip or repeat frame. We take into account the
1277 delay to compute the threshold. I still don't know
1278 if it is the best guess */
1279 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1280 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1281 if (diff <= -sync_threshold)
1282 delay = FFMAX(0, delay + diff);
1283 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1284 delay = delay + diff;
1285 else if (diff >= sync_threshold)
1290 av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
1296 static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp) {
1297 if (vp->serial == nextvp->serial) {
1298 double duration = nextvp->pts - vp->pts;
1299 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1300 return vp->duration;
1308 static void pictq_next_picture(VideoState *is) {
1309 /* update queue size and signal for next picture */
1310 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1311 is->pictq_rindex = 0;
1313 SDL_LockMutex(is->pictq_mutex);
1315 SDL_CondSignal(is->pictq_cond);
1316 SDL_UnlockMutex(is->pictq_mutex);
1319 static int pictq_prev_picture(VideoState *is) {
1320 VideoPicture *prevvp;
1322 /* update queue size and signal for the previous picture */
1323 prevvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
1324 if (prevvp->allocated && prevvp->serial == is->videoq.serial) {
1325 SDL_LockMutex(is->pictq_mutex);
1326 if (is->pictq_size < VIDEO_PICTURE_QUEUE_SIZE) {
1327 if (--is->pictq_rindex == -1)
1328 is->pictq_rindex = VIDEO_PICTURE_QUEUE_SIZE - 1;
1332 SDL_CondSignal(is->pictq_cond);
1333 SDL_UnlockMutex(is->pictq_mutex);
1338 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1339 /* update current video pts */
1340 set_clock(&is->vidclk, pts, serial);
1341 sync_clock_to_slave(&is->extclk, &is->vidclk);
1342 is->video_current_pos = pos;
1343 is->frame_last_pts = pts;
1346 /* called to display each frame */
1347 static void video_refresh(void *opaque, double *remaining_time)
1349 VideoState *is = opaque;
1353 SubPicture *sp, *sp2;
1355 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1356 check_external_clock_speed(is);
1358 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1359 time = av_gettime() / 1000000.0;
1360 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1362 is->last_vis_time = time;
1364 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1369 if (is->force_refresh)
1370 redisplay = pictq_prev_picture(is);
1372 if (is->pictq_size == 0) {
1373 SDL_LockMutex(is->pictq_mutex);
1374 if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
1375 update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, is->frame_last_dropped_serial);
1376 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1378 SDL_UnlockMutex(is->pictq_mutex);
1379 // nothing to do, no picture to display in the queue
1381 double last_duration, duration, delay;
1382 /* dequeue the picture */
1383 vp = &is->pictq[is->pictq_rindex];
1385 if (vp->serial != is->videoq.serial) {
1386 pictq_next_picture(is);
1394 /* compute nominal last_duration */
1395 last_duration = vp->pts - is->frame_last_pts;
1396 if (!isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {
1397 /* if duration of the last frame was sane, update last_duration in video state */
1398 is->frame_last_duration = last_duration;
1403 delay = compute_target_delay(is->frame_last_duration, is);
1405 time= av_gettime()/1000000.0;
1406 if (time < is->frame_timer + delay && !redisplay) {
1407 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1411 is->frame_timer += delay;
1412 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1413 is->frame_timer = time;
1415 SDL_LockMutex(is->pictq_mutex);
1416 if (!redisplay && !isnan(vp->pts))
1417 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1418 SDL_UnlockMutex(is->pictq_mutex);
1420 if (is->pictq_size > 1) {
1421 VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
1422 duration = vp_duration(is, vp, nextvp);
1423 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1425 is->frame_drops_late++;
1426 pictq_next_picture(is);
1432 if (is->subtitle_st) {
1433 while (is->subpq_size > 0) {
1434 sp = &is->subpq[is->subpq_rindex];
1436 if (is->subpq_size > 1)
1437 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1441 if (sp->serial != is->subtitleq.serial
1442 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1443 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1445 free_subpicture(sp);
1447 /* update queue size and signal for next picture */
1448 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1449 is->subpq_rindex = 0;
1451 SDL_LockMutex(is->subpq_mutex);
1453 SDL_CondSignal(is->subpq_cond);
1454 SDL_UnlockMutex(is->subpq_mutex);
1462 /* display picture */
1463 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1466 pictq_next_picture(is);
1468 if (is->step && !is->paused)
1469 stream_toggle_pause(is);
1472 is->force_refresh = 0;
1474 static int64_t last_time;
1476 int aqsize, vqsize, sqsize;
1479 cur_time = av_gettime();
1480 if (!last_time || (cur_time - last_time) >= 30000) {
1485 aqsize = is->audioq.size;
1487 vqsize = is->videoq.size;
1488 if (is->subtitle_st)
1489 sqsize = is->subtitleq.size;
1491 if (is->audio_st && is->video_st)
1492 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1493 else if (is->video_st)
1494 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1495 else if (is->audio_st)
1496 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1497 av_log(NULL, AV_LOG_INFO,
1498 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1499 get_master_clock(is),
1500 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1502 is->frame_drops_early + is->frame_drops_late,
1506 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1507 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1509 last_time = cur_time;
1514 /* allocate a picture (needs to do that in main thread to avoid
1515 potential locking problems */
1516 static void alloc_picture(VideoState *is)
1521 vp = &is->pictq[is->pictq_windex];
1525 video_open(is, 0, vp);
1527 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1530 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1531 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1532 /* SDL allocates a buffer smaller than requested if the video
1533 * overlay hardware is unable to support the requested size. */
1534 av_log(NULL, AV_LOG_FATAL,
1535 "Error: the video system does not support an image\n"
1536 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1537 "to reduce the image size.\n", vp->width, vp->height );
1541 SDL_LockMutex(is->pictq_mutex);
1543 SDL_CondSignal(is->pictq_cond);
1544 SDL_UnlockMutex(is->pictq_mutex);
1547 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1548 int i, width, height;
1550 for (i = 0; i < 3; i++) {
1557 if (bmp->pitches[i] > width) {
1558 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1559 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1565 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1569 #if defined(DEBUG_SYNC) && 0
1570 printf("frame_type=%c pts=%0.3f\n",
1571 av_get_picture_type_char(src_frame->pict_type), pts);
1574 /* wait until we have space to put a new picture */
1575 SDL_LockMutex(is->pictq_mutex);
1577 /* keep the last already displayed picture in the queue */
1578 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 1 &&
1579 !is->videoq.abort_request) {
1580 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1582 SDL_UnlockMutex(is->pictq_mutex);
1584 if (is->videoq.abort_request)
1587 vp = &is->pictq[is->pictq_windex];
1589 vp->sar = src_frame->sample_aspect_ratio;
1591 /* alloc or resize hardware picture buffer */
1592 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1593 vp->width != src_frame->width ||
1594 vp->height != src_frame->height) {
1599 vp->width = src_frame->width;
1600 vp->height = src_frame->height;
1602 /* the allocation must be done in the main thread to avoid
1603 locking problems. */
1604 event.type = FF_ALLOC_EVENT;
1605 event.user.data1 = is;
1606 SDL_PushEvent(&event);
1608 /* wait until the picture is allocated */
1609 SDL_LockMutex(is->pictq_mutex);
1610 while (!vp->allocated && !is->videoq.abort_request) {
1611 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1613 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1614 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1615 while (!vp->allocated) {
1616 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1619 SDL_UnlockMutex(is->pictq_mutex);
1621 if (is->videoq.abort_request)
1625 /* if the frame is not skipped, then display it */
1627 AVPicture pict = { { 0 } };
1629 /* get a pointer on the bitmap */
1630 SDL_LockYUVOverlay (vp->bmp);
1632 pict.data[0] = vp->bmp->pixels[0];
1633 pict.data[1] = vp->bmp->pixels[2];
1634 pict.data[2] = vp->bmp->pixels[1];
1636 pict.linesize[0] = vp->bmp->pitches[0];
1637 pict.linesize[1] = vp->bmp->pitches[2];
1638 pict.linesize[2] = vp->bmp->pitches[1];
1641 // FIXME use direct rendering
1642 av_picture_copy(&pict, (AVPicture *)src_frame,
1643 src_frame->format, vp->width, vp->height);
1645 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1646 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1647 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1648 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1649 if (is->img_convert_ctx == NULL) {
1650 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1653 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1654 0, vp->height, pict.data, pict.linesize);
1656 /* workaround SDL PITCH_WORKAROUND */
1657 duplicate_right_border_pixels(vp->bmp);
1658 /* update the bitmap content */
1659 SDL_UnlockYUVOverlay(vp->bmp);
1662 vp->duration = duration;
1664 vp->serial = serial;
1666 /* now we can update the picture count */
1667 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1668 is->pictq_windex = 0;
1669 SDL_LockMutex(is->pictq_mutex);
1671 SDL_UnlockMutex(is->pictq_mutex);
1676 static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
1680 if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
1683 if (pkt->data == flush_pkt.data) {
1684 avcodec_flush_buffers(is->video_st->codec);
1686 SDL_LockMutex(is->pictq_mutex);
1687 // Make sure there are no long delay timers (ideally we should just flush the queue but that's harder)
1688 while (is->pictq_size && !is->videoq.abort_request) {
1689 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1691 is->video_current_pos = -1;
1692 is->frame_last_pts = AV_NOPTS_VALUE;
1693 is->frame_last_duration = 0;
1694 is->frame_timer = (double)av_gettime() / 1000000.0;
1695 is->frame_last_dropped_pts = AV_NOPTS_VALUE;
1696 SDL_UnlockMutex(is->pictq_mutex);
1700 if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
1703 if (!got_picture && !pkt->data)
1704 is->video_finished = *serial;
1710 if (decoder_reorder_pts == -1) {
1711 frame->pts = av_frame_get_best_effort_timestamp(frame);
1712 } else if (decoder_reorder_pts) {
1713 frame->pts = frame->pkt_pts;
1715 frame->pts = frame->pkt_dts;
1718 if (frame->pts != AV_NOPTS_VALUE)
1719 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1721 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1723 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1724 SDL_LockMutex(is->pictq_mutex);
1725 if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) {
1726 double clockdiff = get_clock(&is->vidclk) - get_master_clock(is);
1727 double ptsdiff = dpts - is->frame_last_pts;
1728 if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
1729 !isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
1730 clockdiff + ptsdiff - is->frame_last_filter_delay < 0 &&
1731 is->videoq.nb_packets) {
1732 is->frame_last_dropped_pos = av_frame_get_pkt_pos(frame);
1733 is->frame_last_dropped_pts = dpts;
1734 is->frame_last_dropped_serial = *serial;
1735 is->frame_drops_early++;
1736 av_frame_unref(frame);
1740 SDL_UnlockMutex(is->pictq_mutex);
1749 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1750 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1753 AVFilterInOut *outputs = NULL, *inputs = NULL;
1756 outputs = avfilter_inout_alloc();
1757 inputs = avfilter_inout_alloc();
1758 if (!outputs || !inputs) {
1759 ret = AVERROR(ENOMEM);
1763 outputs->name = av_strdup("in");
1764 outputs->filter_ctx = source_ctx;
1765 outputs->pad_idx = 0;
1766 outputs->next = NULL;
1768 inputs->name = av_strdup("out");
1769 inputs->filter_ctx = sink_ctx;
1770 inputs->pad_idx = 0;
1771 inputs->next = NULL;
1773 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1776 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1780 ret = avfilter_graph_config(graph, NULL);
1782 avfilter_inout_free(&outputs);
1783 avfilter_inout_free(&inputs);
1787 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1789 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1790 char sws_flags_str[128];
1791 char buffersrc_args[256];
1793 AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_crop;
1794 AVCodecContext *codec = is->video_st->codec;
1795 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1797 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1798 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1799 graph->scale_sws_opts = av_strdup(sws_flags_str);
1801 snprintf(buffersrc_args, sizeof(buffersrc_args),
1802 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1803 frame->width, frame->height, frame->format,
1804 is->video_st->time_base.num, is->video_st->time_base.den,
1805 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1806 if (fr.num && fr.den)
1807 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1809 if ((ret = avfilter_graph_create_filter(&filt_src,
1810 avfilter_get_by_name("buffer"),
1811 "ffplay_buffer", buffersrc_args, NULL,
1815 ret = avfilter_graph_create_filter(&filt_out,
1816 avfilter_get_by_name("buffersink"),
1817 "ffplay_buffersink", NULL, NULL, graph);
1821 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1824 /* SDL YUV code is not handling odd width/height for some driver
1825 * combinations, therefore we crop the picture to an even width/height. */
1826 if ((ret = avfilter_graph_create_filter(&filt_crop,
1827 avfilter_get_by_name("crop"),
1828 "ffplay_crop", "floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
1830 if ((ret = avfilter_link(filt_crop, 0, filt_out, 0)) < 0)
1833 if ((ret = configure_filtergraph(graph, vfilters, filt_src, filt_crop)) < 0)
1836 is->in_video_filter = filt_src;
1837 is->out_video_filter = filt_out;
1843 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1845 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1846 int sample_rates[2] = { 0, -1 };
1847 int64_t channel_layouts[2] = { 0, -1 };
1848 int channels[2] = { 0, -1 };
1849 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1850 char aresample_swr_opts[512] = "";
1851 AVDictionaryEntry *e = NULL;
1852 char asrc_args[256];
1855 avfilter_graph_free(&is->agraph);
1856 if (!(is->agraph = avfilter_graph_alloc()))
1857 return AVERROR(ENOMEM);
1859 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1860 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1861 if (strlen(aresample_swr_opts))
1862 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1863 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1865 ret = snprintf(asrc_args, sizeof(asrc_args),
1866 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1867 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1868 is->audio_filter_src.channels,
1869 1, is->audio_filter_src.freq);
1870 if (is->audio_filter_src.channel_layout)
1871 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1872 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1874 ret = avfilter_graph_create_filter(&filt_asrc,
1875 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1876 asrc_args, NULL, is->agraph);
1881 ret = avfilter_graph_create_filter(&filt_asink,
1882 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1883 NULL, NULL, is->agraph);
1887 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1889 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1892 if (force_output_format) {
1893 channel_layouts[0] = is->audio_tgt.channel_layout;
1894 channels [0] = is->audio_tgt.channels;
1895 sample_rates [0] = is->audio_tgt.freq;
1896 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1898 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1900 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1902 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1907 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1910 is->in_audio_filter = filt_asrc;
1911 is->out_audio_filter = filt_asink;
1915 avfilter_graph_free(&is->agraph);
1918 #endif /* CONFIG_AVFILTER */
1920 static int video_thread(void *arg)
1922 AVPacket pkt = { 0 };
1923 VideoState *is = arg;
1924 AVFrame *frame = av_frame_alloc();
1929 AVRational tb = is->video_st->time_base;
1930 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
1933 AVFilterGraph *graph = avfilter_graph_alloc();
1934 AVFilterContext *filt_out = NULL, *filt_in = NULL;
1937 enum AVPixelFormat last_format = -2;
1938 int last_serial = -1;
1942 while (is->paused && !is->videoq.abort_request)
1945 avcodec_get_frame_defaults(frame);
1946 av_free_packet(&pkt);
1948 ret = get_video_frame(is, frame, &pkt, &serial);
1955 if ( last_w != frame->width
1956 || last_h != frame->height
1957 || last_format != frame->format
1958 || last_serial != serial) {
1959 av_log(NULL, AV_LOG_DEBUG,
1960 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
1962 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
1963 frame->width, frame->height,
1964 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
1965 avfilter_graph_free(&graph);
1966 graph = avfilter_graph_alloc();
1967 if ((ret = configure_video_filters(graph, is, vfilters, frame)) < 0) {
1969 event.type = FF_QUIT_EVENT;
1970 event.user.data1 = is;
1971 SDL_PushEvent(&event);
1972 av_free_packet(&pkt);
1975 filt_in = is->in_video_filter;
1976 filt_out = is->out_video_filter;
1977 last_w = frame->width;
1978 last_h = frame->height;
1979 last_format = frame->format;
1980 last_serial = serial;
1981 frame_rate = filt_out->inputs[0]->frame_rate;
1984 ret = av_buffersrc_add_frame(filt_in, frame);
1987 av_frame_unref(frame);
1988 avcodec_get_frame_defaults(frame);
1989 av_free_packet(&pkt);
1992 is->frame_last_returned_time = av_gettime() / 1000000.0;
1994 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
1996 if (ret == AVERROR_EOF)
1997 is->video_finished = serial;
2002 is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
2003 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2004 is->frame_last_filter_delay = 0;
2005 tb = filt_out->inputs[0]->time_base;
2007 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2008 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2009 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
2010 av_frame_unref(frame);
2019 avcodec_flush_buffers(is->video_st->codec);
2021 avfilter_graph_free(&graph);
2023 av_free_packet(&pkt);
2024 av_frame_free(&frame);
2028 static int subtitle_thread(void *arg)
2030 VideoState *is = arg;
2032 AVPacket pkt1, *pkt = &pkt1;
2037 int r, g, b, y, u, v, a;
2040 while (is->paused && !is->subtitleq.abort_request) {
2043 if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
2046 if (pkt->data == flush_pkt.data) {
2047 avcodec_flush_buffers(is->subtitle_st->codec);
2050 SDL_LockMutex(is->subpq_mutex);
2051 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
2052 !is->subtitleq.abort_request) {
2053 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
2055 SDL_UnlockMutex(is->subpq_mutex);
2057 if (is->subtitleq.abort_request)
2060 sp = &is->subpq[is->subpq_windex];
2062 /* NOTE: ipts is the PTS of the _first_ picture beginning in
2063 this packet, if any */
2065 if (pkt->pts != AV_NOPTS_VALUE)
2066 pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
2068 avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
2069 &got_subtitle, pkt);
2070 if (got_subtitle && sp->sub.format == 0) {
2071 if (sp->sub.pts != AV_NOPTS_VALUE)
2072 pts = sp->sub.pts / (double)AV_TIME_BASE;
2074 sp->serial = serial;
2076 for (i = 0; i < sp->sub.num_rects; i++)
2078 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2080 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2081 y = RGB_TO_Y_CCIR(r, g, b);
2082 u = RGB_TO_U_CCIR(r, g, b, 0);
2083 v = RGB_TO_V_CCIR(r, g, b, 0);
2084 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2088 /* now we can update the picture count */
2089 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
2090 is->subpq_windex = 0;
2091 SDL_LockMutex(is->subpq_mutex);
2093 SDL_UnlockMutex(is->subpq_mutex);
2094 } else if (got_subtitle) {
2095 avsubtitle_free(&sp->sub);
2097 av_free_packet(pkt);
2102 /* copy samples for viewing in editor window */
2103 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2107 size = samples_size / sizeof(short);
2109 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2112 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2114 is->sample_array_index += len;
2115 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2116 is->sample_array_index = 0;
2121 /* return the wanted number of samples to get better sync if sync_type is video
2122 * or external master clock */
2123 static int synchronize_audio(VideoState *is, int nb_samples)
2125 int wanted_nb_samples = nb_samples;
2127 /* if not master, then we try to remove or add samples to correct the clock */
2128 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2129 double diff, avg_diff;
2130 int min_nb_samples, max_nb_samples;
2132 diff = get_clock(&is->audclk) - get_master_clock(is);
2134 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2135 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2136 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2137 /* not enough measures to have a correct estimate */
2138 is->audio_diff_avg_count++;
2140 /* estimate the A-V difference */
2141 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2143 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2144 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2145 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2146 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2147 wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);
2149 av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2150 diff, avg_diff, wanted_nb_samples - nb_samples,
2151 is->audio_clock, is->audio_diff_threshold);
2154 /* too big difference : may be initial PTS errors, so
2156 is->audio_diff_avg_count = 0;
2157 is->audio_diff_cum = 0;
2161 return wanted_nb_samples;
2165 * Decode one audio frame and return its uncompressed size.
2167 * The processed audio frame is decoded, converted if required, and
2168 * stored in is->audio_buf, with size in bytes given by the return
2171 static int audio_decode_frame(VideoState *is)
2173 AVPacket *pkt_temp = &is->audio_pkt_temp;
2174 AVPacket *pkt = &is->audio_pkt;
2175 AVCodecContext *dec = is->audio_st->codec;
2176 int len1, data_size, resampled_data_size;
2177 int64_t dec_channel_layout;
2179 av_unused double audio_clock0;
2180 int wanted_nb_samples;
2186 /* NOTE: the audio packet can contain several frames */
2187 while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
2189 if (!(is->frame = avcodec_alloc_frame()))
2190 return AVERROR(ENOMEM);
2192 av_frame_unref(is->frame);
2193 avcodec_get_frame_defaults(is->frame);
2196 if (is->audioq.serial != is->audio_pkt_temp_serial)
2202 if (!is->audio_buf_frames_pending) {
2203 len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
2205 /* if error, we skip the frame */
2211 pkt_temp->pts = AV_NOPTS_VALUE;
2212 pkt_temp->data += len1;
2213 pkt_temp->size -= len1;
2214 if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
2215 pkt_temp->stream_index = -1;
2216 if (!pkt_temp->data && !got_frame)
2217 is->audio_finished = is->audio_pkt_temp_serial;
2222 tb = (AVRational){1, is->frame->sample_rate};
2223 if (is->frame->pts != AV_NOPTS_VALUE)
2224 is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
2225 else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
2226 is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
2227 else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
2229 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
2231 is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
2234 if (is->frame->pts != AV_NOPTS_VALUE)
2235 is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
2238 dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
2241 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2242 is->frame->format, av_frame_get_channels(is->frame)) ||
2243 is->audio_filter_src.channel_layout != dec_channel_layout ||
2244 is->audio_filter_src.freq != is->frame->sample_rate ||
2245 is->audio_pkt_temp_serial != is->audio_last_serial;
2248 char buf1[1024], buf2[1024];
2249 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2250 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2251 av_log(NULL, AV_LOG_DEBUG,
2252 "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",
2253 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,
2254 is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
2256 is->audio_filter_src.fmt = is->frame->format;
2257 is->audio_filter_src.channels = av_frame_get_channels(is->frame);
2258 is->audio_filter_src.channel_layout = dec_channel_layout;
2259 is->audio_filter_src.freq = is->frame->sample_rate;
2260 is->audio_last_serial = is->audio_pkt_temp_serial;
2262 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2266 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
2268 av_frame_unref(is->frame);
2272 if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
2273 if (ret == AVERROR(EAGAIN)) {
2274 is->audio_buf_frames_pending = 0;
2277 if (ret == AVERROR_EOF)
2278 is->audio_finished = is->audio_pkt_temp_serial;
2281 is->audio_buf_frames_pending = 1;
2282 tb = is->out_audio_filter->inputs[0]->time_base;
2285 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
2286 is->frame->nb_samples,
2287 is->frame->format, 1);
2289 dec_channel_layout =
2290 (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
2291 is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
2292 wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
2294 if (is->frame->format != is->audio_src.fmt ||
2295 dec_channel_layout != is->audio_src.channel_layout ||
2296 is->frame->sample_rate != is->audio_src.freq ||
2297 (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
2298 swr_free(&is->swr_ctx);
2299 is->swr_ctx = swr_alloc_set_opts(NULL,
2300 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2301 dec_channel_layout, is->frame->format, is->frame->sample_rate,
2303 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2304 av_log(NULL, AV_LOG_ERROR,
2305 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2306 is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
2307 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2310 is->audio_src.channel_layout = dec_channel_layout;
2311 is->audio_src.channels = av_frame_get_channels(is->frame);
2312 is->audio_src.freq = is->frame->sample_rate;
2313 is->audio_src.fmt = is->frame->format;
2317 const uint8_t **in = (const uint8_t **)is->frame->extended_data;
2318 uint8_t **out = &is->audio_buf1;
2319 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
2320 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2323 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2326 if (wanted_nb_samples != is->frame->nb_samples) {
2327 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
2328 wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
2329 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2333 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2334 if (!is->audio_buf1)
2335 return AVERROR(ENOMEM);
2336 len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
2338 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2341 if (len2 == out_count) {
2342 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2343 swr_init(is->swr_ctx);
2345 is->audio_buf = is->audio_buf1;
2346 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2348 is->audio_buf = is->frame->data[0];
2349 resampled_data_size = data_size;
2352 audio_clock0 = is->audio_clock;
2353 /* update the audio clock with the pts */
2354 if (is->frame->pts != AV_NOPTS_VALUE)
2355 is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
2357 is->audio_clock = NAN;
2358 is->audio_clock_serial = is->audio_pkt_temp_serial;
2361 static double last_clock;
2362 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2363 is->audio_clock - last_clock,
2364 is->audio_clock, audio_clock0);
2365 last_clock = is->audio_clock;
2368 return resampled_data_size;
2371 /* free the current packet */
2373 av_free_packet(pkt);
2374 memset(pkt_temp, 0, sizeof(*pkt_temp));
2375 pkt_temp->stream_index = -1;
2377 if (is->audioq.abort_request) {
2381 if (is->audioq.nb_packets == 0)
2382 SDL_CondSignal(is->continue_read_thread);
2384 /* read next packet */
2385 if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
2388 if (pkt->data == flush_pkt.data) {
2389 avcodec_flush_buffers(dec);
2390 is->audio_buf_frames_pending = 0;
2391 is->audio_frame_next_pts = AV_NOPTS_VALUE;
2392 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
2393 is->audio_frame_next_pts = is->audio_st->start_time;
2400 /* prepare a new audio buffer */
2401 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2403 VideoState *is = opaque;
2404 int audio_size, len1;
2406 int frame_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, 1, is->audio_tgt.fmt, 1);
2408 audio_callback_time = av_gettime();
2411 if (is->audio_buf_index >= is->audio_buf_size) {
2412 audio_size = audio_decode_frame(is);
2413 if (audio_size < 0) {
2414 /* if error, just output silence */
2415 is->audio_buf = is->silence_buf;
2416 is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
2418 if (is->show_mode != SHOW_MODE_VIDEO)
2419 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2420 is->audio_buf_size = audio_size;
2422 is->audio_buf_index = 0;
2424 len1 = is->audio_buf_size - is->audio_buf_index;
2427 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2430 is->audio_buf_index += len1;
2432 bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2433 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2434 /* Let's assume the audio driver that is used by SDL has two periods. */
2435 if (!isnan(is->audio_clock)) {
2436 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2437 sync_clock_to_slave(&is->extclk, &is->audclk);
2441 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2443 SDL_AudioSpec wanted_spec, spec;
2445 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2447 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2449 wanted_nb_channels = atoi(env);
2450 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2452 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2453 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2454 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2456 wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2457 wanted_spec.freq = wanted_sample_rate;
2458 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2459 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2462 wanted_spec.format = AUDIO_S16SYS;
2463 wanted_spec.silence = 0;
2464 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2465 wanted_spec.callback = sdl_audio_callback;
2466 wanted_spec.userdata = opaque;
2467 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2468 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
2469 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2470 if (!wanted_spec.channels) {
2471 av_log(NULL, AV_LOG_ERROR,
2472 "No more channel combinations to try, audio open failed\n");
2475 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2477 if (spec.format != AUDIO_S16SYS) {
2478 av_log(NULL, AV_LOG_ERROR,
2479 "SDL advised audio format %d is not supported!\n", spec.format);
2482 if (spec.channels != wanted_spec.channels) {
2483 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2484 if (!wanted_channel_layout) {
2485 av_log(NULL, AV_LOG_ERROR,
2486 "SDL advised channel count %d is not supported!\n", spec.channels);
2491 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2492 audio_hw_params->freq = spec.freq;
2493 audio_hw_params->channel_layout = wanted_channel_layout;
2494 audio_hw_params->channels = spec.channels;
2498 /* open a given stream. Return 0 if OK */
2499 static int stream_component_open(VideoState *is, int stream_index)
2501 AVFormatContext *ic = is->ic;
2502 AVCodecContext *avctx;
2504 const char *forced_codec_name = NULL;
2506 AVDictionaryEntry *t = NULL;
2507 int sample_rate, nb_channels;
2508 int64_t channel_layout;
2510 int stream_lowres = lowres;
2512 if (stream_index < 0 || stream_index >= ic->nb_streams)
2514 avctx = ic->streams[stream_index]->codec;
2516 codec = avcodec_find_decoder(avctx->codec_id);
2518 switch(avctx->codec_type){
2519 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2520 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2521 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2523 if (forced_codec_name)
2524 codec = avcodec_find_decoder_by_name(forced_codec_name);
2526 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2527 "No codec could be found with name '%s'\n", forced_codec_name);
2528 else av_log(NULL, AV_LOG_WARNING,
2529 "No codec could be found with id %d\n", avctx->codec_id);
2533 avctx->codec_id = codec->id;
2534 avctx->workaround_bugs = workaround_bugs;
2535 if(stream_lowres > av_codec_get_max_lowres(codec)){
2536 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2537 av_codec_get_max_lowres(codec));
2538 stream_lowres = av_codec_get_max_lowres(codec);
2540 av_codec_set_lowres(avctx, stream_lowres);
2541 avctx->error_concealment = error_concealment;
2543 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2544 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2545 if(codec->capabilities & CODEC_CAP_DR1)
2546 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2548 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2549 if (!av_dict_get(opts, "threads", NULL, 0))
2550 av_dict_set(&opts, "threads", "auto", 0);
2552 av_dict_set(&opts, "lowres", av_asprintf("%d", stream_lowres), AV_DICT_DONT_STRDUP_VAL);
2553 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2554 av_dict_set(&opts, "refcounted_frames", "1", 0);
2555 if (avcodec_open2(avctx, codec, &opts) < 0)
2557 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2558 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2559 return AVERROR_OPTION_NOT_FOUND;
2562 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2563 switch (avctx->codec_type) {
2564 case AVMEDIA_TYPE_AUDIO:
2569 is->audio_filter_src.freq = avctx->sample_rate;
2570 is->audio_filter_src.channels = avctx->channels;
2571 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2572 is->audio_filter_src.fmt = avctx->sample_fmt;
2573 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2575 link = is->out_audio_filter->inputs[0];
2576 sample_rate = link->sample_rate;
2577 nb_channels = link->channels;
2578 channel_layout = link->channel_layout;
2581 sample_rate = avctx->sample_rate;
2582 nb_channels = avctx->channels;
2583 channel_layout = avctx->channel_layout;
2586 /* prepare audio output */
2587 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2589 is->audio_hw_buf_size = ret;
2590 is->audio_src = is->audio_tgt;
2591 is->audio_buf_size = 0;
2592 is->audio_buf_index = 0;
2594 /* init averaging filter */
2595 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2596 is->audio_diff_avg_count = 0;
2597 /* since we do not have a precise anough audio fifo fullness,
2598 we correct audio sync only if larger than this threshold */
2599 is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / av_samples_get_buffer_size(NULL, is->audio_tgt.channels, is->audio_tgt.freq, is->audio_tgt.fmt, 1);
2601 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2602 memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
2603 is->audio_pkt_temp.stream_index = -1;
2605 is->audio_stream = stream_index;
2606 is->audio_st = ic->streams[stream_index];
2608 packet_queue_start(&is->audioq);
2611 case AVMEDIA_TYPE_VIDEO:
2612 is->video_stream = stream_index;
2613 is->video_st = ic->streams[stream_index];
2615 packet_queue_start(&is->videoq);
2616 is->video_tid = SDL_CreateThread(video_thread, is);
2617 is->queue_attachments_req = 1;
2619 case AVMEDIA_TYPE_SUBTITLE:
2620 is->subtitle_stream = stream_index;
2621 is->subtitle_st = ic->streams[stream_index];
2622 packet_queue_start(&is->subtitleq);
2624 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2632 static void stream_component_close(VideoState *is, int stream_index)
2634 AVFormatContext *ic = is->ic;
2635 AVCodecContext *avctx;
2637 if (stream_index < 0 || stream_index >= ic->nb_streams)
2639 avctx = ic->streams[stream_index]->codec;
2641 switch (avctx->codec_type) {
2642 case AVMEDIA_TYPE_AUDIO:
2643 packet_queue_abort(&is->audioq);
2647 packet_queue_flush(&is->audioq);
2648 av_free_packet(&is->audio_pkt);
2649 swr_free(&is->swr_ctx);
2650 av_freep(&is->audio_buf1);
2651 is->audio_buf1_size = 0;
2652 is->audio_buf = NULL;
2653 av_frame_free(&is->frame);
2656 av_rdft_end(is->rdft);
2657 av_freep(&is->rdft_data);
2662 avfilter_graph_free(&is->agraph);
2665 case AVMEDIA_TYPE_VIDEO:
2666 packet_queue_abort(&is->videoq);
2668 /* note: we also signal this mutex to make sure we deblock the
2669 video thread in all cases */
2670 SDL_LockMutex(is->pictq_mutex);
2671 SDL_CondSignal(is->pictq_cond);
2672 SDL_UnlockMutex(is->pictq_mutex);
2674 SDL_WaitThread(is->video_tid, NULL);
2676 packet_queue_flush(&is->videoq);
2678 case AVMEDIA_TYPE_SUBTITLE:
2679 packet_queue_abort(&is->subtitleq);
2681 /* note: we also signal this mutex to make sure we deblock the
2682 video thread in all cases */
2683 SDL_LockMutex(is->subpq_mutex);
2684 SDL_CondSignal(is->subpq_cond);
2685 SDL_UnlockMutex(is->subpq_mutex);
2687 SDL_WaitThread(is->subtitle_tid, NULL);
2689 packet_queue_flush(&is->subtitleq);
2695 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2696 avcodec_close(avctx);
2697 switch (avctx->codec_type) {
2698 case AVMEDIA_TYPE_AUDIO:
2699 is->audio_st = NULL;
2700 is->audio_stream = -1;
2702 case AVMEDIA_TYPE_VIDEO:
2703 is->video_st = NULL;
2704 is->video_stream = -1;
2706 case AVMEDIA_TYPE_SUBTITLE:
2707 is->subtitle_st = NULL;
2708 is->subtitle_stream = -1;
2715 static int decode_interrupt_cb(void *ctx)
2717 VideoState *is = ctx;
2718 return is->abort_request;
2721 static int is_realtime(AVFormatContext *s)
2723 if( !strcmp(s->iformat->name, "rtp")
2724 || !strcmp(s->iformat->name, "rtsp")
2725 || !strcmp(s->iformat->name, "sdp")
2729 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2730 || !strncmp(s->filename, "udp:", 4)
2737 /* this thread gets the stream from the disk or the network */
2738 static int read_thread(void *arg)
2740 VideoState *is = arg;
2741 AVFormatContext *ic = NULL;
2743 int st_index[AVMEDIA_TYPE_NB];
2744 AVPacket pkt1, *pkt = &pkt1;
2746 int64_t stream_start_time;
2747 int pkt_in_play_range = 0;
2748 AVDictionaryEntry *t;
2749 AVDictionary **opts;
2750 int orig_nb_streams;
2751 SDL_mutex *wait_mutex = SDL_CreateMutex();
2753 memset(st_index, -1, sizeof(st_index));
2754 is->last_video_stream = is->video_stream = -1;
2755 is->last_audio_stream = is->audio_stream = -1;
2756 is->last_subtitle_stream = is->subtitle_stream = -1;
2758 ic = avformat_alloc_context();
2759 ic->interrupt_callback.callback = decode_interrupt_cb;
2760 ic->interrupt_callback.opaque = is;
2761 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2763 print_error(is->filename, err);
2767 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2768 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2769 ret = AVERROR_OPTION_NOT_FOUND;
2775 ic->flags |= AVFMT_FLAG_GENPTS;
2777 opts = setup_find_stream_info_opts(ic, codec_opts);
2778 orig_nb_streams = ic->nb_streams;
2780 err = avformat_find_stream_info(ic, opts);
2782 av_log(NULL, AV_LOG_WARNING,
2783 "%s: could not find codec parameters\n", is->filename);
2787 for (i = 0; i < orig_nb_streams; i++)
2788 av_dict_free(&opts[i]);
2792 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
2794 if (seek_by_bytes < 0)
2795 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2797 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2799 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2800 window_title = av_asprintf("%s - %s", t->value, input_filename);
2802 /* if seeking requested, we execute it */
2803 if (start_time != AV_NOPTS_VALUE) {
2806 timestamp = start_time;
2807 /* add the stream start time */
2808 if (ic->start_time != AV_NOPTS_VALUE)
2809 timestamp += ic->start_time;
2810 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2812 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2813 is->filename, (double)timestamp / AV_TIME_BASE);
2817 is->realtime = is_realtime(ic);
2819 for (i = 0; i < ic->nb_streams; i++)
2820 ic->streams[i]->discard = AVDISCARD_ALL;
2822 st_index[AVMEDIA_TYPE_VIDEO] =
2823 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2824 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2826 st_index[AVMEDIA_TYPE_AUDIO] =
2827 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2828 wanted_stream[AVMEDIA_TYPE_AUDIO],
2829 st_index[AVMEDIA_TYPE_VIDEO],
2831 if (!video_disable && !subtitle_disable)
2832 st_index[AVMEDIA_TYPE_SUBTITLE] =
2833 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2834 wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2835 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2836 st_index[AVMEDIA_TYPE_AUDIO] :
2837 st_index[AVMEDIA_TYPE_VIDEO]),
2840 av_dump_format(ic, 0, is->filename, 0);
2843 is->show_mode = show_mode;
2845 /* open the streams */
2846 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2847 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2851 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2852 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2854 if (is->show_mode == SHOW_MODE_NONE)
2855 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2857 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2858 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2861 if (is->video_stream < 0 && is->audio_stream < 0) {
2862 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2868 if (infinite_buffer < 0 && is->realtime)
2869 infinite_buffer = 1;
2872 if (is->abort_request)
2874 if (is->paused != is->last_paused) {
2875 is->last_paused = is->paused;
2877 is->read_pause_return = av_read_pause(ic);
2881 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2883 (!strcmp(ic->iformat->name, "rtsp") ||
2884 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2885 /* wait 10 ms to avoid trying to get another packet */
2892 int64_t seek_target = is->seek_pos;
2893 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2894 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2895 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2896 // of the seek_pos/seek_rel variables
2898 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2900 av_log(NULL, AV_LOG_ERROR,
2901 "%s: error while seeking\n", is->ic->filename);
2903 if (is->audio_stream >= 0) {
2904 packet_queue_flush(&is->audioq);
2905 packet_queue_put(&is->audioq, &flush_pkt);
2907 if (is->subtitle_stream >= 0) {
2908 packet_queue_flush(&is->subtitleq);
2909 packet_queue_put(&is->subtitleq, &flush_pkt);
2911 if (is->video_stream >= 0) {
2912 packet_queue_flush(&is->videoq);
2913 packet_queue_put(&is->videoq, &flush_pkt);
2915 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2916 set_clock(&is->extclk, NAN, 0);
2918 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2922 is->queue_attachments_req = 1;
2925 step_to_next_frame(is);
2927 if (is->queue_attachments_req) {
2928 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2930 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2932 packet_queue_put(&is->videoq, ©);
2933 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2935 is->queue_attachments_req = 0;
2938 /* if the queue are full, no need to read more */
2939 if (infinite_buffer<1 &&
2940 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2941 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2942 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2943 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2944 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2946 SDL_LockMutex(wait_mutex);
2947 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2948 SDL_UnlockMutex(wait_mutex);
2952 (!is->audio_st || is->audio_finished == is->audioq.serial) &&
2953 (!is->video_st || (is->video_finished == is->videoq.serial && is->pictq_size == 0))) {
2954 if (loop != 1 && (!loop || --loop)) {
2955 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2956 } else if (autoexit) {
2962 if (is->video_stream >= 0)
2963 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2964 if (is->audio_stream >= 0)
2965 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2970 ret = av_read_frame(ic, pkt);
2972 if (ret == AVERROR_EOF || url_feof(ic->pb))
2974 if (ic->pb && ic->pb->error)
2976 SDL_LockMutex(wait_mutex);
2977 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2978 SDL_UnlockMutex(wait_mutex);
2981 /* check if packet is in play range specified by user, then queue, otherwise discard */
2982 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2983 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2984 (pkt->pts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2985 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2986 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2987 <= ((double)duration / 1000000);
2988 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2989 packet_queue_put(&is->audioq, pkt);
2990 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2991 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2992 packet_queue_put(&is->videoq, pkt);
2993 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2994 packet_queue_put(&is->subtitleq, pkt);
2996 av_free_packet(pkt);
2999 /* wait until the end */
3000 while (!is->abort_request) {
3006 /* close each stream */
3007 if (is->audio_stream >= 0)
3008 stream_component_close(is, is->audio_stream);
3009 if (is->video_stream >= 0)
3010 stream_component_close(is, is->video_stream);
3011 if (is->subtitle_stream >= 0)
3012 stream_component_close(is, is->subtitle_stream);
3014 avformat_close_input(&is->ic);
3020 event.type = FF_QUIT_EVENT;
3021 event.user.data1 = is;
3022 SDL_PushEvent(&event);
3024 SDL_DestroyMutex(wait_mutex);
3028 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3032 is = av_mallocz(sizeof(VideoState));
3035 av_strlcpy(is->filename, filename, sizeof(is->filename));
3036 is->iformat = iformat;
3040 /* start video display */
3041 is->pictq_mutex = SDL_CreateMutex();
3042 is->pictq_cond = SDL_CreateCond();
3044 is->subpq_mutex = SDL_CreateMutex();
3045 is->subpq_cond = SDL_CreateCond();
3047 packet_queue_init(&is->videoq);
3048 packet_queue_init(&is->audioq);
3049 packet_queue_init(&is->subtitleq);
3051 is->continue_read_thread = SDL_CreateCond();
3053 init_clock(&is->vidclk, &is->videoq.serial);
3054 init_clock(&is->audclk, &is->audioq.serial);
3055 init_clock(&is->extclk, &is->extclk.serial);
3056 is->audio_clock_serial = -1;
3057 is->audio_last_serial = -1;
3058 is->av_sync_type = av_sync_type;
3059 is->read_tid = SDL_CreateThread(read_thread, is);
3060 if (!is->read_tid) {
3067 static void stream_cycle_channel(VideoState *is, int codec_type)
3069 AVFormatContext *ic = is->ic;
3070 int start_index, stream_index;
3073 AVProgram *p = NULL;
3074 int nb_streams = is->ic->nb_streams;
3076 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3077 start_index = is->last_video_stream;
3078 old_index = is->video_stream;
3079 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3080 start_index = is->last_audio_stream;
3081 old_index = is->audio_stream;
3083 start_index = is->last_subtitle_stream;
3084 old_index = is->subtitle_stream;
3086 stream_index = start_index;
3088 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3089 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3091 nb_streams = p->nb_stream_indexes;
3092 for (start_index = 0; start_index < nb_streams; start_index++)
3093 if (p->stream_index[start_index] == stream_index)
3095 if (start_index == nb_streams)
3097 stream_index = start_index;
3102 if (++stream_index >= nb_streams)
3104 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3107 is->last_subtitle_stream = -1;
3110 if (start_index == -1)
3114 if (stream_index == start_index)
3116 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3117 if (st->codec->codec_type == codec_type) {
3118 /* check that parameters are OK */
3119 switch (codec_type) {
3120 case AVMEDIA_TYPE_AUDIO:
3121 if (st->codec->sample_rate != 0 &&
3122 st->codec->channels != 0)
3125 case AVMEDIA_TYPE_VIDEO:
3126 case AVMEDIA_TYPE_SUBTITLE:
3134 if (p && stream_index != -1)
3135 stream_index = p->stream_index[stream_index];
3136 stream_component_close(is, old_index);
3137 stream_component_open(is, stream_index);
3141 static void toggle_full_screen(VideoState *is)
3143 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3144 /* OS X needs to reallocate the SDL overlays */
3146 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3147 is->pictq[i].reallocate = 1;
3149 is_full_screen = !is_full_screen;
3150 video_open(is, 1, NULL);
3153 static void toggle_audio_display(VideoState *is)
3155 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3156 int next = is->show_mode;
3158 next = (next + 1) % SHOW_MODE_NB;
3159 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3160 if (is->show_mode != next) {
3161 fill_rectangle(screen,
3162 is->xleft, is->ytop, is->width, is->height,
3164 is->force_refresh = 1;
3165 is->show_mode = next;
3169 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3170 double remaining_time = 0.0;
3172 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3173 if (!cursor_hidden && av_gettime() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3177 if (remaining_time > 0.0)
3178 av_usleep((int64_t)(remaining_time * 1000000.0));
3179 remaining_time = REFRESH_RATE;
3180 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3181 video_refresh(is, &remaining_time);
3186 /* handle an event sent by the GUI */
3187 static void event_loop(VideoState *cur_stream)
3190 double incr, pos, frac;
3194 refresh_loop_wait_event(cur_stream, &event);
3195 switch (event.type) {
3197 if (exit_on_keydown) {
3198 do_exit(cur_stream);
3201 switch (event.key.keysym.sym) {
3204 do_exit(cur_stream);
3207 toggle_full_screen(cur_stream);
3208 cur_stream->force_refresh = 1;
3212 toggle_pause(cur_stream);
3214 case SDLK_s: // S: Step to next frame
3215 step_to_next_frame(cur_stream);
3218 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3221 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3224 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3225 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3226 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3229 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3232 toggle_audio_display(cur_stream);
3252 if (seek_by_bytes) {
3253 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
3254 pos = cur_stream->video_current_pos;
3255 } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
3256 pos = cur_stream->audio_pkt.pos;
3258 pos = avio_tell(cur_stream->ic->pb);
3259 if (cur_stream->ic->bit_rate)
3260 incr *= cur_stream->ic->bit_rate / 8.0;
3264 stream_seek(cur_stream, pos, incr, 1);
3266 pos = get_master_clock(cur_stream);
3268 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3270 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3271 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3272 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3279 case SDL_VIDEOEXPOSE:
3280 cur_stream->force_refresh = 1;
3282 case SDL_MOUSEBUTTONDOWN:
3283 if (exit_on_mousedown) {
3284 do_exit(cur_stream);
3287 case SDL_MOUSEMOTION:
3288 if (cursor_hidden) {
3292 cursor_last_shown = av_gettime();
3293 if (event.type == SDL_MOUSEBUTTONDOWN) {
3296 if (event.motion.state != SDL_PRESSED)
3300 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3301 uint64_t size = avio_size(cur_stream->ic->pb);
3302 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3306 int tns, thh, tmm, tss;
3307 tns = cur_stream->ic->duration / 1000000LL;
3309 tmm = (tns % 3600) / 60;
3311 frac = x / cur_stream->width;
3314 mm = (ns % 3600) / 60;
3316 av_log(NULL, AV_LOG_INFO,
3317 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3318 hh, mm, ss, thh, tmm, tss);
3319 ts = frac * cur_stream->ic->duration;
3320 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3321 ts += cur_stream->ic->start_time;
3322 stream_seek(cur_stream, ts, 0, 0);
3325 case SDL_VIDEORESIZE:
3326 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3327 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
3329 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3330 do_exit(cur_stream);
3332 screen_width = cur_stream->width = screen->w;
3333 screen_height = cur_stream->height = screen->h;
3334 cur_stream->force_refresh = 1;
3338 do_exit(cur_stream);
3340 case FF_ALLOC_EVENT:
3341 alloc_picture(event.user.data1);
3349 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3351 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3352 return opt_default(NULL, "video_size", arg);
3355 static int opt_width(void *optctx, const char *opt, const char *arg)
3357 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3361 static int opt_height(void *optctx, const char *opt, const char *arg)
3363 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3367 static int opt_format(void *optctx, const char *opt, const char *arg)
3369 file_iformat = av_find_input_format(arg);
3370 if (!file_iformat) {
3371 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3372 return AVERROR(EINVAL);
3377 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3379 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3380 return opt_default(NULL, "pixel_format", arg);
3383 static int opt_sync(void *optctx, const char *opt, const char *arg)
3385 if (!strcmp(arg, "audio"))
3386 av_sync_type = AV_SYNC_AUDIO_MASTER;
3387 else if (!strcmp(arg, "video"))
3388 av_sync_type = AV_SYNC_VIDEO_MASTER;
3389 else if (!strcmp(arg, "ext"))
3390 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3392 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3398 static int opt_seek(void *optctx, const char *opt, const char *arg)
3400 start_time = parse_time_or_die(opt, arg, 1);
3404 static int opt_duration(void *optctx, const char *opt, const char *arg)
3406 duration = parse_time_or_die(opt, arg, 1);
3410 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3412 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3413 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3414 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3415 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3419 static void opt_input_file(void *optctx, const char *filename)
3421 if (input_filename) {
3422 av_log(NULL, AV_LOG_FATAL,
3423 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3424 filename, input_filename);
3427 if (!strcmp(filename, "-"))
3429 input_filename = filename;
3432 static int opt_codec(void *optctx, const char *opt, const char *arg)
3434 const char *spec = strchr(opt, ':');
3436 av_log(NULL, AV_LOG_ERROR,
3437 "No media specifier was specified in '%s' in option '%s'\n",
3439 return AVERROR(EINVAL);
3443 case 'a' : audio_codec_name = arg; break;
3444 case 's' : subtitle_codec_name = arg; break;
3445 case 'v' : video_codec_name = arg; break;
3447 av_log(NULL, AV_LOG_ERROR,
3448 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3449 return AVERROR(EINVAL);
3456 static const OptionDef options[] = {
3457 #include "cmdutils_common_opts.h"
3458 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3459 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3460 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3461 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3462 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3463 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3464 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3465 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
3466 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
3467 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
3468 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3469 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3470 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3471 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3472 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3473 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3474 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3475 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
3476 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3477 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3478 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3479 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3480 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options", "bit_mask" },
3481 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3482 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3483 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3484 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3485 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3486 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3487 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3488 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3490 { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "set video filters", "filter_graph" },
3491 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3493 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3494 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3495 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3496 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3497 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3498 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3499 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3500 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3504 static void show_usage(void)
3506 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3507 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3508 av_log(NULL, AV_LOG_INFO, "\n");
3511 void show_help_default(const char *opt, const char *arg)
3513 av_log_set_callback(log_callback_help);
3515 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3516 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3518 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3519 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3520 #if !CONFIG_AVFILTER
3521 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3523 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3525 printf("\nWhile playing:\n"
3527 "f toggle full screen\n"
3529 "a cycle audio channel in the current program\n"
3530 "v cycle video channel\n"
3531 "t cycle subtitle channel in the current program\n"
3533 "w show audio waves\n"
3534 "s activate frame-step mode\n"
3535 "left/right seek backward/forward 10 seconds\n"
3536 "down/up seek backward/forward 1 minute\n"
3537 "page down/page up seek backward/forward 10 minutes\n"
3538 "mouse click seek to percentage in file corresponding to fraction of width\n"
3542 static int lockmgr(void **mtx, enum AVLockOp op)
3545 case AV_LOCK_CREATE:
3546 *mtx = SDL_CreateMutex();
3550 case AV_LOCK_OBTAIN:
3551 return !!SDL_LockMutex(*mtx);
3552 case AV_LOCK_RELEASE:
3553 return !!SDL_UnlockMutex(*mtx);
3554 case AV_LOCK_DESTROY:
3555 SDL_DestroyMutex(*mtx);
3561 /* Called from the main */
3562 int main(int argc, char **argv)
3566 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3568 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3569 parse_loglevel(argc, argv, options);
3571 /* register all codecs, demux and protocols */
3572 avcodec_register_all();
3574 avdevice_register_all();
3577 avfilter_register_all();
3580 avformat_network_init();
3584 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3585 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3587 show_banner(argc, argv, options);
3589 parse_options(NULL, argc, argv, options, opt_input_file);
3591 if (!input_filename) {
3593 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3594 av_log(NULL, AV_LOG_FATAL,
3595 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3599 if (display_disable) {
3602 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3604 flags &= ~SDL_INIT_AUDIO;
3605 if (display_disable)
3606 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3607 #if !defined(__MINGW32__) && !defined(__APPLE__)
3608 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3610 if (SDL_Init (flags)) {
3611 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3612 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3616 if (!display_disable) {
3617 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3618 fs_screen_width = vi->current_w;
3619 fs_screen_height = vi->current_h;
3622 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3623 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3624 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3626 if (av_lockmgr_register(lockmgr)) {
3627 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3631 av_init_packet(&flush_pkt);
3632 flush_pkt.data = (uint8_t *)&flush_pkt;
3634 is = stream_open(input_filename, file_iformat);
3636 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");