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;
2821 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2822 ret = AVERROR(ENOMEM);
2826 memset(st_index, -1, sizeof(st_index));
2827 is->last_video_stream = is->video_stream = -1;
2828 is->last_audio_stream = is->audio_stream = -1;
2829 is->last_subtitle_stream = is->subtitle_stream = -1;
2832 ic = avformat_alloc_context();
2834 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2835 ret = AVERROR(ENOMEM);
2838 ic->interrupt_callback.callback = decode_interrupt_cb;
2839 ic->interrupt_callback.opaque = is;
2840 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2841 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2842 scan_all_pmts_set = 1;
2844 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2846 print_error(is->filename, err);
2850 if (scan_all_pmts_set)
2851 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2853 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2854 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2855 ret = AVERROR_OPTION_NOT_FOUND;
2861 ic->flags |= AVFMT_FLAG_GENPTS;
2863 av_format_inject_global_side_data(ic);
2865 opts = setup_find_stream_info_opts(ic, codec_opts);
2866 orig_nb_streams = ic->nb_streams;
2868 err = avformat_find_stream_info(ic, opts);
2870 for (i = 0; i < orig_nb_streams; i++)
2871 av_dict_free(&opts[i]);
2875 av_log(NULL, AV_LOG_WARNING,
2876 "%s: could not find codec parameters\n", is->filename);
2882 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2884 if (seek_by_bytes < 0)
2885 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2887 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2889 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2890 window_title = av_asprintf("%s - %s", t->value, input_filename);
2892 /* if seeking requested, we execute it */
2893 if (start_time != AV_NOPTS_VALUE) {
2896 timestamp = start_time;
2897 /* add the stream start time */
2898 if (ic->start_time != AV_NOPTS_VALUE)
2899 timestamp += ic->start_time;
2900 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2902 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2903 is->filename, (double)timestamp / AV_TIME_BASE);
2907 is->realtime = is_realtime(ic);
2910 av_dump_format(ic, 0, is->filename, 0);
2912 for (i = 0; i < ic->nb_streams; i++) {
2913 AVStream *st = ic->streams[i];
2914 enum AVMediaType type = st->codec->codec_type;
2915 st->discard = AVDISCARD_ALL;
2916 if (wanted_stream_spec[type] && st_index[type] == -1)
2917 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2920 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2921 if (wanted_stream_spec[i] && st_index[i] == -1) {
2922 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));
2923 st_index[i] = INT_MAX;
2928 st_index[AVMEDIA_TYPE_VIDEO] =
2929 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2930 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2932 st_index[AVMEDIA_TYPE_AUDIO] =
2933 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2934 st_index[AVMEDIA_TYPE_AUDIO],
2935 st_index[AVMEDIA_TYPE_VIDEO],
2937 if (!video_disable && !subtitle_disable)
2938 st_index[AVMEDIA_TYPE_SUBTITLE] =
2939 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2940 st_index[AVMEDIA_TYPE_SUBTITLE],
2941 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2942 st_index[AVMEDIA_TYPE_AUDIO] :
2943 st_index[AVMEDIA_TYPE_VIDEO]),
2946 is->show_mode = show_mode;
2947 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2948 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2949 AVCodecContext *avctx = st->codec;
2950 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2952 set_default_window_size(avctx->width, avctx->height, sar);
2955 /* open the streams */
2956 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2957 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2961 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2962 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2964 if (is->show_mode == SHOW_MODE_NONE)
2965 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2967 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2968 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2971 if (is->video_stream < 0 && is->audio_stream < 0) {
2972 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2978 if (infinite_buffer < 0 && is->realtime)
2979 infinite_buffer = 1;
2982 if (is->abort_request)
2984 if (is->paused != is->last_paused) {
2985 is->last_paused = is->paused;
2987 is->read_pause_return = av_read_pause(ic);
2991 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2993 (!strcmp(ic->iformat->name, "rtsp") ||
2994 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2995 /* wait 10 ms to avoid trying to get another packet */
3002 int64_t seek_target = is->seek_pos;
3003 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
3004 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
3005 // FIXME the +-2 is due to rounding being not done in the correct direction in generation
3006 // of the seek_pos/seek_rel variables
3008 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
3010 av_log(NULL, AV_LOG_ERROR,
3011 "%s: error while seeking\n", is->ic->filename);
3013 if (is->audio_stream >= 0) {
3014 packet_queue_flush(&is->audioq);
3015 packet_queue_put(&is->audioq, &flush_pkt);
3017 if (is->subtitle_stream >= 0) {
3018 packet_queue_flush(&is->subtitleq);
3019 packet_queue_put(&is->subtitleq, &flush_pkt);
3021 if (is->video_stream >= 0) {
3022 packet_queue_flush(&is->videoq);
3023 packet_queue_put(&is->videoq, &flush_pkt);
3025 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
3026 set_clock(&is->extclk, NAN, 0);
3028 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
3032 is->queue_attachments_req = 1;
3035 step_to_next_frame(is);
3037 if (is->queue_attachments_req) {
3038 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
3040 if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
3042 packet_queue_put(&is->videoq, ©);
3043 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3045 is->queue_attachments_req = 0;
3048 /* if the queue are full, no need to read more */
3049 if (infinite_buffer<1 &&
3050 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
3051 || ( (is->audioq .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
3052 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request
3053 || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))
3054 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
3056 SDL_LockMutex(wait_mutex);
3057 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3058 SDL_UnlockMutex(wait_mutex);
3062 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
3063 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
3064 if (loop != 1 && (!loop || --loop)) {
3065 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
3066 } else if (autoexit) {
3071 ret = av_read_frame(ic, pkt);
3073 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
3074 if (is->video_stream >= 0)
3075 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
3076 if (is->audio_stream >= 0)
3077 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
3078 if (is->subtitle_stream >= 0)
3079 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
3082 if (ic->pb && ic->pb->error)
3084 SDL_LockMutex(wait_mutex);
3085 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
3086 SDL_UnlockMutex(wait_mutex);
3091 /* check if packet is in play range specified by user, then queue, otherwise discard */
3092 stream_start_time = ic->streams[pkt->stream_index]->start_time;
3093 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
3094 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
3095 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
3096 av_q2d(ic->streams[pkt->stream_index]->time_base) -
3097 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
3098 <= ((double)duration / 1000000);
3099 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
3100 packet_queue_put(&is->audioq, pkt);
3101 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
3102 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
3103 packet_queue_put(&is->videoq, pkt);
3104 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
3105 packet_queue_put(&is->subtitleq, pkt);
3107 av_free_packet(pkt);
3110 /* wait until the end */
3111 while (!is->abort_request) {
3117 /* close each stream */
3118 if (is->audio_stream >= 0)
3119 stream_component_close(is, is->audio_stream);
3120 if (is->video_stream >= 0)
3121 stream_component_close(is, is->video_stream);
3122 if (is->subtitle_stream >= 0)
3123 stream_component_close(is, is->subtitle_stream);
3125 avformat_close_input(&ic);
3132 event.type = FF_QUIT_EVENT;
3133 event.user.data1 = is;
3134 SDL_PushEvent(&event);
3136 SDL_DestroyMutex(wait_mutex);
3140 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3144 is = av_mallocz(sizeof(VideoState));
3147 is->filename = av_strdup(filename);
3150 is->iformat = iformat;
3154 /* start video display */
3155 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3157 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3159 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3162 if (packet_queue_init(&is->videoq) < 0 ||
3163 packet_queue_init(&is->audioq) < 0 ||
3164 packet_queue_init(&is->subtitleq) < 0)
3167 is->continue_read_thread = SDL_CreateCond();
3169 init_clock(&is->vidclk, &is->videoq.serial);
3170 init_clock(&is->audclk, &is->audioq.serial);
3171 init_clock(&is->extclk, &is->extclk.serial);
3172 is->audio_clock_serial = -1;
3173 is->audio_volume = SDL_MIX_MAXVOLUME;
3175 is->av_sync_type = av_sync_type;
3176 is->read_tid = SDL_CreateThread(read_thread, is);
3177 if (!is->read_tid) {
3185 static void stream_cycle_channel(VideoState *is, int codec_type)
3187 AVFormatContext *ic = is->ic;
3188 int start_index, stream_index;
3191 AVProgram *p = NULL;
3192 int nb_streams = is->ic->nb_streams;
3194 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3195 start_index = is->last_video_stream;
3196 old_index = is->video_stream;
3197 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3198 start_index = is->last_audio_stream;
3199 old_index = is->audio_stream;
3201 start_index = is->last_subtitle_stream;
3202 old_index = is->subtitle_stream;
3204 stream_index = start_index;
3206 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3207 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3209 nb_streams = p->nb_stream_indexes;
3210 for (start_index = 0; start_index < nb_streams; start_index++)
3211 if (p->stream_index[start_index] == stream_index)
3213 if (start_index == nb_streams)
3215 stream_index = start_index;
3220 if (++stream_index >= nb_streams)
3222 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3225 is->last_subtitle_stream = -1;
3228 if (start_index == -1)
3232 if (stream_index == start_index)
3234 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3235 if (st->codec->codec_type == codec_type) {
3236 /* check that parameters are OK */
3237 switch (codec_type) {
3238 case AVMEDIA_TYPE_AUDIO:
3239 if (st->codec->sample_rate != 0 &&
3240 st->codec->channels != 0)
3243 case AVMEDIA_TYPE_VIDEO:
3244 case AVMEDIA_TYPE_SUBTITLE:
3252 if (p && stream_index != -1)
3253 stream_index = p->stream_index[stream_index];
3254 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3255 av_get_media_type_string(codec_type),
3259 stream_component_close(is, old_index);
3260 stream_component_open(is, stream_index);
3264 static void toggle_full_screen(VideoState *is)
3266 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
3267 /* OS X needs to reallocate the SDL overlays */
3269 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
3270 is->pictq.queue[i].reallocate = 1;
3272 is_full_screen = !is_full_screen;
3273 video_open(is, 1, NULL);
3276 static void toggle_audio_display(VideoState *is)
3278 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
3279 int next = is->show_mode;
3281 next = (next + 1) % SHOW_MODE_NB;
3282 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3283 if (is->show_mode != next) {
3284 fill_rectangle(screen,
3285 is->xleft, is->ytop, is->width, is->height,
3287 is->force_refresh = 1;
3288 is->show_mode = next;
3292 static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3293 double remaining_time = 0.0;
3295 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
3296 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3300 if (remaining_time > 0.0)
3301 av_usleep((int64_t)(remaining_time * 1000000.0));
3302 remaining_time = REFRESH_RATE;
3303 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3304 video_refresh(is, &remaining_time);
3309 static void seek_chapter(VideoState *is, int incr)
3311 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3314 if (!is->ic->nb_chapters)
3317 /* find the current chapter */
3318 for (i = 0; i < is->ic->nb_chapters; i++) {
3319 AVChapter *ch = is->ic->chapters[i];
3320 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3328 if (i >= is->ic->nb_chapters)
3331 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3332 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3333 AV_TIME_BASE_Q), 0, 0);
3336 /* handle an event sent by the GUI */
3337 static void event_loop(VideoState *cur_stream)
3340 double incr, pos, frac;
3344 refresh_loop_wait_event(cur_stream, &event);
3345 switch (event.type) {
3347 if (exit_on_keydown) {
3348 do_exit(cur_stream);
3351 switch (event.key.keysym.sym) {
3354 do_exit(cur_stream);
3357 toggle_full_screen(cur_stream);
3358 cur_stream->force_refresh = 1;
3362 toggle_pause(cur_stream);
3365 toggle_mute(cur_stream);
3367 case SDLK_KP_MULTIPLY:
3369 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3371 case SDLK_KP_DIVIDE:
3373 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3375 case SDLK_s: // S: Step to next frame
3376 step_to_next_frame(cur_stream);
3379 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3382 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3385 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3386 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3387 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3390 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3394 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3395 if (++cur_stream->vfilter_idx >= nb_vfilters)
3396 cur_stream->vfilter_idx = 0;
3398 cur_stream->vfilter_idx = 0;
3399 toggle_audio_display(cur_stream);
3402 toggle_audio_display(cur_stream);
3406 if (cur_stream->ic->nb_chapters <= 1) {
3410 seek_chapter(cur_stream, 1);
3413 if (cur_stream->ic->nb_chapters <= 1) {
3417 seek_chapter(cur_stream, -1);
3431 if (seek_by_bytes) {
3433 if (pos < 0 && cur_stream->video_stream >= 0)
3434 pos = frame_queue_last_pos(&cur_stream->pictq);
3435 if (pos < 0 && cur_stream->audio_stream >= 0)
3436 pos = frame_queue_last_pos(&cur_stream->sampq);
3438 pos = avio_tell(cur_stream->ic->pb);
3439 if (cur_stream->ic->bit_rate)
3440 incr *= cur_stream->ic->bit_rate / 8.0;
3444 stream_seek(cur_stream, pos, incr, 1);
3446 pos = get_master_clock(cur_stream);
3448 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3450 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3451 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3452 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3459 case SDL_VIDEOEXPOSE:
3460 cur_stream->force_refresh = 1;
3462 case SDL_MOUSEBUTTONDOWN:
3463 if (exit_on_mousedown) {
3464 do_exit(cur_stream);
3467 case SDL_MOUSEMOTION:
3468 if (cursor_hidden) {
3472 cursor_last_shown = av_gettime_relative();
3473 if (event.type == SDL_MOUSEBUTTONDOWN) {
3476 if (event.motion.state != SDL_PRESSED)
3480 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3481 uint64_t size = avio_size(cur_stream->ic->pb);
3482 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3486 int tns, thh, tmm, tss;
3487 tns = cur_stream->ic->duration / 1000000LL;
3489 tmm = (tns % 3600) / 60;
3491 frac = x / cur_stream->width;
3494 mm = (ns % 3600) / 60;
3496 av_log(NULL, AV_LOG_INFO,
3497 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3498 hh, mm, ss, thh, tmm, tss);
3499 ts = frac * cur_stream->ic->duration;
3500 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3501 ts += cur_stream->ic->start_time;
3502 stream_seek(cur_stream, ts, 0, 0);
3505 case SDL_VIDEORESIZE:
3506 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
3507 SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
3509 av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
3510 do_exit(cur_stream);
3512 screen_width = cur_stream->width = screen->w;
3513 screen_height = cur_stream->height = screen->h;
3514 cur_stream->force_refresh = 1;
3518 do_exit(cur_stream);
3520 case FF_ALLOC_EVENT:
3521 alloc_picture(event.user.data1);
3529 static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3531 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3532 return opt_default(NULL, "video_size", arg);
3535 static int opt_width(void *optctx, const char *opt, const char *arg)
3537 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3541 static int opt_height(void *optctx, const char *opt, const char *arg)
3543 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3547 static int opt_format(void *optctx, const char *opt, const char *arg)
3549 file_iformat = av_find_input_format(arg);
3550 if (!file_iformat) {
3551 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3552 return AVERROR(EINVAL);
3557 static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3559 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3560 return opt_default(NULL, "pixel_format", arg);
3563 static int opt_sync(void *optctx, const char *opt, const char *arg)
3565 if (!strcmp(arg, "audio"))
3566 av_sync_type = AV_SYNC_AUDIO_MASTER;
3567 else if (!strcmp(arg, "video"))
3568 av_sync_type = AV_SYNC_VIDEO_MASTER;
3569 else if (!strcmp(arg, "ext"))
3570 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3572 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3578 static int opt_seek(void *optctx, const char *opt, const char *arg)
3580 start_time = parse_time_or_die(opt, arg, 1);
3584 static int opt_duration(void *optctx, const char *opt, const char *arg)
3586 duration = parse_time_or_die(opt, arg, 1);
3590 static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3592 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3593 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3594 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3595 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3599 static void opt_input_file(void *optctx, const char *filename)
3601 if (input_filename) {
3602 av_log(NULL, AV_LOG_FATAL,
3603 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3604 filename, input_filename);
3607 if (!strcmp(filename, "-"))
3609 input_filename = filename;
3612 static int opt_codec(void *optctx, const char *opt, const char *arg)
3614 const char *spec = strchr(opt, ':');
3616 av_log(NULL, AV_LOG_ERROR,
3617 "No media specifier was specified in '%s' in option '%s'\n",
3619 return AVERROR(EINVAL);
3623 case 'a' : audio_codec_name = arg; break;
3624 case 's' : subtitle_codec_name = arg; break;
3625 case 'v' : video_codec_name = arg; break;
3627 av_log(NULL, AV_LOG_ERROR,
3628 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3629 return AVERROR(EINVAL);
3636 static const OptionDef options[] = {
3637 #include "cmdutils_common_opts.h"
3638 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3639 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3640 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3641 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3642 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3643 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3644 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3645 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3646 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3647 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3648 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3649 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3650 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3651 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3652 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3653 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3654 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3655 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3656 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3657 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3658 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3659 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3660 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3661 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3662 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3663 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3664 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3665 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3666 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3668 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3669 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3671 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3672 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3673 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3674 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3675 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3676 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3677 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3678 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3679 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3683 static void show_usage(void)
3685 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3686 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3687 av_log(NULL, AV_LOG_INFO, "\n");
3690 void show_help_default(const char *opt, const char *arg)
3692 av_log_set_callback(log_callback_help);
3694 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3695 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3697 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3698 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3699 #if !CONFIG_AVFILTER
3700 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3702 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3704 printf("\nWhile playing:\n"
3706 "f toggle full screen\n"
3709 "9, 0 decrease and increase volume respectively\n"
3710 "/, * decrease and increase volume respectively\n"
3711 "a cycle audio channel in the current program\n"
3712 "v cycle video channel\n"
3713 "t cycle subtitle channel in the current program\n"
3715 "w cycle video filters or show modes\n"
3716 "s activate frame-step mode\n"
3717 "left/right seek backward/forward 10 seconds\n"
3718 "down/up seek backward/forward 1 minute\n"
3719 "page down/page up seek backward/forward 10 minutes\n"
3720 "mouse click seek to percentage in file corresponding to fraction of width\n"
3724 static int lockmgr(void **mtx, enum AVLockOp op)
3727 case AV_LOCK_CREATE:
3728 *mtx = SDL_CreateMutex();
3732 case AV_LOCK_OBTAIN:
3733 return !!SDL_LockMutex(*mtx);
3734 case AV_LOCK_RELEASE:
3735 return !!SDL_UnlockMutex(*mtx);
3736 case AV_LOCK_DESTROY:
3737 SDL_DestroyMutex(*mtx);
3743 /* Called from the main */
3744 int main(int argc, char **argv)
3748 char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
3750 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3751 parse_loglevel(argc, argv, options);
3753 /* register all codecs, demux and protocols */
3755 avdevice_register_all();
3758 avfilter_register_all();
3761 avformat_network_init();
3765 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3766 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3768 show_banner(argc, argv, options);
3770 parse_options(NULL, argc, argv, options, opt_input_file);
3772 if (!input_filename) {
3774 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3775 av_log(NULL, AV_LOG_FATAL,
3776 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3780 if (display_disable) {
3783 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3785 flags &= ~SDL_INIT_AUDIO;
3786 if (display_disable)
3787 SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
3788 #if !defined(_WIN32) && !defined(__APPLE__)
3789 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3791 if (SDL_Init (flags)) {
3792 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3793 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3797 if (!display_disable) {
3798 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3799 fs_screen_width = vi->current_w;
3800 fs_screen_height = vi->current_h;
3803 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3804 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3805 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3807 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
3809 if (av_lockmgr_register(lockmgr)) {
3810 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3814 av_init_packet(&flush_pkt);
3815 flush_pkt.data = (uint8_t *)&flush_pkt;
3817 is = stream_open(input_filename, file_iformat);
3819 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");