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)
71 /* Minimum SDL audio buffer size, in samples. */
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
73 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
76 /* no AV sync correction is done if below the minimum AV sync threshold */
77 #define AV_SYNC_THRESHOLD_MIN 0.04
78 /* AV sync correction is done if above the maximum AV sync threshold */
79 #define AV_SYNC_THRESHOLD_MAX 0.1
80 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
81 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
82 /* no AV correction is done if too big error */
83 #define AV_NOSYNC_THRESHOLD 10.0
85 /* maximum audio speed change to get correct sync */
86 #define SAMPLE_CORRECTION_PERCENT_MAX 10
88 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
89 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
90 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
91 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
93 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
94 #define AUDIO_DIFF_AVG_NB 20
96 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
97 #define REFRESH_RATE 0.01
99 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
100 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
101 #define SAMPLE_ARRAY_SIZE (8 * 65536)
103 #define CURSOR_HIDE_DELAY 1000000
105 static int64_t sws_flags = SWS_BICUBIC;
107 typedef struct MyAVPacketList {
109 struct MyAVPacketList *next;
113 typedef struct PacketQueue {
114 MyAVPacketList *first_pkt, *last_pkt;
123 #define VIDEO_PICTURE_QUEUE_SIZE 3
124 #define SUBPICTURE_QUEUE_SIZE 16
125 #define SAMPLE_QUEUE_SIZE 9
126 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
128 typedef struct AudioParams {
131 int64_t channel_layout;
132 enum AVSampleFormat fmt;
137 typedef struct Clock {
138 double pts; /* clock base */
139 double pts_drift; /* clock base minus time at which we updated the clock */
142 int serial; /* clock is based on a packet with this serial */
144 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
147 /* Common struct for handling all types of decoded data and allocated render buffers. */
148 typedef struct Frame {
152 double pts; /* presentation timestamp for the frame */
153 double duration; /* estimated duration of the frame */
154 int64_t pos; /* byte position of the frame in the input file */
163 typedef struct FrameQueue {
164 Frame queue[FRAME_QUEUE_SIZE];
177 AV_SYNC_AUDIO_MASTER, /* default choice */
178 AV_SYNC_VIDEO_MASTER,
179 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
182 typedef struct Decoder {
186 AVCodecContext *avctx;
190 SDL_cond *empty_queue_cond;
192 AVRational start_pts_tb;
194 AVRational next_pts_tb;
195 SDL_Thread *decoder_tid;
198 typedef struct VideoState {
199 SDL_Thread *read_tid;
200 AVInputFormat *iformat;
205 int queue_attachments_req;
210 int read_pause_return;
234 int audio_clock_serial;
235 double audio_diff_cum; /* used for AV difference average computation */
236 double audio_diff_avg_coef;
237 double audio_diff_threshold;
238 int audio_diff_avg_count;
241 int audio_hw_buf_size;
242 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
245 unsigned int audio_buf_size; /* in bytes */
246 unsigned int audio_buf1_size;
247 int audio_buf_index; /* in bytes */
248 int audio_write_buf_size;
249 struct AudioParams audio_src;
251 struct AudioParams audio_filter_src;
253 struct AudioParams audio_tgt;
254 struct SwrContext *swr_ctx;
255 int frame_drops_early;
256 int frame_drops_late;
259 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
261 int16_t sample_array[SAMPLE_ARRAY_SIZE];
262 int sample_array_index;
266 FFTSample *rdft_data;
268 double last_vis_time;
271 AVStream *subtitle_st;
272 PacketQueue subtitleq;
275 double frame_last_returned_time;
276 double frame_last_filter_delay;
280 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
282 struct SwsContext *img_convert_ctx;
284 struct SwsContext *sub_convert_ctx;
285 SDL_Rect last_display_rect;
289 int width, height, xleft, ytop;
294 AVFilterContext *in_video_filter; // the first filter in the video chain
295 AVFilterContext *out_video_filter; // the last filter in the video chain
296 AVFilterContext *in_audio_filter; // the first filter in the audio chain
297 AVFilterContext *out_audio_filter; // the last filter in the audio chain
298 AVFilterGraph *agraph; // audio filter graph
301 int last_video_stream, last_audio_stream, last_subtitle_stream;
303 SDL_cond *continue_read_thread;
306 /* options specified by the user */
307 static AVInputFormat *file_iformat;
308 static const char *input_filename;
309 static const char *window_title;
310 static int fs_screen_width;
311 static int fs_screen_height;
312 static int default_width = 640;
313 static int default_height = 480;
314 static int screen_width = 0;
315 static int screen_height = 0;
316 static int audio_disable;
317 static int video_disable;
318 static int subtitle_disable;
319 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
320 static int seek_by_bytes = -1;
321 static int display_disable;
322 static int show_status = 1;
323 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
324 static int64_t start_time = AV_NOPTS_VALUE;
325 static int64_t duration = AV_NOPTS_VALUE;
327 static int genpts = 0;
328 static int lowres = 0;
329 static int decoder_reorder_pts = -1;
331 static int exit_on_keydown;
332 static int exit_on_mousedown;
334 static int framedrop = -1;
335 static int infinite_buffer = -1;
336 static enum ShowMode show_mode = SHOW_MODE_NONE;
337 static const char *audio_codec_name;
338 static const char *subtitle_codec_name;
339 static const char *video_codec_name;
340 double rdftspeed = 0.02;
341 static int64_t cursor_last_shown;
342 static int cursor_hidden = 0;
344 static const char **vfilters_list = NULL;
345 static int nb_vfilters = 0;
346 static char *afilters = NULL;
348 static int autorotate = 1;
350 /* current context */
351 static int is_full_screen;
352 static int64_t audio_callback_time;
354 static AVPacket flush_pkt;
356 #define FF_ALLOC_EVENT (SDL_USEREVENT)
357 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
359 static SDL_Surface *screen;
362 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
364 GROW_ARRAY(vfilters_list, nb_vfilters);
365 vfilters_list[nb_vfilters - 1] = arg;
371 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
372 enum AVSampleFormat fmt2, int64_t channel_count2)
374 /* If channel count == 1, planar and non-planar formats are the same */
375 if (channel_count1 == 1 && channel_count2 == 1)
376 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
378 return channel_count1 != channel_count2 || fmt1 != fmt2;
382 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
384 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
385 return channel_layout;
390 static void free_picture(Frame *vp);
392 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
394 MyAVPacketList *pkt1;
396 if (q->abort_request)
399 pkt1 = av_malloc(sizeof(MyAVPacketList));
404 if (pkt == &flush_pkt)
406 pkt1->serial = q->serial;
411 q->last_pkt->next = pkt1;
414 q->size += pkt1->pkt.size + sizeof(*pkt1);
415 /* XXX: should duplicate packet data in DV case */
416 SDL_CondSignal(q->cond);
420 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
424 /* duplicate the packet */
425 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
428 SDL_LockMutex(q->mutex);
429 ret = packet_queue_put_private(q, pkt);
430 SDL_UnlockMutex(q->mutex);
432 if (pkt != &flush_pkt && ret < 0)
438 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
440 AVPacket pkt1, *pkt = &pkt1;
444 pkt->stream_index = stream_index;
445 return packet_queue_put(q, pkt);
448 /* packet queue handling */
449 static void packet_queue_init(PacketQueue *q)
451 memset(q, 0, sizeof(PacketQueue));
452 q->mutex = SDL_CreateMutex();
453 q->cond = SDL_CreateCond();
454 q->abort_request = 1;
457 static void packet_queue_flush(PacketQueue *q)
459 MyAVPacketList *pkt, *pkt1;
461 SDL_LockMutex(q->mutex);
462 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
464 av_free_packet(&pkt->pkt);
471 SDL_UnlockMutex(q->mutex);
474 static void packet_queue_destroy(PacketQueue *q)
476 packet_queue_flush(q);
477 SDL_DestroyMutex(q->mutex);
478 SDL_DestroyCond(q->cond);
481 static void packet_queue_abort(PacketQueue *q)
483 SDL_LockMutex(q->mutex);
485 q->abort_request = 1;
487 SDL_CondSignal(q->cond);
489 SDL_UnlockMutex(q->mutex);
492 static void packet_queue_start(PacketQueue *q)
494 SDL_LockMutex(q->mutex);
495 q->abort_request = 0;
496 packet_queue_put_private(q, &flush_pkt);
497 SDL_UnlockMutex(q->mutex);
500 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
501 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
503 MyAVPacketList *pkt1;
506 SDL_LockMutex(q->mutex);
509 if (q->abort_request) {
516 q->first_pkt = pkt1->next;
520 q->size -= pkt1->pkt.size + sizeof(*pkt1);
523 *serial = pkt1->serial;
531 SDL_CondWait(q->cond, q->mutex);
534 SDL_UnlockMutex(q->mutex);
538 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
539 memset(d, 0, sizeof(Decoder));
542 d->empty_queue_cond = empty_queue_cond;
543 d->start_pts = AV_NOPTS_VALUE;
546 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
552 if (d->queue->abort_request)
555 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
558 if (d->queue->nb_packets == 0)
559 SDL_CondSignal(d->empty_queue_cond);
560 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
562 if (pkt.data == flush_pkt.data) {
563 avcodec_flush_buffers(d->avctx);
565 d->next_pts = d->start_pts;
566 d->next_pts_tb = d->start_pts_tb;
568 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
569 av_free_packet(&d->pkt);
570 d->pkt_temp = d->pkt = pkt;
571 d->packet_pending = 1;
574 switch (d->avctx->codec_type) {
575 case AVMEDIA_TYPE_VIDEO:
576 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
578 if (decoder_reorder_pts == -1) {
579 frame->pts = av_frame_get_best_effort_timestamp(frame);
580 } else if (decoder_reorder_pts) {
581 frame->pts = frame->pkt_pts;
583 frame->pts = frame->pkt_dts;
587 case AVMEDIA_TYPE_AUDIO:
588 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
590 AVRational tb = (AVRational){1, frame->sample_rate};
591 if (frame->pts != AV_NOPTS_VALUE)
592 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
593 else if (frame->pkt_pts != AV_NOPTS_VALUE)
594 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
595 else if (d->next_pts != AV_NOPTS_VALUE)
596 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
597 if (frame->pts != AV_NOPTS_VALUE) {
598 d->next_pts = frame->pts + frame->nb_samples;
603 case AVMEDIA_TYPE_SUBTITLE:
604 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
609 d->packet_pending = 0;
612 d->pkt_temp.pts = AV_NOPTS_VALUE;
613 if (d->pkt_temp.data) {
614 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
615 ret = d->pkt_temp.size;
616 d->pkt_temp.data += ret;
617 d->pkt_temp.size -= ret;
618 if (d->pkt_temp.size <= 0)
619 d->packet_pending = 0;
622 d->packet_pending = 0;
623 d->finished = d->pkt_serial;
627 } while (!got_frame && !d->finished);
632 static void decoder_destroy(Decoder *d) {
633 av_free_packet(&d->pkt);
636 static void frame_queue_unref_item(Frame *vp)
638 av_frame_unref(vp->frame);
639 avsubtitle_free(&vp->sub);
642 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
645 memset(f, 0, sizeof(FrameQueue));
646 if (!(f->mutex = SDL_CreateMutex()))
647 return AVERROR(ENOMEM);
648 if (!(f->cond = SDL_CreateCond()))
649 return AVERROR(ENOMEM);
651 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
652 f->keep_last = !!keep_last;
653 for (i = 0; i < f->max_size; i++)
654 if (!(f->queue[i].frame = av_frame_alloc()))
655 return AVERROR(ENOMEM);
659 static void frame_queue_destory(FrameQueue *f)
662 for (i = 0; i < f->max_size; i++) {
663 Frame *vp = &f->queue[i];
664 frame_queue_unref_item(vp);
665 av_frame_free(&vp->frame);
668 SDL_DestroyMutex(f->mutex);
669 SDL_DestroyCond(f->cond);
672 static void frame_queue_signal(FrameQueue *f)
674 SDL_LockMutex(f->mutex);
675 SDL_CondSignal(f->cond);
676 SDL_UnlockMutex(f->mutex);
679 static Frame *frame_queue_peek(FrameQueue *f)
681 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
684 static Frame *frame_queue_peek_next(FrameQueue *f)
686 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
689 static Frame *frame_queue_peek_last(FrameQueue *f)
691 return &f->queue[f->rindex];
694 static Frame *frame_queue_peek_writable(FrameQueue *f)
696 /* wait until we have space to put a new frame */
697 SDL_LockMutex(f->mutex);
698 while (f->size >= f->max_size &&
699 !f->pktq->abort_request) {
700 SDL_CondWait(f->cond, f->mutex);
702 SDL_UnlockMutex(f->mutex);
704 if (f->pktq->abort_request)
707 return &f->queue[f->windex];
710 static Frame *frame_queue_peek_readable(FrameQueue *f)
712 /* wait until we have a readable a new frame */
713 SDL_LockMutex(f->mutex);
714 while (f->size - f->rindex_shown <= 0 &&
715 !f->pktq->abort_request) {
716 SDL_CondWait(f->cond, f->mutex);
718 SDL_UnlockMutex(f->mutex);
720 if (f->pktq->abort_request)
723 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
726 static void frame_queue_push(FrameQueue *f)
728 if (++f->windex == f->max_size)
730 SDL_LockMutex(f->mutex);
732 SDL_CondSignal(f->cond);
733 SDL_UnlockMutex(f->mutex);
736 static void frame_queue_next(FrameQueue *f)
738 if (f->keep_last && !f->rindex_shown) {
742 frame_queue_unref_item(&f->queue[f->rindex]);
743 if (++f->rindex == f->max_size)
745 SDL_LockMutex(f->mutex);
747 SDL_CondSignal(f->cond);
748 SDL_UnlockMutex(f->mutex);
751 /* jump back to the previous frame if available by resetting rindex_shown */
752 static int frame_queue_prev(FrameQueue *f)
754 int ret = f->rindex_shown;
759 /* return the number of undisplayed frames in the queue */
760 static int frame_queue_nb_remaining(FrameQueue *f)
762 return f->size - f->rindex_shown;
765 /* return last shown position */
766 static int64_t frame_queue_last_pos(FrameQueue *f)
768 Frame *fp = &f->queue[f->rindex];
769 if (f->rindex_shown && fp->serial == f->pktq->serial)
775 static void decoder_abort(Decoder *d, FrameQueue *fq)
777 packet_queue_abort(d->queue);
778 frame_queue_signal(fq);
779 SDL_WaitThread(d->decoder_tid, NULL);
780 d->decoder_tid = NULL;
781 packet_queue_flush(d->queue);
784 static inline void fill_rectangle(SDL_Surface *screen,
785 int x, int y, int w, int h, int color, int update)
792 SDL_FillRect(screen, &rect, color);
793 if (update && w > 0 && h > 0)
794 SDL_UpdateRect(screen, x, y, w, h);
797 /* draw only the border of a rectangle */
798 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
802 /* fill the background */
806 w2 = width - (x + w);
812 h2 = height - (y + h);
815 fill_rectangle(screen,
819 fill_rectangle(screen,
820 xleft + width - w2, ytop,
823 fill_rectangle(screen,
827 fill_rectangle(screen,
828 xleft + w1, ytop + height - h2,
833 #define ALPHA_BLEND(a, oldp, newp, s)\
834 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
840 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
842 int x, y, Y, U, V, A;
843 uint8_t *lum, *cb, *cr;
844 int dstx, dsty, dstw, dsth;
845 const AVPicture *src = &rect->pict;
847 dstw = av_clip(rect->w, 0, imgw);
848 dsth = av_clip(rect->h, 0, imgh);
849 dstx = av_clip(rect->x, 0, imgw - dstw);
850 dsty = av_clip(rect->y, 0, imgh - dsth);
851 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
852 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
853 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
855 for (y = 0; y<dsth; y++) {
856 for (x = 0; x<dstw; x++) {
857 Y = src->data[0][x + y*src->linesize[0]];
858 A = src->data[3][x + y*src->linesize[3]];
859 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
862 lum += dst->linesize[0] - dstw;
865 for (y = 0; y<dsth/2; y++) {
866 for (x = 0; x<dstw/2; x++) {
867 U = src->data[1][x + y*src->linesize[1]];
868 V = src->data[2][x + y*src->linesize[2]];
869 A = src->data[3][2*x + 2*y *src->linesize[3]]
870 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
871 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
872 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
873 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
874 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
878 cb += dst->linesize[1] - dstw/2;
879 cr += dst->linesize[2] - dstw/2;
883 static void free_picture(Frame *vp)
886 SDL_FreeYUVOverlay(vp->bmp);
891 static void calculate_display_rect(SDL_Rect *rect,
892 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
893 int pic_width, int pic_height, AVRational pic_sar)
896 int width, height, x, y;
898 if (pic_sar.num == 0)
901 aspect_ratio = av_q2d(pic_sar);
903 if (aspect_ratio <= 0.0)
905 aspect_ratio *= (float)pic_width / (float)pic_height;
907 /* XXX: we suppose the screen has a 1.0 pixel ratio */
909 width = ((int)rint(height * aspect_ratio)) & ~1;
910 if (width > scr_width) {
912 height = ((int)rint(width / aspect_ratio)) & ~1;
914 x = (scr_width - width) / 2;
915 y = (scr_height - height) / 2;
916 rect->x = scr_xleft + x;
917 rect->y = scr_ytop + y;
918 rect->w = FFMAX(width, 1);
919 rect->h = FFMAX(height, 1);
922 static void video_image_display(VideoState *is)
930 vp = frame_queue_peek(&is->pictq);
932 if (is->subtitle_st) {
933 if (frame_queue_nb_remaining(&is->subpq) > 0) {
934 sp = frame_queue_peek(&is->subpq);
936 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
937 SDL_LockYUVOverlay (vp->bmp);
939 pict.data[0] = vp->bmp->pixels[0];
940 pict.data[1] = vp->bmp->pixels[2];
941 pict.data[2] = vp->bmp->pixels[1];
943 pict.linesize[0] = vp->bmp->pitches[0];
944 pict.linesize[1] = vp->bmp->pitches[2];
945 pict.linesize[2] = vp->bmp->pitches[1];
947 for (i = 0; i < sp->sub.num_rects; i++)
948 blend_subrect(&pict, sp->sub.rects[i],
949 vp->bmp->w, vp->bmp->h);
951 SDL_UnlockYUVOverlay (vp->bmp);
956 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
958 SDL_DisplayYUVOverlay(vp->bmp, &rect);
960 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) {
961 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
962 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
963 is->last_display_rect = rect;
968 static inline int compute_mod(int a, int b)
970 return a < 0 ? a%b + b : a%b;
973 static void video_audio_display(VideoState *s)
975 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
976 int ch, channels, h, h2, bgcolor, fgcolor;
978 int rdft_bits, nb_freq;
980 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
982 nb_freq = 1 << (rdft_bits - 1);
984 /* compute display index : center on currently output samples */
985 channels = s->audio_tgt.channels;
986 nb_display_channels = channels;
988 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
990 delay = s->audio_write_buf_size;
993 /* to be more precise, we take into account the time spent since
994 the last buffer computation */
995 if (audio_callback_time) {
996 time_diff = av_gettime_relative() - audio_callback_time;
997 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1000 delay += 2 * data_used;
1001 if (delay < data_used)
1004 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1005 if (s->show_mode == SHOW_MODE_WAVES) {
1007 for (i = 0; i < 1000; i += channels) {
1008 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1009 int a = s->sample_array[idx];
1010 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1011 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1012 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1014 if (h < score && (b ^ c) < 0) {
1021 s->last_i_start = i_start;
1023 i_start = s->last_i_start;
1026 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1027 if (s->show_mode == SHOW_MODE_WAVES) {
1028 fill_rectangle(screen,
1029 s->xleft, s->ytop, s->width, s->height,
1032 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1034 /* total height for one channel */
1035 h = s->height / nb_display_channels;
1036 /* graph height / 2 */
1038 for (ch = 0; ch < nb_display_channels; ch++) {
1040 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1041 for (x = 0; x < s->width; x++) {
1042 y = (s->sample_array[i] * h2) >> 15;
1049 fill_rectangle(screen,
1050 s->xleft + x, ys, 1, y,
1053 if (i >= SAMPLE_ARRAY_SIZE)
1054 i -= SAMPLE_ARRAY_SIZE;
1058 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1060 for (ch = 1; ch < nb_display_channels; ch++) {
1061 y = s->ytop + ch * h;
1062 fill_rectangle(screen,
1063 s->xleft, y, s->width, 1,
1066 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1068 nb_display_channels= FFMIN(nb_display_channels, 2);
1069 if (rdft_bits != s->rdft_bits) {
1070 av_rdft_end(s->rdft);
1071 av_free(s->rdft_data);
1072 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1073 s->rdft_bits = rdft_bits;
1074 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1076 if (!s->rdft || !s->rdft_data){
1077 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1078 s->show_mode = SHOW_MODE_WAVES;
1081 for (ch = 0; ch < nb_display_channels; ch++) {
1082 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1084 for (x = 0; x < 2 * nb_freq; x++) {
1085 double w = (x-nb_freq) * (1.0 / nb_freq);
1086 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1088 if (i >= SAMPLE_ARRAY_SIZE)
1089 i -= SAMPLE_ARRAY_SIZE;
1091 av_rdft_calc(s->rdft, data[ch]);
1093 /* Least efficient way to do this, we should of course
1094 * directly access it but it is more than fast enough. */
1095 for (y = 0; y < s->height; y++) {
1096 double w = 1 / sqrt(nb_freq);
1097 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]));
1098 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1099 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1102 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1104 fill_rectangle(screen,
1105 s->xpos, s->height-y, 1, 1,
1109 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1112 if (s->xpos >= s->width)
1117 static void stream_close(VideoState *is)
1119 /* XXX: use a special url_shutdown call to abort parse cleanly */
1120 is->abort_request = 1;
1121 SDL_WaitThread(is->read_tid, NULL);
1122 packet_queue_destroy(&is->videoq);
1123 packet_queue_destroy(&is->audioq);
1124 packet_queue_destroy(&is->subtitleq);
1126 /* free all pictures */
1127 frame_queue_destory(&is->pictq);
1128 frame_queue_destory(&is->sampq);
1129 frame_queue_destory(&is->subpq);
1130 SDL_DestroyCond(is->continue_read_thread);
1131 #if !CONFIG_AVFILTER
1132 sws_freeContext(is->img_convert_ctx);
1134 sws_freeContext(is->sub_convert_ctx);
1138 static void do_exit(VideoState *is)
1143 av_lockmgr_register(NULL);
1146 av_freep(&vfilters_list);
1148 avformat_network_deinit();
1152 av_log(NULL, AV_LOG_QUIET, "%s", "");
1156 static void sigterm_handler(int sig)
1161 static void set_default_window_size(int width, int height, AVRational sar)
1164 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1165 default_width = rect.w;
1166 default_height = rect.h;
1169 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1171 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1174 if (is_full_screen) flags |= SDL_FULLSCREEN;
1175 else flags |= SDL_RESIZABLE;
1177 if (vp && vp->width)
1178 set_default_window_size(vp->width, vp->height, vp->sar);
1180 if (is_full_screen && fs_screen_width) {
1181 w = fs_screen_width;
1182 h = fs_screen_height;
1183 } else if (!is_full_screen && screen_width) {
1190 w = FFMIN(16383, w);
1191 if (screen && is->width == screen->w && screen->w == w
1192 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1194 screen = SDL_SetVideoMode(w, h, 0, flags);
1196 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1200 window_title = input_filename;
1201 SDL_WM_SetCaption(window_title, window_title);
1203 is->width = screen->w;
1204 is->height = screen->h;
1209 /* display the current picture, if any */
1210 static void video_display(VideoState *is)
1213 video_open(is, 0, NULL);
1214 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1215 video_audio_display(is);
1216 else if (is->video_st)
1217 video_image_display(is);
1220 static double get_clock(Clock *c)
1222 if (*c->queue_serial != c->serial)
1227 double time = av_gettime_relative() / 1000000.0;
1228 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1232 static void set_clock_at(Clock *c, double pts, int serial, double time)
1235 c->last_updated = time;
1236 c->pts_drift = c->pts - time;
1240 static void set_clock(Clock *c, double pts, int serial)
1242 double time = av_gettime_relative() / 1000000.0;
1243 set_clock_at(c, pts, serial, time);
1246 static void set_clock_speed(Clock *c, double speed)
1248 set_clock(c, get_clock(c), c->serial);
1252 static void init_clock(Clock *c, int *queue_serial)
1256 c->queue_serial = queue_serial;
1257 set_clock(c, NAN, -1);
1260 static void sync_clock_to_slave(Clock *c, Clock *slave)
1262 double clock = get_clock(c);
1263 double slave_clock = get_clock(slave);
1264 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1265 set_clock(c, slave_clock, slave->serial);
1268 static int get_master_sync_type(VideoState *is) {
1269 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1271 return AV_SYNC_VIDEO_MASTER;
1273 return AV_SYNC_AUDIO_MASTER;
1274 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1276 return AV_SYNC_AUDIO_MASTER;
1278 return AV_SYNC_EXTERNAL_CLOCK;
1280 return AV_SYNC_EXTERNAL_CLOCK;
1284 /* get the current master clock value */
1285 static double get_master_clock(VideoState *is)
1289 switch (get_master_sync_type(is)) {
1290 case AV_SYNC_VIDEO_MASTER:
1291 val = get_clock(&is->vidclk);
1293 case AV_SYNC_AUDIO_MASTER:
1294 val = get_clock(&is->audclk);
1297 val = get_clock(&is->extclk);
1303 static void check_external_clock_speed(VideoState *is) {
1304 if (is->video_stream >= 0 && is->videoq.nb_packets <= MIN_FRAMES / 2 ||
1305 is->audio_stream >= 0 && is->audioq.nb_packets <= MIN_FRAMES / 2) {
1306 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1307 } else if ((is->video_stream < 0 || is->videoq.nb_packets > MIN_FRAMES * 2) &&
1308 (is->audio_stream < 0 || is->audioq.nb_packets > MIN_FRAMES * 2)) {
1309 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1311 double speed = is->extclk.speed;
1313 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1317 /* seek in the stream */
1318 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1320 if (!is->seek_req) {
1323 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1325 is->seek_flags |= AVSEEK_FLAG_BYTE;
1327 SDL_CondSignal(is->continue_read_thread);
1331 /* pause or resume the video */
1332 static void stream_toggle_pause(VideoState *is)
1335 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1336 if (is->read_pause_return != AVERROR(ENOSYS)) {
1337 is->vidclk.paused = 0;
1339 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1341 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1342 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1345 static void toggle_pause(VideoState *is)
1347 stream_toggle_pause(is);
1351 static void step_to_next_frame(VideoState *is)
1353 /* if the stream is paused unpause it, then step */
1355 stream_toggle_pause(is);
1359 static double compute_target_delay(double delay, VideoState *is)
1361 double sync_threshold, diff = 0;
1363 /* update delay to follow master synchronisation source */
1364 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1365 /* if video is slave, we try to correct big delays by
1366 duplicating or deleting a frame */
1367 diff = get_clock(&is->vidclk) - get_master_clock(is);
1369 /* skip or repeat frame. We take into account the
1370 delay to compute the threshold. I still don't know
1371 if it is the best guess */
1372 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1373 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1374 if (diff <= -sync_threshold)
1375 delay = FFMAX(0, delay + diff);
1376 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1377 delay = delay + diff;
1378 else if (diff >= sync_threshold)
1383 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1389 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1390 if (vp->serial == nextvp->serial) {
1391 double duration = nextvp->pts - vp->pts;
1392 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1393 return vp->duration;
1401 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1402 /* update current video pts */
1403 set_clock(&is->vidclk, pts, serial);
1404 sync_clock_to_slave(&is->extclk, &is->vidclk);
1407 /* called to display each frame */
1408 static void video_refresh(void *opaque, double *remaining_time)
1410 VideoState *is = opaque;
1415 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1416 check_external_clock_speed(is);
1418 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1419 time = av_gettime_relative() / 1000000.0;
1420 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1422 is->last_vis_time = time;
1424 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1429 if (is->force_refresh)
1430 redisplay = frame_queue_prev(&is->pictq);
1432 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1433 // nothing to do, no picture to display in the queue
1435 double last_duration, duration, delay;
1438 /* dequeue the picture */
1439 lastvp = frame_queue_peek_last(&is->pictq);
1440 vp = frame_queue_peek(&is->pictq);
1442 if (vp->serial != is->videoq.serial) {
1443 frame_queue_next(&is->pictq);
1448 if (lastvp->serial != vp->serial && !redisplay)
1449 is->frame_timer = av_gettime_relative() / 1000000.0;
1454 /* compute nominal last_duration */
1455 last_duration = vp_duration(is, lastvp, vp);
1459 delay = compute_target_delay(last_duration, is);
1461 time= av_gettime_relative()/1000000.0;
1462 if (time < is->frame_timer + delay && !redisplay) {
1463 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1467 is->frame_timer += delay;
1468 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1469 is->frame_timer = time;
1471 SDL_LockMutex(is->pictq.mutex);
1472 if (!redisplay && !isnan(vp->pts))
1473 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1474 SDL_UnlockMutex(is->pictq.mutex);
1476 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1477 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1478 duration = vp_duration(is, vp, nextvp);
1479 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1481 is->frame_drops_late++;
1482 frame_queue_next(&is->pictq);
1488 if (is->subtitle_st) {
1489 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1490 sp = frame_queue_peek(&is->subpq);
1492 if (frame_queue_nb_remaining(&is->subpq) > 1)
1493 sp2 = frame_queue_peek_next(&is->subpq);
1497 if (sp->serial != is->subtitleq.serial
1498 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1499 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1501 frame_queue_next(&is->subpq);
1509 /* display picture */
1510 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1513 frame_queue_next(&is->pictq);
1515 if (is->step && !is->paused)
1516 stream_toggle_pause(is);
1519 is->force_refresh = 0;
1521 static int64_t last_time;
1523 int aqsize, vqsize, sqsize;
1526 cur_time = av_gettime_relative();
1527 if (!last_time || (cur_time - last_time) >= 30000) {
1532 aqsize = is->audioq.size;
1534 vqsize = is->videoq.size;
1535 if (is->subtitle_st)
1536 sqsize = is->subtitleq.size;
1538 if (is->audio_st && is->video_st)
1539 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1540 else if (is->video_st)
1541 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1542 else if (is->audio_st)
1543 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1544 av_log(NULL, AV_LOG_INFO,
1545 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1546 get_master_clock(is),
1547 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1549 is->frame_drops_early + is->frame_drops_late,
1553 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1554 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1556 last_time = cur_time;
1561 /* allocate a picture (needs to do that in main thread to avoid
1562 potential locking problems */
1563 static void alloc_picture(VideoState *is)
1568 vp = &is->pictq.queue[is->pictq.windex];
1572 video_open(is, 0, vp);
1574 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1577 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1578 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1579 /* SDL allocates a buffer smaller than requested if the video
1580 * overlay hardware is unable to support the requested size. */
1581 av_log(NULL, AV_LOG_FATAL,
1582 "Error: the video system does not support an image\n"
1583 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1584 "to reduce the image size.\n", vp->width, vp->height );
1588 SDL_LockMutex(is->pictq.mutex);
1590 SDL_CondSignal(is->pictq.cond);
1591 SDL_UnlockMutex(is->pictq.mutex);
1594 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1595 int i, width, height;
1597 for (i = 0; i < 3; i++) {
1604 if (bmp->pitches[i] > width) {
1605 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1606 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1612 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1616 #if defined(DEBUG_SYNC) && 0
1617 printf("frame_type=%c pts=%0.3f\n",
1618 av_get_picture_type_char(src_frame->pict_type), pts);
1621 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1624 vp->sar = src_frame->sample_aspect_ratio;
1626 /* alloc or resize hardware picture buffer */
1627 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1628 vp->width != src_frame->width ||
1629 vp->height != src_frame->height) {
1634 vp->width = src_frame->width;
1635 vp->height = src_frame->height;
1637 /* the allocation must be done in the main thread to avoid
1638 locking problems. */
1639 event.type = FF_ALLOC_EVENT;
1640 event.user.data1 = is;
1641 SDL_PushEvent(&event);
1643 /* wait until the picture is allocated */
1644 SDL_LockMutex(is->pictq.mutex);
1645 while (!vp->allocated && !is->videoq.abort_request) {
1646 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1648 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1649 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1650 while (!vp->allocated && !is->abort_request) {
1651 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1654 SDL_UnlockMutex(is->pictq.mutex);
1656 if (is->videoq.abort_request)
1660 /* if the frame is not skipped, then display it */
1662 AVPicture pict = { { 0 } };
1664 /* get a pointer on the bitmap */
1665 SDL_LockYUVOverlay (vp->bmp);
1667 pict.data[0] = vp->bmp->pixels[0];
1668 pict.data[1] = vp->bmp->pixels[2];
1669 pict.data[2] = vp->bmp->pixels[1];
1671 pict.linesize[0] = vp->bmp->pitches[0];
1672 pict.linesize[1] = vp->bmp->pitches[2];
1673 pict.linesize[2] = vp->bmp->pitches[1];
1676 // FIXME use direct rendering
1677 av_picture_copy(&pict, (AVPicture *)src_frame,
1678 src_frame->format, vp->width, vp->height);
1680 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1681 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1682 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1683 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1684 if (!is->img_convert_ctx) {
1685 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1688 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1689 0, vp->height, pict.data, pict.linesize);
1691 /* workaround SDL PITCH_WORKAROUND */
1692 duplicate_right_border_pixels(vp->bmp);
1693 /* update the bitmap content */
1694 SDL_UnlockYUVOverlay(vp->bmp);
1697 vp->duration = duration;
1699 vp->serial = serial;
1701 /* now we can update the picture count */
1702 frame_queue_push(&is->pictq);
1707 static int get_video_frame(VideoState *is, AVFrame *frame)
1711 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1717 if (frame->pts != AV_NOPTS_VALUE)
1718 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1720 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1722 is->viddec_width = frame->width;
1723 is->viddec_height = frame->height;
1725 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1726 if (frame->pts != AV_NOPTS_VALUE) {
1727 double diff = dpts - get_master_clock(is);
1728 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1729 diff - is->frame_last_filter_delay < 0 &&
1730 is->viddec.pkt_serial == is->vidclk.serial &&
1731 is->videoq.nb_packets) {
1732 is->frame_drops_early++;
1733 av_frame_unref(frame);
1744 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1745 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1748 int nb_filters = graph->nb_filters;
1749 AVFilterInOut *outputs = NULL, *inputs = NULL;
1752 outputs = avfilter_inout_alloc();
1753 inputs = avfilter_inout_alloc();
1754 if (!outputs || !inputs) {
1755 ret = AVERROR(ENOMEM);
1759 outputs->name = av_strdup("in");
1760 outputs->filter_ctx = source_ctx;
1761 outputs->pad_idx = 0;
1762 outputs->next = NULL;
1764 inputs->name = av_strdup("out");
1765 inputs->filter_ctx = sink_ctx;
1766 inputs->pad_idx = 0;
1767 inputs->next = NULL;
1769 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1772 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1776 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1777 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1778 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1780 ret = avfilter_graph_config(graph, NULL);
1782 avfilter_inout_free(&outputs);
1783 avfilter_inout_free(&inputs);
1787 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1789 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1790 char sws_flags_str[128];
1791 char buffersrc_args[256];
1793 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1794 AVCodecContext *codec = is->video_st->codec;
1795 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1797 av_opt_get_int(sws_opts, "sws_flags", 0, &sws_flags);
1798 snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%"PRId64, sws_flags);
1799 graph->scale_sws_opts = av_strdup(sws_flags_str);
1801 snprintf(buffersrc_args, sizeof(buffersrc_args),
1802 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1803 frame->width, frame->height, frame->format,
1804 is->video_st->time_base.num, is->video_st->time_base.den,
1805 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1806 if (fr.num && fr.den)
1807 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1809 if ((ret = avfilter_graph_create_filter(&filt_src,
1810 avfilter_get_by_name("buffer"),
1811 "ffplay_buffer", buffersrc_args, NULL,
1815 ret = avfilter_graph_create_filter(&filt_out,
1816 avfilter_get_by_name("buffersink"),
1817 "ffplay_buffersink", NULL, NULL, graph);
1821 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1824 last_filter = filt_out;
1826 /* Note: this macro adds a filter before the lastly added filter, so the
1827 * processing order of the filters is in reverse */
1828 #define INSERT_FILT(name, arg) do { \
1829 AVFilterContext *filt_ctx; \
1831 ret = avfilter_graph_create_filter(&filt_ctx, \
1832 avfilter_get_by_name(name), \
1833 "ffplay_" name, arg, NULL, graph); \
1837 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1841 last_filter = filt_ctx; \
1844 /* SDL YUV code is not handling odd width/height for some driver
1845 * combinations, therefore we crop the picture to an even width/height. */
1846 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1849 double theta = get_rotation(is->video_st);
1851 if (fabs(theta - 90) < 1.0) {
1852 INSERT_FILT("transpose", "clock");
1853 } else if (fabs(theta - 180) < 1.0) {
1854 INSERT_FILT("hflip", NULL);
1855 INSERT_FILT("vflip", NULL);
1856 } else if (fabs(theta - 270) < 1.0) {
1857 INSERT_FILT("transpose", "cclock");
1858 } else if (fabs(theta) > 1.0) {
1859 char rotate_buf[64];
1860 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1861 INSERT_FILT("rotate", rotate_buf);
1865 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1868 is->in_video_filter = filt_src;
1869 is->out_video_filter = filt_out;
1875 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1877 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1878 int sample_rates[2] = { 0, -1 };
1879 int64_t channel_layouts[2] = { 0, -1 };
1880 int channels[2] = { 0, -1 };
1881 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1882 char aresample_swr_opts[512] = "";
1883 AVDictionaryEntry *e = NULL;
1884 char asrc_args[256];
1887 avfilter_graph_free(&is->agraph);
1888 if (!(is->agraph = avfilter_graph_alloc()))
1889 return AVERROR(ENOMEM);
1891 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1892 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1893 if (strlen(aresample_swr_opts))
1894 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1895 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1897 ret = snprintf(asrc_args, sizeof(asrc_args),
1898 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1899 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1900 is->audio_filter_src.channels,
1901 1, is->audio_filter_src.freq);
1902 if (is->audio_filter_src.channel_layout)
1903 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1904 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1906 ret = avfilter_graph_create_filter(&filt_asrc,
1907 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1908 asrc_args, NULL, is->agraph);
1913 ret = avfilter_graph_create_filter(&filt_asink,
1914 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1915 NULL, NULL, is->agraph);
1919 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1921 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1924 if (force_output_format) {
1925 channel_layouts[0] = is->audio_tgt.channel_layout;
1926 channels [0] = is->audio_tgt.channels;
1927 sample_rates [0] = is->audio_tgt.freq;
1928 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1930 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1932 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1934 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1939 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1942 is->in_audio_filter = filt_asrc;
1943 is->out_audio_filter = filt_asink;
1947 avfilter_graph_free(&is->agraph);
1950 #endif /* CONFIG_AVFILTER */
1952 static int audio_thread(void *arg)
1954 VideoState *is = arg;
1955 AVFrame *frame = av_frame_alloc();
1958 int last_serial = -1;
1959 int64_t dec_channel_layout;
1967 return AVERROR(ENOMEM);
1970 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1974 tb = (AVRational){1, frame->sample_rate};
1977 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1980 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1981 frame->format, av_frame_get_channels(frame)) ||
1982 is->audio_filter_src.channel_layout != dec_channel_layout ||
1983 is->audio_filter_src.freq != frame->sample_rate ||
1984 is->auddec.pkt_serial != last_serial;
1987 char buf1[1024], buf2[1024];
1988 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1989 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1990 av_log(NULL, AV_LOG_DEBUG,
1991 "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",
1992 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
1993 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
1995 is->audio_filter_src.fmt = frame->format;
1996 is->audio_filter_src.channels = av_frame_get_channels(frame);
1997 is->audio_filter_src.channel_layout = dec_channel_layout;
1998 is->audio_filter_src.freq = frame->sample_rate;
1999 last_serial = is->auddec.pkt_serial;
2001 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2005 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2008 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2009 tb = is->out_audio_filter->inputs[0]->time_base;
2011 if (!(af = frame_queue_peek_writable(&is->sampq)))
2014 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2015 af->pos = av_frame_get_pkt_pos(frame);
2016 af->serial = is->auddec.pkt_serial;
2017 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2019 av_frame_move_ref(af->frame, frame);
2020 frame_queue_push(&is->sampq);
2023 if (is->audioq.serial != is->auddec.pkt_serial)
2026 if (ret == AVERROR_EOF)
2027 is->auddec.finished = is->auddec.pkt_serial;
2030 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2033 avfilter_graph_free(&is->agraph);
2035 av_frame_free(&frame);
2039 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2041 packet_queue_start(d->queue);
2042 d->decoder_tid = SDL_CreateThread(fn, arg);
2045 static int video_thread(void *arg)
2047 VideoState *is = arg;
2048 AVFrame *frame = av_frame_alloc();
2052 AVRational tb = is->video_st->time_base;
2053 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2056 AVFilterGraph *graph = avfilter_graph_alloc();
2057 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2060 enum AVPixelFormat last_format = -2;
2061 int last_serial = -1;
2062 int last_vfilter_idx = 0;
2064 av_frame_free(&frame);
2065 return AVERROR(ENOMEM);
2072 avfilter_graph_free(&graph);
2074 return AVERROR(ENOMEM);
2078 ret = get_video_frame(is, frame);
2085 if ( last_w != frame->width
2086 || last_h != frame->height
2087 || last_format != frame->format
2088 || last_serial != is->viddec.pkt_serial
2089 || last_vfilter_idx != is->vfilter_idx) {
2090 av_log(NULL, AV_LOG_DEBUG,
2091 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2093 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2094 frame->width, frame->height,
2095 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2096 avfilter_graph_free(&graph);
2097 graph = avfilter_graph_alloc();
2098 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2100 event.type = FF_QUIT_EVENT;
2101 event.user.data1 = is;
2102 SDL_PushEvent(&event);
2105 filt_in = is->in_video_filter;
2106 filt_out = is->out_video_filter;
2107 last_w = frame->width;
2108 last_h = frame->height;
2109 last_format = frame->format;
2110 last_serial = is->viddec.pkt_serial;
2111 last_vfilter_idx = is->vfilter_idx;
2112 frame_rate = filt_out->inputs[0]->frame_rate;
2115 ret = av_buffersrc_add_frame(filt_in, frame);
2120 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2122 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2124 if (ret == AVERROR_EOF)
2125 is->viddec.finished = is->viddec.pkt_serial;
2130 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2131 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2132 is->frame_last_filter_delay = 0;
2133 tb = filt_out->inputs[0]->time_base;
2135 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2136 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2137 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2138 av_frame_unref(frame);
2148 avfilter_graph_free(&graph);
2150 av_frame_free(&frame);
2154 static int subtitle_thread(void *arg)
2156 VideoState *is = arg;
2163 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2166 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2171 if (got_subtitle && sp->sub.format == 0) {
2172 if (sp->sub.pts != AV_NOPTS_VALUE)
2173 pts = sp->sub.pts / (double)AV_TIME_BASE;
2175 sp->serial = is->subdec.pkt_serial;
2177 for (i = 0; i < sp->sub.num_rects; i++)
2179 int in_w = sp->sub.rects[i]->w;
2180 int in_h = sp->sub.rects[i]->h;
2181 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2182 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2183 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2184 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2187 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2188 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2189 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2190 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2191 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2192 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2194 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2195 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2196 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2197 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2198 !newpic.data[1] || !newpic.data[2]
2200 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2203 sws_scale(is->sub_convert_ctx,
2204 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2205 0, in_h, newpic.data, newpic.linesize);
2207 av_free(sp->sub.rects[i]->pict.data[0]);
2208 av_free(sp->sub.rects[i]->pict.data[1]);
2209 sp->sub.rects[i]->pict = newpic;
2210 sp->sub.rects[i]->w = out_w;
2211 sp->sub.rects[i]->h = out_h;
2212 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2213 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2216 /* now we can update the picture count */
2217 frame_queue_push(&is->subpq);
2218 } else if (got_subtitle) {
2219 avsubtitle_free(&sp->sub);
2225 /* copy samples for viewing in editor window */
2226 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2230 size = samples_size / sizeof(short);
2232 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2235 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2237 is->sample_array_index += len;
2238 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2239 is->sample_array_index = 0;
2244 /* return the wanted number of samples to get better sync if sync_type is video
2245 * or external master clock */
2246 static int synchronize_audio(VideoState *is, int nb_samples)
2248 int wanted_nb_samples = nb_samples;
2250 /* if not master, then we try to remove or add samples to correct the clock */
2251 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2252 double diff, avg_diff;
2253 int min_nb_samples, max_nb_samples;
2255 diff = get_clock(&is->audclk) - get_master_clock(is);
2257 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2258 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2259 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2260 /* not enough measures to have a correct estimate */
2261 is->audio_diff_avg_count++;
2263 /* estimate the A-V difference */
2264 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2266 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2267 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2268 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2269 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2270 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2272 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2273 diff, avg_diff, wanted_nb_samples - nb_samples,
2274 is->audio_clock, is->audio_diff_threshold);
2277 /* too big difference : may be initial PTS errors, so
2279 is->audio_diff_avg_count = 0;
2280 is->audio_diff_cum = 0;
2284 return wanted_nb_samples;
2288 * Decode one audio frame and return its uncompressed size.
2290 * The processed audio frame is decoded, converted if required, and
2291 * stored in is->audio_buf, with size in bytes given by the return
2294 static int audio_decode_frame(VideoState *is)
2296 int data_size, resampled_data_size;
2297 int64_t dec_channel_layout;
2298 av_unused double audio_clock0;
2299 int wanted_nb_samples;
2307 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2308 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2313 if (!(af = frame_queue_peek_readable(&is->sampq)))
2315 frame_queue_next(&is->sampq);
2316 } while (af->serial != is->audioq.serial);
2318 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2319 af->frame->nb_samples,
2320 af->frame->format, 1);
2322 dec_channel_layout =
2323 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2324 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2325 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2327 if (af->frame->format != is->audio_src.fmt ||
2328 dec_channel_layout != is->audio_src.channel_layout ||
2329 af->frame->sample_rate != is->audio_src.freq ||
2330 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2331 swr_free(&is->swr_ctx);
2332 is->swr_ctx = swr_alloc_set_opts(NULL,
2333 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2334 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2336 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2337 av_log(NULL, AV_LOG_ERROR,
2338 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2339 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2340 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2341 swr_free(&is->swr_ctx);
2344 is->audio_src.channel_layout = dec_channel_layout;
2345 is->audio_src.channels = av_frame_get_channels(af->frame);
2346 is->audio_src.freq = af->frame->sample_rate;
2347 is->audio_src.fmt = af->frame->format;
2351 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2352 uint8_t **out = &is->audio_buf1;
2353 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2354 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2357 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2360 if (wanted_nb_samples != af->frame->nb_samples) {
2361 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2362 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2363 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2367 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2368 if (!is->audio_buf1)
2369 return AVERROR(ENOMEM);
2370 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2372 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2375 if (len2 == out_count) {
2376 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2377 if (swr_init(is->swr_ctx) < 0)
2378 swr_free(&is->swr_ctx);
2380 is->audio_buf = is->audio_buf1;
2381 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2383 is->audio_buf = af->frame->data[0];
2384 resampled_data_size = data_size;
2387 audio_clock0 = is->audio_clock;
2388 /* update the audio clock with the pts */
2389 if (!isnan(af->pts))
2390 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2392 is->audio_clock = NAN;
2393 is->audio_clock_serial = af->serial;
2396 static double last_clock;
2397 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2398 is->audio_clock - last_clock,
2399 is->audio_clock, audio_clock0);
2400 last_clock = is->audio_clock;
2403 return resampled_data_size;
2406 /* prepare a new audio buffer */
2407 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2409 VideoState *is = opaque;
2410 int audio_size, len1;
2412 audio_callback_time = av_gettime_relative();
2415 if (is->audio_buf_index >= is->audio_buf_size) {
2416 audio_size = audio_decode_frame(is);
2417 if (audio_size < 0) {
2418 /* if error, just output silence */
2419 is->audio_buf = is->silence_buf;
2420 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2422 if (is->show_mode != SHOW_MODE_VIDEO)
2423 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2424 is->audio_buf_size = audio_size;
2426 is->audio_buf_index = 0;
2428 len1 = is->audio_buf_size - is->audio_buf_index;
2431 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2434 is->audio_buf_index += len1;
2436 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2437 /* Let's assume the audio driver that is used by SDL has two periods. */
2438 if (!isnan(is->audio_clock)) {
2439 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);
2440 sync_clock_to_slave(&is->extclk, &is->audclk);
2444 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2446 SDL_AudioSpec wanted_spec, spec;
2448 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2449 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2450 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2452 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2454 wanted_nb_channels = atoi(env);
2455 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2457 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2458 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2459 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2461 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2462 wanted_spec.channels = wanted_nb_channels;
2463 wanted_spec.freq = wanted_sample_rate;
2464 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2465 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2468 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2469 next_sample_rate_idx--;
2470 wanted_spec.format = AUDIO_S16SYS;
2471 wanted_spec.silence = 0;
2472 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2473 wanted_spec.callback = sdl_audio_callback;
2474 wanted_spec.userdata = opaque;
2475 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2476 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2477 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2478 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2479 if (!wanted_spec.channels) {
2480 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2481 wanted_spec.channels = wanted_nb_channels;
2482 if (!wanted_spec.freq) {
2483 av_log(NULL, AV_LOG_ERROR,
2484 "No more combinations to try, audio open failed\n");
2488 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2490 if (spec.format != AUDIO_S16SYS) {
2491 av_log(NULL, AV_LOG_ERROR,
2492 "SDL advised audio format %d is not supported!\n", spec.format);
2495 if (spec.channels != wanted_spec.channels) {
2496 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2497 if (!wanted_channel_layout) {
2498 av_log(NULL, AV_LOG_ERROR,
2499 "SDL advised channel count %d is not supported!\n", spec.channels);
2504 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2505 audio_hw_params->freq = spec.freq;
2506 audio_hw_params->channel_layout = wanted_channel_layout;
2507 audio_hw_params->channels = spec.channels;
2508 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2509 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);
2510 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2511 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2517 /* open a given stream. Return 0 if OK */
2518 static int stream_component_open(VideoState *is, int stream_index)
2520 AVFormatContext *ic = is->ic;
2521 AVCodecContext *avctx;
2523 const char *forced_codec_name = NULL;
2525 AVDictionaryEntry *t = NULL;
2526 int sample_rate, nb_channels;
2527 int64_t channel_layout;
2529 int stream_lowres = lowres;
2531 if (stream_index < 0 || stream_index >= ic->nb_streams)
2533 avctx = ic->streams[stream_index]->codec;
2535 codec = avcodec_find_decoder(avctx->codec_id);
2537 switch(avctx->codec_type){
2538 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2539 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2540 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2542 if (forced_codec_name)
2543 codec = avcodec_find_decoder_by_name(forced_codec_name);
2545 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2546 "No codec could be found with name '%s'\n", forced_codec_name);
2547 else av_log(NULL, AV_LOG_WARNING,
2548 "No codec could be found with id %d\n", avctx->codec_id);
2552 avctx->codec_id = codec->id;
2553 if(stream_lowres > av_codec_get_max_lowres(codec)){
2554 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2555 av_codec_get_max_lowres(codec));
2556 stream_lowres = av_codec_get_max_lowres(codec);
2558 av_codec_set_lowres(avctx, stream_lowres);
2560 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2562 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2563 if(codec->capabilities & AV_CODEC_CAP_DR1)
2564 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2566 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2567 if (!av_dict_get(opts, "threads", NULL, 0))
2568 av_dict_set(&opts, "threads", "auto", 0);
2570 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2571 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2572 av_dict_set(&opts, "refcounted_frames", "1", 0);
2573 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2576 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2577 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2578 ret = AVERROR_OPTION_NOT_FOUND;
2583 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2584 switch (avctx->codec_type) {
2585 case AVMEDIA_TYPE_AUDIO:
2590 is->audio_filter_src.freq = avctx->sample_rate;
2591 is->audio_filter_src.channels = avctx->channels;
2592 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2593 is->audio_filter_src.fmt = avctx->sample_fmt;
2594 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2596 link = is->out_audio_filter->inputs[0];
2597 sample_rate = link->sample_rate;
2598 nb_channels = link->channels;
2599 channel_layout = link->channel_layout;
2602 sample_rate = avctx->sample_rate;
2603 nb_channels = avctx->channels;
2604 channel_layout = avctx->channel_layout;
2607 /* prepare audio output */
2608 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2610 is->audio_hw_buf_size = ret;
2611 is->audio_src = is->audio_tgt;
2612 is->audio_buf_size = 0;
2613 is->audio_buf_index = 0;
2615 /* init averaging filter */
2616 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2617 is->audio_diff_avg_count = 0;
2618 /* since we do not have a precise anough audio fifo fullness,
2619 we correct audio sync only if larger than this threshold */
2620 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2622 is->audio_stream = stream_index;
2623 is->audio_st = ic->streams[stream_index];
2625 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2626 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2627 is->auddec.start_pts = is->audio_st->start_time;
2628 is->auddec.start_pts_tb = is->audio_st->time_base;
2630 decoder_start(&is->auddec, audio_thread, is);
2633 case AVMEDIA_TYPE_VIDEO:
2634 is->video_stream = stream_index;
2635 is->video_st = ic->streams[stream_index];
2637 is->viddec_width = avctx->width;
2638 is->viddec_height = avctx->height;
2640 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2641 decoder_start(&is->viddec, video_thread, is);
2642 is->queue_attachments_req = 1;
2644 case AVMEDIA_TYPE_SUBTITLE:
2645 is->subtitle_stream = stream_index;
2646 is->subtitle_st = ic->streams[stream_index];
2648 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2649 decoder_start(&is->subdec, subtitle_thread, is);
2656 av_dict_free(&opts);
2661 static void stream_component_close(VideoState *is, int stream_index)
2663 AVFormatContext *ic = is->ic;
2664 AVCodecContext *avctx;
2666 if (stream_index < 0 || stream_index >= ic->nb_streams)
2668 avctx = ic->streams[stream_index]->codec;
2670 switch (avctx->codec_type) {
2671 case AVMEDIA_TYPE_AUDIO:
2672 decoder_abort(&is->auddec, &is->sampq);
2674 decoder_destroy(&is->auddec);
2675 swr_free(&is->swr_ctx);
2676 av_freep(&is->audio_buf1);
2677 is->audio_buf1_size = 0;
2678 is->audio_buf = NULL;
2681 av_rdft_end(is->rdft);
2682 av_freep(&is->rdft_data);
2687 case AVMEDIA_TYPE_VIDEO:
2688 decoder_abort(&is->viddec, &is->pictq);
2689 decoder_destroy(&is->viddec);
2691 case AVMEDIA_TYPE_SUBTITLE:
2692 decoder_abort(&is->subdec, &is->subpq);
2693 decoder_destroy(&is->subdec);
2699 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2700 avcodec_close(avctx);
2701 switch (avctx->codec_type) {
2702 case AVMEDIA_TYPE_AUDIO:
2703 is->audio_st = NULL;
2704 is->audio_stream = -1;
2706 case AVMEDIA_TYPE_VIDEO:
2707 is->video_st = NULL;
2708 is->video_stream = -1;
2710 case AVMEDIA_TYPE_SUBTITLE:
2711 is->subtitle_st = NULL;
2712 is->subtitle_stream = -1;
2719 static int decode_interrupt_cb(void *ctx)
2721 VideoState *is = ctx;
2722 return is->abort_request;
2725 static int is_realtime(AVFormatContext *s)
2727 if( !strcmp(s->iformat->name, "rtp")
2728 || !strcmp(s->iformat->name, "rtsp")
2729 || !strcmp(s->iformat->name, "sdp")
2733 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2734 || !strncmp(s->filename, "udp:", 4)
2741 /* this thread gets the stream from the disk or the network */
2742 static int read_thread(void *arg)
2744 VideoState *is = arg;
2745 AVFormatContext *ic = NULL;
2747 int st_index[AVMEDIA_TYPE_NB];
2748 AVPacket pkt1, *pkt = &pkt1;
2749 int64_t stream_start_time;
2750 int pkt_in_play_range = 0;
2751 AVDictionaryEntry *t;
2752 AVDictionary **opts;
2753 int orig_nb_streams;
2754 SDL_mutex *wait_mutex = SDL_CreateMutex();
2755 int scan_all_pmts_set = 0;
2758 memset(st_index, -1, sizeof(st_index));
2759 is->last_video_stream = is->video_stream = -1;
2760 is->last_audio_stream = is->audio_stream = -1;
2761 is->last_subtitle_stream = is->subtitle_stream = -1;
2764 ic = avformat_alloc_context();
2766 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2767 ret = AVERROR(ENOMEM);
2770 ic->interrupt_callback.callback = decode_interrupt_cb;
2771 ic->interrupt_callback.opaque = is;
2772 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2773 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2774 scan_all_pmts_set = 1;
2776 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2778 print_error(is->filename, err);
2782 if (scan_all_pmts_set)
2783 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2785 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2786 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2787 ret = AVERROR_OPTION_NOT_FOUND;
2793 ic->flags |= AVFMT_FLAG_GENPTS;
2795 av_format_inject_global_side_data(ic);
2797 opts = setup_find_stream_info_opts(ic, codec_opts);
2798 orig_nb_streams = ic->nb_streams;
2800 err = avformat_find_stream_info(ic, opts);
2802 for (i = 0; i < orig_nb_streams; i++)
2803 av_dict_free(&opts[i]);
2807 av_log(NULL, AV_LOG_WARNING,
2808 "%s: could not find codec parameters\n", is->filename);
2814 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2816 if (seek_by_bytes < 0)
2817 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2819 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2821 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2822 window_title = av_asprintf("%s - %s", t->value, input_filename);
2824 /* if seeking requested, we execute it */
2825 if (start_time != AV_NOPTS_VALUE) {
2828 timestamp = start_time;
2829 /* add the stream start time */
2830 if (ic->start_time != AV_NOPTS_VALUE)
2831 timestamp += ic->start_time;
2832 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2834 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2835 is->filename, (double)timestamp / AV_TIME_BASE);
2839 is->realtime = is_realtime(ic);
2842 av_dump_format(ic, 0, is->filename, 0);
2844 for (i = 0; i < ic->nb_streams; i++) {
2845 AVStream *st = ic->streams[i];
2846 enum AVMediaType type = st->codec->codec_type;
2847 st->discard = AVDISCARD_ALL;
2848 if (wanted_stream_spec[type] && st_index[type] == -1)
2849 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2852 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2853 if (wanted_stream_spec[i] && st_index[i] == -1) {
2854 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));
2855 st_index[i] = INT_MAX;
2860 st_index[AVMEDIA_TYPE_VIDEO] =
2861 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2862 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2864 st_index[AVMEDIA_TYPE_AUDIO] =
2865 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2866 st_index[AVMEDIA_TYPE_AUDIO],
2867 st_index[AVMEDIA_TYPE_VIDEO],
2869 if (!video_disable && !subtitle_disable)
2870 st_index[AVMEDIA_TYPE_SUBTITLE] =
2871 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2872 st_index[AVMEDIA_TYPE_SUBTITLE],
2873 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2874 st_index[AVMEDIA_TYPE_AUDIO] :
2875 st_index[AVMEDIA_TYPE_VIDEO]),
2878 is->show_mode = show_mode;
2879 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2880 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2881 AVCodecContext *avctx = st->codec;
2882 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2884 set_default_window_size(avctx->width, avctx->height, sar);
2887 /* open the streams */
2888 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2889 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2893 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2894 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2896 if (is->show_mode == SHOW_MODE_NONE)
2897 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2899 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2900 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2903 if (is->video_stream < 0 && is->audio_stream < 0) {
2904 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2910 if (infinite_buffer < 0 && is->realtime)
2911 infinite_buffer = 1;
2914 if (is->abort_request)
2916 if (is->paused != is->last_paused) {
2917 is->last_paused = is->paused;
2919 is->read_pause_return = av_read_pause(ic);
2923 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2925 (!strcmp(ic->iformat->name, "rtsp") ||
2926 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2927 /* wait 10 ms to avoid trying to get another packet */
2934 int64_t seek_target = is->seek_pos;
2935 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2936 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2937 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2938 // of the seek_pos/seek_rel variables
2940 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2942 av_log(NULL, AV_LOG_ERROR,
2943 "%s: error while seeking\n", is->ic->filename);
2945 if (is->audio_stream >= 0) {
2946 packet_queue_flush(&is->audioq);
2947 packet_queue_put(&is->audioq, &flush_pkt);
2949 if (is->subtitle_stream >= 0) {
2950 packet_queue_flush(&is->subtitleq);
2951 packet_queue_put(&is->subtitleq, &flush_pkt);
2953 if (is->video_stream >= 0) {
2954 packet_queue_flush(&is->videoq);
2955 packet_queue_put(&is->videoq, &flush_pkt);
2957 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2958 set_clock(&is->extclk, NAN, 0);
2960 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2964 is->queue_attachments_req = 1;
2967 step_to_next_frame(is);
2969 if (is->queue_attachments_req) {
2970 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2972 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
2974 packet_queue_put(&is->videoq, ©);
2975 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2977 is->queue_attachments_req = 0;
2980 /* if the queue are full, no need to read more */
2981 if (infinite_buffer<1 &&
2982 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2983 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
2984 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
2985 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
2986 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
2988 SDL_LockMutex(wait_mutex);
2989 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2990 SDL_UnlockMutex(wait_mutex);
2994 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2995 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2996 if (loop != 1 && (!loop || --loop)) {
2997 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2998 } else if (autoexit) {
3003 ret = av_read_frame(ic, pkt);
3005 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3006 if (is->video_stream >= 0)
3007 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3008 if (is->audio_stream >= 0)
3009 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3010 if (is->subtitle_stream >= 0)
3011 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3014 if (ic->pb && ic->pb->error)
3016 SDL_LockMutex(wait_mutex);
3017 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3018 SDL_UnlockMutex(wait_mutex);
3023 /* check if packet is in play range specified by user, then queue, otherwise discard */
3024 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3025 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3026 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3027 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3028 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3029 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3030 <= ((double)duration / 1000000);
3031 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3032 packet_queue_put(&is->audioq, pkt);
3033 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3034 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3035 packet_queue_put(&is->videoq, pkt);
3036 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3037 packet_queue_put(&is->subtitleq, pkt);
3039 av_free_packet(pkt);
3042 /* wait until the end */
3043 while (!is->abort_request) {
3049 /* close each stream */
3050 if (is->audio_stream >= 0)
3051 stream_component_close(is, is->audio_stream);
3052 if (is->video_stream >= 0)
3053 stream_component_close(is, is->video_stream);
3054 if (is->subtitle_stream >= 0)
3055 stream_component_close(is, is->subtitle_stream);
3057 avformat_close_input(&ic);
3064 event.type = FF_QUIT_EVENT;
3065 event.user.data1 = is;
3066 SDL_PushEvent(&event);
3068 SDL_DestroyMutex(wait_mutex);
3072 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3076 is = av_mallocz(sizeof(VideoState));
3079 av_strlcpy(is->filename, filename, sizeof(is->filename));
3080 is->iformat = iformat;
3084 /* start video display */
3085 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3087 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3089 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3092 packet_queue_init(&is->videoq);
3093 packet_queue_init(&is->audioq);
3094 packet_queue_init(&is->subtitleq);
3096 is->continue_read_thread = SDL_CreateCond();
3098 init_clock(&is->vidclk, &is->videoq.serial);
3099 init_clock(&is->audclk, &is->audioq.serial);
3100 init_clock(&is->extclk, &is->extclk.serial);
3101 is->audio_clock_serial = -1;
3102 is->av_sync_type = av_sync_type;
3103 is->read_tid = SDL_CreateThread(read_thread, is);
3104 if (!is->read_tid) {
3112 static void stream_cycle_channel(VideoState *is, int codec_type)
3114 AVFormatContext *ic = is->ic;
3115 int start_index, stream_index;
3118 AVProgram *p = NULL;
3119 int nb_streams = is->ic->nb_streams;
3121 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3122 start_index = is->last_video_stream;
3123 old_index = is->video_stream;
3124 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3125 start_index = is->last_audio_stream;
3126 old_index = is->audio_stream;
3128 start_index = is->last_subtitle_stream;
3129 old_index = is->subtitle_stream;
3131 stream_index = start_index;
3133 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3134 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3136 nb_streams = p->nb_stream_indexes;
3137 for (start_index = 0; start_index < nb_streams; start_index++)
3138 if (p->stream_index[start_index] == stream_index)
3140 if (start_index == nb_streams)
3142 stream_index = start_index;
3147 if (++stream_index >= nb_streams)
3149 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3152 is->last_subtitle_stream = -1;
3155 if (start_index == -1)
3159 if (stream_index == start_index)
3161 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3162 if (st->codec->codec_type == codec_type) {
3163 /* check that parameters are OK */
3164 switch (codec_type) {
3165 case AVMEDIA_TYPE_AUDIO:
3166 if (st->codec->sample_rate != 0 &&
3167 st->codec->channels != 0)
3170 case AVMEDIA_TYPE_VIDEO:
3171 case AVMEDIA_TYPE_SUBTITLE:
3179 if (p && stream_index != -1)
3180 stream_index = p->stream_index[stream_index];
3181 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3182 av_get_media_type_string(codec_type),
3186 stream_component_close(is, old_index);
3187 stream_component_open(is, stream_index);
3191 static void toggle_full_screen(VideoState *is)
3193 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3194 /* OS X needs to reallocate the SDL overlays */
3196 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3197 is->pictq.queue[i].reallocate = 1;
3199 is_full_screen = !is_full_screen;
3200 video_open(is, 1, NULL);
3203 static void toggle_audio_display(VideoState *is)
3205 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3206 int next = is->show_mode;
3208 next = (next + 1) % SHOW_MODE_NB;
3209 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3210 if (is->show_mode != next) {
3211 fill_rectangle(screen,
3212 is->xleft, is->ytop, is->width, is->height,
3214 is->force_refresh = 1;
3215 is->show_mode = next;
3219 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3220 double remaining_time = 0.0;
3222 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3223 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3227 if (remaining_time > 0.0)
3228 av_usleep((int64_t)(remaining_time * 1000000.0));
3229 remaining_time = REFRESH_RATE;
3230 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3231 video_refresh(is, &remaining_time);
3236 static void seek_chapter(VideoState *is, int incr)
3238 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3241 if (!is->ic->nb_chapters)
3244 /* find the current chapter */
3245 for (i = 0; i < is->ic->nb_chapters; i++) {
3246 AVChapter *ch = is->ic->chapters[i];
3247 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3255 if (i >= is->ic->nb_chapters)
3258 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3259 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3260 AV_TIME_BASE_Q), 0, 0);
3263 /* handle an event sent by the GUI */
3264 static void event_loop(VideoState *cur_stream)
3267 double incr, pos, frac;
3271 refresh_loop_wait_event(cur_stream, &event);
3272 switch (event.type) {
3274 if (exit_on_keydown) {
3275 do_exit(cur_stream);
3278 switch (event.key.keysym.sym) {
3281 do_exit(cur_stream);
3284 toggle_full_screen(cur_stream);
3285 cur_stream->force_refresh = 1;
3289 toggle_pause(cur_stream);
3291 case SDLK_s: // S: Step to next frame
3292 step_to_next_frame(cur_stream);
3295 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3298 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3301 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3302 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3303 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3306 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3310 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3311 if (++cur_stream->vfilter_idx >= nb_vfilters)
3312 cur_stream->vfilter_idx = 0;
3314 cur_stream->vfilter_idx = 0;
3315 toggle_audio_display(cur_stream);
3318 toggle_audio_display(cur_stream);
3322 if (cur_stream->ic->nb_chapters <= 1) {
3326 seek_chapter(cur_stream, 1);
3329 if (cur_stream->ic->nb_chapters <= 1) {
3333 seek_chapter(cur_stream, -1);
3347 if (seek_by_bytes) {
3349 if (pos < 0 && cur_stream->video_stream >= 0)
3350 pos = frame_queue_last_pos(&cur_stream->pictq);
3351 if (pos < 0 && cur_stream->audio_stream >= 0)
3352 pos = frame_queue_last_pos(&cur_stream->sampq);
3354 pos = avio_tell(cur_stream->ic->pb);
3355 if (cur_stream->ic->bit_rate)
3356 incr *= cur_stream->ic->bit_rate / 8.0;
3360 stream_seek(cur_stream, pos, incr, 1);
3362 pos = get_master_clock(cur_stream);
3364 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3366 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3367 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3368 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3375 case SDL_VIDEOEXPOSE:
3376 cur_stream->force_refresh = 1;
3378 case SDL_MOUSEBUTTONDOWN:
3379 if (exit_on_mousedown) {
3380 do_exit(cur_stream);
3383 case SDL_MOUSEMOTION:
3384 if (cursor_hidden) {
3388 cursor_last_shown = av_gettime_relative();
3389 if (event.type == SDL_MOUSEBUTTONDOWN) {
3392 if (event.motion.state != SDL_PRESSED)
3396 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3397 uint64_t size = avio_size(cur_stream->ic->pb);
3398 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3402 int tns, thh, tmm, tss;
3403 tns = cur_stream->ic->duration / 1000000LL;
3405 tmm = (tns % 3600) / 60;
3407 frac = x / cur_stream->width;
3410 mm = (ns % 3600) / 60;
3412 av_log(NULL, AV_LOG_INFO,
3413 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3414 hh, mm, ss, thh, tmm, tss);
3415 ts = frac * cur_stream->ic->duration;
3416 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3417 ts += cur_stream->ic->start_time;
3418 stream_seek(cur_stream, ts, 0, 0);
3421 case SDL_VIDEORESIZE:
3422 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3423 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3425 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3426 do_exit(cur_stream);
3428 screen_width = cur_stream->width = screen->w;
3429 screen_height = cur_stream->height = screen->h;
3430 cur_stream->force_refresh = 1;
3434 do_exit(cur_stream);
3436 case FF_ALLOC_EVENT:
3437 alloc_picture(event.user.data1);
3445 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3447 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3448 return opt_default(NULL, "video_size", arg);
3451 static int opt_width(void *optctx, const char *opt, const char *arg)
3453 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3457 static int opt_height(void *optctx, const char *opt, const char *arg)
3459 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3463 static int opt_format(void *optctx, const char *opt, const char *arg)
3465 file_iformat = av_find_input_format(arg);
3466 if (!file_iformat) {
3467 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3468 return AVERROR(EINVAL);
3473 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3475 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3476 return opt_default(NULL, "pixel_format", arg);
3479 static int opt_sync(void *optctx, const char *opt, const char *arg)
3481 if (!strcmp(arg, "audio"))
3482 av_sync_type = AV_SYNC_AUDIO_MASTER;
3483 else if (!strcmp(arg, "video"))
3484 av_sync_type = AV_SYNC_VIDEO_MASTER;
3485 else if (!strcmp(arg, "ext"))
3486 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3488 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3494 static int opt_seek(void *optctx, const char *opt, const char *arg)
3496 start_time = parse_time_or_die(opt, arg, 1);
3500 static int opt_duration(void *optctx, const char *opt, const char *arg)
3502 duration = parse_time_or_die(opt, arg, 1);
3506 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3508 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3509 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3510 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3511 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3515 static void opt_input_file(void *optctx, const char *filename)
3517 if (input_filename) {
3518 av_log(NULL, AV_LOG_FATAL,
3519 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3520 filename, input_filename);
3523 if (!strcmp(filename, "-"))
3525 input_filename = filename;
3528 static int opt_codec(void *optctx, const char *opt, const char *arg)
3530 const char *spec = strchr(opt, ':');
3532 av_log(NULL, AV_LOG_ERROR,
3533 "No media specifier was specified in '%s' in option '%s'\n",
3535 return AVERROR(EINVAL);
3539 case 'a' : audio_codec_name = arg; break;
3540 case 's' : subtitle_codec_name = arg; break;
3541 case 'v' : video_codec_name = arg; break;
3543 av_log(NULL, AV_LOG_ERROR,
3544 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3545 return AVERROR(EINVAL);
3552 static const OptionDef options[] = {
3553 #include "cmdutils_common_opts.h"
3554 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3555 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3556 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3557 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3558 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3559 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3560 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3561 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3562 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3563 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3564 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3565 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3566 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3567 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3568 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3569 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3570 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3571 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3572 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3573 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3574 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3575 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3576 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3577 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3578 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3579 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3580 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3581 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3582 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3584 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3585 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3587 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3588 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3589 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3590 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3591 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3592 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3593 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3594 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3595 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3599 static void show_usage(void)
3601 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3602 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3603 av_log(NULL, AV_LOG_INFO, "\n");
3606 void show_help_default(const char *opt, const char *arg)
3608 av_log_set_callback(log_callback_help);
3610 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3611 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3613 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3614 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3615 #if !CONFIG_AVFILTER
3616 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3618 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3620 printf("\nWhile playing:\n"
3622 "f toggle full screen\n"
3624 "a cycle audio channel in the current program\n"
3625 "v cycle video channel\n"
3626 "t cycle subtitle channel in the current program\n"
3628 "w cycle video filters or show modes\n"
3629 "s activate frame-step mode\n"
3630 "left/right seek backward/forward 10 seconds\n"
3631 "down/up seek backward/forward 1 minute\n"
3632 "page down/page up seek backward/forward 10 minutes\n"
3633 "mouse click seek to percentage in file corresponding to fraction of width\n"
3637 static int lockmgr(void **mtx, enum AVLockOp op)
3640 case AV_LOCK_CREATE:
3641 *mtx = SDL_CreateMutex();
3645 case AV_LOCK_OBTAIN:
3646 return !!SDL_LockMutex(*mtx);
3647 case AV_LOCK_RELEASE:
3648 return !!SDL_UnlockMutex(*mtx);
3649 case AV_LOCK_DESTROY:
3650 SDL_DestroyMutex(*mtx);
3656 /* Called from the main */
3657 int main(int argc, char **argv)
3661 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3663 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3664 parse_loglevel(argc, argv, options);
3666 /* register all codecs, demux and protocols */
3668 avdevice_register_all();
3671 avfilter_register_all();
3674 avformat_network_init();
3678 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3679 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3681 show_banner(argc, argv, options);
3683 parse_options(NULL, argc, argv, options, opt_input_file);
3685 if (!input_filename) {
3687 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3688 av_log(NULL, AV_LOG_FATAL,
3689 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3693 if (display_disable) {
3696 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3698 flags &= ~SDL_INIT_AUDIO;
3699 if (display_disable)
3700 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3701 #if !defined(_WIN32) && !defined(__APPLE__)
3702 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3704 if (SDL_Init (flags)) {
3705 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3706 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3710 if (!display_disable) {
3711 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3712 fs_screen_width = vi->current_w;
3713 fs_screen_height = vi->current_h;
3716 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3717 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3718 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3720 if (av_lockmgr_register(lockmgr)) {
3721 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3725 av_init_packet(&flush_pkt);
3726 flush_pkt.data = (uint8_t *)&flush_pkt;
3728 is = stream_open(input_filename, file_iformat);
3730 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");