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/eval.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/imgutils.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/samplefmt.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/time.h"
43 #include "libavformat/avformat.h"
44 #include "libavdevice/avdevice.h"
45 #include "libswscale/swscale.h"
46 #include "libavutil/opt.h"
47 #include "libavcodec/avfft.h"
48 #include "libswresample/swresample.h"
51 # include "libavfilter/avfilter.h"
52 # include "libavfilter/buffersink.h"
53 # include "libavfilter/buffersrc.h"
57 #include <SDL_thread.h>
63 const char program_name[] = "ffplay";
64 const int program_birth_year = 2003;
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
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 /* Step size for volume control */
77 #define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
79 /* no AV sync correction is done if below the minimum AV sync threshold */
80 #define AV_SYNC_THRESHOLD_MIN 0.04
81 /* AV sync correction is done if above the maximum AV sync threshold */
82 #define AV_SYNC_THRESHOLD_MAX 0.1
83 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
85 /* no AV correction is done if too big error */
86 #define AV_NOSYNC_THRESHOLD 10.0
88 /* maximum audio speed change to get correct sync */
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
91 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
96 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97 #define AUDIO_DIFF_AVG_NB 20
99 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
100 #define REFRESH_RATE 0.01
102 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
103 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 static unsigned sws_flags = SWS_BICUBIC;
110 typedef struct MyAVPacketList {
112 struct MyAVPacketList *next;
116 typedef struct PacketQueue {
117 MyAVPacketList *first_pkt, *last_pkt;
126 #define VIDEO_PICTURE_QUEUE_SIZE 3
127 #define SUBPICTURE_QUEUE_SIZE 16
128 #define SAMPLE_QUEUE_SIZE 9
129 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
131 typedef struct AudioParams {
134 int64_t channel_layout;
135 enum AVSampleFormat fmt;
140 typedef struct Clock {
141 double pts; /* clock base */
142 double pts_drift; /* clock base minus time at which we updated the clock */
145 int serial; /* clock is based on a packet with this serial */
147 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
150 /* Common struct for handling all types of decoded data and allocated render buffers. */
151 typedef struct Frame {
155 double pts; /* presentation timestamp for the frame */
156 double duration; /* estimated duration of the frame */
157 int64_t pos; /* byte position of the frame in the input file */
166 typedef struct FrameQueue {
167 Frame queue[FRAME_QUEUE_SIZE];
180 AV_SYNC_AUDIO_MASTER, /* default choice */
181 AV_SYNC_VIDEO_MASTER,
182 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
185 typedef struct Decoder {
189 AVCodecContext *avctx;
193 SDL_cond *empty_queue_cond;
195 AVRational start_pts_tb;
197 AVRational next_pts_tb;
198 SDL_Thread *decoder_tid;
201 typedef struct VideoState {
202 SDL_Thread *read_tid;
203 AVInputFormat *iformat;
208 int queue_attachments_req;
213 int read_pause_return;
237 int audio_clock_serial;
238 double audio_diff_cum; /* used for AV difference average computation */
239 double audio_diff_avg_coef;
240 double audio_diff_threshold;
241 int audio_diff_avg_count;
244 int audio_hw_buf_size;
245 uint8_t silence_buf[SDL_AUDIO_MIN_BUFFER_SIZE];
248 unsigned int audio_buf_size; /* in bytes */
249 unsigned int audio_buf1_size;
250 int audio_buf_index; /* in bytes */
251 int audio_write_buf_size;
254 struct AudioParams audio_src;
256 struct AudioParams audio_filter_src;
258 struct AudioParams audio_tgt;
259 struct SwrContext *swr_ctx;
260 int frame_drops_early;
261 int frame_drops_late;
264 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
266 int16_t sample_array[SAMPLE_ARRAY_SIZE];
267 int sample_array_index;
271 FFTSample *rdft_data;
273 double last_vis_time;
276 AVStream *subtitle_st;
277 PacketQueue subtitleq;
280 double frame_last_returned_time;
281 double frame_last_filter_delay;
285 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
287 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
290 SDL_Rect last_display_rect;
294 int width, height, xleft, ytop;
299 AVFilterContext *in_video_filter; // the first filter in the video chain
300 AVFilterContext *out_video_filter; // the last filter in the video chain
301 AVFilterContext *in_audio_filter; // the first filter in the audio chain
302 AVFilterContext *out_audio_filter; // the last filter in the audio chain
303 AVFilterGraph *agraph; // audio filter graph
306 int last_video_stream, last_audio_stream, last_subtitle_stream;
308 SDL_cond *continue_read_thread;
311 /* options specified by the user */
312 static AVInputFormat *file_iformat;
313 static const char *input_filename;
314 static const char *window_title;
315 static int fs_screen_width;
316 static int fs_screen_height;
317 static int default_width = 640;
318 static int default_height = 480;
319 static int screen_width = 0;
320 static int screen_height = 0;
321 static int audio_disable;
322 static int video_disable;
323 static int subtitle_disable;
324 static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
325 static int seek_by_bytes = -1;
326 static int display_disable;
327 static int show_status = 1;
328 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
329 static int64_t start_time = AV_NOPTS_VALUE;
330 static int64_t duration = AV_NOPTS_VALUE;
332 static int genpts = 0;
333 static int lowres = 0;
334 static int decoder_reorder_pts = -1;
336 static int exit_on_keydown;
337 static int exit_on_mousedown;
339 static int framedrop = -1;
340 static int infinite_buffer = -1;
341 static enum ShowMode show_mode = SHOW_MODE_NONE;
342 static const char *audio_codec_name;
343 static const char *subtitle_codec_name;
344 static const char *video_codec_name;
345 double rdftspeed = 0.02;
346 static int64_t cursor_last_shown;
347 static int cursor_hidden = 0;
349 static const char **vfilters_list = NULL;
350 static int nb_vfilters = 0;
351 static char *afilters = NULL;
353 static int autorotate = 1;
355 /* current context */
356 static int is_full_screen;
357 static int64_t audio_callback_time;
359 static AVPacket flush_pkt;
361 #define FF_ALLOC_EVENT (SDL_USEREVENT)
362 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
364 static SDL_Surface *screen;
367 static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
369 GROW_ARRAY(vfilters_list, nb_vfilters);
370 vfilters_list[nb_vfilters - 1] = arg;
376 int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
377 enum AVSampleFormat fmt2, int64_t channel_count2)
379 /* If channel count == 1, planar and non-planar formats are the same */
380 if (channel_count1 == 1 && channel_count2 == 1)
381 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
383 return channel_count1 != channel_count2 || fmt1 != fmt2;
387 int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
389 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
390 return channel_layout;
395 static void free_picture(Frame *vp);
397 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
399 MyAVPacketList *pkt1;
401 if (q->abort_request)
404 pkt1 = av_malloc(sizeof(MyAVPacketList));
409 if (pkt == &flush_pkt)
411 pkt1->serial = q->serial;
416 q->last_pkt->next = pkt1;
419 q->size += pkt1->pkt.size + sizeof(*pkt1);
420 /* XXX: should duplicate packet data in DV case */
421 SDL_CondSignal(q->cond);
425 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
429 /* duplicate the packet */
430 if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
433 SDL_LockMutex(q->mutex);
434 ret = packet_queue_put_private(q, pkt);
435 SDL_UnlockMutex(q->mutex);
437 if (pkt != &flush_pkt && ret < 0)
443 static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
445 AVPacket pkt1, *pkt = &pkt1;
449 pkt->stream_index = stream_index;
450 return packet_queue_put(q, pkt);
453 /* packet queue handling */
454 static void packet_queue_init(PacketQueue *q)
456 memset(q, 0, sizeof(PacketQueue));
457 q->mutex = SDL_CreateMutex();
458 q->cond = SDL_CreateCond();
459 q->abort_request = 1;
462 static void packet_queue_flush(PacketQueue *q)
464 MyAVPacketList *pkt, *pkt1;
466 SDL_LockMutex(q->mutex);
467 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
469 av_free_packet(&pkt->pkt);
476 SDL_UnlockMutex(q->mutex);
479 static void packet_queue_destroy(PacketQueue *q)
481 packet_queue_flush(q);
482 SDL_DestroyMutex(q->mutex);
483 SDL_DestroyCond(q->cond);
486 static void packet_queue_abort(PacketQueue *q)
488 SDL_LockMutex(q->mutex);
490 q->abort_request = 1;
492 SDL_CondSignal(q->cond);
494 SDL_UnlockMutex(q->mutex);
497 static void packet_queue_start(PacketQueue *q)
499 SDL_LockMutex(q->mutex);
500 q->abort_request = 0;
501 packet_queue_put_private(q, &flush_pkt);
502 SDL_UnlockMutex(q->mutex);
505 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
506 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
508 MyAVPacketList *pkt1;
511 SDL_LockMutex(q->mutex);
514 if (q->abort_request) {
521 q->first_pkt = pkt1->next;
525 q->size -= pkt1->pkt.size + sizeof(*pkt1);
528 *serial = pkt1->serial;
536 SDL_CondWait(q->cond, q->mutex);
539 SDL_UnlockMutex(q->mutex);
543 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
544 memset(d, 0, sizeof(Decoder));
547 d->empty_queue_cond = empty_queue_cond;
548 d->start_pts = AV_NOPTS_VALUE;
551 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
557 if (d->queue->abort_request)
560 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
563 if (d->queue->nb_packets == 0)
564 SDL_CondSignal(d->empty_queue_cond);
565 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
567 if (pkt.data == flush_pkt.data) {
568 avcodec_flush_buffers(d->avctx);
570 d->next_pts = d->start_pts;
571 d->next_pts_tb = d->start_pts_tb;
573 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
574 av_free_packet(&d->pkt);
575 d->pkt_temp = d->pkt = pkt;
576 d->packet_pending = 1;
579 switch (d->avctx->codec_type) {
580 case AVMEDIA_TYPE_VIDEO:
581 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
583 if (decoder_reorder_pts == -1) {
584 frame->pts = av_frame_get_best_effort_timestamp(frame);
585 } else if (decoder_reorder_pts) {
586 frame->pts = frame->pkt_pts;
588 frame->pts = frame->pkt_dts;
592 case AVMEDIA_TYPE_AUDIO:
593 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
595 AVRational tb = (AVRational){1, frame->sample_rate};
596 if (frame->pts != AV_NOPTS_VALUE)
597 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
598 else if (frame->pkt_pts != AV_NOPTS_VALUE)
599 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
600 else if (d->next_pts != AV_NOPTS_VALUE)
601 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
602 if (frame->pts != AV_NOPTS_VALUE) {
603 d->next_pts = frame->pts + frame->nb_samples;
608 case AVMEDIA_TYPE_SUBTITLE:
609 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
614 d->packet_pending = 0;
617 d->pkt_temp.pts = AV_NOPTS_VALUE;
618 if (d->pkt_temp.data) {
619 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
620 ret = d->pkt_temp.size;
621 d->pkt_temp.data += ret;
622 d->pkt_temp.size -= ret;
623 if (d->pkt_temp.size <= 0)
624 d->packet_pending = 0;
627 d->packet_pending = 0;
628 d->finished = d->pkt_serial;
632 } while (!got_frame && !d->finished);
637 static void decoder_destroy(Decoder *d) {
638 av_free_packet(&d->pkt);
641 static void frame_queue_unref_item(Frame *vp)
643 av_frame_unref(vp->frame);
644 avsubtitle_free(&vp->sub);
647 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
650 memset(f, 0, sizeof(FrameQueue));
651 if (!(f->mutex = SDL_CreateMutex()))
652 return AVERROR(ENOMEM);
653 if (!(f->cond = SDL_CreateCond()))
654 return AVERROR(ENOMEM);
656 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
657 f->keep_last = !!keep_last;
658 for (i = 0; i < f->max_size; i++)
659 if (!(f->queue[i].frame = av_frame_alloc()))
660 return AVERROR(ENOMEM);
664 static void frame_queue_destory(FrameQueue *f)
667 for (i = 0; i < f->max_size; i++) {
668 Frame *vp = &f->queue[i];
669 frame_queue_unref_item(vp);
670 av_frame_free(&vp->frame);
673 SDL_DestroyMutex(f->mutex);
674 SDL_DestroyCond(f->cond);
677 static void frame_queue_signal(FrameQueue *f)
679 SDL_LockMutex(f->mutex);
680 SDL_CondSignal(f->cond);
681 SDL_UnlockMutex(f->mutex);
684 static Frame *frame_queue_peek(FrameQueue *f)
686 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
689 static Frame *frame_queue_peek_next(FrameQueue *f)
691 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
694 static Frame *frame_queue_peek_last(FrameQueue *f)
696 return &f->queue[f->rindex];
699 static Frame *frame_queue_peek_writable(FrameQueue *f)
701 /* wait until we have space to put a new frame */
702 SDL_LockMutex(f->mutex);
703 while (f->size >= f->max_size &&
704 !f->pktq->abort_request) {
705 SDL_CondWait(f->cond, f->mutex);
707 SDL_UnlockMutex(f->mutex);
709 if (f->pktq->abort_request)
712 return &f->queue[f->windex];
715 static Frame *frame_queue_peek_readable(FrameQueue *f)
717 /* wait until we have a readable a new frame */
718 SDL_LockMutex(f->mutex);
719 while (f->size - f->rindex_shown <= 0 &&
720 !f->pktq->abort_request) {
721 SDL_CondWait(f->cond, f->mutex);
723 SDL_UnlockMutex(f->mutex);
725 if (f->pktq->abort_request)
728 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
731 static void frame_queue_push(FrameQueue *f)
733 if (++f->windex == f->max_size)
735 SDL_LockMutex(f->mutex);
737 SDL_CondSignal(f->cond);
738 SDL_UnlockMutex(f->mutex);
741 static void frame_queue_next(FrameQueue *f)
743 if (f->keep_last && !f->rindex_shown) {
747 frame_queue_unref_item(&f->queue[f->rindex]);
748 if (++f->rindex == f->max_size)
750 SDL_LockMutex(f->mutex);
752 SDL_CondSignal(f->cond);
753 SDL_UnlockMutex(f->mutex);
756 /* jump back to the previous frame if available by resetting rindex_shown */
757 static int frame_queue_prev(FrameQueue *f)
759 int ret = f->rindex_shown;
764 /* return the number of undisplayed frames in the queue */
765 static int frame_queue_nb_remaining(FrameQueue *f)
767 return f->size - f->rindex_shown;
770 /* return last shown position */
771 static int64_t frame_queue_last_pos(FrameQueue *f)
773 Frame *fp = &f->queue[f->rindex];
774 if (f->rindex_shown && fp->serial == f->pktq->serial)
780 static void decoder_abort(Decoder *d, FrameQueue *fq)
782 packet_queue_abort(d->queue);
783 frame_queue_signal(fq);
784 SDL_WaitThread(d->decoder_tid, NULL);
785 d->decoder_tid = NULL;
786 packet_queue_flush(d->queue);
789 static inline void fill_rectangle(SDL_Surface *screen,
790 int x, int y, int w, int h, int color, int update)
797 SDL_FillRect(screen, &rect, color);
798 if (update && w > 0 && h > 0)
799 SDL_UpdateRect(screen, x, y, w, h);
802 /* draw only the border of a rectangle */
803 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
807 /* fill the background */
811 w2 = width - (x + w);
817 h2 = height - (y + h);
820 fill_rectangle(screen,
824 fill_rectangle(screen,
825 xleft + width - w2, ytop,
828 fill_rectangle(screen,
832 fill_rectangle(screen,
833 xleft + w1, ytop + height - h2,
838 #define ALPHA_BLEND(a, oldp, newp, s)\
839 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
845 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
847 int x, y, Y, U, V, A;
848 uint8_t *lum, *cb, *cr;
849 int dstx, dsty, dstw, dsth;
850 const AVPicture *src = &rect->pict;
852 dstw = av_clip(rect->w, 0, imgw);
853 dsth = av_clip(rect->h, 0, imgh);
854 dstx = av_clip(rect->x, 0, imgw - dstw);
855 dsty = av_clip(rect->y, 0, imgh - dsth);
856 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
857 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
858 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
860 for (y = 0; y<dsth; y++) {
861 for (x = 0; x<dstw; x++) {
862 Y = src->data[0][x + y*src->linesize[0]];
863 A = src->data[3][x + y*src->linesize[3]];
864 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
867 lum += dst->linesize[0] - dstw;
870 for (y = 0; y<dsth/2; y++) {
871 for (x = 0; x<dstw/2; x++) {
872 U = src->data[1][x + y*src->linesize[1]];
873 V = src->data[2][x + y*src->linesize[2]];
874 A = src->data[3][2*x + 2*y *src->linesize[3]]
875 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
876 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
877 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
878 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
879 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
883 cb += dst->linesize[1] - dstw/2;
884 cr += dst->linesize[2] - dstw/2;
888 static void free_picture(Frame *vp)
891 SDL_FreeYUVOverlay(vp->bmp);
896 static void calculate_display_rect(SDL_Rect *rect,
897 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
898 int pic_width, int pic_height, AVRational pic_sar)
901 int width, height, x, y;
903 if (pic_sar.num == 0)
906 aspect_ratio = av_q2d(pic_sar);
908 if (aspect_ratio <= 0.0)
910 aspect_ratio *= (float)pic_width / (float)pic_height;
912 /* XXX: we suppose the screen has a 1.0 pixel ratio */
914 width = ((int)rint(height * aspect_ratio)) & ~1;
915 if (width > scr_width) {
917 height = ((int)rint(width / aspect_ratio)) & ~1;
919 x = (scr_width - width) / 2;
920 y = (scr_height - height) / 2;
921 rect->x = scr_xleft + x;
922 rect->y = scr_ytop + y;
923 rect->w = FFMAX(width, 1);
924 rect->h = FFMAX(height, 1);
927 static void video_image_display(VideoState *is)
935 vp = frame_queue_peek(&is->pictq);
937 if (is->subtitle_st) {
938 if (frame_queue_nb_remaining(&is->subpq) > 0) {
939 sp = frame_queue_peek(&is->subpq);
941 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
942 SDL_LockYUVOverlay (vp->bmp);
944 pict.data[0] = vp->bmp->pixels[0];
945 pict.data[1] = vp->bmp->pixels[2];
946 pict.data[2] = vp->bmp->pixels[1];
948 pict.linesize[0] = vp->bmp->pitches[0];
949 pict.linesize[1] = vp->bmp->pitches[2];
950 pict.linesize[2] = vp->bmp->pitches[1];
952 for (i = 0; i < sp->sub.num_rects; i++)
953 blend_subrect(&pict, sp->sub.rects[i],
954 vp->bmp->w, vp->bmp->h);
956 SDL_UnlockYUVOverlay (vp->bmp);
961 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
963 SDL_DisplayYUVOverlay(vp->bmp, &rect);
965 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) {
966 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
967 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
968 is->last_display_rect = rect;
973 static inline int compute_mod(int a, int b)
975 return a < 0 ? a%b + b : a%b;
978 static void video_audio_display(VideoState *s)
980 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
981 int ch, channels, h, h2, bgcolor, fgcolor;
983 int rdft_bits, nb_freq;
985 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
987 nb_freq = 1 << (rdft_bits - 1);
989 /* compute display index : center on currently output samples */
990 channels = s->audio_tgt.channels;
991 nb_display_channels = channels;
993 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
995 delay = s->audio_write_buf_size;
998 /* to be more precise, we take into account the time spent since
999 the last buffer computation */
1000 if (audio_callback_time) {
1001 time_diff = av_gettime_relative() - audio_callback_time;
1002 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1005 delay += 2 * data_used;
1006 if (delay < data_used)
1009 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1010 if (s->show_mode == SHOW_MODE_WAVES) {
1012 for (i = 0; i < 1000; i += channels) {
1013 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1014 int a = s->sample_array[idx];
1015 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1016 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1017 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1019 if (h < score && (b ^ c) < 0) {
1026 s->last_i_start = i_start;
1028 i_start = s->last_i_start;
1031 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1032 if (s->show_mode == SHOW_MODE_WAVES) {
1033 fill_rectangle(screen,
1034 s->xleft, s->ytop, s->width, s->height,
1037 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1039 /* total height for one channel */
1040 h = s->height / nb_display_channels;
1041 /* graph height / 2 */
1043 for (ch = 0; ch < nb_display_channels; ch++) {
1045 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1046 for (x = 0; x < s->width; x++) {
1047 y = (s->sample_array[i] * h2) >> 15;
1054 fill_rectangle(screen,
1055 s->xleft + x, ys, 1, y,
1058 if (i >= SAMPLE_ARRAY_SIZE)
1059 i -= SAMPLE_ARRAY_SIZE;
1063 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1065 for (ch = 1; ch < nb_display_channels; ch++) {
1066 y = s->ytop + ch * h;
1067 fill_rectangle(screen,
1068 s->xleft, y, s->width, 1,
1071 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1073 nb_display_channels= FFMIN(nb_display_channels, 2);
1074 if (rdft_bits != s->rdft_bits) {
1075 av_rdft_end(s->rdft);
1076 av_free(s->rdft_data);
1077 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1078 s->rdft_bits = rdft_bits;
1079 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1081 if (!s->rdft || !s->rdft_data){
1082 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1083 s->show_mode = SHOW_MODE_WAVES;
1086 for (ch = 0; ch < nb_display_channels; ch++) {
1087 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1089 for (x = 0; x < 2 * nb_freq; x++) {
1090 double w = (x-nb_freq) * (1.0 / nb_freq);
1091 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1093 if (i >= SAMPLE_ARRAY_SIZE)
1094 i -= SAMPLE_ARRAY_SIZE;
1096 av_rdft_calc(s->rdft, data[ch]);
1098 /* Least efficient way to do this, we should of course
1099 * directly access it but it is more than fast enough. */
1100 for (y = 0; y < s->height; y++) {
1101 double w = 1 / sqrt(nb_freq);
1102 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]));
1103 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1104 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1107 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1109 fill_rectangle(screen,
1110 s->xpos, s->height-y, 1, 1,
1114 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1117 if (s->xpos >= s->width)
1122 static void stream_close(VideoState *is)
1124 /* XXX: use a special url_shutdown call to abort parse cleanly */
1125 is->abort_request = 1;
1126 SDL_WaitThread(is->read_tid, NULL);
1127 packet_queue_destroy(&is->videoq);
1128 packet_queue_destroy(&is->audioq);
1129 packet_queue_destroy(&is->subtitleq);
1131 /* free all pictures */
1132 frame_queue_destory(&is->pictq);
1133 frame_queue_destory(&is->sampq);
1134 frame_queue_destory(&is->subpq);
1135 SDL_DestroyCond(is->continue_read_thread);
1136 #if !CONFIG_AVFILTER
1137 sws_freeContext(is->img_convert_ctx);
1139 sws_freeContext(is->sub_convert_ctx);
1140 av_free(is->filename);
1144 static void do_exit(VideoState *is)
1149 av_lockmgr_register(NULL);
1152 av_freep(&vfilters_list);
1154 avformat_network_deinit();
1158 av_log(NULL, AV_LOG_QUIET, "%s", "");
1162 static void sigterm_handler(int sig)
1167 static void set_default_window_size(int width, int height, AVRational sar)
1170 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1171 default_width = rect.w;
1172 default_height = rect.h;
1175 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1177 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1180 if (is_full_screen) flags |= SDL_FULLSCREEN;
1181 else flags |= SDL_RESIZABLE;
1183 if (vp && vp->width)
1184 set_default_window_size(vp->width, vp->height, vp->sar);
1186 if (is_full_screen && fs_screen_width) {
1187 w = fs_screen_width;
1188 h = fs_screen_height;
1189 } else if (!is_full_screen && screen_width) {
1196 w = FFMIN(16383, w);
1197 if (screen && is->width == screen->w && screen->w == w
1198 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1200 screen = SDL_SetVideoMode(w, h, 0, flags);
1202 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1206 window_title = input_filename;
1207 SDL_WM_SetCaption(window_title, window_title);
1209 is->width = screen->w;
1210 is->height = screen->h;
1215 /* display the current picture, if any */
1216 static void video_display(VideoState *is)
1219 video_open(is, 0, NULL);
1220 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1221 video_audio_display(is);
1222 else if (is->video_st)
1223 video_image_display(is);
1226 static double get_clock(Clock *c)
1228 if (*c->queue_serial != c->serial)
1233 double time = av_gettime_relative() / 1000000.0;
1234 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1238 static void set_clock_at(Clock *c, double pts, int serial, double time)
1241 c->last_updated = time;
1242 c->pts_drift = c->pts - time;
1246 static void set_clock(Clock *c, double pts, int serial)
1248 double time = av_gettime_relative() / 1000000.0;
1249 set_clock_at(c, pts, serial, time);
1252 static void set_clock_speed(Clock *c, double speed)
1254 set_clock(c, get_clock(c), c->serial);
1258 static void init_clock(Clock *c, int *queue_serial)
1262 c->queue_serial = queue_serial;
1263 set_clock(c, NAN, -1);
1266 static void sync_clock_to_slave(Clock *c, Clock *slave)
1268 double clock = get_clock(c);
1269 double slave_clock = get_clock(slave);
1270 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1271 set_clock(c, slave_clock, slave->serial);
1274 static int get_master_sync_type(VideoState *is) {
1275 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1277 return AV_SYNC_VIDEO_MASTER;
1279 return AV_SYNC_AUDIO_MASTER;
1280 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1282 return AV_SYNC_AUDIO_MASTER;
1284 return AV_SYNC_EXTERNAL_CLOCK;
1286 return AV_SYNC_EXTERNAL_CLOCK;
1290 /* get the current master clock value */
1291 static double get_master_clock(VideoState *is)
1295 switch (get_master_sync_type(is)) {
1296 case AV_SYNC_VIDEO_MASTER:
1297 val = get_clock(&is->vidclk);
1299 case AV_SYNC_AUDIO_MASTER:
1300 val = get_clock(&is->audclk);
1303 val = get_clock(&is->extclk);
1309 static void check_external_clock_speed(VideoState *is) {
1310 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1311 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1312 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1313 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1314 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1315 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1317 double speed = is->extclk.speed;
1319 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1323 /* seek in the stream */
1324 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1326 if (!is->seek_req) {
1329 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1331 is->seek_flags |= AVSEEK_FLAG_BYTE;
1333 SDL_CondSignal(is->continue_read_thread);
1337 /* pause or resume the video */
1338 static void stream_toggle_pause(VideoState *is)
1341 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1342 if (is->read_pause_return != AVERROR(ENOSYS)) {
1343 is->vidclk.paused = 0;
1345 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1347 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1348 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1351 static void toggle_pause(VideoState *is)
1353 stream_toggle_pause(is);
1357 static void toggle_mute(VideoState *is)
1359 is->muted = !is->muted;
1362 static void update_volume(VideoState *is, int sign, int step)
1364 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1367 static void step_to_next_frame(VideoState *is)
1369 /* if the stream is paused unpause it, then step */
1371 stream_toggle_pause(is);
1375 static double compute_target_delay(double delay, VideoState *is)
1377 double sync_threshold, diff = 0;
1379 /* update delay to follow master synchronisation source */
1380 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1381 /* if video is slave, we try to correct big delays by
1382 duplicating or deleting a frame */
1383 diff = get_clock(&is->vidclk) - get_master_clock(is);
1385 /* skip or repeat frame. We take into account the
1386 delay to compute the threshold. I still don't know
1387 if it is the best guess */
1388 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1389 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1390 if (diff <= -sync_threshold)
1391 delay = FFMAX(0, delay + diff);
1392 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1393 delay = delay + diff;
1394 else if (diff >= sync_threshold)
1399 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1405 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1406 if (vp->serial == nextvp->serial) {
1407 double duration = nextvp->pts - vp->pts;
1408 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1409 return vp->duration;
1417 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1418 /* update current video pts */
1419 set_clock(&is->vidclk, pts, serial);
1420 sync_clock_to_slave(&is->extclk, &is->vidclk);
1423 /* called to display each frame */
1424 static void video_refresh(void *opaque, double *remaining_time)
1426 VideoState *is = opaque;
1431 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1432 check_external_clock_speed(is);
1434 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1435 time = av_gettime_relative() / 1000000.0;
1436 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1438 is->last_vis_time = time;
1440 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1445 if (is->force_refresh)
1446 redisplay = frame_queue_prev(&is->pictq);
1448 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1449 // nothing to do, no picture to display in the queue
1451 double last_duration, duration, delay;
1454 /* dequeue the picture */
1455 lastvp = frame_queue_peek_last(&is->pictq);
1456 vp = frame_queue_peek(&is->pictq);
1458 if (vp->serial != is->videoq.serial) {
1459 frame_queue_next(&is->pictq);
1464 if (lastvp->serial != vp->serial && !redisplay)
1465 is->frame_timer = av_gettime_relative() / 1000000.0;
1470 /* compute nominal last_duration */
1471 last_duration = vp_duration(is, lastvp, vp);
1475 delay = compute_target_delay(last_duration, is);
1477 time= av_gettime_relative()/1000000.0;
1478 if (time < is->frame_timer + delay && !redisplay) {
1479 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1483 is->frame_timer += delay;
1484 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1485 is->frame_timer = time;
1487 SDL_LockMutex(is->pictq.mutex);
1488 if (!redisplay && !isnan(vp->pts))
1489 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1490 SDL_UnlockMutex(is->pictq.mutex);
1492 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1493 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1494 duration = vp_duration(is, vp, nextvp);
1495 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1497 is->frame_drops_late++;
1498 frame_queue_next(&is->pictq);
1504 if (is->subtitle_st) {
1505 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1506 sp = frame_queue_peek(&is->subpq);
1508 if (frame_queue_nb_remaining(&is->subpq) > 1)
1509 sp2 = frame_queue_peek_next(&is->subpq);
1513 if (sp->serial != is->subtitleq.serial
1514 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1515 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1517 frame_queue_next(&is->subpq);
1525 /* display picture */
1526 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1529 frame_queue_next(&is->pictq);
1531 if (is->step && !is->paused)
1532 stream_toggle_pause(is);
1535 is->force_refresh = 0;
1537 static int64_t last_time;
1539 int aqsize, vqsize, sqsize;
1542 cur_time = av_gettime_relative();
1543 if (!last_time || (cur_time - last_time) >= 30000) {
1548 aqsize = is->audioq.size;
1550 vqsize = is->videoq.size;
1551 if (is->subtitle_st)
1552 sqsize = is->subtitleq.size;
1554 if (is->audio_st && is->video_st)
1555 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1556 else if (is->video_st)
1557 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1558 else if (is->audio_st)
1559 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1560 av_log(NULL, AV_LOG_INFO,
1561 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1562 get_master_clock(is),
1563 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1565 is->frame_drops_early + is->frame_drops_late,
1569 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1570 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1572 last_time = cur_time;
1577 /* allocate a picture (needs to do that in main thread to avoid
1578 potential locking problems */
1579 static void alloc_picture(VideoState *is)
1584 vp = &is->pictq.queue[is->pictq.windex];
1588 video_open(is, 0, vp);
1590 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1593 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1594 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1595 /* SDL allocates a buffer smaller than requested if the video
1596 * overlay hardware is unable to support the requested size. */
1597 av_log(NULL, AV_LOG_FATAL,
1598 "Error: the video system does not support an image\n"
1599 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1600 "to reduce the image size.\n", vp->width, vp->height );
1604 SDL_LockMutex(is->pictq.mutex);
1606 SDL_CondSignal(is->pictq.cond);
1607 SDL_UnlockMutex(is->pictq.mutex);
1610 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1611 int i, width, height;
1613 for (i = 0; i < 3; i++) {
1620 if (bmp->pitches[i] > width) {
1621 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1622 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1628 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1632 #if defined(DEBUG_SYNC) && 0
1633 printf("frame_type=%c pts=%0.3f\n",
1634 av_get_picture_type_char(src_frame->pict_type), pts);
1637 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1640 vp->sar = src_frame->sample_aspect_ratio;
1642 /* alloc or resize hardware picture buffer */
1643 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1644 vp->width != src_frame->width ||
1645 vp->height != src_frame->height) {
1650 vp->width = src_frame->width;
1651 vp->height = src_frame->height;
1653 /* the allocation must be done in the main thread to avoid
1654 locking problems. */
1655 event.type = FF_ALLOC_EVENT;
1656 event.user.data1 = is;
1657 SDL_PushEvent(&event);
1659 /* wait until the picture is allocated */
1660 SDL_LockMutex(is->pictq.mutex);
1661 while (!vp->allocated && !is->videoq.abort_request) {
1662 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1664 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1665 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1666 while (!vp->allocated && !is->abort_request) {
1667 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1670 SDL_UnlockMutex(is->pictq.mutex);
1672 if (is->videoq.abort_request)
1676 /* if the frame is not skipped, then display it */
1678 AVPicture pict = { { 0 } };
1680 /* get a pointer on the bitmap */
1681 SDL_LockYUVOverlay (vp->bmp);
1683 pict.data[0] = vp->bmp->pixels[0];
1684 pict.data[1] = vp->bmp->pixels[2];
1685 pict.data[2] = vp->bmp->pixels[1];
1687 pict.linesize[0] = vp->bmp->pitches[0];
1688 pict.linesize[1] = vp->bmp->pitches[2];
1689 pict.linesize[2] = vp->bmp->pitches[1];
1692 // FIXME use direct rendering
1693 av_picture_copy(&pict, (AVPicture *)src_frame,
1694 src_frame->format, vp->width, vp->height);
1697 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1699 const AVClass *class = sws_get_class();
1700 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1701 AV_OPT_SEARCH_FAKE_OBJ);
1702 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1708 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1709 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1710 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1711 if (!is->img_convert_ctx) {
1712 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1715 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1716 0, vp->height, pict.data, pict.linesize);
1718 /* workaround SDL PITCH_WORKAROUND */
1719 duplicate_right_border_pixels(vp->bmp);
1720 /* update the bitmap content */
1721 SDL_UnlockYUVOverlay(vp->bmp);
1724 vp->duration = duration;
1726 vp->serial = serial;
1728 /* now we can update the picture count */
1729 frame_queue_push(&is->pictq);
1734 static int get_video_frame(VideoState *is, AVFrame *frame)
1738 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1744 if (frame->pts != AV_NOPTS_VALUE)
1745 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1747 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1749 is->viddec_width = frame->width;
1750 is->viddec_height = frame->height;
1752 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1753 if (frame->pts != AV_NOPTS_VALUE) {
1754 double diff = dpts - get_master_clock(is);
1755 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1756 diff - is->frame_last_filter_delay < 0 &&
1757 is->viddec.pkt_serial == is->vidclk.serial &&
1758 is->videoq.nb_packets) {
1759 is->frame_drops_early++;
1760 av_frame_unref(frame);
1771 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1772 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1775 int nb_filters = graph->nb_filters;
1776 AVFilterInOut *outputs = NULL, *inputs = NULL;
1779 outputs = avfilter_inout_alloc();
1780 inputs = avfilter_inout_alloc();
1781 if (!outputs || !inputs) {
1782 ret = AVERROR(ENOMEM);
1786 outputs->name = av_strdup("in");
1787 outputs->filter_ctx = source_ctx;
1788 outputs->pad_idx = 0;
1789 outputs->next = NULL;
1791 inputs->name = av_strdup("out");
1792 inputs->filter_ctx = sink_ctx;
1793 inputs->pad_idx = 0;
1794 inputs->next = NULL;
1796 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1799 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1803 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1804 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1805 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1807 ret = avfilter_graph_config(graph, NULL);
1809 avfilter_inout_free(&outputs);
1810 avfilter_inout_free(&inputs);
1814 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1816 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1817 char sws_flags_str[512] = "";
1818 char buffersrc_args[256];
1820 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1821 AVCodecContext *codec = is->video_st->codec;
1822 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1823 AVDictionaryEntry *e = NULL;
1825 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1826 if (!strcmp(e->key, "sws_flags")) {
1827 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1829 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1831 if (strlen(sws_flags_str))
1832 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1834 graph->scale_sws_opts = av_strdup(sws_flags_str);
1836 snprintf(buffersrc_args, sizeof(buffersrc_args),
1837 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1838 frame->width, frame->height, frame->format,
1839 is->video_st->time_base.num, is->video_st->time_base.den,
1840 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1841 if (fr.num && fr.den)
1842 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1844 if ((ret = avfilter_graph_create_filter(&filt_src,
1845 avfilter_get_by_name("buffer"),
1846 "ffplay_buffer", buffersrc_args, NULL,
1850 ret = avfilter_graph_create_filter(&filt_out,
1851 avfilter_get_by_name("buffersink"),
1852 "ffplay_buffersink", NULL, NULL, graph);
1856 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1859 last_filter = filt_out;
1861 /* Note: this macro adds a filter before the lastly added filter, so the
1862 * processing order of the filters is in reverse */
1863 #define INSERT_FILT(name, arg) do { \
1864 AVFilterContext *filt_ctx; \
1866 ret = avfilter_graph_create_filter(&filt_ctx, \
1867 avfilter_get_by_name(name), \
1868 "ffplay_" name, arg, NULL, graph); \
1872 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1876 last_filter = filt_ctx; \
1879 /* SDL YUV code is not handling odd width/height for some driver
1880 * combinations, therefore we crop the picture to an even width/height. */
1881 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1884 double theta = get_rotation(is->video_st);
1886 if (fabs(theta - 90) < 1.0) {
1887 INSERT_FILT("transpose", "clock");
1888 } else if (fabs(theta - 180) < 1.0) {
1889 INSERT_FILT("hflip", NULL);
1890 INSERT_FILT("vflip", NULL);
1891 } else if (fabs(theta - 270) < 1.0) {
1892 INSERT_FILT("transpose", "cclock");
1893 } else if (fabs(theta) > 1.0) {
1894 char rotate_buf[64];
1895 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1896 INSERT_FILT("rotate", rotate_buf);
1900 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1903 is->in_video_filter = filt_src;
1904 is->out_video_filter = filt_out;
1910 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1912 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1913 int sample_rates[2] = { 0, -1 };
1914 int64_t channel_layouts[2] = { 0, -1 };
1915 int channels[2] = { 0, -1 };
1916 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1917 char aresample_swr_opts[512] = "";
1918 AVDictionaryEntry *e = NULL;
1919 char asrc_args[256];
1922 avfilter_graph_free(&is->agraph);
1923 if (!(is->agraph = avfilter_graph_alloc()))
1924 return AVERROR(ENOMEM);
1926 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1927 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1928 if (strlen(aresample_swr_opts))
1929 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1930 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1932 ret = snprintf(asrc_args, sizeof(asrc_args),
1933 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1934 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1935 is->audio_filter_src.channels,
1936 1, is->audio_filter_src.freq);
1937 if (is->audio_filter_src.channel_layout)
1938 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1939 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1941 ret = avfilter_graph_create_filter(&filt_asrc,
1942 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1943 asrc_args, NULL, is->agraph);
1948 ret = avfilter_graph_create_filter(&filt_asink,
1949 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1950 NULL, NULL, is->agraph);
1954 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1956 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1959 if (force_output_format) {
1960 channel_layouts[0] = is->audio_tgt.channel_layout;
1961 channels [0] = is->audio_tgt.channels;
1962 sample_rates [0] = is->audio_tgt.freq;
1963 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1965 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1967 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1969 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1974 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1977 is->in_audio_filter = filt_asrc;
1978 is->out_audio_filter = filt_asink;
1982 avfilter_graph_free(&is->agraph);
1985 #endif /* CONFIG_AVFILTER */
1987 static int audio_thread(void *arg)
1989 VideoState *is = arg;
1990 AVFrame *frame = av_frame_alloc();
1993 int last_serial = -1;
1994 int64_t dec_channel_layout;
2002 return AVERROR(ENOMEM);
2005 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2009 tb = (AVRational){1, frame->sample_rate};
2012 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2015 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2016 frame->format, av_frame_get_channels(frame)) ||
2017 is->audio_filter_src.channel_layout != dec_channel_layout ||
2018 is->audio_filter_src.freq != frame->sample_rate ||
2019 is->auddec.pkt_serial != last_serial;
2022 char buf1[1024], buf2[1024];
2023 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2024 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2025 av_log(NULL, AV_LOG_DEBUG,
2026 "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",
2027 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2028 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2030 is->audio_filter_src.fmt = frame->format;
2031 is->audio_filter_src.channels = av_frame_get_channels(frame);
2032 is->audio_filter_src.channel_layout = dec_channel_layout;
2033 is->audio_filter_src.freq = frame->sample_rate;
2034 last_serial = is->auddec.pkt_serial;
2036 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2040 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2043 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2044 tb = is->out_audio_filter->inputs[0]->time_base;
2046 if (!(af = frame_queue_peek_writable(&is->sampq)))
2049 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2050 af->pos = av_frame_get_pkt_pos(frame);
2051 af->serial = is->auddec.pkt_serial;
2052 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2054 av_frame_move_ref(af->frame, frame);
2055 frame_queue_push(&is->sampq);
2058 if (is->audioq.serial != is->auddec.pkt_serial)
2061 if (ret == AVERROR_EOF)
2062 is->auddec.finished = is->auddec.pkt_serial;
2065 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2068 avfilter_graph_free(&is->agraph);
2070 av_frame_free(&frame);
2074 static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2076 packet_queue_start(d->queue);
2077 d->decoder_tid = SDL_CreateThread(fn, arg);
2080 static int video_thread(void *arg)
2082 VideoState *is = arg;
2083 AVFrame *frame = av_frame_alloc();
2087 AVRational tb = is->video_st->time_base;
2088 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2091 AVFilterGraph *graph = avfilter_graph_alloc();
2092 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2095 enum AVPixelFormat last_format = -2;
2096 int last_serial = -1;
2097 int last_vfilter_idx = 0;
2099 av_frame_free(&frame);
2100 return AVERROR(ENOMEM);
2107 avfilter_graph_free(&graph);
2109 return AVERROR(ENOMEM);
2113 ret = get_video_frame(is, frame);
2120 if ( last_w != frame->width
2121 || last_h != frame->height
2122 || last_format != frame->format
2123 || last_serial != is->viddec.pkt_serial
2124 || last_vfilter_idx != is->vfilter_idx) {
2125 av_log(NULL, AV_LOG_DEBUG,
2126 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2128 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2129 frame->width, frame->height,
2130 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2131 avfilter_graph_free(&graph);
2132 graph = avfilter_graph_alloc();
2133 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2135 event.type = FF_QUIT_EVENT;
2136 event.user.data1 = is;
2137 SDL_PushEvent(&event);
2140 filt_in = is->in_video_filter;
2141 filt_out = is->out_video_filter;
2142 last_w = frame->width;
2143 last_h = frame->height;
2144 last_format = frame->format;
2145 last_serial = is->viddec.pkt_serial;
2146 last_vfilter_idx = is->vfilter_idx;
2147 frame_rate = filt_out->inputs[0]->frame_rate;
2150 ret = av_buffersrc_add_frame(filt_in, frame);
2155 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2157 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2159 if (ret == AVERROR_EOF)
2160 is->viddec.finished = is->viddec.pkt_serial;
2165 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2166 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2167 is->frame_last_filter_delay = 0;
2168 tb = filt_out->inputs[0]->time_base;
2170 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2171 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2172 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2173 av_frame_unref(frame);
2183 avfilter_graph_free(&graph);
2185 av_frame_free(&frame);
2189 static int subtitle_thread(void *arg)
2191 VideoState *is = arg;
2198 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2201 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2206 if (got_subtitle && sp->sub.format == 0) {
2207 if (sp->sub.pts != AV_NOPTS_VALUE)
2208 pts = sp->sub.pts / (double)AV_TIME_BASE;
2210 sp->serial = is->subdec.pkt_serial;
2212 for (i = 0; i < sp->sub.num_rects; i++)
2214 int in_w = sp->sub.rects[i]->w;
2215 int in_h = sp->sub.rects[i]->h;
2216 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2217 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2218 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2219 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2222 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2223 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2224 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2225 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2226 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2227 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2229 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2230 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2231 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2232 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2233 !newpic.data[1] || !newpic.data[2]
2235 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2238 sws_scale(is->sub_convert_ctx,
2239 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2240 0, in_h, newpic.data, newpic.linesize);
2242 av_free(sp->sub.rects[i]->pict.data[0]);
2243 av_free(sp->sub.rects[i]->pict.data[1]);
2244 sp->sub.rects[i]->pict = newpic;
2245 sp->sub.rects[i]->w = out_w;
2246 sp->sub.rects[i]->h = out_h;
2247 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2248 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2251 /* now we can update the picture count */
2252 frame_queue_push(&is->subpq);
2253 } else if (got_subtitle) {
2254 avsubtitle_free(&sp->sub);
2260 /* copy samples for viewing in editor window */
2261 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2265 size = samples_size / sizeof(short);
2267 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2270 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2272 is->sample_array_index += len;
2273 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2274 is->sample_array_index = 0;
2279 /* return the wanted number of samples to get better sync if sync_type is video
2280 * or external master clock */
2281 static int synchronize_audio(VideoState *is, int nb_samples)
2283 int wanted_nb_samples = nb_samples;
2285 /* if not master, then we try to remove or add samples to correct the clock */
2286 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2287 double diff, avg_diff;
2288 int min_nb_samples, max_nb_samples;
2290 diff = get_clock(&is->audclk) - get_master_clock(is);
2292 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2293 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2294 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2295 /* not enough measures to have a correct estimate */
2296 is->audio_diff_avg_count++;
2298 /* estimate the A-V difference */
2299 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2301 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2302 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2303 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2304 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2305 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2307 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2308 diff, avg_diff, wanted_nb_samples - nb_samples,
2309 is->audio_clock, is->audio_diff_threshold);
2312 /* too big difference : may be initial PTS errors, so
2314 is->audio_diff_avg_count = 0;
2315 is->audio_diff_cum = 0;
2319 return wanted_nb_samples;
2323 * Decode one audio frame and return its uncompressed size.
2325 * The processed audio frame is decoded, converted if required, and
2326 * stored in is->audio_buf, with size in bytes given by the return
2329 static int audio_decode_frame(VideoState *is)
2331 int data_size, resampled_data_size;
2332 int64_t dec_channel_layout;
2333 av_unused double audio_clock0;
2334 int wanted_nb_samples;
2342 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2343 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2348 if (!(af = frame_queue_peek_readable(&is->sampq)))
2350 frame_queue_next(&is->sampq);
2351 } while (af->serial != is->audioq.serial);
2353 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2354 af->frame->nb_samples,
2355 af->frame->format, 1);
2357 dec_channel_layout =
2358 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2359 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2360 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2362 if (af->frame->format != is->audio_src.fmt ||
2363 dec_channel_layout != is->audio_src.channel_layout ||
2364 af->frame->sample_rate != is->audio_src.freq ||
2365 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2366 swr_free(&is->swr_ctx);
2367 is->swr_ctx = swr_alloc_set_opts(NULL,
2368 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2369 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2371 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2372 av_log(NULL, AV_LOG_ERROR,
2373 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2374 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2375 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2376 swr_free(&is->swr_ctx);
2379 is->audio_src.channel_layout = dec_channel_layout;
2380 is->audio_src.channels = av_frame_get_channels(af->frame);
2381 is->audio_src.freq = af->frame->sample_rate;
2382 is->audio_src.fmt = af->frame->format;
2386 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2387 uint8_t **out = &is->audio_buf1;
2388 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2389 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2392 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2395 if (wanted_nb_samples != af->frame->nb_samples) {
2396 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2397 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2398 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2402 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2403 if (!is->audio_buf1)
2404 return AVERROR(ENOMEM);
2405 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2407 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2410 if (len2 == out_count) {
2411 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2412 if (swr_init(is->swr_ctx) < 0)
2413 swr_free(&is->swr_ctx);
2415 is->audio_buf = is->audio_buf1;
2416 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2418 is->audio_buf = af->frame->data[0];
2419 resampled_data_size = data_size;
2422 audio_clock0 = is->audio_clock;
2423 /* update the audio clock with the pts */
2424 if (!isnan(af->pts))
2425 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2427 is->audio_clock = NAN;
2428 is->audio_clock_serial = af->serial;
2431 static double last_clock;
2432 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2433 is->audio_clock - last_clock,
2434 is->audio_clock, audio_clock0);
2435 last_clock = is->audio_clock;
2438 return resampled_data_size;
2441 /* prepare a new audio buffer */
2442 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2444 VideoState *is = opaque;
2445 int audio_size, len1;
2447 audio_callback_time = av_gettime_relative();
2450 if (is->audio_buf_index >= is->audio_buf_size) {
2451 audio_size = audio_decode_frame(is);
2452 if (audio_size < 0) {
2453 /* if error, just output silence */
2454 is->audio_buf = is->silence_buf;
2455 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2457 if (is->show_mode != SHOW_MODE_VIDEO)
2458 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2459 is->audio_buf_size = audio_size;
2461 is->audio_buf_index = 0;
2463 len1 = is->audio_buf_size - is->audio_buf_index;
2466 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2467 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2469 memset(stream, is->silence_buf[0], len1);
2471 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2475 is->audio_buf_index += len1;
2477 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2478 /* Let's assume the audio driver that is used by SDL has two periods. */
2479 if (!isnan(is->audio_clock)) {
2480 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);
2481 sync_clock_to_slave(&is->extclk, &is->audclk);
2485 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2487 SDL_AudioSpec wanted_spec, spec;
2489 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2490 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2491 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2493 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2495 wanted_nb_channels = atoi(env);
2496 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2498 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2499 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2500 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2502 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2503 wanted_spec.channels = wanted_nb_channels;
2504 wanted_spec.freq = wanted_sample_rate;
2505 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2506 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2509 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2510 next_sample_rate_idx--;
2511 wanted_spec.format = AUDIO_S16SYS;
2512 wanted_spec.silence = 0;
2513 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2514 wanted_spec.callback = sdl_audio_callback;
2515 wanted_spec.userdata = opaque;
2516 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2517 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2518 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2519 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2520 if (!wanted_spec.channels) {
2521 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2522 wanted_spec.channels = wanted_nb_channels;
2523 if (!wanted_spec.freq) {
2524 av_log(NULL, AV_LOG_ERROR,
2525 "No more combinations to try, audio open failed\n");
2529 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2531 if (spec.format != AUDIO_S16SYS) {
2532 av_log(NULL, AV_LOG_ERROR,
2533 "SDL advised audio format %d is not supported!\n", spec.format);
2536 if (spec.channels != wanted_spec.channels) {
2537 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2538 if (!wanted_channel_layout) {
2539 av_log(NULL, AV_LOG_ERROR,
2540 "SDL advised channel count %d is not supported!\n", spec.channels);
2545 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2546 audio_hw_params->freq = spec.freq;
2547 audio_hw_params->channel_layout = wanted_channel_layout;
2548 audio_hw_params->channels = spec.channels;
2549 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2550 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);
2551 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2552 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2558 /* open a given stream. Return 0 if OK */
2559 static int stream_component_open(VideoState *is, int stream_index)
2561 AVFormatContext *ic = is->ic;
2562 AVCodecContext *avctx;
2564 const char *forced_codec_name = NULL;
2566 AVDictionaryEntry *t = NULL;
2567 int sample_rate, nb_channels;
2568 int64_t channel_layout;
2570 int stream_lowres = lowres;
2572 if (stream_index < 0 || stream_index >= ic->nb_streams)
2574 avctx = ic->streams[stream_index]->codec;
2576 codec = avcodec_find_decoder(avctx->codec_id);
2578 switch(avctx->codec_type){
2579 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2580 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2581 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2583 if (forced_codec_name)
2584 codec = avcodec_find_decoder_by_name(forced_codec_name);
2586 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2587 "No codec could be found with name '%s'\n", forced_codec_name);
2588 else av_log(NULL, AV_LOG_WARNING,
2589 "No codec could be found with id %d\n", avctx->codec_id);
2593 avctx->codec_id = codec->id;
2594 if(stream_lowres > av_codec_get_max_lowres(codec)){
2595 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2596 av_codec_get_max_lowres(codec));
2597 stream_lowres = av_codec_get_max_lowres(codec);
2599 av_codec_set_lowres(avctx, stream_lowres);
2602 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2605 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2607 if(codec->capabilities & AV_CODEC_CAP_DR1)
2608 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2611 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2612 if (!av_dict_get(opts, "threads", NULL, 0))
2613 av_dict_set(&opts, "threads", "auto", 0);
2615 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2616 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2617 av_dict_set(&opts, "refcounted_frames", "1", 0);
2618 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2621 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2622 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2623 ret = AVERROR_OPTION_NOT_FOUND;
2628 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2629 switch (avctx->codec_type) {
2630 case AVMEDIA_TYPE_AUDIO:
2635 is->audio_filter_src.freq = avctx->sample_rate;
2636 is->audio_filter_src.channels = avctx->channels;
2637 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2638 is->audio_filter_src.fmt = avctx->sample_fmt;
2639 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2641 link = is->out_audio_filter->inputs[0];
2642 sample_rate = link->sample_rate;
2643 nb_channels = link->channels;
2644 channel_layout = link->channel_layout;
2647 sample_rate = avctx->sample_rate;
2648 nb_channels = avctx->channels;
2649 channel_layout = avctx->channel_layout;
2652 /* prepare audio output */
2653 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2655 is->audio_hw_buf_size = ret;
2656 is->audio_src = is->audio_tgt;
2657 is->audio_buf_size = 0;
2658 is->audio_buf_index = 0;
2660 /* init averaging filter */
2661 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2662 is->audio_diff_avg_count = 0;
2663 /* since we do not have a precise anough audio fifo fullness,
2664 we correct audio sync only if larger than this threshold */
2665 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2667 is->audio_stream = stream_index;
2668 is->audio_st = ic->streams[stream_index];
2670 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2671 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2672 is->auddec.start_pts = is->audio_st->start_time;
2673 is->auddec.start_pts_tb = is->audio_st->time_base;
2675 decoder_start(&is->auddec, audio_thread, is);
2678 case AVMEDIA_TYPE_VIDEO:
2679 is->video_stream = stream_index;
2680 is->video_st = ic->streams[stream_index];
2682 is->viddec_width = avctx->width;
2683 is->viddec_height = avctx->height;
2685 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2686 decoder_start(&is->viddec, video_thread, is);
2687 is->queue_attachments_req = 1;
2689 case AVMEDIA_TYPE_SUBTITLE:
2690 is->subtitle_stream = stream_index;
2691 is->subtitle_st = ic->streams[stream_index];
2693 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2694 decoder_start(&is->subdec, subtitle_thread, is);
2701 av_dict_free(&opts);
2706 static void stream_component_close(VideoState *is, int stream_index)
2708 AVFormatContext *ic = is->ic;
2709 AVCodecContext *avctx;
2711 if (stream_index < 0 || stream_index >= ic->nb_streams)
2713 avctx = ic->streams[stream_index]->codec;
2715 switch (avctx->codec_type) {
2716 case AVMEDIA_TYPE_AUDIO:
2717 decoder_abort(&is->auddec, &is->sampq);
2719 decoder_destroy(&is->auddec);
2720 swr_free(&is->swr_ctx);
2721 av_freep(&is->audio_buf1);
2722 is->audio_buf1_size = 0;
2723 is->audio_buf = NULL;
2726 av_rdft_end(is->rdft);
2727 av_freep(&is->rdft_data);
2732 case AVMEDIA_TYPE_VIDEO:
2733 decoder_abort(&is->viddec, &is->pictq);
2734 decoder_destroy(&is->viddec);
2736 case AVMEDIA_TYPE_SUBTITLE:
2737 decoder_abort(&is->subdec, &is->subpq);
2738 decoder_destroy(&is->subdec);
2744 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2745 avcodec_close(avctx);
2746 switch (avctx->codec_type) {
2747 case AVMEDIA_TYPE_AUDIO:
2748 is->audio_st = NULL;
2749 is->audio_stream = -1;
2751 case AVMEDIA_TYPE_VIDEO:
2752 is->video_st = NULL;
2753 is->video_stream = -1;
2755 case AVMEDIA_TYPE_SUBTITLE:
2756 is->subtitle_st = NULL;
2757 is->subtitle_stream = -1;
2764 static int decode_interrupt_cb(void *ctx)
2766 VideoState *is = ctx;
2767 return is->abort_request;
2770 static int is_realtime(AVFormatContext *s)
2772 if( !strcmp(s->iformat->name, "rtp")
2773 || !strcmp(s->iformat->name, "rtsp")
2774 || !strcmp(s->iformat->name, "sdp")
2778 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2779 || !strncmp(s->filename, "udp:", 4)
2786 /* this thread gets the stream from the disk or the network */
2787 static int read_thread(void *arg)
2789 VideoState *is = arg;
2790 AVFormatContext *ic = NULL;
2792 int st_index[AVMEDIA_TYPE_NB];
2793 AVPacket pkt1, *pkt = &pkt1;
2794 int64_t stream_start_time;
2795 int pkt_in_play_range = 0;
2796 AVDictionaryEntry *t;
2797 AVDictionary **opts;
2798 int orig_nb_streams;
2799 SDL_mutex *wait_mutex = SDL_CreateMutex();
2800 int scan_all_pmts_set = 0;
2803 memset(st_index, -1, sizeof(st_index));
2804 is->last_video_stream = is->video_stream = -1;
2805 is->last_audio_stream = is->audio_stream = -1;
2806 is->last_subtitle_stream = is->subtitle_stream = -1;
2809 ic = avformat_alloc_context();
2811 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2812 ret = AVERROR(ENOMEM);
2815 ic->interrupt_callback.callback = decode_interrupt_cb;
2816 ic->interrupt_callback.opaque = is;
2817 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2818 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2819 scan_all_pmts_set = 1;
2821 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2823 print_error(is->filename, err);
2827 if (scan_all_pmts_set)
2828 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2830 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2831 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2832 ret = AVERROR_OPTION_NOT_FOUND;
2838 ic->flags |= AVFMT_FLAG_GENPTS;
2840 av_format_inject_global_side_data(ic);
2842 opts = setup_find_stream_info_opts(ic, codec_opts);
2843 orig_nb_streams = ic->nb_streams;
2845 err = avformat_find_stream_info(ic, opts);
2847 for (i = 0; i < orig_nb_streams; i++)
2848 av_dict_free(&opts[i]);
2852 av_log(NULL, AV_LOG_WARNING,
2853 "%s: could not find codec parameters\n", is->filename);
2859 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2861 if (seek_by_bytes < 0)
2862 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2864 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2866 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2867 window_title = av_asprintf("%s - %s", t->value, input_filename);
2869 /* if seeking requested, we execute it */
2870 if (start_time != AV_NOPTS_VALUE) {
2873 timestamp = start_time;
2874 /* add the stream start time */
2875 if (ic->start_time != AV_NOPTS_VALUE)
2876 timestamp += ic->start_time;
2877 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2879 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2880 is->filename, (double)timestamp / AV_TIME_BASE);
2884 is->realtime = is_realtime(ic);
2887 av_dump_format(ic, 0, is->filename, 0);
2889 for (i = 0; i < ic->nb_streams; i++) {
2890 AVStream *st = ic->streams[i];
2891 enum AVMediaType type = st->codec->codec_type;
2892 st->discard = AVDISCARD_ALL;
2893 if (wanted_stream_spec[type] && st_index[type] == -1)
2894 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2897 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2898 if (wanted_stream_spec[i] && st_index[i] == -1) {
2899 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));
2900 st_index[i] = INT_MAX;
2905 st_index[AVMEDIA_TYPE_VIDEO] =
2906 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2907 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2909 st_index[AVMEDIA_TYPE_AUDIO] =
2910 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2911 st_index[AVMEDIA_TYPE_AUDIO],
2912 st_index[AVMEDIA_TYPE_VIDEO],
2914 if (!video_disable && !subtitle_disable)
2915 st_index[AVMEDIA_TYPE_SUBTITLE] =
2916 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2917 st_index[AVMEDIA_TYPE_SUBTITLE],
2918 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2919 st_index[AVMEDIA_TYPE_AUDIO] :
2920 st_index[AVMEDIA_TYPE_VIDEO]),
2923 is->show_mode = show_mode;
2924 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2925 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2926 AVCodecContext *avctx = st->codec;
2927 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2929 set_default_window_size(avctx->width, avctx->height, sar);
2932 /* open the streams */
2933 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2934 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2938 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2939 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2941 if (is->show_mode == SHOW_MODE_NONE)
2942 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2944 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2945 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2948 if (is->video_stream < 0 && is->audio_stream < 0) {
2949 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2955 if (infinite_buffer < 0 && is->realtime)
2956 infinite_buffer = 1;
2959 if (is->abort_request)
2961 if (is->paused != is->last_paused) {
2962 is->last_paused = is->paused;
2964 is->read_pause_return = av_read_pause(ic);
2968 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2970 (!strcmp(ic->iformat->name, "rtsp") ||
2971 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2972 /* wait 10 ms to avoid trying to get another packet */
2979 int64_t seek_target = is->seek_pos;
2980 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2981 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2982 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
2983 // of the seek_pos/seek_rel variables
2985 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2987 av_log(NULL, AV_LOG_ERROR,
2988 "%s: error while seeking\n", is->ic->filename);
2990 if (is->audio_stream >= 0) {
2991 packet_queue_flush(&is->audioq);
2992 packet_queue_put(&is->audioq, &flush_pkt);
2994 if (is->subtitle_stream >= 0) {
2995 packet_queue_flush(&is->subtitleq);
2996 packet_queue_put(&is->subtitleq, &flush_pkt);
2998 if (is->video_stream >= 0) {
2999 packet_queue_flush(&is->videoq);
3000 packet_queue_put(&is->videoq, &flush_pkt);
3002 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3003 set_clock(&is->extclk, NAN, 0);
3005 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3009 is->queue_attachments_req = 1;
3012 step_to_next_frame(is);
3014 if (is->queue_attachments_req) {
3015 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3017 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3019 packet_queue_put(&is->videoq, ©);
3020 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3022 is->queue_attachments_req = 0;
3025 /* if the queue are full, no need to read more */
3026 if (infinite_buffer<1 &&
3027 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3028 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3029 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3030 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3031 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3033 SDL_LockMutex(wait_mutex);
3034 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3035 SDL_UnlockMutex(wait_mutex);
3039 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3040 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3041 if (loop != 1 && (!loop || --loop)) {
3042 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3043 } else if (autoexit) {
3048 ret = av_read_frame(ic, pkt);
3050 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3051 if (is->video_stream >= 0)
3052 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3053 if (is->audio_stream >= 0)
3054 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3055 if (is->subtitle_stream >= 0)
3056 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3059 if (ic->pb && ic->pb->error)
3061 SDL_LockMutex(wait_mutex);
3062 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3063 SDL_UnlockMutex(wait_mutex);
3068 /* check if packet is in play range specified by user, then queue, otherwise discard */
3069 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3070 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3071 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3072 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3073 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3074 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3075 <= ((double)duration / 1000000);
3076 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3077 packet_queue_put(&is->audioq, pkt);
3078 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3079 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3080 packet_queue_put(&is->videoq, pkt);
3081 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3082 packet_queue_put(&is->subtitleq, pkt);
3084 av_free_packet(pkt);
3087 /* wait until the end */
3088 while (!is->abort_request) {
3094 /* close each stream */
3095 if (is->audio_stream >= 0)
3096 stream_component_close(is, is->audio_stream);
3097 if (is->video_stream >= 0)
3098 stream_component_close(is, is->video_stream);
3099 if (is->subtitle_stream >= 0)
3100 stream_component_close(is, is->subtitle_stream);
3102 avformat_close_input(&ic);
3109 event.type = FF_QUIT_EVENT;
3110 event.user.data1 = is;
3111 SDL_PushEvent(&event);
3113 SDL_DestroyMutex(wait_mutex);
3117 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3121 is = av_mallocz(sizeof(VideoState));
3124 is->filename = av_strdup(filename);
3127 is->iformat = iformat;
3131 /* start video display */
3132 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3134 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3136 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3139 packet_queue_init(&is->videoq);
3140 packet_queue_init(&is->audioq);
3141 packet_queue_init(&is->subtitleq);
3143 is->continue_read_thread = SDL_CreateCond();
3145 init_clock(&is->vidclk, &is->videoq.serial);
3146 init_clock(&is->audclk, &is->audioq.serial);
3147 init_clock(&is->extclk, &is->extclk.serial);
3148 is->audio_clock_serial = -1;
3149 is->audio_volume = SDL_MIX_MAXVOLUME;
3151 is->av_sync_type = av_sync_type;
3152 is->read_tid = SDL_CreateThread(read_thread, is);
3153 if (!is->read_tid) {
3161 static void stream_cycle_channel(VideoState *is, int codec_type)
3163 AVFormatContext *ic = is->ic;
3164 int start_index, stream_index;
3167 AVProgram *p = NULL;
3168 int nb_streams = is->ic->nb_streams;
3170 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3171 start_index = is->last_video_stream;
3172 old_index = is->video_stream;
3173 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3174 start_index = is->last_audio_stream;
3175 old_index = is->audio_stream;
3177 start_index = is->last_subtitle_stream;
3178 old_index = is->subtitle_stream;
3180 stream_index = start_index;
3182 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3183 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3185 nb_streams = p->nb_stream_indexes;
3186 for (start_index = 0; start_index < nb_streams; start_index++)
3187 if (p->stream_index[start_index] == stream_index)
3189 if (start_index == nb_streams)
3191 stream_index = start_index;
3196 if (++stream_index >= nb_streams)
3198 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3201 is->last_subtitle_stream = -1;
3204 if (start_index == -1)
3208 if (stream_index == start_index)
3210 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3211 if (st->codec->codec_type == codec_type) {
3212 /* check that parameters are OK */
3213 switch (codec_type) {
3214 case AVMEDIA_TYPE_AUDIO:
3215 if (st->codec->sample_rate != 0 &&
3216 st->codec->channels != 0)
3219 case AVMEDIA_TYPE_VIDEO:
3220 case AVMEDIA_TYPE_SUBTITLE:
3228 if (p && stream_index != -1)
3229 stream_index = p->stream_index[stream_index];
3230 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3231 av_get_media_type_string(codec_type),
3235 stream_component_close(is, old_index);
3236 stream_component_open(is, stream_index);
3240 static void toggle_full_screen(VideoState *is)
3242 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3243 /* OS X needs to reallocate the SDL overlays */
3245 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3246 is->pictq.queue[i].reallocate = 1;
3248 is_full_screen = !is_full_screen;
3249 video_open(is, 1, NULL);
3252 static void toggle_audio_display(VideoState *is)
3254 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3255 int next = is->show_mode;
3257 next = (next + 1) % SHOW_MODE_NB;
3258 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3259 if (is->show_mode != next) {
3260 fill_rectangle(screen,
3261 is->xleft, is->ytop, is->width, is->height,
3263 is->force_refresh = 1;
3264 is->show_mode = next;
3268 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3269 double remaining_time = 0.0;
3271 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3272 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3276 if (remaining_time > 0.0)
3277 av_usleep((int64_t)(remaining_time * 1000000.0));
3278 remaining_time = REFRESH_RATE;
3279 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3280 video_refresh(is, &remaining_time);
3285 static void seek_chapter(VideoState *is, int incr)
3287 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3290 if (!is->ic->nb_chapters)
3293 /* find the current chapter */
3294 for (i = 0; i < is->ic->nb_chapters; i++) {
3295 AVChapter *ch = is->ic->chapters[i];
3296 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3304 if (i >= is->ic->nb_chapters)
3307 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3308 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3309 AV_TIME_BASE_Q), 0, 0);
3312 /* handle an event sent by the GUI */
3313 static void event_loop(VideoState *cur_stream)
3316 double incr, pos, frac;
3320 refresh_loop_wait_event(cur_stream, &event);
3321 switch (event.type) {
3323 if (exit_on_keydown) {
3324 do_exit(cur_stream);
3327 switch (event.key.keysym.sym) {
3330 do_exit(cur_stream);
3333 toggle_full_screen(cur_stream);
3334 cur_stream->force_refresh = 1;
3338 toggle_pause(cur_stream);
3341 toggle_mute(cur_stream);
3343 case SDLK_KP_MULTIPLY:
3345 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3347 case SDLK_KP_DIVIDE:
3349 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3351 case SDLK_s: // S: Step to next frame
3352 step_to_next_frame(cur_stream);
3355 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3358 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3361 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3362 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3363 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3366 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3370 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3371 if (++cur_stream->vfilter_idx >= nb_vfilters)
3372 cur_stream->vfilter_idx = 0;
3374 cur_stream->vfilter_idx = 0;
3375 toggle_audio_display(cur_stream);
3378 toggle_audio_display(cur_stream);
3382 if (cur_stream->ic->nb_chapters <= 1) {
3386 seek_chapter(cur_stream, 1);
3389 if (cur_stream->ic->nb_chapters <= 1) {
3393 seek_chapter(cur_stream, -1);
3407 if (seek_by_bytes) {
3409 if (pos < 0 && cur_stream->video_stream >= 0)
3410 pos = frame_queue_last_pos(&cur_stream->pictq);
3411 if (pos < 0 && cur_stream->audio_stream >= 0)
3412 pos = frame_queue_last_pos(&cur_stream->sampq);
3414 pos = avio_tell(cur_stream->ic->pb);
3415 if (cur_stream->ic->bit_rate)
3416 incr *= cur_stream->ic->bit_rate / 8.0;
3420 stream_seek(cur_stream, pos, incr, 1);
3422 pos = get_master_clock(cur_stream);
3424 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3426 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3427 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3428 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3435 case SDL_VIDEOEXPOSE:
3436 cur_stream->force_refresh = 1;
3438 case SDL_MOUSEBUTTONDOWN:
3439 if (exit_on_mousedown) {
3440 do_exit(cur_stream);
3443 case SDL_MOUSEMOTION:
3444 if (cursor_hidden) {
3448 cursor_last_shown = av_gettime_relative();
3449 if (event.type == SDL_MOUSEBUTTONDOWN) {
3452 if (event.motion.state != SDL_PRESSED)
3456 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3457 uint64_t size = avio_size(cur_stream->ic->pb);
3458 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3462 int tns, thh, tmm, tss;
3463 tns = cur_stream->ic->duration / 1000000LL;
3465 tmm = (tns % 3600) / 60;
3467 frac = x / cur_stream->width;
3470 mm = (ns % 3600) / 60;
3472 av_log(NULL, AV_LOG_INFO,
3473 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3474 hh, mm, ss, thh, tmm, tss);
3475 ts = frac * cur_stream->ic->duration;
3476 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3477 ts += cur_stream->ic->start_time;
3478 stream_seek(cur_stream, ts, 0, 0);
3481 case SDL_VIDEORESIZE:
3482 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3483 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3485 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3486 do_exit(cur_stream);
3488 screen_width = cur_stream->width = screen->w;
3489 screen_height = cur_stream->height = screen->h;
3490 cur_stream->force_refresh = 1;
3494 do_exit(cur_stream);
3496 case FF_ALLOC_EVENT:
3497 alloc_picture(event.user.data1);
3505 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3507 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3508 return opt_default(NULL, "video_size", arg);
3511 static int opt_width(void *optctx, const char *opt, const char *arg)
3513 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3517 static int opt_height(void *optctx, const char *opt, const char *arg)
3519 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3523 static int opt_format(void *optctx, const char *opt, const char *arg)
3525 file_iformat = av_find_input_format(arg);
3526 if (!file_iformat) {
3527 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3528 return AVERROR(EINVAL);
3533 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3535 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3536 return opt_default(NULL, "pixel_format", arg);
3539 static int opt_sync(void *optctx, const char *opt, const char *arg)
3541 if (!strcmp(arg, "audio"))
3542 av_sync_type = AV_SYNC_AUDIO_MASTER;
3543 else if (!strcmp(arg, "video"))
3544 av_sync_type = AV_SYNC_VIDEO_MASTER;
3545 else if (!strcmp(arg, "ext"))
3546 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3548 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3554 static int opt_seek(void *optctx, const char *opt, const char *arg)
3556 start_time = parse_time_or_die(opt, arg, 1);
3560 static int opt_duration(void *optctx, const char *opt, const char *arg)
3562 duration = parse_time_or_die(opt, arg, 1);
3566 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3568 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3569 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3570 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3571 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3575 static void opt_input_file(void *optctx, const char *filename)
3577 if (input_filename) {
3578 av_log(NULL, AV_LOG_FATAL,
3579 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3580 filename, input_filename);
3583 if (!strcmp(filename, "-"))
3585 input_filename = filename;
3588 static int opt_codec(void *optctx, const char *opt, const char *arg)
3590 const char *spec = strchr(opt, ':');
3592 av_log(NULL, AV_LOG_ERROR,
3593 "No media specifier was specified in '%s' in option '%s'\n",
3595 return AVERROR(EINVAL);
3599 case 'a' : audio_codec_name = arg; break;
3600 case 's' : subtitle_codec_name = arg; break;
3601 case 'v' : video_codec_name = arg; break;
3603 av_log(NULL, AV_LOG_ERROR,
3604 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3605 return AVERROR(EINVAL);
3612 static const OptionDef options[] = {
3613 #include "cmdutils_common_opts.h"
3614 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3615 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3616 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3617 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3618 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3619 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3620 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3621 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3622 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3623 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3624 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3625 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3626 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3627 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3628 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3629 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3630 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3631 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3632 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3633 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3634 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3635 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3636 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3637 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3638 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3639 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3640 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3641 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3642 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3644 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3645 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3647 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3648 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3649 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3650 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3651 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3652 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3653 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3654 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3655 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3659 static void show_usage(void)
3661 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3662 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3663 av_log(NULL, AV_LOG_INFO, "\n");
3666 void show_help_default(const char *opt, const char *arg)
3668 av_log_set_callback(log_callback_help);
3670 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3671 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3673 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3674 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3675 #if !CONFIG_AVFILTER
3676 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3678 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3680 printf("\nWhile playing:\n"
3682 "f toggle full screen\n"
3685 "9, 0 decrease and increase volume respectively\n"
3686 "/, * decrease and increase volume respectively\n"
3687 "a cycle audio channel in the current program\n"
3688 "v cycle video channel\n"
3689 "t cycle subtitle channel in the current program\n"
3691 "w cycle video filters or show modes\n"
3692 "s activate frame-step mode\n"
3693 "left/right seek backward/forward 10 seconds\n"
3694 "down/up seek backward/forward 1 minute\n"
3695 "page down/page up seek backward/forward 10 minutes\n"
3696 "mouse click seek to percentage in file corresponding to fraction of width\n"
3700 static int lockmgr(void **mtx, enum AVLockOp op)
3703 case AV_LOCK_CREATE:
3704 *mtx = SDL_CreateMutex();
3708 case AV_LOCK_OBTAIN:
3709 return !!SDL_LockMutex(*mtx);
3710 case AV_LOCK_RELEASE:
3711 return !!SDL_UnlockMutex(*mtx);
3712 case AV_LOCK_DESTROY:
3713 SDL_DestroyMutex(*mtx);
3719 /* Called from the main */
3720 int main(int argc, char **argv)
3724 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3726 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3727 parse_loglevel(argc, argv, options);
3729 /* register all codecs, demux and protocols */
3731 avdevice_register_all();
3734 avfilter_register_all();
3737 avformat_network_init();
3741 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3742 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3744 show_banner(argc, argv, options);
3746 parse_options(NULL, argc, argv, options, opt_input_file);
3748 if (!input_filename) {
3750 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3751 av_log(NULL, AV_LOG_FATAL,
3752 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3756 if (display_disable) {
3759 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3761 flags &= ~SDL_INIT_AUDIO;
3762 if (display_disable)
3763 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3764 #if !defined(_WIN32) && !defined(__APPLE__)
3765 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3767 if (SDL_Init (flags)) {
3768 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3769 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3773 if (!display_disable) {
3774 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3775 fs_screen_width = vi->current_w;
3776 fs_screen_height = vi->current_h;
3779 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3780 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3781 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3783 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3785 if (av_lockmgr_register(lockmgr)) {
3786 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3790 av_init_packet(&flush_pkt);
3791 flush_pkt.data = (uint8_t *)&flush_pkt;
3793 is = stream_open(input_filename, file_iformat);
3795 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");