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 int packet_queue_init(PacketQueue *q)
456 memset(q, 0, sizeof(PacketQueue));
457 q->mutex = SDL_CreateMutex();
459 av_log(q, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
460 return AVERROR(ENOMEM);
462 q->cond = SDL_CreateCond();
464 av_log(q, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
465 return AVERROR(ENOMEM);
467 q->abort_request = 1;
471 static void packet_queue_flush(PacketQueue *q)
473 MyAVPacketList *pkt, *pkt1;
475 SDL_LockMutex(q->mutex);
476 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
478 av_free_packet(&pkt->pkt);
485 SDL_UnlockMutex(q->mutex);
488 static void packet_queue_destroy(PacketQueue *q)
490 packet_queue_flush(q);
491 SDL_DestroyMutex(q->mutex);
492 SDL_DestroyCond(q->cond);
495 static void packet_queue_abort(PacketQueue *q)
497 SDL_LockMutex(q->mutex);
499 q->abort_request = 1;
501 SDL_CondSignal(q->cond);
503 SDL_UnlockMutex(q->mutex);
506 static void packet_queue_start(PacketQueue *q)
508 SDL_LockMutex(q->mutex);
509 q->abort_request = 0;
510 packet_queue_put_private(q, &flush_pkt);
511 SDL_UnlockMutex(q->mutex);
514 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
515 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
517 MyAVPacketList *pkt1;
520 SDL_LockMutex(q->mutex);
523 if (q->abort_request) {
530 q->first_pkt = pkt1->next;
534 q->size -= pkt1->pkt.size + sizeof(*pkt1);
537 *serial = pkt1->serial;
545 SDL_CondWait(q->cond, q->mutex);
548 SDL_UnlockMutex(q->mutex);
552 static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
553 memset(d, 0, sizeof(Decoder));
556 d->empty_queue_cond = empty_queue_cond;
557 d->start_pts = AV_NOPTS_VALUE;
560 static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
566 if (d->queue->abort_request)
569 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
572 if (d->queue->nb_packets == 0)
573 SDL_CondSignal(d->empty_queue_cond);
574 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
576 if (pkt.data == flush_pkt.data) {
577 avcodec_flush_buffers(d->avctx);
579 d->next_pts = d->start_pts;
580 d->next_pts_tb = d->start_pts_tb;
582 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
583 av_free_packet(&d->pkt);
584 d->pkt_temp = d->pkt = pkt;
585 d->packet_pending = 1;
588 switch (d->avctx->codec_type) {
589 case AVMEDIA_TYPE_VIDEO:
590 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
592 if (decoder_reorder_pts == -1) {
593 frame->pts = av_frame_get_best_effort_timestamp(frame);
594 } else if (decoder_reorder_pts) {
595 frame->pts = frame->pkt_pts;
597 frame->pts = frame->pkt_dts;
601 case AVMEDIA_TYPE_AUDIO:
602 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
604 AVRational tb = (AVRational){1, frame->sample_rate};
605 if (frame->pts != AV_NOPTS_VALUE)
606 frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
607 else if (frame->pkt_pts != AV_NOPTS_VALUE)
608 frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
609 else if (d->next_pts != AV_NOPTS_VALUE)
610 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
611 if (frame->pts != AV_NOPTS_VALUE) {
612 d->next_pts = frame->pts + frame->nb_samples;
617 case AVMEDIA_TYPE_SUBTITLE:
618 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
623 d->packet_pending = 0;
626 d->pkt_temp.pts = AV_NOPTS_VALUE;
627 if (d->pkt_temp.data) {
628 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
629 ret = d->pkt_temp.size;
630 d->pkt_temp.data += ret;
631 d->pkt_temp.size -= ret;
632 if (d->pkt_temp.size <= 0)
633 d->packet_pending = 0;
636 d->packet_pending = 0;
637 d->finished = d->pkt_serial;
641 } while (!got_frame && !d->finished);
646 static void decoder_destroy(Decoder *d) {
647 av_free_packet(&d->pkt);
650 static void frame_queue_unref_item(Frame *vp)
652 av_frame_unref(vp->frame);
653 avsubtitle_free(&vp->sub);
656 static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
659 memset(f, 0, sizeof(FrameQueue));
660 if (!(f->mutex = SDL_CreateMutex()))
661 return AVERROR(ENOMEM);
662 if (!(f->cond = SDL_CreateCond()))
663 return AVERROR(ENOMEM);
665 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
666 f->keep_last = !!keep_last;
667 for (i = 0; i < f->max_size; i++)
668 if (!(f->queue[i].frame = av_frame_alloc()))
669 return AVERROR(ENOMEM);
673 static void frame_queue_destory(FrameQueue *f)
676 for (i = 0; i < f->max_size; i++) {
677 Frame *vp = &f->queue[i];
678 frame_queue_unref_item(vp);
679 av_frame_free(&vp->frame);
682 SDL_DestroyMutex(f->mutex);
683 SDL_DestroyCond(f->cond);
686 static void frame_queue_signal(FrameQueue *f)
688 SDL_LockMutex(f->mutex);
689 SDL_CondSignal(f->cond);
690 SDL_UnlockMutex(f->mutex);
693 static Frame *frame_queue_peek(FrameQueue *f)
695 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
698 static Frame *frame_queue_peek_next(FrameQueue *f)
700 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
703 static Frame *frame_queue_peek_last(FrameQueue *f)
705 return &f->queue[f->rindex];
708 static Frame *frame_queue_peek_writable(FrameQueue *f)
710 /* wait until we have space to put a new frame */
711 SDL_LockMutex(f->mutex);
712 while (f->size >= f->max_size &&
713 !f->pktq->abort_request) {
714 SDL_CondWait(f->cond, f->mutex);
716 SDL_UnlockMutex(f->mutex);
718 if (f->pktq->abort_request)
721 return &f->queue[f->windex];
724 static Frame *frame_queue_peek_readable(FrameQueue *f)
726 /* wait until we have a readable a new frame */
727 SDL_LockMutex(f->mutex);
728 while (f->size - f->rindex_shown <= 0 &&
729 !f->pktq->abort_request) {
730 SDL_CondWait(f->cond, f->mutex);
732 SDL_UnlockMutex(f->mutex);
734 if (f->pktq->abort_request)
737 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
740 static void frame_queue_push(FrameQueue *f)
742 if (++f->windex == f->max_size)
744 SDL_LockMutex(f->mutex);
746 SDL_CondSignal(f->cond);
747 SDL_UnlockMutex(f->mutex);
750 static void frame_queue_next(FrameQueue *f)
752 if (f->keep_last && !f->rindex_shown) {
756 frame_queue_unref_item(&f->queue[f->rindex]);
757 if (++f->rindex == f->max_size)
759 SDL_LockMutex(f->mutex);
761 SDL_CondSignal(f->cond);
762 SDL_UnlockMutex(f->mutex);
765 /* jump back to the previous frame if available by resetting rindex_shown */
766 static int frame_queue_prev(FrameQueue *f)
768 int ret = f->rindex_shown;
773 /* return the number of undisplayed frames in the queue */
774 static int frame_queue_nb_remaining(FrameQueue *f)
776 return f->size - f->rindex_shown;
779 /* return last shown position */
780 static int64_t frame_queue_last_pos(FrameQueue *f)
782 Frame *fp = &f->queue[f->rindex];
783 if (f->rindex_shown && fp->serial == f->pktq->serial)
789 static void decoder_abort(Decoder *d, FrameQueue *fq)
791 packet_queue_abort(d->queue);
792 frame_queue_signal(fq);
793 SDL_WaitThread(d->decoder_tid, NULL);
794 d->decoder_tid = NULL;
795 packet_queue_flush(d->queue);
798 static inline void fill_rectangle(SDL_Surface *screen,
799 int x, int y, int w, int h, int color, int update)
806 SDL_FillRect(screen, &rect, color);
807 if (update && w > 0 && h > 0)
808 SDL_UpdateRect(screen, x, y, w, h);
811 /* draw only the border of a rectangle */
812 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
816 /* fill the background */
820 w2 = width - (x + w);
826 h2 = height - (y + h);
829 fill_rectangle(screen,
833 fill_rectangle(screen,
834 xleft + width - w2, ytop,
837 fill_rectangle(screen,
841 fill_rectangle(screen,
842 xleft + w1, ytop + height - h2,
847 #define ALPHA_BLEND(a, oldp, newp, s)\
848 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
854 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
856 int x, y, Y, U, V, A;
857 uint8_t *lum, *cb, *cr;
858 int dstx, dsty, dstw, dsth;
859 const AVPicture *src = &rect->pict;
861 dstw = av_clip(rect->w, 0, imgw);
862 dsth = av_clip(rect->h, 0, imgh);
863 dstx = av_clip(rect->x, 0, imgw - dstw);
864 dsty = av_clip(rect->y, 0, imgh - dsth);
865 lum = dst->data[0] + dstx + dsty * dst->linesize[0];
866 cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
867 cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
869 for (y = 0; y<dsth; y++) {
870 for (x = 0; x<dstw; x++) {
871 Y = src->data[0][x + y*src->linesize[0]];
872 A = src->data[3][x + y*src->linesize[3]];
873 lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
876 lum += dst->linesize[0] - dstw;
879 for (y = 0; y<dsth/2; y++) {
880 for (x = 0; x<dstw/2; x++) {
881 U = src->data[1][x + y*src->linesize[1]];
882 V = src->data[2][x + y*src->linesize[2]];
883 A = src->data[3][2*x + 2*y *src->linesize[3]]
884 + src->data[3][2*x + 1 + 2*y *src->linesize[3]]
885 + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
886 + src->data[3][2*x + (2*y+1)*src->linesize[3]];
887 cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
888 cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
892 cb += dst->linesize[1] - dstw/2;
893 cr += dst->linesize[2] - dstw/2;
897 static void free_picture(Frame *vp)
900 SDL_FreeYUVOverlay(vp->bmp);
905 static void calculate_display_rect(SDL_Rect *rect,
906 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
907 int pic_width, int pic_height, AVRational pic_sar)
910 int width, height, x, y;
912 if (pic_sar.num == 0)
915 aspect_ratio = av_q2d(pic_sar);
917 if (aspect_ratio <= 0.0)
919 aspect_ratio *= (float)pic_width / (float)pic_height;
921 /* XXX: we suppose the screen has a 1.0 pixel ratio */
923 width = ((int)rint(height * aspect_ratio)) & ~1;
924 if (width > scr_width) {
926 height = ((int)rint(width / aspect_ratio)) & ~1;
928 x = (scr_width - width) / 2;
929 y = (scr_height - height) / 2;
930 rect->x = scr_xleft + x;
931 rect->y = scr_ytop + y;
932 rect->w = FFMAX(width, 1);
933 rect->h = FFMAX(height, 1);
936 static void video_image_display(VideoState *is)
944 vp = frame_queue_peek(&is->pictq);
946 if (is->subtitle_st) {
947 if (frame_queue_nb_remaining(&is->subpq) > 0) {
948 sp = frame_queue_peek(&is->subpq);
950 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
951 SDL_LockYUVOverlay (vp->bmp);
953 pict.data[0] = vp->bmp->pixels[0];
954 pict.data[1] = vp->bmp->pixels[2];
955 pict.data[2] = vp->bmp->pixels[1];
957 pict.linesize[0] = vp->bmp->pitches[0];
958 pict.linesize[1] = vp->bmp->pitches[2];
959 pict.linesize[2] = vp->bmp->pitches[1];
961 for (i = 0; i < sp->sub.num_rects; i++)
962 blend_subrect(&pict, sp->sub.rects[i],
963 vp->bmp->w, vp->bmp->h);
965 SDL_UnlockYUVOverlay (vp->bmp);
970 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
972 SDL_DisplayYUVOverlay(vp->bmp, &rect);
974 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) {
975 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
976 fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
977 is->last_display_rect = rect;
982 static inline int compute_mod(int a, int b)
984 return a < 0 ? a%b + b : a%b;
987 static void video_audio_display(VideoState *s)
989 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
990 int ch, channels, h, h2, bgcolor, fgcolor;
992 int rdft_bits, nb_freq;
994 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
996 nb_freq = 1 << (rdft_bits - 1);
998 /* compute display index : center on currently output samples */
999 channels = s->audio_tgt.channels;
1000 nb_display_channels = channels;
1002 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
1004 delay = s->audio_write_buf_size;
1007 /* to be more precise, we take into account the time spent since
1008 the last buffer computation */
1009 if (audio_callback_time) {
1010 time_diff = av_gettime_relative() - audio_callback_time;
1011 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1014 delay += 2 * data_used;
1015 if (delay < data_used)
1018 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1019 if (s->show_mode == SHOW_MODE_WAVES) {
1021 for (i = 0; i < 1000; i += channels) {
1022 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1023 int a = s->sample_array[idx];
1024 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1025 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1026 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1028 if (h < score && (b ^ c) < 0) {
1035 s->last_i_start = i_start;
1037 i_start = s->last_i_start;
1040 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
1041 if (s->show_mode == SHOW_MODE_WAVES) {
1042 fill_rectangle(screen,
1043 s->xleft, s->ytop, s->width, s->height,
1046 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
1048 /* total height for one channel */
1049 h = s->height / nb_display_channels;
1050 /* graph height / 2 */
1052 for (ch = 0; ch < nb_display_channels; ch++) {
1054 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1055 for (x = 0; x < s->width; x++) {
1056 y = (s->sample_array[i] * h2) >> 15;
1063 fill_rectangle(screen,
1064 s->xleft + x, ys, 1, y,
1067 if (i >= SAMPLE_ARRAY_SIZE)
1068 i -= SAMPLE_ARRAY_SIZE;
1072 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
1074 for (ch = 1; ch < nb_display_channels; ch++) {
1075 y = s->ytop + ch * h;
1076 fill_rectangle(screen,
1077 s->xleft, y, s->width, 1,
1080 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
1082 nb_display_channels= FFMIN(nb_display_channels, 2);
1083 if (rdft_bits != s->rdft_bits) {
1084 av_rdft_end(s->rdft);
1085 av_free(s->rdft_data);
1086 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1087 s->rdft_bits = rdft_bits;
1088 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1090 if (!s->rdft || !s->rdft_data){
1091 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1092 s->show_mode = SHOW_MODE_WAVES;
1095 for (ch = 0; ch < nb_display_channels; ch++) {
1096 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1098 for (x = 0; x < 2 * nb_freq; x++) {
1099 double w = (x-nb_freq) * (1.0 / nb_freq);
1100 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1102 if (i >= SAMPLE_ARRAY_SIZE)
1103 i -= SAMPLE_ARRAY_SIZE;
1105 av_rdft_calc(s->rdft, data[ch]);
1107 /* Least efficient way to do this, we should of course
1108 * directly access it but it is more than fast enough. */
1109 for (y = 0; y < s->height; y++) {
1110 double w = 1 / sqrt(nb_freq);
1111 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]));
1112 int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
1113 + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
1116 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
1118 fill_rectangle(screen,
1119 s->xpos, s->height-y, 1, 1,
1123 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
1126 if (s->xpos >= s->width)
1131 static void stream_close(VideoState *is)
1133 /* XXX: use a special url_shutdown call to abort parse cleanly */
1134 is->abort_request = 1;
1135 SDL_WaitThread(is->read_tid, NULL);
1136 packet_queue_destroy(&is->videoq);
1137 packet_queue_destroy(&is->audioq);
1138 packet_queue_destroy(&is->subtitleq);
1140 /* free all pictures */
1141 frame_queue_destory(&is->pictq);
1142 frame_queue_destory(&is->sampq);
1143 frame_queue_destory(&is->subpq);
1144 SDL_DestroyCond(is->continue_read_thread);
1145 #if !CONFIG_AVFILTER
1146 sws_freeContext(is->img_convert_ctx);
1148 sws_freeContext(is->sub_convert_ctx);
1149 av_free(is->filename);
1153 static void do_exit(VideoState *is)
1158 av_lockmgr_register(NULL);
1161 av_freep(&vfilters_list);
1163 avformat_network_deinit();
1167 av_log(NULL, AV_LOG_QUIET, "%s", "");
1171 static void sigterm_handler(int sig)
1176 static void set_default_window_size(int width, int height, AVRational sar)
1179 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1180 default_width = rect.w;
1181 default_height = rect.h;
1184 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
1186 int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
1189 if (is_full_screen) flags |= SDL_FULLSCREEN;
1190 else flags |= SDL_RESIZABLE;
1192 if (vp && vp->width)
1193 set_default_window_size(vp->width, vp->height, vp->sar);
1195 if (is_full_screen && fs_screen_width) {
1196 w = fs_screen_width;
1197 h = fs_screen_height;
1198 } else if (!is_full_screen && screen_width) {
1205 w = FFMIN(16383, w);
1206 if (screen && is->width == screen->w && screen->w == w
1207 && is->height== screen->h && screen->h == h && !force_set_video_mode)
1209 screen = SDL_SetVideoMode(w, h, 0, flags);
1211 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1215 window_title = input_filename;
1216 SDL_WM_SetCaption(window_title, window_title);
1218 is->width = screen->w;
1219 is->height = screen->h;
1224 /* display the current picture, if any */
1225 static void video_display(VideoState *is)
1228 video_open(is, 0, NULL);
1229 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1230 video_audio_display(is);
1231 else if (is->video_st)
1232 video_image_display(is);
1235 static double get_clock(Clock *c)
1237 if (*c->queue_serial != c->serial)
1242 double time = av_gettime_relative() / 1000000.0;
1243 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1247 static void set_clock_at(Clock *c, double pts, int serial, double time)
1250 c->last_updated = time;
1251 c->pts_drift = c->pts - time;
1255 static void set_clock(Clock *c, double pts, int serial)
1257 double time = av_gettime_relative() / 1000000.0;
1258 set_clock_at(c, pts, serial, time);
1261 static void set_clock_speed(Clock *c, double speed)
1263 set_clock(c, get_clock(c), c->serial);
1267 static void init_clock(Clock *c, int *queue_serial)
1271 c->queue_serial = queue_serial;
1272 set_clock(c, NAN, -1);
1275 static void sync_clock_to_slave(Clock *c, Clock *slave)
1277 double clock = get_clock(c);
1278 double slave_clock = get_clock(slave);
1279 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1280 set_clock(c, slave_clock, slave->serial);
1283 static int get_master_sync_type(VideoState *is) {
1284 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1286 return AV_SYNC_VIDEO_MASTER;
1288 return AV_SYNC_AUDIO_MASTER;
1289 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1291 return AV_SYNC_AUDIO_MASTER;
1293 return AV_SYNC_EXTERNAL_CLOCK;
1295 return AV_SYNC_EXTERNAL_CLOCK;
1299 /* get the current master clock value */
1300 static double get_master_clock(VideoState *is)
1304 switch (get_master_sync_type(is)) {
1305 case AV_SYNC_VIDEO_MASTER:
1306 val = get_clock(&is->vidclk);
1308 case AV_SYNC_AUDIO_MASTER:
1309 val = get_clock(&is->audclk);
1312 val = get_clock(&is->extclk);
1318 static void check_external_clock_speed(VideoState *is) {
1319 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1320 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1321 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1322 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1323 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1324 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1326 double speed = is->extclk.speed;
1328 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1332 /* seek in the stream */
1333 static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1335 if (!is->seek_req) {
1338 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1340 is->seek_flags |= AVSEEK_FLAG_BYTE;
1342 SDL_CondSignal(is->continue_read_thread);
1346 /* pause or resume the video */
1347 static void stream_toggle_pause(VideoState *is)
1350 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1351 if (is->read_pause_return != AVERROR(ENOSYS)) {
1352 is->vidclk.paused = 0;
1354 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1356 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1357 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1360 static void toggle_pause(VideoState *is)
1362 stream_toggle_pause(is);
1366 static void toggle_mute(VideoState *is)
1368 is->muted = !is->muted;
1371 static void update_volume(VideoState *is, int sign, int step)
1373 is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
1376 static void step_to_next_frame(VideoState *is)
1378 /* if the stream is paused unpause it, then step */
1380 stream_toggle_pause(is);
1384 static double compute_target_delay(double delay, VideoState *is)
1386 double sync_threshold, diff = 0;
1388 /* update delay to follow master synchronisation source */
1389 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1390 /* if video is slave, we try to correct big delays by
1391 duplicating or deleting a frame */
1392 diff = get_clock(&is->vidclk) - get_master_clock(is);
1394 /* skip or repeat frame. We take into account the
1395 delay to compute the threshold. I still don't know
1396 if it is the best guess */
1397 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1398 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1399 if (diff <= -sync_threshold)
1400 delay = FFMAX(0, delay + diff);
1401 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1402 delay = delay + diff;
1403 else if (diff >= sync_threshold)
1408 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1414 static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1415 if (vp->serial == nextvp->serial) {
1416 double duration = nextvp->pts - vp->pts;
1417 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1418 return vp->duration;
1426 static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1427 /* update current video pts */
1428 set_clock(&is->vidclk, pts, serial);
1429 sync_clock_to_slave(&is->extclk, &is->vidclk);
1432 /* called to display each frame */
1433 static void video_refresh(void *opaque, double *remaining_time)
1435 VideoState *is = opaque;
1440 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1441 check_external_clock_speed(is);
1443 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1444 time = av_gettime_relative() / 1000000.0;
1445 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1447 is->last_vis_time = time;
1449 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1454 if (is->force_refresh)
1455 redisplay = frame_queue_prev(&is->pictq);
1457 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1458 // nothing to do, no picture to display in the queue
1460 double last_duration, duration, delay;
1463 /* dequeue the picture */
1464 lastvp = frame_queue_peek_last(&is->pictq);
1465 vp = frame_queue_peek(&is->pictq);
1467 if (vp->serial != is->videoq.serial) {
1468 frame_queue_next(&is->pictq);
1473 if (lastvp->serial != vp->serial && !redisplay)
1474 is->frame_timer = av_gettime_relative() / 1000000.0;
1479 /* compute nominal last_duration */
1480 last_duration = vp_duration(is, lastvp, vp);
1484 delay = compute_target_delay(last_duration, is);
1486 time= av_gettime_relative()/1000000.0;
1487 if (time < is->frame_timer + delay && !redisplay) {
1488 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1492 is->frame_timer += delay;
1493 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1494 is->frame_timer = time;
1496 SDL_LockMutex(is->pictq.mutex);
1497 if (!redisplay && !isnan(vp->pts))
1498 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1499 SDL_UnlockMutex(is->pictq.mutex);
1501 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1502 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1503 duration = vp_duration(is, vp, nextvp);
1504 if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1506 is->frame_drops_late++;
1507 frame_queue_next(&is->pictq);
1513 if (is->subtitle_st) {
1514 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1515 sp = frame_queue_peek(&is->subpq);
1517 if (frame_queue_nb_remaining(&is->subpq) > 1)
1518 sp2 = frame_queue_peek_next(&is->subpq);
1522 if (sp->serial != is->subtitleq.serial
1523 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1524 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1526 frame_queue_next(&is->subpq);
1534 /* display picture */
1535 if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
1538 frame_queue_next(&is->pictq);
1540 if (is->step && !is->paused)
1541 stream_toggle_pause(is);
1544 is->force_refresh = 0;
1546 static int64_t last_time;
1548 int aqsize, vqsize, sqsize;
1551 cur_time = av_gettime_relative();
1552 if (!last_time || (cur_time - last_time) >= 30000) {
1557 aqsize = is->audioq.size;
1559 vqsize = is->videoq.size;
1560 if (is->subtitle_st)
1561 sqsize = is->subtitleq.size;
1563 if (is->audio_st && is->video_st)
1564 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1565 else if (is->video_st)
1566 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1567 else if (is->audio_st)
1568 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1569 av_log(NULL, AV_LOG_INFO,
1570 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1571 get_master_clock(is),
1572 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1574 is->frame_drops_early + is->frame_drops_late,
1578 is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1579 is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1581 last_time = cur_time;
1586 /* allocate a picture (needs to do that in main thread to avoid
1587 potential locking problems */
1588 static void alloc_picture(VideoState *is)
1593 vp = &is->pictq.queue[is->pictq.windex];
1597 video_open(is, 0, vp);
1599 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1602 bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
1603 if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
1604 /* SDL allocates a buffer smaller than requested if the video
1605 * overlay hardware is unable to support the requested size. */
1606 av_log(NULL, AV_LOG_FATAL,
1607 "Error: the video system does not support an image\n"
1608 "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1609 "to reduce the image size.\n", vp->width, vp->height );
1613 SDL_LockMutex(is->pictq.mutex);
1615 SDL_CondSignal(is->pictq.cond);
1616 SDL_UnlockMutex(is->pictq.mutex);
1619 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
1620 int i, width, height;
1622 for (i = 0; i < 3; i++) {
1629 if (bmp->pitches[i] > width) {
1630 maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
1631 for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
1637 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1641 #if defined(DEBUG_SYNC) && 0
1642 printf("frame_type=%c pts=%0.3f\n",
1643 av_get_picture_type_char(src_frame->pict_type), pts);
1646 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1649 vp->sar = src_frame->sample_aspect_ratio;
1651 /* alloc or resize hardware picture buffer */
1652 if (!vp->bmp || vp->reallocate || !vp->allocated ||
1653 vp->width != src_frame->width ||
1654 vp->height != src_frame->height) {
1659 vp->width = src_frame->width;
1660 vp->height = src_frame->height;
1662 /* the allocation must be done in the main thread to avoid
1663 locking problems. */
1664 event.type = FF_ALLOC_EVENT;
1665 event.user.data1 = is;
1666 SDL_PushEvent(&event);
1668 /* wait until the picture is allocated */
1669 SDL_LockMutex(is->pictq.mutex);
1670 while (!vp->allocated && !is->videoq.abort_request) {
1671 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1673 /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
1674 if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
1675 while (!vp->allocated && !is->abort_request) {
1676 SDL_CondWait(is->pictq.cond, is->pictq.mutex);
1679 SDL_UnlockMutex(is->pictq.mutex);
1681 if (is->videoq.abort_request)
1685 /* if the frame is not skipped, then display it */
1687 AVPicture pict = { { 0 } };
1689 /* get a pointer on the bitmap */
1690 SDL_LockYUVOverlay (vp->bmp);
1692 pict.data[0] = vp->bmp->pixels[0];
1693 pict.data[1] = vp->bmp->pixels[2];
1694 pict.data[2] = vp->bmp->pixels[1];
1696 pict.linesize[0] = vp->bmp->pitches[0];
1697 pict.linesize[1] = vp->bmp->pitches[2];
1698 pict.linesize[2] = vp->bmp->pitches[1];
1701 // FIXME use direct rendering
1702 av_picture_copy(&pict, (AVPicture *)src_frame,
1703 src_frame->format, vp->width, vp->height);
1706 AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
1708 const AVClass *class = sws_get_class();
1709 const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
1710 AV_OPT_SEARCH_FAKE_OBJ);
1711 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
1717 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1718 vp->width, vp->height, src_frame->format, vp->width, vp->height,
1719 AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
1720 if (!is->img_convert_ctx) {
1721 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
1724 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1725 0, vp->height, pict.data, pict.linesize);
1727 /* workaround SDL PITCH_WORKAROUND */
1728 duplicate_right_border_pixels(vp->bmp);
1729 /* update the bitmap content */
1730 SDL_UnlockYUVOverlay(vp->bmp);
1733 vp->duration = duration;
1735 vp->serial = serial;
1737 /* now we can update the picture count */
1738 frame_queue_push(&is->pictq);
1743 static int get_video_frame(VideoState *is, AVFrame *frame)
1747 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1753 if (frame->pts != AV_NOPTS_VALUE)
1754 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1756 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1758 is->viddec_width = frame->width;
1759 is->viddec_height = frame->height;
1761 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1762 if (frame->pts != AV_NOPTS_VALUE) {
1763 double diff = dpts - get_master_clock(is);
1764 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1765 diff - is->frame_last_filter_delay < 0 &&
1766 is->viddec.pkt_serial == is->vidclk.serial &&
1767 is->videoq.nb_packets) {
1768 is->frame_drops_early++;
1769 av_frame_unref(frame);
1780 static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1781 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1784 int nb_filters = graph->nb_filters;
1785 AVFilterInOut *outputs = NULL, *inputs = NULL;
1788 outputs = avfilter_inout_alloc();
1789 inputs = avfilter_inout_alloc();
1790 if (!outputs || !inputs) {
1791 ret = AVERROR(ENOMEM);
1795 outputs->name = av_strdup("in");
1796 outputs->filter_ctx = source_ctx;
1797 outputs->pad_idx = 0;
1798 outputs->next = NULL;
1800 inputs->name = av_strdup("out");
1801 inputs->filter_ctx = sink_ctx;
1802 inputs->pad_idx = 0;
1803 inputs->next = NULL;
1805 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1808 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1812 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1813 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1814 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1816 ret = avfilter_graph_config(graph, NULL);
1818 avfilter_inout_free(&outputs);
1819 avfilter_inout_free(&inputs);
1823 static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1825 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
1826 char sws_flags_str[512] = "";
1827 char buffersrc_args[256];
1829 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1830 AVCodecContext *codec = is->video_st->codec;
1831 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1832 AVDictionaryEntry *e = NULL;
1834 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1835 if (!strcmp(e->key, "sws_flags")) {
1836 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1838 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1840 if (strlen(sws_flags_str))
1841 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1843 graph->scale_sws_opts = av_strdup(sws_flags_str);
1845 snprintf(buffersrc_args, sizeof(buffersrc_args),
1846 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1847 frame->width, frame->height, frame->format,
1848 is->video_st->time_base.num, is->video_st->time_base.den,
1849 codec->sample_aspect_ratio.num, FFMAX(codec->sample_aspect_ratio.den, 1));
1850 if (fr.num && fr.den)
1851 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1853 if ((ret = avfilter_graph_create_filter(&filt_src,
1854 avfilter_get_by_name("buffer"),
1855 "ffplay_buffer", buffersrc_args, NULL,
1859 ret = avfilter_graph_create_filter(&filt_out,
1860 avfilter_get_by_name("buffersink"),
1861 "ffplay_buffersink", NULL, NULL, graph);
1865 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1868 last_filter = filt_out;
1870 /* Note: this macro adds a filter before the lastly added filter, so the
1871 * processing order of the filters is in reverse */
1872 #define INSERT_FILT(name, arg) do { \
1873 AVFilterContext *filt_ctx; \
1875 ret = avfilter_graph_create_filter(&filt_ctx, \
1876 avfilter_get_by_name(name), \
1877 "ffplay_" name, arg, NULL, graph); \
1881 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1885 last_filter = filt_ctx; \
1888 /* SDL YUV code is not handling odd width/height for some driver
1889 * combinations, therefore we crop the picture to an even width/height. */
1890 INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
1893 double theta = get_rotation(is->video_st);
1895 if (fabs(theta - 90) < 1.0) {
1896 INSERT_FILT("transpose", "clock");
1897 } else if (fabs(theta - 180) < 1.0) {
1898 INSERT_FILT("hflip", NULL);
1899 INSERT_FILT("vflip", NULL);
1900 } else if (fabs(theta - 270) < 1.0) {
1901 INSERT_FILT("transpose", "cclock");
1902 } else if (fabs(theta) > 1.0) {
1903 char rotate_buf[64];
1904 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1905 INSERT_FILT("rotate", rotate_buf);
1909 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1912 is->in_video_filter = filt_src;
1913 is->out_video_filter = filt_out;
1919 static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1921 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1922 int sample_rates[2] = { 0, -1 };
1923 int64_t channel_layouts[2] = { 0, -1 };
1924 int channels[2] = { 0, -1 };
1925 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1926 char aresample_swr_opts[512] = "";
1927 AVDictionaryEntry *e = NULL;
1928 char asrc_args[256];
1931 avfilter_graph_free(&is->agraph);
1932 if (!(is->agraph = avfilter_graph_alloc()))
1933 return AVERROR(ENOMEM);
1935 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1936 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1937 if (strlen(aresample_swr_opts))
1938 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1939 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1941 ret = snprintf(asrc_args, sizeof(asrc_args),
1942 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1943 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1944 is->audio_filter_src.channels,
1945 1, is->audio_filter_src.freq);
1946 if (is->audio_filter_src.channel_layout)
1947 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1948 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1950 ret = avfilter_graph_create_filter(&filt_asrc,
1951 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1952 asrc_args, NULL, is->agraph);
1957 ret = avfilter_graph_create_filter(&filt_asink,
1958 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1959 NULL, NULL, is->agraph);
1963 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1965 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1968 if (force_output_format) {
1969 channel_layouts[0] = is->audio_tgt.channel_layout;
1970 channels [0] = is->audio_tgt.channels;
1971 sample_rates [0] = is->audio_tgt.freq;
1972 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1974 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1976 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1978 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1983 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1986 is->in_audio_filter = filt_asrc;
1987 is->out_audio_filter = filt_asink;
1991 avfilter_graph_free(&is->agraph);
1994 #endif /* CONFIG_AVFILTER */
1996 static int audio_thread(void *arg)
1998 VideoState *is = arg;
1999 AVFrame *frame = av_frame_alloc();
2002 int last_serial = -1;
2003 int64_t dec_channel_layout;
2011 return AVERROR(ENOMEM);
2014 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
2018 tb = (AVRational){1, frame->sample_rate};
2021 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
2024 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
2025 frame->format, av_frame_get_channels(frame)) ||
2026 is->audio_filter_src.channel_layout != dec_channel_layout ||
2027 is->audio_filter_src.freq != frame->sample_rate ||
2028 is->auddec.pkt_serial != last_serial;
2031 char buf1[1024], buf2[1024];
2032 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
2033 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
2034 av_log(NULL, AV_LOG_DEBUG,
2035 "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",
2036 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
2037 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
2039 is->audio_filter_src.fmt = frame->format;
2040 is->audio_filter_src.channels = av_frame_get_channels(frame);
2041 is->audio_filter_src.channel_layout = dec_channel_layout;
2042 is->audio_filter_src.freq = frame->sample_rate;
2043 last_serial = is->auddec.pkt_serial;
2045 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2049 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2052 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2053 tb = is->out_audio_filter->inputs[0]->time_base;
2055 if (!(af = frame_queue_peek_writable(&is->sampq)))
2058 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2059 af->pos = av_frame_get_pkt_pos(frame);
2060 af->serial = is->auddec.pkt_serial;
2061 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2063 av_frame_move_ref(af->frame, frame);
2064 frame_queue_push(&is->sampq);
2067 if (is->audioq.serial != is->auddec.pkt_serial)
2070 if (ret == AVERROR_EOF)
2071 is->auddec.finished = is->auddec.pkt_serial;
2074 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2077 avfilter_graph_free(&is->agraph);
2079 av_frame_free(&frame);
2083 static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2085 packet_queue_start(d->queue);
2086 d->decoder_tid = SDL_CreateThread(fn, arg);
2087 if (!d->decoder_tid) {
2088 av_log(d, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2089 return AVERROR(ENOMEM);
2094 static int video_thread(void *arg)
2096 VideoState *is = arg;
2097 AVFrame *frame = av_frame_alloc();
2101 AVRational tb = is->video_st->time_base;
2102 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2105 AVFilterGraph *graph = avfilter_graph_alloc();
2106 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2109 enum AVPixelFormat last_format = -2;
2110 int last_serial = -1;
2111 int last_vfilter_idx = 0;
2113 av_frame_free(&frame);
2114 return AVERROR(ENOMEM);
2121 avfilter_graph_free(&graph);
2123 return AVERROR(ENOMEM);
2127 ret = get_video_frame(is, frame);
2134 if ( last_w != frame->width
2135 || last_h != frame->height
2136 || last_format != frame->format
2137 || last_serial != is->viddec.pkt_serial
2138 || last_vfilter_idx != is->vfilter_idx) {
2139 av_log(NULL, AV_LOG_DEBUG,
2140 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2142 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2143 frame->width, frame->height,
2144 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2145 avfilter_graph_free(&graph);
2146 graph = avfilter_graph_alloc();
2147 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2149 event.type = FF_QUIT_EVENT;
2150 event.user.data1 = is;
2151 SDL_PushEvent(&event);
2154 filt_in = is->in_video_filter;
2155 filt_out = is->out_video_filter;
2156 last_w = frame->width;
2157 last_h = frame->height;
2158 last_format = frame->format;
2159 last_serial = is->viddec.pkt_serial;
2160 last_vfilter_idx = is->vfilter_idx;
2161 frame_rate = filt_out->inputs[0]->frame_rate;
2164 ret = av_buffersrc_add_frame(filt_in, frame);
2169 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2171 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2173 if (ret == AVERROR_EOF)
2174 is->viddec.finished = is->viddec.pkt_serial;
2179 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2180 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2181 is->frame_last_filter_delay = 0;
2182 tb = filt_out->inputs[0]->time_base;
2184 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2185 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2186 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2187 av_frame_unref(frame);
2197 avfilter_graph_free(&graph);
2199 av_frame_free(&frame);
2203 static int subtitle_thread(void *arg)
2205 VideoState *is = arg;
2212 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2215 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2220 if (got_subtitle && sp->sub.format == 0) {
2221 if (sp->sub.pts != AV_NOPTS_VALUE)
2222 pts = sp->sub.pts / (double)AV_TIME_BASE;
2224 sp->serial = is->subdec.pkt_serial;
2226 for (i = 0; i < sp->sub.num_rects; i++)
2228 int in_w = sp->sub.rects[i]->w;
2229 int in_h = sp->sub.rects[i]->h;
2230 int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2231 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2232 int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2233 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2236 //can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2237 av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2238 newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2239 newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2240 newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2241 newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2243 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2244 in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2245 AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2246 if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2247 !newpic.data[1] || !newpic.data[2]
2249 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2252 sws_scale(is->sub_convert_ctx,
2253 (void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2254 0, in_h, newpic.data, newpic.linesize);
2256 av_free(sp->sub.rects[i]->pict.data[0]);
2257 av_free(sp->sub.rects[i]->pict.data[1]);
2258 sp->sub.rects[i]->pict = newpic;
2259 sp->sub.rects[i]->w = out_w;
2260 sp->sub.rects[i]->h = out_h;
2261 sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2262 sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2265 /* now we can update the picture count */
2266 frame_queue_push(&is->subpq);
2267 } else if (got_subtitle) {
2268 avsubtitle_free(&sp->sub);
2274 /* copy samples for viewing in editor window */
2275 static void update_sample_display(VideoState *is, short *samples, int samples_size)
2279 size = samples_size / sizeof(short);
2281 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2284 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2286 is->sample_array_index += len;
2287 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2288 is->sample_array_index = 0;
2293 /* return the wanted number of samples to get better sync if sync_type is video
2294 * or external master clock */
2295 static int synchronize_audio(VideoState *is, int nb_samples)
2297 int wanted_nb_samples = nb_samples;
2299 /* if not master, then we try to remove or add samples to correct the clock */
2300 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2301 double diff, avg_diff;
2302 int min_nb_samples, max_nb_samples;
2304 diff = get_clock(&is->audclk) - get_master_clock(is);
2306 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2307 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2308 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2309 /* not enough measures to have a correct estimate */
2310 is->audio_diff_avg_count++;
2312 /* estimate the A-V difference */
2313 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2315 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2316 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2317 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2318 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2319 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2321 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2322 diff, avg_diff, wanted_nb_samples - nb_samples,
2323 is->audio_clock, is->audio_diff_threshold);
2326 /* too big difference : may be initial PTS errors, so
2328 is->audio_diff_avg_count = 0;
2329 is->audio_diff_cum = 0;
2333 return wanted_nb_samples;
2337 * Decode one audio frame and return its uncompressed size.
2339 * The processed audio frame is decoded, converted if required, and
2340 * stored in is->audio_buf, with size in bytes given by the return
2343 static int audio_decode_frame(VideoState *is)
2345 int data_size, resampled_data_size;
2346 int64_t dec_channel_layout;
2347 av_unused double audio_clock0;
2348 int wanted_nb_samples;
2356 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2357 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2362 if (!(af = frame_queue_peek_readable(&is->sampq)))
2364 frame_queue_next(&is->sampq);
2365 } while (af->serial != is->audioq.serial);
2367 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2368 af->frame->nb_samples,
2369 af->frame->format, 1);
2371 dec_channel_layout =
2372 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2373 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2374 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2376 if (af->frame->format != is->audio_src.fmt ||
2377 dec_channel_layout != is->audio_src.channel_layout ||
2378 af->frame->sample_rate != is->audio_src.freq ||
2379 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2380 swr_free(&is->swr_ctx);
2381 is->swr_ctx = swr_alloc_set_opts(NULL,
2382 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2383 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2385 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2386 av_log(NULL, AV_LOG_ERROR,
2387 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2388 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2389 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2390 swr_free(&is->swr_ctx);
2393 is->audio_src.channel_layout = dec_channel_layout;
2394 is->audio_src.channels = av_frame_get_channels(af->frame);
2395 is->audio_src.freq = af->frame->sample_rate;
2396 is->audio_src.fmt = af->frame->format;
2400 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2401 uint8_t **out = &is->audio_buf1;
2402 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2403 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2406 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2409 if (wanted_nb_samples != af->frame->nb_samples) {
2410 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2411 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2412 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2416 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2417 if (!is->audio_buf1)
2418 return AVERROR(ENOMEM);
2419 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2421 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2424 if (len2 == out_count) {
2425 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2426 if (swr_init(is->swr_ctx) < 0)
2427 swr_free(&is->swr_ctx);
2429 is->audio_buf = is->audio_buf1;
2430 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2432 is->audio_buf = af->frame->data[0];
2433 resampled_data_size = data_size;
2436 audio_clock0 = is->audio_clock;
2437 /* update the audio clock with the pts */
2438 if (!isnan(af->pts))
2439 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2441 is->audio_clock = NAN;
2442 is->audio_clock_serial = af->serial;
2445 static double last_clock;
2446 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2447 is->audio_clock - last_clock,
2448 is->audio_clock, audio_clock0);
2449 last_clock = is->audio_clock;
2452 return resampled_data_size;
2455 /* prepare a new audio buffer */
2456 static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2458 VideoState *is = opaque;
2459 int audio_size, len1;
2461 audio_callback_time = av_gettime_relative();
2464 if (is->audio_buf_index >= is->audio_buf_size) {
2465 audio_size = audio_decode_frame(is);
2466 if (audio_size < 0) {
2467 /* if error, just output silence */
2468 is->audio_buf = is->silence_buf;
2469 is->audio_buf_size = sizeof(is->silence_buf) / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2471 if (is->show_mode != SHOW_MODE_VIDEO)
2472 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2473 is->audio_buf_size = audio_size;
2475 is->audio_buf_index = 0;
2477 len1 = is->audio_buf_size - is->audio_buf_index;
2480 if (!is->muted && is->audio_volume == SDL_MIX_MAXVOLUME)
2481 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2483 memset(stream, is->silence_buf[0], len1);
2485 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2489 is->audio_buf_index += len1;
2491 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2492 /* Let's assume the audio driver that is used by SDL has two periods. */
2493 if (!isnan(is->audio_clock)) {
2494 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);
2495 sync_clock_to_slave(&is->extclk, &is->audclk);
2499 static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2501 SDL_AudioSpec wanted_spec, spec;
2503 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2504 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2505 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2507 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2509 wanted_nb_channels = atoi(env);
2510 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2512 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2513 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2514 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2516 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2517 wanted_spec.channels = wanted_nb_channels;
2518 wanted_spec.freq = wanted_sample_rate;
2519 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2520 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2523 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2524 next_sample_rate_idx--;
2525 wanted_spec.format = AUDIO_S16SYS;
2526 wanted_spec.silence = 0;
2527 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2528 wanted_spec.callback = sdl_audio_callback;
2529 wanted_spec.userdata = opaque;
2530 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2531 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2532 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2533 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2534 if (!wanted_spec.channels) {
2535 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2536 wanted_spec.channels = wanted_nb_channels;
2537 if (!wanted_spec.freq) {
2538 av_log(NULL, AV_LOG_ERROR,
2539 "No more combinations to try, audio open failed\n");
2543 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2545 if (spec.format != AUDIO_S16SYS) {
2546 av_log(NULL, AV_LOG_ERROR,
2547 "SDL advised audio format %d is not supported!\n", spec.format);
2550 if (spec.channels != wanted_spec.channels) {
2551 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2552 if (!wanted_channel_layout) {
2553 av_log(NULL, AV_LOG_ERROR,
2554 "SDL advised channel count %d is not supported!\n", spec.channels);
2559 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2560 audio_hw_params->freq = spec.freq;
2561 audio_hw_params->channel_layout = wanted_channel_layout;
2562 audio_hw_params->channels = spec.channels;
2563 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2564 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);
2565 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2566 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2572 /* open a given stream. Return 0 if OK */
2573 static int stream_component_open(VideoState *is, int stream_index)
2575 AVFormatContext *ic = is->ic;
2576 AVCodecContext *avctx;
2578 const char *forced_codec_name = NULL;
2580 AVDictionaryEntry *t = NULL;
2581 int sample_rate, nb_channels;
2582 int64_t channel_layout;
2584 int stream_lowres = lowres;
2586 if (stream_index < 0 || stream_index >= ic->nb_streams)
2588 avctx = ic->streams[stream_index]->codec;
2590 codec = avcodec_find_decoder(avctx->codec_id);
2592 switch(avctx->codec_type){
2593 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2594 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2595 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2597 if (forced_codec_name)
2598 codec = avcodec_find_decoder_by_name(forced_codec_name);
2600 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2601 "No codec could be found with name '%s'\n", forced_codec_name);
2602 else av_log(NULL, AV_LOG_WARNING,
2603 "No codec could be found with id %d\n", avctx->codec_id);
2607 avctx->codec_id = codec->id;
2608 if(stream_lowres > av_codec_get_max_lowres(codec)){
2609 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2610 av_codec_get_max_lowres(codec));
2611 stream_lowres = av_codec_get_max_lowres(codec);
2613 av_codec_set_lowres(avctx, stream_lowres);
2616 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2619 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2621 if(codec->capabilities & AV_CODEC_CAP_DR1)
2622 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2625 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2626 if (!av_dict_get(opts, "threads", NULL, 0))
2627 av_dict_set(&opts, "threads", "auto", 0);
2629 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2630 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2631 av_dict_set(&opts, "refcounted_frames", "1", 0);
2632 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2635 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2636 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2637 ret = AVERROR_OPTION_NOT_FOUND;
2642 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2643 switch (avctx->codec_type) {
2644 case AVMEDIA_TYPE_AUDIO:
2649 is->audio_filter_src.freq = avctx->sample_rate;
2650 is->audio_filter_src.channels = avctx->channels;
2651 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2652 is->audio_filter_src.fmt = avctx->sample_fmt;
2653 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2655 link = is->out_audio_filter->inputs[0];
2656 sample_rate = link->sample_rate;
2657 nb_channels = link->channels;
2658 channel_layout = link->channel_layout;
2661 sample_rate = avctx->sample_rate;
2662 nb_channels = avctx->channels;
2663 channel_layout = avctx->channel_layout;
2666 /* prepare audio output */
2667 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2669 is->audio_hw_buf_size = ret;
2670 is->audio_src = is->audio_tgt;
2671 is->audio_buf_size = 0;
2672 is->audio_buf_index = 0;
2674 /* init averaging filter */
2675 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2676 is->audio_diff_avg_count = 0;
2677 /* since we do not have a precise anough audio fifo fullness,
2678 we correct audio sync only if larger than this threshold */
2679 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2681 is->audio_stream = stream_index;
2682 is->audio_st = ic->streams[stream_index];
2684 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2685 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2686 is->auddec.start_pts = is->audio_st->start_time;
2687 is->auddec.start_pts_tb = is->audio_st->time_base;
2689 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2693 case AVMEDIA_TYPE_VIDEO:
2694 is->video_stream = stream_index;
2695 is->video_st = ic->streams[stream_index];
2697 is->viddec_width = avctx->width;
2698 is->viddec_height = avctx->height;
2700 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2701 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2703 is->queue_attachments_req = 1;
2705 case AVMEDIA_TYPE_SUBTITLE:
2706 is->subtitle_stream = stream_index;
2707 is->subtitle_st = ic->streams[stream_index];
2709 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2710 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2718 av_dict_free(&opts);
2723 static void stream_component_close(VideoState *is, int stream_index)
2725 AVFormatContext *ic = is->ic;
2726 AVCodecContext *avctx;
2728 if (stream_index < 0 || stream_index >= ic->nb_streams)
2730 avctx = ic->streams[stream_index]->codec;
2732 switch (avctx->codec_type) {
2733 case AVMEDIA_TYPE_AUDIO:
2734 decoder_abort(&is->auddec, &is->sampq);
2736 decoder_destroy(&is->auddec);
2737 swr_free(&is->swr_ctx);
2738 av_freep(&is->audio_buf1);
2739 is->audio_buf1_size = 0;
2740 is->audio_buf = NULL;
2743 av_rdft_end(is->rdft);
2744 av_freep(&is->rdft_data);
2749 case AVMEDIA_TYPE_VIDEO:
2750 decoder_abort(&is->viddec, &is->pictq);
2751 decoder_destroy(&is->viddec);
2753 case AVMEDIA_TYPE_SUBTITLE:
2754 decoder_abort(&is->subdec, &is->subpq);
2755 decoder_destroy(&is->subdec);
2761 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2762 avcodec_close(avctx);
2763 switch (avctx->codec_type) {
2764 case AVMEDIA_TYPE_AUDIO:
2765 is->audio_st = NULL;
2766 is->audio_stream = -1;
2768 case AVMEDIA_TYPE_VIDEO:
2769 is->video_st = NULL;
2770 is->video_stream = -1;
2772 case AVMEDIA_TYPE_SUBTITLE:
2773 is->subtitle_st = NULL;
2774 is->subtitle_stream = -1;
2781 static int decode_interrupt_cb(void *ctx)
2783 VideoState *is = ctx;
2784 return is->abort_request;
2787 static int is_realtime(AVFormatContext *s)
2789 if( !strcmp(s->iformat->name, "rtp")
2790 || !strcmp(s->iformat->name, "rtsp")
2791 || !strcmp(s->iformat->name, "sdp")
2795 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2796 || !strncmp(s->filename, "udp:", 4)
2803 /* this thread gets the stream from the disk or the network */
2804 static int read_thread(void *arg)
2806 VideoState *is = arg;
2807 AVFormatContext *ic = NULL;
2809 int st_index[AVMEDIA_TYPE_NB];
2810 AVPacket pkt1, *pkt = &pkt1;
2811 int64_t stream_start_time;
2812 int pkt_in_play_range = 0;
2813 AVDictionaryEntry *t;
2814 AVDictionary **opts;
2815 int orig_nb_streams;
2816 SDL_mutex *wait_mutex = SDL_CreateMutex();
2817 int scan_all_pmts_set = 0;
2820 memset(st_index, -1, sizeof(st_index));
2821 is->last_video_stream = is->video_stream = -1;
2822 is->last_audio_stream = is->audio_stream = -1;
2823 is->last_subtitle_stream = is->subtitle_stream = -1;
2826 ic = avformat_alloc_context();
2828 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2829 ret = AVERROR(ENOMEM);
2832 ic->interrupt_callback.callback = decode_interrupt_cb;
2833 ic->interrupt_callback.opaque = is;
2834 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2835 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2836 scan_all_pmts_set = 1;
2838 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2840 print_error(is->filename, err);
2844 if (scan_all_pmts_set)
2845 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2847 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2848 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2849 ret = AVERROR_OPTION_NOT_FOUND;
2855 ic->flags |= AVFMT_FLAG_GENPTS;
2857 av_format_inject_global_side_data(ic);
2859 opts = setup_find_stream_info_opts(ic, codec_opts);
2860 orig_nb_streams = ic->nb_streams;
2862 err = avformat_find_stream_info(ic, opts);
2864 for (i = 0; i < orig_nb_streams; i++)
2865 av_dict_free(&opts[i]);
2869 av_log(NULL, AV_LOG_WARNING,
2870 "%s: could not find codec parameters\n", is->filename);
2876 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2878 if (seek_by_bytes < 0)
2879 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2881 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2883 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2884 window_title = av_asprintf("%s - %s", t->value, input_filename);
2886 /* if seeking requested, we execute it */
2887 if (start_time != AV_NOPTS_VALUE) {
2890 timestamp = start_time;
2891 /* add the stream start time */
2892 if (ic->start_time != AV_NOPTS_VALUE)
2893 timestamp += ic->start_time;
2894 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2896 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2897 is->filename, (double)timestamp / AV_TIME_BASE);
2901 is->realtime = is_realtime(ic);
2904 av_dump_format(ic, 0, is->filename, 0);
2906 for (i = 0; i < ic->nb_streams; i++) {
2907 AVStream *st = ic->streams[i];
2908 enum AVMediaType type = st->codec->codec_type;
2909 st->discard = AVDISCARD_ALL;
2910 if (wanted_stream_spec[type] && st_index[type] == -1)
2911 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2914 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2915 if (wanted_stream_spec[i] && st_index[i] == -1) {
2916 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));
2917 st_index[i] = INT_MAX;
2922 st_index[AVMEDIA_TYPE_VIDEO] =
2923 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2924 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2926 st_index[AVMEDIA_TYPE_AUDIO] =
2927 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2928 st_index[AVMEDIA_TYPE_AUDIO],
2929 st_index[AVMEDIA_TYPE_VIDEO],
2931 if (!video_disable && !subtitle_disable)
2932 st_index[AVMEDIA_TYPE_SUBTITLE] =
2933 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2934 st_index[AVMEDIA_TYPE_SUBTITLE],
2935 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2936 st_index[AVMEDIA_TYPE_AUDIO] :
2937 st_index[AVMEDIA_TYPE_VIDEO]),
2940 is->show_mode = show_mode;
2941 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2942 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2943 AVCodecContext *avctx = st->codec;
2944 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2946 set_default_window_size(avctx->width, avctx->height, sar);
2949 /* open the streams */
2950 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2951 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2955 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2956 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2958 if (is->show_mode == SHOW_MODE_NONE)
2959 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2961 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2962 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2965 if (is->video_stream < 0 && is->audio_stream < 0) {
2966 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2972 if (infinite_buffer < 0 && is->realtime)
2973 infinite_buffer = 1;
2976 if (is->abort_request)
2978 if (is->paused != is->last_paused) {
2979 is->last_paused = is->paused;
2981 is->read_pause_return = av_read_pause(ic);
2985 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2987 (!strcmp(ic->iformat->name, "rtsp") ||
2988 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2989 /* wait 10 ms to avoid trying to get another packet */
2996 int64_t seek_target = is->seek_pos;
2997 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2998 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2999 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3000 // of the seek_pos/seek_rel variables
3002 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3004 av_log(NULL, AV_LOG_ERROR,
3005 "%s: error while seeking\n", is->ic->filename);
3007 if (is->audio_stream >= 0) {
3008 packet_queue_flush(&is->audioq);
3009 packet_queue_put(&is->audioq, &flush_pkt);
3011 if (is->subtitle_stream >= 0) {
3012 packet_queue_flush(&is->subtitleq);
3013 packet_queue_put(&is->subtitleq, &flush_pkt);
3015 if (is->video_stream >= 0) {
3016 packet_queue_flush(&is->videoq);
3017 packet_queue_put(&is->videoq, &flush_pkt);
3019 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3020 set_clock(&is->extclk, NAN, 0);
3022 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3026 is->queue_attachments_req = 1;
3029 step_to_next_frame(is);
3031 if (is->queue_attachments_req) {
3032 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3034 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3036 packet_queue_put(&is->videoq, ©);
3037 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3039 is->queue_attachments_req = 0;
3042 /* if the queue are full, no need to read more */
3043 if (infinite_buffer<1 &&
3044 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3045 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3046 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3047 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3048 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3050 SDL_LockMutex(wait_mutex);
3051 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3052 SDL_UnlockMutex(wait_mutex);
3056 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3057 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3058 if (loop != 1 && (!loop || --loop)) {
3059 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3060 } else if (autoexit) {
3065 ret = av_read_frame(ic, pkt);
3067 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3068 if (is->video_stream >= 0)
3069 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3070 if (is->audio_stream >= 0)
3071 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3072 if (is->subtitle_stream >= 0)
3073 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3076 if (ic->pb && ic->pb->error)
3078 SDL_LockMutex(wait_mutex);
3079 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3080 SDL_UnlockMutex(wait_mutex);
3085 /* check if packet is in play range specified by user, then queue, otherwise discard */
3086 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3087 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3088 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3089 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3090 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3091 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3092 <= ((double)duration / 1000000);
3093 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3094 packet_queue_put(&is->audioq, pkt);
3095 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3096 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3097 packet_queue_put(&is->videoq, pkt);
3098 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3099 packet_queue_put(&is->subtitleq, pkt);
3101 av_free_packet(pkt);
3104 /* wait until the end */
3105 while (!is->abort_request) {
3111 /* close each stream */
3112 if (is->audio_stream >= 0)
3113 stream_component_close(is, is->audio_stream);
3114 if (is->video_stream >= 0)
3115 stream_component_close(is, is->video_stream);
3116 if (is->subtitle_stream >= 0)
3117 stream_component_close(is, is->subtitle_stream);
3119 avformat_close_input(&ic);
3126 event.type = FF_QUIT_EVENT;
3127 event.user.data1 = is;
3128 SDL_PushEvent(&event);
3130 SDL_DestroyMutex(wait_mutex);
3134 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3138 is = av_mallocz(sizeof(VideoState));
3141 is->filename = av_strdup(filename);
3144 is->iformat = iformat;
3148 /* start video display */
3149 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3151 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3153 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3156 if (packet_queue_init(&is->videoq) < 0 ||
3157 packet_queue_init(&is->audioq) < 0 ||
3158 packet_queue_init(&is->subtitleq) < 0)
3161 is->continue_read_thread = SDL_CreateCond();
3163 init_clock(&is->vidclk, &is->videoq.serial);
3164 init_clock(&is->audclk, &is->audioq.serial);
3165 init_clock(&is->extclk, &is->extclk.serial);
3166 is->audio_clock_serial = -1;
3167 is->audio_volume = SDL_MIX_MAXVOLUME;
3169 is->av_sync_type = av_sync_type;
3170 is->read_tid = SDL_CreateThread(read_thread, is);
3171 if (!is->read_tid) {
3179 static void stream_cycle_channel(VideoState *is, int codec_type)
3181 AVFormatContext *ic = is->ic;
3182 int start_index, stream_index;
3185 AVProgram *p = NULL;
3186 int nb_streams = is->ic->nb_streams;
3188 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3189 start_index = is->last_video_stream;
3190 old_index = is->video_stream;
3191 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3192 start_index = is->last_audio_stream;
3193 old_index = is->audio_stream;
3195 start_index = is->last_subtitle_stream;
3196 old_index = is->subtitle_stream;
3198 stream_index = start_index;
3200 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3201 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3203 nb_streams = p->nb_stream_indexes;
3204 for (start_index = 0; start_index < nb_streams; start_index++)
3205 if (p->stream_index[start_index] == stream_index)
3207 if (start_index == nb_streams)
3209 stream_index = start_index;
3214 if (++stream_index >= nb_streams)
3216 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3219 is->last_subtitle_stream = -1;
3222 if (start_index == -1)
3226 if (stream_index == start_index)
3228 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3229 if (st->codec->codec_type == codec_type) {
3230 /* check that parameters are OK */
3231 switch (codec_type) {
3232 case AVMEDIA_TYPE_AUDIO:
3233 if (st->codec->sample_rate != 0 &&
3234 st->codec->channels != 0)
3237 case AVMEDIA_TYPE_VIDEO:
3238 case AVMEDIA_TYPE_SUBTITLE:
3246 if (p && stream_index != -1)
3247 stream_index = p->stream_index[stream_index];
3248 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3249 av_get_media_type_string(codec_type),
3253 stream_component_close(is, old_index);
3254 stream_component_open(is, stream_index);
3258 static void toggle_full_screen(VideoState *is)
3260 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3261 /* OS X needs to reallocate the SDL overlays */
3263 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3264 is->pictq.queue[i].reallocate = 1;
3266 is_full_screen = !is_full_screen;
3267 video_open(is, 1, NULL);
3270 static void toggle_audio_display(VideoState *is)
3272 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3273 int next = is->show_mode;
3275 next = (next + 1) % SHOW_MODE_NB;
3276 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3277 if (is->show_mode != next) {
3278 fill_rectangle(screen,
3279 is->xleft, is->ytop, is->width, is->height,
3281 is->force_refresh = 1;
3282 is->show_mode = next;
3286 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3287 double remaining_time = 0.0;
3289 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3290 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3294 if (remaining_time > 0.0)
3295 av_usleep((int64_t)(remaining_time * 1000000.0));
3296 remaining_time = REFRESH_RATE;
3297 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3298 video_refresh(is, &remaining_time);
3303 static void seek_chapter(VideoState *is, int incr)
3305 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3308 if (!is->ic->nb_chapters)
3311 /* find the current chapter */
3312 for (i = 0; i < is->ic->nb_chapters; i++) {
3313 AVChapter *ch = is->ic->chapters[i];
3314 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3322 if (i >= is->ic->nb_chapters)
3325 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3326 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3327 AV_TIME_BASE_Q), 0, 0);
3330 /* handle an event sent by the GUI */
3331 static void event_loop(VideoState *cur_stream)
3334 double incr, pos, frac;
3338 refresh_loop_wait_event(cur_stream, &event);
3339 switch (event.type) {
3341 if (exit_on_keydown) {
3342 do_exit(cur_stream);
3345 switch (event.key.keysym.sym) {
3348 do_exit(cur_stream);
3351 toggle_full_screen(cur_stream);
3352 cur_stream->force_refresh = 1;
3356 toggle_pause(cur_stream);
3359 toggle_mute(cur_stream);
3361 case SDLK_KP_MULTIPLY:
3363 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3365 case SDLK_KP_DIVIDE:
3367 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3369 case SDLK_s: // S: Step to next frame
3370 step_to_next_frame(cur_stream);
3373 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3376 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3379 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3380 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3381 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3384 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3388 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3389 if (++cur_stream->vfilter_idx >= nb_vfilters)
3390 cur_stream->vfilter_idx = 0;
3392 cur_stream->vfilter_idx = 0;
3393 toggle_audio_display(cur_stream);
3396 toggle_audio_display(cur_stream);
3400 if (cur_stream->ic->nb_chapters <= 1) {
3404 seek_chapter(cur_stream, 1);
3407 if (cur_stream->ic->nb_chapters <= 1) {
3411 seek_chapter(cur_stream, -1);
3425 if (seek_by_bytes) {
3427 if (pos < 0 && cur_stream->video_stream >= 0)
3428 pos = frame_queue_last_pos(&cur_stream->pictq);
3429 if (pos < 0 && cur_stream->audio_stream >= 0)
3430 pos = frame_queue_last_pos(&cur_stream->sampq);
3432 pos = avio_tell(cur_stream->ic->pb);
3433 if (cur_stream->ic->bit_rate)
3434 incr *= cur_stream->ic->bit_rate / 8.0;
3438 stream_seek(cur_stream, pos, incr, 1);
3440 pos = get_master_clock(cur_stream);
3442 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3444 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3445 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3446 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3453 case SDL_VIDEOEXPOSE:
3454 cur_stream->force_refresh = 1;
3456 case SDL_MOUSEBUTTONDOWN:
3457 if (exit_on_mousedown) {
3458 do_exit(cur_stream);
3461 case SDL_MOUSEMOTION:
3462 if (cursor_hidden) {
3466 cursor_last_shown = av_gettime_relative();
3467 if (event.type == SDL_MOUSEBUTTONDOWN) {
3470 if (event.motion.state != SDL_PRESSED)
3474 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3475 uint64_t size = avio_size(cur_stream->ic->pb);
3476 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3480 int tns, thh, tmm, tss;
3481 tns = cur_stream->ic->duration / 1000000LL;
3483 tmm = (tns % 3600) / 60;
3485 frac = x / cur_stream->width;
3488 mm = (ns % 3600) / 60;
3490 av_log(NULL, AV_LOG_INFO,
3491 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3492 hh, mm, ss, thh, tmm, tss);
3493 ts = frac * cur_stream->ic->duration;
3494 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3495 ts += cur_stream->ic->start_time;
3496 stream_seek(cur_stream, ts, 0, 0);
3499 case SDL_VIDEORESIZE:
3500 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3501 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3503 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3504 do_exit(cur_stream);
3506 screen_width = cur_stream->width = screen->w;
3507 screen_height = cur_stream->height = screen->h;
3508 cur_stream->force_refresh = 1;
3512 do_exit(cur_stream);
3514 case FF_ALLOC_EVENT:
3515 alloc_picture(event.user.data1);
3523 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3525 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3526 return opt_default(NULL, "video_size", arg);
3529 static int opt_width(void *optctx, const char *opt, const char *arg)
3531 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3535 static int opt_height(void *optctx, const char *opt, const char *arg)
3537 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3541 static int opt_format(void *optctx, const char *opt, const char *arg)
3543 file_iformat = av_find_input_format(arg);
3544 if (!file_iformat) {
3545 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3546 return AVERROR(EINVAL);
3551 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3553 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3554 return opt_default(NULL, "pixel_format", arg);
3557 static int opt_sync(void *optctx, const char *opt, const char *arg)
3559 if (!strcmp(arg, "audio"))
3560 av_sync_type = AV_SYNC_AUDIO_MASTER;
3561 else if (!strcmp(arg, "video"))
3562 av_sync_type = AV_SYNC_VIDEO_MASTER;
3563 else if (!strcmp(arg, "ext"))
3564 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3566 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3572 static int opt_seek(void *optctx, const char *opt, const char *arg)
3574 start_time = parse_time_or_die(opt, arg, 1);
3578 static int opt_duration(void *optctx, const char *opt, const char *arg)
3580 duration = parse_time_or_die(opt, arg, 1);
3584 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3586 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3587 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3588 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3589 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3593 static void opt_input_file(void *optctx, const char *filename)
3595 if (input_filename) {
3596 av_log(NULL, AV_LOG_FATAL,
3597 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3598 filename, input_filename);
3601 if (!strcmp(filename, "-"))
3603 input_filename = filename;
3606 static int opt_codec(void *optctx, const char *opt, const char *arg)
3608 const char *spec = strchr(opt, ':');
3610 av_log(NULL, AV_LOG_ERROR,
3611 "No media specifier was specified in '%s' in option '%s'\n",
3613 return AVERROR(EINVAL);
3617 case 'a' : audio_codec_name = arg; break;
3618 case 's' : subtitle_codec_name = arg; break;
3619 case 'v' : video_codec_name = arg; break;
3621 av_log(NULL, AV_LOG_ERROR,
3622 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3623 return AVERROR(EINVAL);
3630 static const OptionDef options[] = {
3631 #include "cmdutils_common_opts.h"
3632 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3633 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3634 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3635 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3636 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3637 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3638 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3639 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3640 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3641 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3642 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3643 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3644 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3645 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3646 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3647 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3648 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3649 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3650 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3651 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3652 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3653 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3654 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3655 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3656 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3657 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3658 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3659 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3660 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3662 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3663 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3665 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3666 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3667 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3668 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3669 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3670 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3671 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3672 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3673 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3677 static void show_usage(void)
3679 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3680 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3681 av_log(NULL, AV_LOG_INFO, "\n");
3684 void show_help_default(const char *opt, const char *arg)
3686 av_log_set_callback(log_callback_help);
3688 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3689 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3691 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3692 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3693 #if !CONFIG_AVFILTER
3694 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3696 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3698 printf("\nWhile playing:\n"
3700 "f toggle full screen\n"
3703 "9, 0 decrease and increase volume respectively\n"
3704 "/, * decrease and increase volume respectively\n"
3705 "a cycle audio channel in the current program\n"
3706 "v cycle video channel\n"
3707 "t cycle subtitle channel in the current program\n"
3709 "w cycle video filters or show modes\n"
3710 "s activate frame-step mode\n"
3711 "left/right seek backward/forward 10 seconds\n"
3712 "down/up seek backward/forward 1 minute\n"
3713 "page down/page up seek backward/forward 10 minutes\n"
3714 "mouse click seek to percentage in file corresponding to fraction of width\n"
3718 static int lockmgr(void **mtx, enum AVLockOp op)
3721 case AV_LOCK_CREATE:
3722 *mtx = SDL_CreateMutex();
3726 case AV_LOCK_OBTAIN:
3727 return !!SDL_LockMutex(*mtx);
3728 case AV_LOCK_RELEASE:
3729 return !!SDL_UnlockMutex(*mtx);
3730 case AV_LOCK_DESTROY:
3731 SDL_DestroyMutex(*mtx);
3737 /* Called from the main */
3738 int main(int argc, char **argv)
3742 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3744 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3745 parse_loglevel(argc, argv, options);
3747 /* register all codecs, demux and protocols */
3749 avdevice_register_all();
3752 avfilter_register_all();
3755 avformat_network_init();
3759 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3760 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3762 show_banner(argc, argv, options);
3764 parse_options(NULL, argc, argv, options, opt_input_file);
3766 if (!input_filename) {
3768 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3769 av_log(NULL, AV_LOG_FATAL,
3770 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3774 if (display_disable) {
3777 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3779 flags &= ~SDL_INIT_AUDIO;
3780 if (display_disable)
3781 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3782 #if !defined(_WIN32) && !defined(__APPLE__)
3783 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3785 if (SDL_Init (flags)) {
3786 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3787 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3791 if (!display_disable) {
3792 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3793 fs_screen_width = vi->current_w;
3794 fs_screen_height = vi->current_h;
3797 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3798 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3799 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3801 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3803 if (av_lockmgr_register(lockmgr)) {
3804 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3808 av_init_packet(&flush_pkt);
3809 flush_pkt.data = (uint8_t *)&flush_pkt;
3811 is = stream_open(input_filename, file_iformat);
3813 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");