2 * Copyright (c) 2003 Fabrice Bellard
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * simple media player based on the FFmpeg libraries
33 #include "libavutil/avstring.h"
34 #include "libavutil/colorspace.h"
35 #include "libavutil/eval.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/imgutils.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/parseutils.h"
41 #include "libavutil/samplefmt.h"
42 #include "libavutil/avassert.h"
43 #include "libavutil/time.h"
44 #include "libavformat/avformat.h"
45 #include "libavdevice/avdevice.h"
46 #include "libswscale/swscale.h"
47 #include "libavutil/opt.h"
48 #include "libavcodec/avfft.h"
49 #include "libswresample/swresample.h"
52 # include "libavfilter/avcodec.h"
53 # include "libavfilter/avfilter.h"
54 # include "libavfilter/buffersink.h"
55 # include "libavfilter/buffersrc.h"
59 #include <SDL_thread.h>
65 const char program_name[] = "ffplay";
66 const int program_birth_year = 2003;
68 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
70 #define EXTERNAL_CLOCK_MIN_FRAMES 2
71 #define EXTERNAL_CLOCK_MAX_FRAMES 10
73 /* Minimum SDL audio buffer size, in samples. */
74 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
75 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
76 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
78 /* no AV sync correction is done if below the minimum AV sync threshold */
79 #define AV_SYNC_THRESHOLD_MIN 0.04
80 /* AV sync correction is done if above the maximum AV sync threshold */
81 #define AV_SYNC_THRESHOLD_MAX 0.1
82 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
83 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
84 /* no AV correction is done if too big error */
85 #define AV_NOSYNC_THRESHOLD 10.0
87 /* maximum audio speed change to get correct sync */
88 #define SAMPLE_CORRECTION_PERCENT_MAX 10
90 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
91 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
92 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
93 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
95 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
96 #define AUDIO_DIFF_AVG_NB 20
98 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
99 #define REFRESH_RATE 0.01
101 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
102 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
103 #define SAMPLE_ARRAY_SIZE (8 * 65536)
105 #define CURSOR_HIDE_DELAY 1000000
107 static unsigned sws_flags = SWS_BICUBIC;
109 typedef struct MyAVPacketList {
111 struct MyAVPacketList *next;
115 typedef struct PacketQueue {
116 MyAVPacketList *first_pkt, *last_pkt;
125 #define VIDEO_PICTURE_QUEUE_SIZE 3
126 #define SUBPICTURE_QUEUE_SIZE 16
127 #define SAMPLE_QUEUE_SIZE 9
128 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
130 typedef struct AudioParams {
133 int64_t channel_layout;
134 enum AVSampleFormat fmt;
139 typedef struct Clock {
140 double pts; /* clock base */
141 double pts_drift; /* clock base minus time at which we updated the clock */
144 int serial; /* clock is based on a packet with this serial */
146 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
149 /* Common struct for handling all types of decoded data and allocated render buffers. */
150 typedef struct Frame {
154 double pts; /* presentation timestamp for the frame */
155 double duration; /* estimated duration of the frame */
156 int64_t pos; /* byte position of the frame in the input file */
165 typedef struct FrameQueue {
166 Frame queue[FRAME_QUEUE_SIZE];
179 AV_SYNC_AUDIO_MASTER, /* default choice */
180 AV_SYNC_VIDEO_MASTER,
181 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
184 typedef struct Decoder {
188 AVCodecContext *avctx;
192 SDL_cond *empty_queue_cond;
194 AVRational start_pts_tb;
196 AVRational next_pts_tb;
197 SDL_Thread *decoder_tid;
200 typedef struct VideoState {
201 SDL_Thread *read_tid;
202 AVInputFormat *iformat;
207 int queue_attachments_req;
212 int read_pause_return;
236 int audio_clock_serial;
237 double audio_diff_cum; /* used for AV difference average computation */
238 double audio_diff_avg_coef;
239 double audio_diff_threshold;
240 int audio_diff_avg_count;
243 int audio_hw_buf_size;
244 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
247 unsigned int audio_buf_size; /* in bytes */
248 unsigned int audio_buf1_size;
249 int audio_buf_index; /* in bytes */
250 int audio_write_buf_size;
251 struct AudioParams audio_src;
253 struct AudioParams audio_filter_src;
255 struct AudioParams audio_tgt;
256 struct SwrContext *swr_ctx;
257 int frame_drops_early;
258 int frame_drops_late;
261 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
263 int16_t sample_array[SAMPLE_ARRAY_SIZE];
264 int sample_array_index;
268 FFTSample *rdft_data;
270 double last_vis_time;
273 AVStream *subtitle_st;
274 PacketQueue subtitleq;
277 double frame_last_returned_time;
278 double frame_last_filter_delay;
282 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
284 struct SwsContext *img_convert_ctx;
286 struct SwsContext *sub_convert_ctx;
287 SDL_Rect last_display_rect;
291 int width, height, xleft, ytop;
296 AVFilterContext *in_video_filter; // the first filter in the video chain
297 AVFilterContext *out_video_filter; // the last filter in the video chain
298 AVFilterContext *in_audio_filter; // the first filter in the audio chain
299 AVFilterContext *out_audio_filter; // the last filter in the audio chain
300 AVFilterGraph *agraph; // audio filter graph
303 int last_video_stream, last_audio_stream, last_subtitle_stream;
305 SDL_cond *continue_read_thread;
308 /* options specified by the user */
309 static AVInputFormat *file_iformat;
310 static const char *input_filename;
311 static const char *window_title;
312 static int fs_screen_width;
313 static int fs_screen_height;
314 static int default_width = 640;
315 static int default_height = 480;
316 static int screen_width = 0;
317 static int screen_height = 0;
318 static int audio_disable;
319 static int video_disable;
320 static int subtitle_disable;
321 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322 static int seek_by_bytes = -1;
323 static int display_disable;
324 static int show_status = 1;
325 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
326 static int64_t start_time = AV_NOPTS_VALUE;
327 static int64_t duration = AV_NOPTS_VALUE;
329 static int genpts = 0;
330 static int lowres = 0;
331 static int decoder_reorder_pts = -1;
333 static int exit_on_keydown;
334 static int exit_on_mousedown;
336 static int framedrop = -1;
337 static int infinite_buffer = -1;
338 static enum ShowMode show_mode = SHOW_MODE_NONE;
339 static const char *audio_codec_name;
340 static const char *subtitle_codec_name;
341 static const char *video_codec_name;
342 double rdftspeed = 0.02;
343 static int64_t cursor_last_shown;
344 static int cursor_hidden = 0;
346 static const char **vfilters_list = NULL;
347 static int nb_vfilters = 0;
348 static char *afilters = NULL;
350 static int autorotate = 1;
352 /* current context */
353 static int is_full_screen;
354 static int64_t audio_callback_time;
356 static AVPacket flush_pkt;
358 #define FF_ALLOC_EVENT (SDL_USEREVENT)
359 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361 static SDL_Surface *screen;
364 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
366 GROW_ARRAY(vfilters_list, nb_vfilters);
367 vfilters_list[nb_vfilters - 1] = arg;
373 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
374 enum AVSampleFormat fmt2, int64_t channel_count2)
376 /* If channel count == 1, planar and non-planar formats are the same */
377 if (channel_count1 == 1 && channel_count2 == 1)
378 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
380 return channel_count1 != channel_count2 || fmt1 != fmt2;
384 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
386 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
387 return channel_layout;
392 static void free_picture(Frame *vp);
394 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
396 MyAVPacketList *pkt1;
398 if (q->abort_request)
401 pkt1 = av_malloc(sizeof(MyAVPacketList));
406 if (pkt == &flush_pkt)
408 pkt1->serial = q->serial;
413 q->last_pkt->next = pkt1;
416 q->size += pkt1->pkt.size + sizeof(*pkt1);
417 /* XXX: should duplicate packet data in DV case */
418 SDL_CondSignal(q->cond);
422 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
426 /* duplicate the packet */
427 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
430 SDL_LockMutex(q->mutex);
431 ret = packet_queue_put_private(q, pkt);
432 SDL_UnlockMutex(q->mutex);
434 if (pkt != &flush_pkt && ret < 0)
440 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
442 AVPacket pkt1, *pkt = &pkt1;
446 pkt->stream_index = stream_index;
447 return packet_queue_put(q, pkt);
450 /* packet queue handling */
451 static void packet_queue_init(PacketQueue *q)
453 memset(q, 0, sizeof(PacketQueue));
454 q->mutex = SDL_CreateMutex();
455 q->cond = SDL_CreateCond();
456 q->abort_request = 1;
459 static void packet_queue_flush(PacketQueue *q)
461 MyAVPacketList *pkt, *pkt1;
463 SDL_LockMutex(q->mutex);
464 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
466 av_free_packet(&pkt->pkt);
473 SDL_UnlockMutex(q->mutex);
476 static void packet_queue_destroy(PacketQueue *q)
478 packet_queue_flush(q);
479 SDL_DestroyMutex(q->mutex);
480 SDL_DestroyCond(q->cond);
483 static void packet_queue_abort(PacketQueue *q)
485 SDL_LockMutex(q->mutex);
487 q->abort_request = 1;
489 SDL_CondSignal(q->cond);
491 SDL_UnlockMutex(q->mutex);
494 static void packet_queue_start(PacketQueue *q)
496 SDL_LockMutex(q->mutex);
497 q->abort_request = 0;
498 packet_queue_put_private(q, &flush_pkt);
499 SDL_UnlockMutex(q->mutex);
502 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
503 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
505 MyAVPacketList *pkt1;
508 SDL_LockMutex(q->mutex);
511 if (q->abort_request) {
518 q->first_pkt = pkt1->next;
522 q->size -= pkt1->pkt.size + sizeof(*pkt1);
525 *serial = pkt1->serial;
533 SDL_CondWait(q->cond, q->mutex);
536 SDL_UnlockMutex(q->mutex);
540 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
541 memset(d, 0, sizeof(Decoder));
544 d->empty_queue_cond = empty_queue_cond;
545 d->start_pts = AV_NOPTS_VALUE;
548 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
554 if (d->queue->abort_request)
557 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
560 if (d->queue->nb_packets == 0)
561 SDL_CondSignal(d->empty_queue_cond);
562 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
564 if (pkt.data == flush_pkt.data) {
565 avcodec_flush_buffers(d->avctx);
567 d->next_pts = d->start_pts;
568 d->next_pts_tb = d->start_pts_tb;
570 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
571 av_free_packet(&d->pkt);
572 d->pkt_temp = d->pkt = pkt;
573 d->packet_pending = 1;
576 switch (d->avctx->codec_type) {
577 case AVMEDIA_TYPE_VIDEO:
578 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
580 if (decoder_reorder_pts == -1) {
581 frame->pts = av_frame_get_best_effort_timestamp(frame);
582 } else if (decoder_reorder_pts) {
583 frame->pts = frame->pkt_pts;
585 frame->pts = frame->pkt_dts;
589 case AVMEDIA_TYPE_AUDIO:
590 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
592 AVRational tb = (AVRational){1, frame->sample_rate};
593 if (frame->pts != AV_NOPTS_VALUE)
594 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
595 else if (frame->pkt_pts != AV_NOPTS_VALUE)
596 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
597 else if (d->next_pts != AV_NOPTS_VALUE)
598 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
599 if (frame->pts != AV_NOPTS_VALUE) {
600 d->next_pts = frame->pts + frame->nb_samples;
605 case AVMEDIA_TYPE_SUBTITLE:
606 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
611 d->packet_pending = 0;
614 d->pkt_temp.pts = AV_NOPTS_VALUE;
615 if (d->pkt_temp.data) {
616 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
617 ret = d->pkt_temp.size;
618 d->pkt_temp.data += ret;
619 d->pkt_temp.size -= ret;
620 if (d->pkt_temp.size <= 0)
621 d->packet_pending = 0;
624 d->packet_pending = 0;
625 d->finished = d->pkt_serial;
629 } while (!got_frame && !d->finished);
634 static void decoder_destroy(Decoder *d) {
635 av_free_packet(&d->pkt);
638 static void frame_queue_unref_item(Frame *vp)
640 av_frame_unref(vp->frame);
641 avsubtitle_free(&vp->sub);
644 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
647 memset(f, 0, sizeof(FrameQueue));
648 if (!(f->mutex = SDL_CreateMutex()))
649 return AVERROR(ENOMEM);
650 if (!(f->cond = SDL_CreateCond()))
651 return AVERROR(ENOMEM);
653 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
654 f->keep_last = !!keep_last;
655 for (i = 0; i < f->max_size; i++)
656 if (!(f->queue[i].frame = av_frame_alloc()))
657 return AVERROR(ENOMEM);
661 static void frame_queue_destory(FrameQueue *f)
664 for (i = 0; i < f->max_size; i++) {
665 Frame *vp = &f->queue[i];
666 frame_queue_unref_item(vp);
667 av_frame_free(&vp->frame);
670 SDL_DestroyMutex(f->mutex);
671 SDL_DestroyCond(f->cond);
674 static void frame_queue_signal(FrameQueue *f)
676 SDL_LockMutex(f->mutex);
677 SDL_CondSignal(f->cond);
678 SDL_UnlockMutex(f->mutex);
681 static Frame *frame_queue_peek(FrameQueue *f)
683 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
686 static Frame *frame_queue_peek_next(FrameQueue *f)
688 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
691 static Frame *frame_queue_peek_last(FrameQueue *f)
693 return &f->queue[f->rindex];
696 static Frame *frame_queue_peek_writable(FrameQueue *f)
698 /* wait until we have space to put a new frame */
699 SDL_LockMutex(f->mutex);
700 while (f->size >= f->max_size &&
701 !f->pktq->abort_request) {
702 SDL_CondWait(f->cond, f->mutex);
704 SDL_UnlockMutex(f->mutex);
706 if (f->pktq->abort_request)
709 return &f->queue[f->windex];
712 static Frame *frame_queue_peek_readable(FrameQueue *f)
714 /* wait until we have a readable a new frame */
715 SDL_LockMutex(f->mutex);
716 while (f->size - f->rindex_shown <= 0 &&
717 !f->pktq->abort_request) {
718 SDL_CondWait(f->cond, f->mutex);
720 SDL_UnlockMutex(f->mutex);
722 if (f->pktq->abort_request)
725 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
728 static void frame_queue_push(FrameQueue *f)
730 if (++f->windex == f->max_size)
732 SDL_LockMutex(f->mutex);
734 SDL_CondSignal(f->cond);
735 SDL_UnlockMutex(f->mutex);
738 static void frame_queue_next(FrameQueue *f)
740 if (f->keep_last && !f->rindex_shown) {
744 frame_queue_unref_item(&f->queue[f->rindex]);
745 if (++f->rindex == f->max_size)
747 SDL_LockMutex(f->mutex);
749 SDL_CondSignal(f->cond);
750 SDL_UnlockMutex(f->mutex);
753 /* jump back to the previous frame if available by resetting rindex_shown */
754 static int frame_queue_prev(FrameQueue *f)
756 int ret = f->rindex_shown;
761 /* return the number of undisplayed frames in the queue */
762 static int frame_queue_nb_remaining(FrameQueue *f)
764 return f->size - f->rindex_shown;
767 /* return last shown position */
768 static int64_t frame_queue_last_pos(FrameQueue *f)
770 Frame *fp = &f->queue[f->rindex];
771 if (f->rindex_shown && fp->serial == f->pktq->serial)
777 static void decoder_abort(Decoder *d, FrameQueue *fq)
779 packet_queue_abort(d->queue);
780 frame_queue_signal(fq);
781 SDL_WaitThread(d->decoder_tid, NULL);
782 d->decoder_tid = NULL;
783 packet_queue_flush(d->queue);
786 static inline void fill_rectangle(SDL_Surface *screen,
787 int x, int y, int w, int h, int color, int update)
794 SDL_FillRect(screen, &rect, color);
795 if (update && w > 0 && h > 0)
796 SDL_UpdateRect(screen, x, y, w, h);
799 /* draw only the border of a rectangle */
800 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
804 /* fill the background */
808 w2 = width - (x + w);
814 h2 = height - (y + h);
817 fill_rectangle(screen,
821 fill_rectangle(screen,
822 xleft + width - w2, ytop,
825 fill_rectangle(screen,
829 fill_rectangle(screen,
830 xleft + w1, ytop + height - h2,
835 #define ALPHA_BLEND(a, oldp, newp, s)\
836 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
842 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
844 int x, y, Y, U, V, A;
845 uint8_t *lum, *cb, *cr;
846 int dstx, dsty, dstw, dsth;
847 const AVPicture *src = &rect->pict;
849 dstw = av_clip(rect->w, 0, imgw);
850 dsth = av_clip(rect->h, 0, imgh);
851 dstx = av_clip(rect->x, 0, imgw - dstw);
852 dsty = av_clip(rect->y, 0, imgh - dsth);
853 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
854 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
855 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
857 for (y = 0; y<dsth; y++) {
858 for (x = 0; x<dstw; x++) {
859 Y = src->data[0][x + y*src->linesize[0]];
860 A = src->data[3][x + y*src->linesize[3]];
861 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
864 lum += dst->linesize[0] - dstw;
867 for (y = 0; y<dsth/2; y++) {
868 for (x = 0; x<dstw/2; x++) {
869 U = src->data[1][x + y*src->linesize[1]];
870 V = src->data[2][x + y*src->linesize[2]];
871 A = src->data[3][2*x + 2*y *src->linesize[3]]
872 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
873 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
874 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
875 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
876 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
880 cb += dst->linesize[1] - dstw/2;
881 cr += dst->linesize[2] - dstw/2;
885 static void free_picture(Frame *vp)
888 SDL_FreeYUVOverlay(vp->bmp);
893 static void calculate_display_rect(SDL_Rect *rect,
894 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
895 int pic_width, int pic_height, AVRational pic_sar)
898 int width, height, x, y;
900 if (pic_sar.num == 0)
903 aspect_ratio = av_q2d(pic_sar);
905 if (aspect_ratio <= 0.0)
907 aspect_ratio *= (float)pic_width / (float)pic_height;
909 /* XXX: we suppose the screen has a 1.0 pixel ratio */
911 width = ((int)rint(height * aspect_ratio)) & ~1;
912 if (width > scr_width) {
914 height = ((int)rint(width / aspect_ratio)) & ~1;
916 x = (scr_width - width) / 2;
917 y = (scr_height - height) / 2;
918 rect->x = scr_xleft + x;
919 rect->y = scr_ytop + y;
920 rect->w = FFMAX(width, 1);
921 rect->h = FFMAX(height, 1);
924 static void video_image_display(VideoState *is)
932 vp = frame_queue_peek(&is->pictq);
934 if (is->subtitle_st) {
935 if (frame_queue_nb_remaining(&is->subpq) > 0) {
936 sp = frame_queue_peek(&is->subpq);
938 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
939 SDL_LockYUVOverlay (vp->bmp);
941 pict.data[0] = vp->bmp->pixels[0];
942 pict.data[1] = vp->bmp->pixels[2];
943 pict.data[2] = vp->bmp->pixels[1];
945 pict.linesize[0] = vp->bmp->pitches[0];
946 pict.linesize[1] = vp->bmp->pitches[2];
947 pict.linesize[2] = vp->bmp->pitches[1];
949 for (i = 0; i < sp->sub.num_rects; i++)
950 blend_subrect(&pict, sp->sub.rects[i],
951 vp->bmp->w, vp->bmp->h);
953 SDL_UnlockYUVOverlay (vp->bmp);
958 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
960 SDL_DisplayYUVOverlay(vp->bmp, &rect);
962 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) {
963 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
964 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
965 is->last_display_rect = rect;
970 static inline int compute_mod(int a, int b)
972 return a < 0 ? a%b + b : a%b;
975 static void video_audio_display(VideoState *s)
977 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
978 int ch, channels, h, h2, bgcolor, fgcolor;
980 int rdft_bits, nb_freq;
982 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
984 nb_freq = 1 << (rdft_bits - 1);
986 /* compute display index : center on currently output samples */
987 channels = s->audio_tgt.channels;
988 nb_display_channels = channels;
990 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
992 delay = s->audio_write_buf_size;
995 /* to be more precise, we take into account the time spent since
996 the last buffer computation */
997 if (audio_callback_time) {
998 time_diff = av_gettime_relative() - audio_callback_time;
999 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1002 delay += 2 * data_used;
1003 if (delay < data_used)
1006 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1007 if (s->show_mode == SHOW_MODE_WAVES) {
1009 for (i = 0; i < 1000; i += channels) {
1010 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1011 int a = s->sample_array[idx];
1012 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1013 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1014 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1016 if (h < score && (b ^ c) < 0) {
1023 s->last_i_start = i_start;
1025 i_start = s->last_i_start;
1028 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1029 if (s->show_mode == SHOW_MODE_WAVES) {
1030 fill_rectangle(screen,
1031 s->xleft, s->ytop, s->width, s->height,
1034 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1036 /* total height for one channel */
1037 h = s->height / nb_display_channels;
1038 /* graph height / 2 */
1040 for (ch = 0; ch < nb_display_channels; ch++) {
1042 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1043 for (x = 0; x < s->width; x++) {
1044 y = (s->sample_array[i] * h2) >> 15;
1051 fill_rectangle(screen,
1052 s->xleft + x, ys, 1, y,
1055 if (i >= SAMPLE_ARRAY_SIZE)
1056 i -= SAMPLE_ARRAY_SIZE;
1060 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1062 for (ch = 1; ch < nb_display_channels; ch++) {
1063 y = s->ytop + ch * h;
1064 fill_rectangle(screen,
1065 s->xleft, y, s->width, 1,
1068 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1070 nb_display_channels= FFMIN(nb_display_channels, 2);
1071 if (rdft_bits != s->rdft_bits) {
1072 av_rdft_end(s->rdft);
1073 av_free(s->rdft_data);
1074 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1075 s->rdft_bits = rdft_bits;
1076 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1078 if (!s->rdft || !s->rdft_data){
1079 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1080 s->show_mode = SHOW_MODE_WAVES;
1083 for (ch = 0; ch < nb_display_channels; ch++) {
1084 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1086 for (x = 0; x < 2 * nb_freq; x++) {
1087 double w = (x-nb_freq) * (1.0 / nb_freq);
1088 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1090 if (i >= SAMPLE_ARRAY_SIZE)
1091 i -= SAMPLE_ARRAY_SIZE;
1093 av_rdft_calc(s->rdft, data[ch]);
1095 /* Least efficient way to do this, we should of course
1096 * directly access it but it is more than fast enough. */
1097 for (y = 0; y < s->height; y++) {
1098 double w = 1 / sqrt(nb_freq);
1099 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]));
1100 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1101 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1104 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1106 fill_rectangle(screen,
1107 s->xpos, s->height-y, 1, 1,
1111 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1114 if (s->xpos >= s->width)
1119 static void stream_close(VideoState *is)
1121 /* XXX: use a special url_shutdown call to abort parse cleanly */
1122 is->abort_request = 1;
1123 SDL_WaitThread(is->read_tid, NULL);
1124 packet_queue_destroy(&is->videoq);
1125 packet_queue_destroy(&is->audioq);
1126 packet_queue_destroy(&is->subtitleq);
1128 /* free all pictures */
1129 frame_queue_destory(&is->pictq);
1130 frame_queue_destory(&is->sampq);
1131 frame_queue_destory(&is->subpq);
1132 SDL_DestroyCond(is->continue_read_thread);
1133 #if !CONFIG_AVFILTER
1134 sws_freeContext(is->img_convert_ctx);
1136 sws_freeContext(is->sub_convert_ctx);
1140 static void do_exit(VideoState *is)
1145 av_lockmgr_register(NULL);
1148 av_freep(&vfilters_list);
1150 avformat_network_deinit();
1154 av_log(NULL, AV_LOG_QUIET, "%s", "");
1158 static void sigterm_handler(int sig)
1163 static void set_default_window_size(int width, int height, AVRational sar)
1166 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1167 default_width = rect.w;
1168 default_height = rect.h;
1171 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1173 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1176 if (is_full_screen) flags |= SDL_FULLSCREEN;
1177 else flags |= SDL_RESIZABLE;
1179 if (vp && vp->width)
1180 set_default_window_size(vp->width, vp->height, vp->sar);
1182 if (is_full_screen && fs_screen_width) {
1183 w = fs_screen_width;
1184 h = fs_screen_height;
1185 } else if (!is_full_screen && screen_width) {
1192 w = FFMIN(16383, w);
1193 if (screen && is->width == screen->w && screen->w == w
1194 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1196 screen = SDL_SetVideoMode(w, h, 0, flags);
1198 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1202 window_title = input_filename;
1203 SDL_WM_SetCaption(window_title, window_title);
1205 is->width = screen->w;
1206 is->height = screen->h;
1211 /* display the current picture, if any */
1212 static void video_display(VideoState *is)
1215 video_open(is, 0, NULL);
1216 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1217 video_audio_display(is);
1218 else if (is->video_st)
1219 video_image_display(is);
1222 static double get_clock(Clock *c)
1224 if (*c->queue_serial != c->serial)
1229 double time = av_gettime_relative() / 1000000.0;
1230 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1234 static void set_clock_at(Clock *c, double pts, int serial, double time)
1237 c->last_updated = time;
1238 c->pts_drift = c->pts - time;
1242 static void set_clock(Clock *c, double pts, int serial)
1244 double time = av_gettime_relative() / 1000000.0;
1245 set_clock_at(c, pts, serial, time);
1248 static void set_clock_speed(Clock *c, double speed)
1250 set_clock(c, get_clock(c), c->serial);
1254 static void init_clock(Clock *c, int *queue_serial)
1258 c->queue_serial = queue_serial;
1259 set_clock(c, NAN, -1);
1262 static void sync_clock_to_slave(Clock *c, Clock *slave)
1264 double clock = get_clock(c);
1265 double slave_clock = get_clock(slave);
1266 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1267 set_clock(c, slave_clock, slave->serial);
1270 static int get_master_sync_type(VideoState *is) {
1271 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1273 return AV_SYNC_VIDEO_MASTER;
1275 return AV_SYNC_AUDIO_MASTER;
1276 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1278 return AV_SYNC_AUDIO_MASTER;
1280 return AV_SYNC_EXTERNAL_CLOCK;
1282 return AV_SYNC_EXTERNAL_CLOCK;
1286 /* get the current master clock value */
1287 static double get_master_clock(VideoState *is)
1291 switch (get_master_sync_type(is)) {
1292 case AV_SYNC_VIDEO_MASTER:
1293 val = get_clock(&is->vidclk);
1295 case AV_SYNC_AUDIO_MASTER:
1296 val = get_clock(&is->audclk);
1299 val = get_clock(&is->extclk);
1305 static void check_external_clock_speed(VideoState *is) {
1306 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1307 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1308 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1309 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1310 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1311 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1313 double speed = is->extclk.speed;
1315 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1319 /* seek in the stream */
1320 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1322 if (!is->seek_req) {
1325 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1327 is->seek_flags |= AVSEEK_FLAG_BYTE;
1329 SDL_CondSignal(is->continue_read_thread);
1333 /* pause or resume the video */
1334 static void stream_toggle_pause(VideoState *is)
1337 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1338 if (is->read_pause_return != AVERROR(ENOSYS)) {
1339 is->vidclk.paused = 0;
1341 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1343 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1344 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1347 static void toggle_pause(VideoState *is)
1349 stream_toggle_pause(is);
1353 static void step_to_next_frame(VideoState *is)
1355 /* if the stream is paused unpause it, then step */
1357 stream_toggle_pause(is);
1361 static double compute_target_delay(double delay, VideoState *is)
1363 double sync_threshold, diff = 0;
1365 /* update delay to follow master synchronisation source */
1366 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1367 /* if video is slave, we try to correct big delays by
1368 duplicating or deleting a frame */
1369 diff = get_clock(&is->vidclk) - get_master_clock(is);
1371 /* skip or repeat frame. We take into account the
1372 delay to compute the threshold. I still don't know
1373 if it is the best guess */
1374 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1375 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1376 if (diff <= -sync_threshold)
1377 delay = FFMAX(0, delay + diff);
1378 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1379 delay = delay + diff;
1380 else if (diff >= sync_threshold)
1385 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1391 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1392 if (vp->serial == nextvp->serial) {
1393 double duration = nextvp->pts - vp->pts;
1394 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1395 return vp->duration;
1403 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1404 /* update current video pts */
1405 set_clock(&is->vidclk, pts, serial);
1406 sync_clock_to_slave(&is->extclk, &is->vidclk);
1409 /* called to display each frame */
1410 static void video_refresh(void *opaque, double *remaining_time)
1412 VideoState *is = opaque;
1417 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1418 check_external_clock_speed(is);
1420 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1421 time = av_gettime_relative() / 1000000.0;
1422 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1424 is->last_vis_time = time;
1426 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1431 if (is->force_refresh)
1432 redisplay = frame_queue_prev(&is->pictq);
1434 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1435 // nothing to do, no picture to display in the queue
1437 double last_duration, duration, delay;
1440 /* dequeue the picture */
1441 lastvp = frame_queue_peek_last(&is->pictq);
1442 vp = frame_queue_peek(&is->pictq);
1444 if (vp->serial != is->videoq.serial) {
1445 frame_queue_next(&is->pictq);
1450 if (lastvp->serial != vp->serial && !redisplay)
1451 is->frame_timer = av_gettime_relative() / 1000000.0;
1456 /* compute nominal last_duration */
1457 last_duration = vp_duration(is, lastvp, vp);
1461 delay = compute_target_delay(last_duration, is);
1463 time= av_gettime_relative()/1000000.0;
1464 if (time < is->frame_timer + delay && !redisplay) {
1465 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1469 is->frame_timer += delay;
1470 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1471 is->frame_timer = time;
1473 SDL_LockMutex(is->pictq.mutex);
1474 if (!redisplay && !isnan(vp->pts))
1475 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1476 SDL_UnlockMutex(is->pictq.mutex);
1478 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1479 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1480 duration = vp_duration(is, vp, nextvp);
1481 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1483 is->frame_drops_late++;
1484 frame_queue_next(&is->pictq);
1490 if (is->subtitle_st) {
1491 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1492 sp = frame_queue_peek(&is->subpq);
1494 if (frame_queue_nb_remaining(&is->subpq) > 1)
1495 sp2 = frame_queue_peek_next(&is->subpq);
1499 if (sp->serial != is->subtitleq.serial
1500 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1501 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1503 frame_queue_next(&is->subpq);
1511 /* display picture */
1512 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1515 frame_queue_next(&is->pictq);
1517 if (is->step && !is->paused)
1518 stream_toggle_pause(is);
1521 is->force_refresh = 0;
1523 static int64_t last_time;
1525 int aqsize, vqsize, sqsize;
1528 cur_time = av_gettime_relative();
1529 if (!last_time || (cur_time - last_time) >= 30000) {
1534 aqsize = is->audioq.size;
1536 vqsize = is->videoq.size;
1537 if (is->subtitle_st)
1538 sqsize = is->subtitleq.size;
1540 if (is->audio_st && is->video_st)
1541 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1542 else if (is->video_st)
1543 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1544 else if (is->audio_st)
1545 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1546 av_log(NULL, AV_LOG_INFO,
1547 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1548 get_master_clock(is),
1549 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1551 is->frame_drops_early + is->frame_drops_late,
1555 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1556 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1558 last_time = cur_time;
1563 /* allocate a picture (needs to do that in main thread to avoid
1564 potential locking problems */
1565 static void alloc_picture(VideoState *is)
1570 vp = &is->pictq.queue[is->pictq.windex];
1574 video_open(is, 0, vp);
1576 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1579 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1580 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1581 /* SDL allocates a buffer smaller than requested if the video
1582 * overlay hardware is unable to support the requested size. */
1583 av_log(NULL, AV_LOG_FATAL,
1584 "Error: the video system does not support an image\n"
1585 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1586 "to reduce the image size.\n", vp->width, vp->height );
1590 SDL_LockMutex(is->pictq.mutex);
1592 SDL_CondSignal(is->pictq.cond);
1593 SDL_UnlockMutex(is->pictq.mutex);
1596 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1597 int i, width, height;
1599 for (i = 0; i < 3; i++) {
1606 if (bmp->pitches[i] > width) {
1607 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1608 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1614 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1618 #if defined(DEBUG_SYNC) && 0
1619 printf("frame_type=%c pts=%0.3f\n",
1620 av_get_picture_type_char(src_frame->pict_type), pts);
1623 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1626 vp->sar = src_frame->sample_aspect_ratio;
1628 /* alloc or resize hardware picture buffer */
1629 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1630 vp->width != src_frame->width ||
1631 vp->height != src_frame->height) {
1636 vp->width = src_frame->width;
1637 vp->height = src_frame->height;
1639 /* the allocation must be done in the main thread to avoid
1640 locking problems. */
1641 event.type = FF_ALLOC_EVENT;
1642 event.user.data1 = is;
1643 SDL_PushEvent(&event);
1645 /* wait until the picture is allocated */
1646 SDL_LockMutex(is->pictq.mutex);
1647 while (!vp->allocated && !is->videoq.abort_request) {
1648 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1650 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1651 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1652 while (!vp->allocated && !is->abort_request) {
1653 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1656 SDL_UnlockMutex(is->pictq.mutex);
1658 if (is->videoq.abort_request)
1662 /* if the frame is not skipped, then display it */
1664 AVPicture pict = { { 0 } };
1666 /* get a pointer on the bitmap */
1667 SDL_LockYUVOverlay (vp->bmp);
1669 pict.data[0] = vp->bmp->pixels[0];
1670 pict.data[1] = vp->bmp->pixels[2];
1671 pict.data[2] = vp->bmp->pixels[1];
1673 pict.linesize[0] = vp->bmp->pitches[0];
1674 pict.linesize[1] = vp->bmp->pitches[2];
1675 pict.linesize[2] = vp->bmp->pitches[1];
1678 // FIXME use direct rendering
1679 av_picture_copy(&pict, (AVPicture *)src_frame,
1680 src_frame->format, vp->width, vp->height);
1683 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1685 const AVClass *class = sws_get_class();
1686 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1687 AV_OPT_SEARCH_FAKE_OBJ);
1688 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1694 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1695 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1696 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1697 if (!is->img_convert_ctx) {
1698 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1701 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1702 0, vp->height, pict.data, pict.linesize);
1704 /* workaround SDL PITCH_WORKAROUND */
1705 duplicate_right_border_pixels(vp->bmp);
1706 /* update the bitmap content */
1707 SDL_UnlockYUVOverlay(vp->bmp);
1710 vp->duration = duration;
1712 vp->serial = serial;
1714 /* now we can update the picture count */
1715 frame_queue_push(&is->pictq);
1720 static int get_video_frame(VideoState *is, AVFrame *frame)
1724 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1730 if (frame->pts != AV_NOPTS_VALUE)
1731 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1733 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1735 is->viddec_width = frame->width;
1736 is->viddec_height = frame->height;
1738 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1739 if (frame->pts != AV_NOPTS_VALUE) {
1740 double diff = dpts - get_master_clock(is);
1741 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1742 diff - is->frame_last_filter_delay < 0 &&
1743 is->viddec.pkt_serial == is->vidclk.serial &&
1744 is->videoq.nb_packets) {
1745 is->frame_drops_early++;
1746 av_frame_unref(frame);
1757 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1758 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1761 int nb_filters = graph->nb_filters;
1762 AVFilterInOut *outputs = NULL, *inputs = NULL;
1765 outputs = avfilter_inout_alloc();
1766 inputs = avfilter_inout_alloc();
1767 if (!outputs || !inputs) {
1768 ret = AVERROR(ENOMEM);
1772 outputs->name = av_strdup("in");
1773 outputs->filter_ctx = source_ctx;
1774 outputs->pad_idx = 0;
1775 outputs->next = NULL;
1777 inputs->name = av_strdup("out");
1778 inputs->filter_ctx = sink_ctx;
1779 inputs->pad_idx = 0;
1780 inputs->next = NULL;
1782 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1785 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1789 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1790 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1791 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1793 ret = avfilter_graph_config(graph, NULL);
1795 avfilter_inout_free(&outputs);
1796 avfilter_inout_free(&inputs);
1800 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1802 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1803 char sws_flags_str[512] = "";
1804 char buffersrc_args[256];
1806 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1807 AVCodecContext *codec = is->video_st->codec;
1808 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1809 AVDictionaryEntry *e = NULL;
1811 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1812 if (!strcmp(e->key, "sws_flags")) {
1813 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1815 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1817 if (strlen(sws_flags_str))
1818 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1820 graph->scale_sws_opts = av_strdup(sws_flags_str);
1822 snprintf(buffersrc_args, sizeof(buffersrc_args),
1823 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1824 frame->width, frame->height, frame->format,
1825 is->video_st->time_base.num, is->video_st->time_base.den,
1826 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1827 if (fr.num && fr.den)
1828 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1830 if ((ret = avfilter_graph_create_filter(&filt_src,
1831 avfilter_get_by_name("buffer"),
1832 "ffplay_buffer", buffersrc_args, NULL,
1836 ret = avfilter_graph_create_filter(&filt_out,
1837 avfilter_get_by_name("buffersink"),
1838 "ffplay_buffersink", NULL, NULL, graph);
1842 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1845 last_filter = filt_out;
1847 /* Note: this macro adds a filter before the lastly added filter, so the
1848 * processing order of the filters is in reverse */
1849 #define INSERT_FILT(name, arg) do { \
1850 AVFilterContext *filt_ctx; \
1852 ret = avfilter_graph_create_filter(&filt_ctx, \
1853 avfilter_get_by_name(name), \
1854 "ffplay_" name, arg, NULL, graph); \
1858 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1862 last_filter = filt_ctx; \
1865 /* SDL YUV code is not handling odd width/height for some driver
1866 * combinations, therefore we crop the picture to an even width/height. */
1867 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1870 double theta = get_rotation(is->video_st);
1872 if (fabs(theta - 90) < 1.0) {
1873 INSERT_FILT("transpose", "clock");
1874 } else if (fabs(theta - 180) < 1.0) {
1875 INSERT_FILT("hflip", NULL);
1876 INSERT_FILT("vflip", NULL);
1877 } else if (fabs(theta - 270) < 1.0) {
1878 INSERT_FILT("transpose", "cclock");
1879 } else if (fabs(theta) > 1.0) {
1880 char rotate_buf[64];
1881 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1882 INSERT_FILT("rotate", rotate_buf);
1886 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1889 is->in_video_filter = filt_src;
1890 is->out_video_filter = filt_out;
1896 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1898 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1899 int sample_rates[2] = { 0, -1 };
1900 int64_t channel_layouts[2] = { 0, -1 };
1901 int channels[2] = { 0, -1 };
1902 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1903 char aresample_swr_opts[512] = "";
1904 AVDictionaryEntry *e = NULL;
1905 char asrc_args[256];
1908 avfilter_graph_free(&is->agraph);
1909 if (!(is->agraph = avfilter_graph_alloc()))
1910 return AVERROR(ENOMEM);
1912 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1913 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1914 if (strlen(aresample_swr_opts))
1915 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1916 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1918 ret = snprintf(asrc_args, sizeof(asrc_args),
1919 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1920 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1921 is->audio_filter_src.channels,
1922 1, is->audio_filter_src.freq);
1923 if (is->audio_filter_src.channel_layout)
1924 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1925 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1927 ret = avfilter_graph_create_filter(&filt_asrc,
1928 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1929 asrc_args, NULL, is->agraph);
1934 ret = avfilter_graph_create_filter(&filt_asink,
1935 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1936 NULL, NULL, is->agraph);
1940 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1942 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1945 if (force_output_format) {
1946 channel_layouts[0] = is->audio_tgt.channel_layout;
1947 channels [0] = is->audio_tgt.channels;
1948 sample_rates [0] = is->audio_tgt.freq;
1949 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1951 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1953 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1955 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1960 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1963 is->in_audio_filter = filt_asrc;
1964 is->out_audio_filter = filt_asink;
1968 avfilter_graph_free(&is->agraph);
1971 #endif /* CONFIG_AVFILTER */
1973 static int audio_thread(void *arg)
1975 VideoState *is = arg;
1976 AVFrame *frame = av_frame_alloc();
1979 int last_serial = -1;
1980 int64_t dec_channel_layout;
1988 return AVERROR(ENOMEM);
1991 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1995 tb = (AVRational){1, frame->sample_rate};
1998 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2001 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2002 frame->format, av_frame_get_channels(frame)) ||
2003 is->audio_filter_src.channel_layout != dec_channel_layout ||
2004 is->audio_filter_src.freq != frame->sample_rate ||
2005 is->auddec.pkt_serial != last_serial;
2008 char buf1[1024], buf2[1024];
2009 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2010 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2011 av_log(NULL, AV_LOG_DEBUG,
2012 "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",
2013 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2014 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2016 is->audio_filter_src.fmt = frame->format;
2017 is->audio_filter_src.channels = av_frame_get_channels(frame);
2018 is->audio_filter_src.channel_layout = dec_channel_layout;
2019 is->audio_filter_src.freq = frame->sample_rate;
2020 last_serial = is->auddec.pkt_serial;
2022 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2026 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2029 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2030 tb = is->out_audio_filter->inputs[0]->time_base;
2032 if (!(af = frame_queue_peek_writable(&is->sampq)))
2035 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2036 af->pos = av_frame_get_pkt_pos(frame);
2037 af->serial = is->auddec.pkt_serial;
2038 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2040 av_frame_move_ref(af->frame, frame);
2041 frame_queue_push(&is->sampq);
2044 if (is->audioq.serial != is->auddec.pkt_serial)
2047 if (ret == AVERROR_EOF)
2048 is->auddec.finished = is->auddec.pkt_serial;
2051 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2054 avfilter_graph_free(&is->agraph);
2056 av_frame_free(&frame);
2060 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2062 packet_queue_start(d->queue);
2063 d->decoder_tid = SDL_CreateThread(fn, arg);
2066 static int video_thread(void *arg)
2068 VideoState *is = arg;
2069 AVFrame *frame = av_frame_alloc();
2073 AVRational tb = is->video_st->time_base;
2074 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2077 AVFilterGraph *graph = avfilter_graph_alloc();
2078 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2081 enum AVPixelFormat last_format = -2;
2082 int last_serial = -1;
2083 int last_vfilter_idx = 0;
2085 av_frame_free(&frame);
2086 return AVERROR(ENOMEM);
2093 avfilter_graph_free(&graph);
2095 return AVERROR(ENOMEM);
2099 ret = get_video_frame(is, frame);
2106 if ( last_w != frame->width
2107 || last_h != frame->height
2108 || last_format != frame->format
2109 || last_serial != is->viddec.pkt_serial
2110 || last_vfilter_idx != is->vfilter_idx) {
2111 av_log(NULL, AV_LOG_DEBUG,
2112 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2114 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2115 frame->width, frame->height,
2116 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2117 avfilter_graph_free(&graph);
2118 graph = avfilter_graph_alloc();
2119 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2121 event.type = FF_QUIT_EVENT;
2122 event.user.data1 = is;
2123 SDL_PushEvent(&event);
2126 filt_in = is->in_video_filter;
2127 filt_out = is->out_video_filter;
2128 last_w = frame->width;
2129 last_h = frame->height;
2130 last_format = frame->format;
2131 last_serial = is->viddec.pkt_serial;
2132 last_vfilter_idx = is->vfilter_idx;
2133 frame_rate = filt_out->inputs[0]->frame_rate;
2136 ret = av_buffersrc_add_frame(filt_in, frame);
2141 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2143 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2145 if (ret == AVERROR_EOF)
2146 is->viddec.finished = is->viddec.pkt_serial;
2151 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2152 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2153 is->frame_last_filter_delay = 0;
2154 tb = filt_out->inputs[0]->time_base;
2156 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2157 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2158 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2159 av_frame_unref(frame);
2169 avfilter_graph_free(&graph);
2171 av_frame_free(&frame);
2175 static int subtitle_thread(void *arg)
2177 VideoState *is = arg;
2184 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2187 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2192 if (got_subtitle && sp->sub.format == 0) {
2193 if (sp->sub.pts != AV_NOPTS_VALUE)
2194 pts = sp->sub.pts / (double)AV_TIME_BASE;
2196 sp->serial = is->subdec.pkt_serial;
2198 for (i = 0; i < sp->sub.num_rects; i++)
2200 int in_w = sp->sub.rects[i]->w;
2201 int in_h = sp->sub.rects[i]->h;
2202 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2203 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2204 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2205 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2208 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2209 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2210 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2211 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2212 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2213 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2215 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2216 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2217 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2218 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2219 !newpic.data[1] || !newpic.data[2]
2221 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2224 sws_scale(is->sub_convert_ctx,
2225 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2226 0, in_h, newpic.data, newpic.linesize);
2228 av_free(sp->sub.rects[i]->pict.data[0]);
2229 av_free(sp->sub.rects[i]->pict.data[1]);
2230 sp->sub.rects[i]->pict = newpic;
2231 sp->sub.rects[i]->w = out_w;
2232 sp->sub.rects[i]->h = out_h;
2233 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2234 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2237 /* now we can update the picture count */
2238 frame_queue_push(&is->subpq);
2239 } else if (got_subtitle) {
2240 avsubtitle_free(&sp->sub);
2246 /* copy samples for viewing in editor window */
2247 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2251 size = samples_size / sizeof(short);
2253 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2256 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2258 is->sample_array_index += len;
2259 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2260 is->sample_array_index = 0;
2265 /* return the wanted number of samples to get better sync if sync_type is video
2266 * or external master clock */
2267 static int synchronize_audio(VideoState *is, int nb_samples)
2269 int wanted_nb_samples = nb_samples;
2271 /* if not master, then we try to remove or add samples to correct the clock */
2272 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2273 double diff, avg_diff;
2274 int min_nb_samples, max_nb_samples;
2276 diff = get_clock(&is->audclk) - get_master_clock(is);
2278 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2279 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2280 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2281 /* not enough measures to have a correct estimate */
2282 is->audio_diff_avg_count++;
2284 /* estimate the A-V difference */
2285 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2287 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2288 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2289 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2290 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2291 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2293 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2294 diff, avg_diff, wanted_nb_samples - nb_samples,
2295 is->audio_clock, is->audio_diff_threshold);
2298 /* too big difference : may be initial PTS errors, so
2300 is->audio_diff_avg_count = 0;
2301 is->audio_diff_cum = 0;
2305 return wanted_nb_samples;
2309 * Decode one audio frame and return its uncompressed size.
2311 * The processed audio frame is decoded, converted if required, and
2312 * stored in is->audio_buf, with size in bytes given by the return
2315 static int audio_decode_frame(VideoState *is)
2317 int data_size, resampled_data_size;
2318 int64_t dec_channel_layout;
2319 av_unused double audio_clock0;
2320 int wanted_nb_samples;
2328 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2329 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2334 if (!(af = frame_queue_peek_readable(&is->sampq)))
2336 frame_queue_next(&is->sampq);
2337 } while (af->serial != is->audioq.serial);
2339 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2340 af->frame->nb_samples,
2341 af->frame->format, 1);
2343 dec_channel_layout =
2344 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2345 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2346 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2348 if (af->frame->format != is->audio_src.fmt ||
2349 dec_channel_layout != is->audio_src.channel_layout ||
2350 af->frame->sample_rate != is->audio_src.freq ||
2351 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2352 swr_free(&is->swr_ctx);
2353 is->swr_ctx = swr_alloc_set_opts(NULL,
2354 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2355 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2357 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2358 av_log(NULL, AV_LOG_ERROR,
2359 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2360 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2361 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2362 swr_free(&is->swr_ctx);
2365 is->audio_src.channel_layout = dec_channel_layout;
2366 is->audio_src.channels = av_frame_get_channels(af->frame);
2367 is->audio_src.freq = af->frame->sample_rate;
2368 is->audio_src.fmt = af->frame->format;
2372 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2373 uint8_t **out = &is->audio_buf1;
2374 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2375 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2378 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2381 if (wanted_nb_samples != af->frame->nb_samples) {
2382 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2383 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2384 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2388 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2389 if (!is->audio_buf1)
2390 return AVERROR(ENOMEM);
2391 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2393 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2396 if (len2 == out_count) {
2397 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2398 if (swr_init(is->swr_ctx) < 0)
2399 swr_free(&is->swr_ctx);
2401 is->audio_buf = is->audio_buf1;
2402 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2404 is->audio_buf = af->frame->data[0];
2405 resampled_data_size = data_size;
2408 audio_clock0 = is->audio_clock;
2409 /* update the audio clock with the pts */
2410 if (!isnan(af->pts))
2411 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2413 is->audio_clock = NAN;
2414 is->audio_clock_serial = af->serial;
2417 static double last_clock;
2418 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2419 is->audio_clock - last_clock,
2420 is->audio_clock, audio_clock0);
2421 last_clock = is->audio_clock;
2424 return resampled_data_size;
2427 /* prepare a new audio buffer */
2428 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2430 VideoState *is = opaque;
2431 int audio_size, len1;
2433 audio_callback_time = av_gettime_relative();
2436 if (is->audio_buf_index >= is->audio_buf_size) {
2437 audio_size = audio_decode_frame(is);
2438 if (audio_size < 0) {
2439 /* if error, just output silence */
2440 is->audio_buf = is->silence_buf;
2441 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2443 if (is->show_mode != SHOW_MODE_VIDEO)
2444 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2445 is->audio_buf_size = audio_size;
2447 is->audio_buf_index = 0;
2449 len1 = is->audio_buf_size - is->audio_buf_index;
2452 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2455 is->audio_buf_index += len1;
2457 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2458 /* Let's assume the audio driver that is used by SDL has two periods. */
2459 if (!isnan(is->audio_clock)) {
2460 set_clock_at(&is->audclk, is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / is->audio_tgt.bytes_per_sec, is->audio_clock_serial, audio_callback_time / 1000000.0);
2461 sync_clock_to_slave(&is->extclk, &is->audclk);
2465 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2467 SDL_AudioSpec wanted_spec, spec;
2469 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2470 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2471 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2473 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2475 wanted_nb_channels = atoi(env);
2476 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2478 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2479 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2480 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2482 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2483 wanted_spec.channels = wanted_nb_channels;
2484 wanted_spec.freq = wanted_sample_rate;
2485 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2486 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2489 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2490 next_sample_rate_idx--;
2491 wanted_spec.format = AUDIO_S16SYS;
2492 wanted_spec.silence = 0;
2493 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2494 wanted_spec.callback = sdl_audio_callback;
2495 wanted_spec.userdata = opaque;
2496 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2497 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2498 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2499 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2500 if (!wanted_spec.channels) {
2501 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2502 wanted_spec.channels = wanted_nb_channels;
2503 if (!wanted_spec.freq) {
2504 av_log(NULL, AV_LOG_ERROR,
2505 "No more combinations to try, audio open failed\n");
2509 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2511 if (spec.format != AUDIO_S16SYS) {
2512 av_log(NULL, AV_LOG_ERROR,
2513 "SDL advised audio format %d is not supported!\n", spec.format);
2516 if (spec.channels != wanted_spec.channels) {
2517 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2518 if (!wanted_channel_layout) {
2519 av_log(NULL, AV_LOG_ERROR,
2520 "SDL advised channel count %d is not supported!\n", spec.channels);
2525 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2526 audio_hw_params->freq = spec.freq;
2527 audio_hw_params->channel_layout = wanted_channel_layout;
2528 audio_hw_params->channels = spec.channels;
2529 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2530 audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
2531 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2532 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2538 /* open a given stream. Return 0 if OK */
2539 static int stream_component_open(VideoState *is, int stream_index)
2541 AVFormatContext *ic = is->ic;
2542 AVCodecContext *avctx;
2544 const char *forced_codec_name = NULL;
2546 AVDictionaryEntry *t = NULL;
2547 int sample_rate, nb_channels;
2548 int64_t channel_layout;
2550 int stream_lowres = lowres;
2552 if (stream_index < 0 || stream_index >= ic->nb_streams)
2554 avctx = ic->streams[stream_index]->codec;
2556 codec = avcodec_find_decoder(avctx->codec_id);
2558 switch(avctx->codec_type){
2559 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2560 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2561 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2563 if (forced_codec_name)
2564 codec = avcodec_find_decoder_by_name(forced_codec_name);
2566 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2567 "No codec could be found with name '%s'\n", forced_codec_name);
2568 else av_log(NULL, AV_LOG_WARNING,
2569 "No codec could be found with id %d\n", avctx->codec_id);
2573 avctx->codec_id = codec->id;
2574 if(stream_lowres > av_codec_get_max_lowres(codec)){
2575 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2576 av_codec_get_max_lowres(codec));
2577 stream_lowres = av_codec_get_max_lowres(codec);
2579 av_codec_set_lowres(avctx, stream_lowres);
2581 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2583 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2584 if(codec->capabilities & AV_CODEC_CAP_DR1)
2585 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2587 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2588 if (!av_dict_get(opts, "threads", NULL, 0))
2589 av_dict_set(&opts, "threads", "auto", 0);
2591 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2592 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2593 av_dict_set(&opts, "refcounted_frames", "1", 0);
2594 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2597 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2598 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2599 ret = AVERROR_OPTION_NOT_FOUND;
2604 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2605 switch (avctx->codec_type) {
2606 case AVMEDIA_TYPE_AUDIO:
2611 is->audio_filter_src.freq = avctx->sample_rate;
2612 is->audio_filter_src.channels = avctx->channels;
2613 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2614 is->audio_filter_src.fmt = avctx->sample_fmt;
2615 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2617 link = is->out_audio_filter->inputs[0];
2618 sample_rate = link->sample_rate;
2619 nb_channels = link->channels;
2620 channel_layout = link->channel_layout;
2623 sample_rate = avctx->sample_rate;
2624 nb_channels = avctx->channels;
2625 channel_layout = avctx->channel_layout;
2628 /* prepare audio output */
2629 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2631 is->audio_hw_buf_size = ret;
2632 is->audio_src = is->audio_tgt;
2633 is->audio_buf_size = 0;
2634 is->audio_buf_index = 0;
2636 /* init averaging filter */
2637 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2638 is->audio_diff_avg_count = 0;
2639 /* since we do not have a precise anough audio fifo fullness,
2640 we correct audio sync only if larger than this threshold */
2641 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2643 is->audio_stream = stream_index;
2644 is->audio_st = ic->streams[stream_index];
2646 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2647 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2648 is->auddec.start_pts = is->audio_st->start_time;
2649 is->auddec.start_pts_tb = is->audio_st->time_base;
2651 decoder_start(&is->auddec, audio_thread, is);
2654 case AVMEDIA_TYPE_VIDEO:
2655 is->video_stream = stream_index;
2656 is->video_st = ic->streams[stream_index];
2658 is->viddec_width = avctx->width;
2659 is->viddec_height = avctx->height;
2661 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2662 decoder_start(&is->viddec, video_thread, is);
2663 is->queue_attachments_req = 1;
2665 case AVMEDIA_TYPE_SUBTITLE:
2666 is->subtitle_stream = stream_index;
2667 is->subtitle_st = ic->streams[stream_index];
2669 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2670 decoder_start(&is->subdec, subtitle_thread, is);
2677 av_dict_free(&opts);
2682 static void stream_component_close(VideoState *is, int stream_index)
2684 AVFormatContext *ic = is->ic;
2685 AVCodecContext *avctx;
2687 if (stream_index < 0 || stream_index >= ic->nb_streams)
2689 avctx = ic->streams[stream_index]->codec;
2691 switch (avctx->codec_type) {
2692 case AVMEDIA_TYPE_AUDIO:
2693 decoder_abort(&is->auddec, &is->sampq);
2695 decoder_destroy(&is->auddec);
2696 swr_free(&is->swr_ctx);
2697 av_freep(&is->audio_buf1);
2698 is->audio_buf1_size = 0;
2699 is->audio_buf = NULL;
2702 av_rdft_end(is->rdft);
2703 av_freep(&is->rdft_data);
2708 case AVMEDIA_TYPE_VIDEO:
2709 decoder_abort(&is->viddec, &is->pictq);
2710 decoder_destroy(&is->viddec);
2712 case AVMEDIA_TYPE_SUBTITLE:
2713 decoder_abort(&is->subdec, &is->subpq);
2714 decoder_destroy(&is->subdec);
2720 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2721 avcodec_close(avctx);
2722 switch (avctx->codec_type) {
2723 case AVMEDIA_TYPE_AUDIO:
2724 is->audio_st = NULL;
2725 is->audio_stream = -1;
2727 case AVMEDIA_TYPE_VIDEO:
2728 is->video_st = NULL;
2729 is->video_stream = -1;
2731 case AVMEDIA_TYPE_SUBTITLE:
2732 is->subtitle_st = NULL;
2733 is->subtitle_stream = -1;
2740 static int decode_interrupt_cb(void *ctx)
2742 VideoState *is = ctx;
2743 return is->abort_request;
2746 static int is_realtime(AVFormatContext *s)
2748 if( !strcmp(s->iformat->name, "rtp")
2749 || !strcmp(s->iformat->name, "rtsp")
2750 || !strcmp(s->iformat->name, "sdp")
2754 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2755 || !strncmp(s->filename, "udp:", 4)
2762 /* this thread gets the stream from the disk or the network */
2763 static int read_thread(void *arg)
2765 VideoState *is = arg;
2766 AVFormatContext *ic = NULL;
2768 int st_index[AVMEDIA_TYPE_NB];
2769 AVPacket pkt1, *pkt = &pkt1;
2770 int64_t stream_start_time;
2771 int pkt_in_play_range = 0;
2772 AVDictionaryEntry *t;
2773 AVDictionary **opts;
2774 int orig_nb_streams;
2775 SDL_mutex *wait_mutex = SDL_CreateMutex();
2776 int scan_all_pmts_set = 0;
2779 memset(st_index, -1, sizeof(st_index));
2780 is->last_video_stream = is->video_stream = -1;
2781 is->last_audio_stream = is->audio_stream = -1;
2782 is->last_subtitle_stream = is->subtitle_stream = -1;
2785 ic = avformat_alloc_context();
2787 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2788 ret = AVERROR(ENOMEM);
2791 ic->interrupt_callback.callback = decode_interrupt_cb;
2792 ic->interrupt_callback.opaque = is;
2793 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2794 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2795 scan_all_pmts_set = 1;
2797 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2799 print_error(is->filename, err);
2803 if (scan_all_pmts_set)
2804 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2806 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2807 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2808 ret = AVERROR_OPTION_NOT_FOUND;
2814 ic->flags |= AVFMT_FLAG_GENPTS;
2816 av_format_inject_global_side_data(ic);
2818 opts = setup_find_stream_info_opts(ic, codec_opts);
2819 orig_nb_streams = ic->nb_streams;
2821 err = avformat_find_stream_info(ic, opts);
2823 for (i = 0; i < orig_nb_streams; i++)
2824 av_dict_free(&opts[i]);
2828 av_log(NULL, AV_LOG_WARNING,
2829 "%s: could not find codec parameters\n", is->filename);
2835 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2837 if (seek_by_bytes < 0)
2838 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2840 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2842 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2843 window_title = av_asprintf("%s - %s", t->value, input_filename);
2845 /* if seeking requested, we execute it */
2846 if (start_time != AV_NOPTS_VALUE) {
2849 timestamp = start_time;
2850 /* add the stream start time */
2851 if (ic->start_time != AV_NOPTS_VALUE)
2852 timestamp += ic->start_time;
2853 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2855 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2856 is->filename, (double)timestamp / AV_TIME_BASE);
2860 is->realtime = is_realtime(ic);
2863 av_dump_format(ic, 0, is->filename, 0);
2865 for (i = 0; i < ic->nb_streams; i++) {
2866 AVStream *st = ic->streams[i];
2867 enum AVMediaType type = st->codec->codec_type;
2868 st->discard = AVDISCARD_ALL;
2869 if (wanted_stream_spec[type] && st_index[type] == -1)
2870 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2873 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2874 if (wanted_stream_spec[i] && st_index[i] == -1) {
2875 av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));
2876 st_index[i] = INT_MAX;
2881 st_index[AVMEDIA_TYPE_VIDEO] =
2882 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2883 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2885 st_index[AVMEDIA_TYPE_AUDIO] =
2886 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2887 st_index[AVMEDIA_TYPE_AUDIO],
2888 st_index[AVMEDIA_TYPE_VIDEO],
2890 if (!video_disable && !subtitle_disable)
2891 st_index[AVMEDIA_TYPE_SUBTITLE] =
2892 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2893 st_index[AVMEDIA_TYPE_SUBTITLE],
2894 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2895 st_index[AVMEDIA_TYPE_AUDIO] :
2896 st_index[AVMEDIA_TYPE_VIDEO]),
2899 is->show_mode = show_mode;
2900 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2901 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2902 AVCodecContext *avctx = st->codec;
2903 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2905 set_default_window_size(avctx->width, avctx->height, sar);
2908 /* open the streams */
2909 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2910 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2914 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2915 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2917 if (is->show_mode == SHOW_MODE_NONE)
2918 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2920 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2921 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2924 if (is->video_stream < 0 && is->audio_stream < 0) {
2925 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2931 if (infinite_buffer < 0 && is->realtime)
2932 infinite_buffer = 1;
2935 if (is->abort_request)
2937 if (is->paused != is->last_paused) {
2938 is->last_paused = is->paused;
2940 is->read_pause_return = av_read_pause(ic);
2944 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2946 (!strcmp(ic->iformat->name, "rtsp") ||
2947 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2948 /* wait 10 ms to avoid trying to get another packet */
2955 int64_t seek_target = is->seek_pos;
2956 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2957 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2958 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2959 // of the seek_pos/seek_rel variables
2961 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2963 av_log(NULL, AV_LOG_ERROR,
2964 "%s: error while seeking\n", is->ic->filename);
2966 if (is->audio_stream >= 0) {
2967 packet_queue_flush(&is->audioq);
2968 packet_queue_put(&is->audioq, &flush_pkt);
2970 if (is->subtitle_stream >= 0) {
2971 packet_queue_flush(&is->subtitleq);
2972 packet_queue_put(&is->subtitleq, &flush_pkt);
2974 if (is->video_stream >= 0) {
2975 packet_queue_flush(&is->videoq);
2976 packet_queue_put(&is->videoq, &flush_pkt);
2978 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2979 set_clock(&is->extclk, NAN, 0);
2981 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2985 is->queue_attachments_req = 1;
2988 step_to_next_frame(is);
2990 if (is->queue_attachments_req) {
2991 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2993 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2995 packet_queue_put(&is->videoq, ©);
2996 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2998 is->queue_attachments_req = 0;
3001 /* if the queue are full, no need to read more */
3002 if (infinite_buffer<1 &&
3003 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3004 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3005 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3006 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3007 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3009 SDL_LockMutex(wait_mutex);
3010 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3011 SDL_UnlockMutex(wait_mutex);
3015 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3016 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3017 if (loop != 1 && (!loop || --loop)) {
3018 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3019 } else if (autoexit) {
3024 ret = av_read_frame(ic, pkt);
3026 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3027 if (is->video_stream >= 0)
3028 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3029 if (is->audio_stream >= 0)
3030 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3031 if (is->subtitle_stream >= 0)
3032 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3035 if (ic->pb && ic->pb->error)
3037 SDL_LockMutex(wait_mutex);
3038 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3039 SDL_UnlockMutex(wait_mutex);
3044 /* check if packet is in play range specified by user, then queue, otherwise discard */
3045 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3046 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3047 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3048 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3049 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3050 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3051 <= ((double)duration / 1000000);
3052 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3053 packet_queue_put(&is->audioq, pkt);
3054 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3055 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3056 packet_queue_put(&is->videoq, pkt);
3057 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3058 packet_queue_put(&is->subtitleq, pkt);
3060 av_free_packet(pkt);
3063 /* wait until the end */
3064 while (!is->abort_request) {
3070 /* close each stream */
3071 if (is->audio_stream >= 0)
3072 stream_component_close(is, is->audio_stream);
3073 if (is->video_stream >= 0)
3074 stream_component_close(is, is->video_stream);
3075 if (is->subtitle_stream >= 0)
3076 stream_component_close(is, is->subtitle_stream);
3078 avformat_close_input(&ic);
3085 event.type = FF_QUIT_EVENT;
3086 event.user.data1 = is;
3087 SDL_PushEvent(&event);
3089 SDL_DestroyMutex(wait_mutex);
3093 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3097 is = av_mallocz(sizeof(VideoState));
3100 av_strlcpy(is->filename, filename, sizeof(is->filename));
3101 is->iformat = iformat;
3105 /* start video display */
3106 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3108 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3110 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3113 packet_queue_init(&is->videoq);
3114 packet_queue_init(&is->audioq);
3115 packet_queue_init(&is->subtitleq);
3117 is->continue_read_thread = SDL_CreateCond();
3119 init_clock(&is->vidclk, &is->videoq.serial);
3120 init_clock(&is->audclk, &is->audioq.serial);
3121 init_clock(&is->extclk, &is->extclk.serial);
3122 is->audio_clock_serial = -1;
3123 is->av_sync_type = av_sync_type;
3124 is->read_tid = SDL_CreateThread(read_thread, is);
3125 if (!is->read_tid) {
3133 static void stream_cycle_channel(VideoState *is, int codec_type)
3135 AVFormatContext *ic = is->ic;
3136 int start_index, stream_index;
3139 AVProgram *p = NULL;
3140 int nb_streams = is->ic->nb_streams;
3142 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3143 start_index = is->last_video_stream;
3144 old_index = is->video_stream;
3145 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3146 start_index = is->last_audio_stream;
3147 old_index = is->audio_stream;
3149 start_index = is->last_subtitle_stream;
3150 old_index = is->subtitle_stream;
3152 stream_index = start_index;
3154 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3155 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3157 nb_streams = p->nb_stream_indexes;
3158 for (start_index = 0; start_index < nb_streams; start_index++)
3159 if (p->stream_index[start_index] == stream_index)
3161 if (start_index == nb_streams)
3163 stream_index = start_index;
3168 if (++stream_index >= nb_streams)
3170 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3173 is->last_subtitle_stream = -1;
3176 if (start_index == -1)
3180 if (stream_index == start_index)
3182 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3183 if (st->codec->codec_type == codec_type) {
3184 /* check that parameters are OK */
3185 switch (codec_type) {
3186 case AVMEDIA_TYPE_AUDIO:
3187 if (st->codec->sample_rate != 0 &&
3188 st->codec->channels != 0)
3191 case AVMEDIA_TYPE_VIDEO:
3192 case AVMEDIA_TYPE_SUBTITLE:
3200 if (p && stream_index != -1)
3201 stream_index = p->stream_index[stream_index];
3202 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3203 av_get_media_type_string(codec_type),
3207 stream_component_close(is, old_index);
3208 stream_component_open(is, stream_index);
3212 static void toggle_full_screen(VideoState *is)
3214 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3215 /* OS X needs to reallocate the SDL overlays */
3217 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3218 is->pictq.queue[i].reallocate = 1;
3220 is_full_screen = !is_full_screen;
3221 video_open(is, 1, NULL);
3224 static void toggle_audio_display(VideoState *is)
3226 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3227 int next = is->show_mode;
3229 next = (next + 1) % SHOW_MODE_NB;
3230 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3231 if (is->show_mode != next) {
3232 fill_rectangle(screen,
3233 is->xleft, is->ytop, is->width, is->height,
3235 is->force_refresh = 1;
3236 is->show_mode = next;
3240 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3241 double remaining_time = 0.0;
3243 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3244 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3248 if (remaining_time > 0.0)
3249 av_usleep((int64_t)(remaining_time * 1000000.0));
3250 remaining_time = REFRESH_RATE;
3251 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3252 video_refresh(is, &remaining_time);
3257 static void seek_chapter(VideoState *is, int incr)
3259 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3262 if (!is->ic->nb_chapters)
3265 /* find the current chapter */
3266 for (i = 0; i < is->ic->nb_chapters; i++) {
3267 AVChapter *ch = is->ic->chapters[i];
3268 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3276 if (i >= is->ic->nb_chapters)
3279 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3280 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3281 AV_TIME_BASE_Q), 0, 0);
3284 /* handle an event sent by the GUI */
3285 static void event_loop(VideoState *cur_stream)
3288 double incr, pos, frac;
3292 refresh_loop_wait_event(cur_stream, &event);
3293 switch (event.type) {
3295 if (exit_on_keydown) {
3296 do_exit(cur_stream);
3299 switch (event.key.keysym.sym) {
3302 do_exit(cur_stream);
3305 toggle_full_screen(cur_stream);
3306 cur_stream->force_refresh = 1;
3310 toggle_pause(cur_stream);
3312 case SDLK_s: // S: Step to next frame
3313 step_to_next_frame(cur_stream);
3316 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3319 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3322 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3323 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3324 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3327 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3331 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3332 if (++cur_stream->vfilter_idx >= nb_vfilters)
3333 cur_stream->vfilter_idx = 0;
3335 cur_stream->vfilter_idx = 0;
3336 toggle_audio_display(cur_stream);
3339 toggle_audio_display(cur_stream);
3343 if (cur_stream->ic->nb_chapters <= 1) {
3347 seek_chapter(cur_stream, 1);
3350 if (cur_stream->ic->nb_chapters <= 1) {
3354 seek_chapter(cur_stream, -1);
3368 if (seek_by_bytes) {
3370 if (pos < 0 && cur_stream->video_stream >= 0)
3371 pos = frame_queue_last_pos(&cur_stream->pictq);
3372 if (pos < 0 && cur_stream->audio_stream >= 0)
3373 pos = frame_queue_last_pos(&cur_stream->sampq);
3375 pos = avio_tell(cur_stream->ic->pb);
3376 if (cur_stream->ic->bit_rate)
3377 incr *= cur_stream->ic->bit_rate / 8.0;
3381 stream_seek(cur_stream, pos, incr, 1);
3383 pos = get_master_clock(cur_stream);
3385 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3387 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3388 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3389 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3396 case SDL_VIDEOEXPOSE:
3397 cur_stream->force_refresh = 1;
3399 case SDL_MOUSEBUTTONDOWN:
3400 if (exit_on_mousedown) {
3401 do_exit(cur_stream);
3404 case SDL_MOUSEMOTION:
3405 if (cursor_hidden) {
3409 cursor_last_shown = av_gettime_relative();
3410 if (event.type == SDL_MOUSEBUTTONDOWN) {
3413 if (event.motion.state != SDL_PRESSED)
3417 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3418 uint64_t size = avio_size(cur_stream->ic->pb);
3419 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3423 int tns, thh, tmm, tss;
3424 tns = cur_stream->ic->duration / 1000000LL;
3426 tmm = (tns % 3600) / 60;
3428 frac = x / cur_stream->width;
3431 mm = (ns % 3600) / 60;
3433 av_log(NULL, AV_LOG_INFO,
3434 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3435 hh, mm, ss, thh, tmm, tss);
3436 ts = frac * cur_stream->ic->duration;
3437 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3438 ts += cur_stream->ic->start_time;
3439 stream_seek(cur_stream, ts, 0, 0);
3442 case SDL_VIDEORESIZE:
3443 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3444 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3446 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3447 do_exit(cur_stream);
3449 screen_width = cur_stream->width = screen->w;
3450 screen_height = cur_stream->height = screen->h;
3451 cur_stream->force_refresh = 1;
3455 do_exit(cur_stream);
3457 case FF_ALLOC_EVENT:
3458 alloc_picture(event.user.data1);
3466 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3468 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3469 return opt_default(NULL, "video_size", arg);
3472 static int opt_width(void *optctx, const char *opt, const char *arg)
3474 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3478 static int opt_height(void *optctx, const char *opt, const char *arg)
3480 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3484 static int opt_format(void *optctx, const char *opt, const char *arg)
3486 file_iformat = av_find_input_format(arg);
3487 if (!file_iformat) {
3488 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3489 return AVERROR(EINVAL);
3494 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3496 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3497 return opt_default(NULL, "pixel_format", arg);
3500 static int opt_sync(void *optctx, const char *opt, const char *arg)
3502 if (!strcmp(arg, "audio"))
3503 av_sync_type = AV_SYNC_AUDIO_MASTER;
3504 else if (!strcmp(arg, "video"))
3505 av_sync_type = AV_SYNC_VIDEO_MASTER;
3506 else if (!strcmp(arg, "ext"))
3507 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3509 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3515 static int opt_seek(void *optctx, const char *opt, const char *arg)
3517 start_time = parse_time_or_die(opt, arg, 1);
3521 static int opt_duration(void *optctx, const char *opt, const char *arg)
3523 duration = parse_time_or_die(opt, arg, 1);
3527 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3529 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3530 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3531 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3532 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3536 static void opt_input_file(void *optctx, const char *filename)
3538 if (input_filename) {
3539 av_log(NULL, AV_LOG_FATAL,
3540 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3541 filename, input_filename);
3544 if (!strcmp(filename, "-"))
3546 input_filename = filename;
3549 static int opt_codec(void *optctx, const char *opt, const char *arg)
3551 const char *spec = strchr(opt, ':');
3553 av_log(NULL, AV_LOG_ERROR,
3554 "No media specifier was specified in '%s' in option '%s'\n",
3556 return AVERROR(EINVAL);
3560 case 'a' : audio_codec_name = arg; break;
3561 case 's' : subtitle_codec_name = arg; break;
3562 case 'v' : video_codec_name = arg; break;
3564 av_log(NULL, AV_LOG_ERROR,
3565 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3566 return AVERROR(EINVAL);
3573 static const OptionDef options[] = {
3574 #include "cmdutils_common_opts.h"
3575 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3576 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3577 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3578 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3579 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3580 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3581 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3582 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3583 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3584 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3585 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3586 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3587 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3588 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3589 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3590 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3591 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3592 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3593 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3594 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3595 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3596 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3597 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3598 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3599 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3600 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3601 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3602 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3603 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3605 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3606 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3608 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3609 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3610 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3611 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3612 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3613 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3614 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3615 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3616 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3620 static void show_usage(void)
3622 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3623 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3624 av_log(NULL, AV_LOG_INFO, "\n");
3627 void show_help_default(const char *opt, const char *arg)
3629 av_log_set_callback(log_callback_help);
3631 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3632 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3634 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3635 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3636 #if !CONFIG_AVFILTER
3637 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3639 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3641 printf("\nWhile playing:\n"
3643 "f toggle full screen\n"
3645 "a cycle audio channel in the current program\n"
3646 "v cycle video channel\n"
3647 "t cycle subtitle channel in the current program\n"
3649 "w cycle video filters or show modes\n"
3650 "s activate frame-step mode\n"
3651 "left/right seek backward/forward 10 seconds\n"
3652 "down/up seek backward/forward 1 minute\n"
3653 "page down/page up seek backward/forward 10 minutes\n"
3654 "mouse click seek to percentage in file corresponding to fraction of width\n"
3658 static int lockmgr(void **mtx, enum AVLockOp op)
3661 case AV_LOCK_CREATE:
3662 *mtx = SDL_CreateMutex();
3666 case AV_LOCK_OBTAIN:
3667 return !!SDL_LockMutex(*mtx);
3668 case AV_LOCK_RELEASE:
3669 return !!SDL_UnlockMutex(*mtx);
3670 case AV_LOCK_DESTROY:
3671 SDL_DestroyMutex(*mtx);
3677 /* Called from the main */
3678 int main(int argc, char **argv)
3682 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3684 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3685 parse_loglevel(argc, argv, options);
3687 /* register all codecs, demux and protocols */
3689 avdevice_register_all();
3692 avfilter_register_all();
3695 avformat_network_init();
3699 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3700 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3702 show_banner(argc, argv, options);
3704 parse_options(NULL, argc, argv, options, opt_input_file);
3706 if (!input_filename) {
3708 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3709 av_log(NULL, AV_LOG_FATAL,
3710 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3714 if (display_disable) {
3717 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3719 flags &= ~SDL_INIT_AUDIO;
3720 if (display_disable)
3721 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3722 #if !defined(_WIN32) && !defined(__APPLE__)
3723 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3725 if (SDL_Init (flags)) {
3726 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3727 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3731 if (!display_disable) {
3732 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3733 fs_screen_width = vi->current_w;
3734 fs_screen_height = vi->current_h;
3737 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3738 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3739 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3741 if (av_lockmgr_register(lockmgr)) {
3742 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3746 av_init_packet(&flush_pkt);
3747 flush_pkt.data = (uint8_t *)&flush_pkt;
3749 is = stream_open(input_filename, file_iformat);
3751 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");