summaryrefslogtreecommitdiff
path: root/ffplay.c (plain)
blob: cf138dc51513eaba4f8392ba3e2288e4ddb64c14
1/*
2 * Copyright (c) 2003 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
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.
10 *
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.
15 *
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
19 */
20
21/**
22 * @file
23 * simple media player based on the FFmpeg libraries
24 */
25
26#include "config.h"
27#include <inttypes.h>
28#include <math.h>
29#include <limits.h>
30#include <signal.h>
31#include <stdint.h>
32
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"
49
50#if CONFIG_AVFILTER
51# include "libavfilter/avfilter.h"
52# include "libavfilter/buffersink.h"
53# include "libavfilter/buffersrc.h"
54#endif
55
56#include <SDL.h>
57#include <SDL_thread.h>
58
59#include "cmdutils.h"
60
61#include <assert.h>
62
63const char program_name[] = "ffplay";
64const int program_birth_year = 2003;
65
66#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
67#define MIN_FRAMES 25
68#define EXTERNAL_CLOCK_MIN_FRAMES 2
69#define EXTERNAL_CLOCK_MAX_FRAMES 10
70
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
75
76/* Step size for volume control in dB */
77#define SDL_VOLUME_STEP (0.75)
78
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
87
88/* maximum audio speed change to get correct sync */
89#define SAMPLE_CORRECTION_PERCENT_MAX 10
90
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
95
96/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
97#define AUDIO_DIFF_AVG_NB 20
98
99/* polls for possible required screen refresh at least this often, should be less than 1/fps */
100#define REFRESH_RATE 0.01
101
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)
105
106#define CURSOR_HIDE_DELAY 1000000
107
108#define USE_ONEPASS_SUBTITLE_RENDER 1
109
110static unsigned sws_flags = SWS_BICUBIC;
111
112typedef struct MyAVPacketList {
113 AVPacket pkt;
114 struct MyAVPacketList *next;
115 int serial;
116} MyAVPacketList;
117
118typedef struct PacketQueue {
119 MyAVPacketList *first_pkt, *last_pkt;
120 int nb_packets;
121 int size;
122 int64_t duration;
123 int abort_request;
124 int serial;
125 SDL_mutex *mutex;
126 SDL_cond *cond;
127} PacketQueue;
128
129#define VIDEO_PICTURE_QUEUE_SIZE 3
130#define SUBPICTURE_QUEUE_SIZE 16
131#define SAMPLE_QUEUE_SIZE 9
132#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
133
134typedef struct AudioParams {
135 int freq;
136 int channels;
137 int64_t channel_layout;
138 enum AVSampleFormat fmt;
139 int frame_size;
140 int bytes_per_sec;
141} AudioParams;
142
143typedef struct Clock {
144 double pts; /* clock base */
145 double pts_drift; /* clock base minus time at which we updated the clock */
146 double last_updated;
147 double speed;
148 int serial; /* clock is based on a packet with this serial */
149 int paused;
150 int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
151} Clock;
152
153/* Common struct for handling all types of decoded data and allocated render buffers. */
154typedef struct Frame {
155 AVFrame *frame;
156 AVSubtitle sub;
157 int serial;
158 double pts; /* presentation timestamp for the frame */
159 double duration; /* estimated duration of the frame */
160 int64_t pos; /* byte position of the frame in the input file */
161 int width;
162 int height;
163 int format;
164 AVRational sar;
165 int uploaded;
166 int flip_v;
167} Frame;
168
169typedef struct FrameQueue {
170 Frame queue[FRAME_QUEUE_SIZE];
171 int rindex;
172 int windex;
173 int size;
174 int max_size;
175 int keep_last;
176 int rindex_shown;
177 SDL_mutex *mutex;
178 SDL_cond *cond;
179 PacketQueue *pktq;
180} FrameQueue;
181
182enum {
183 AV_SYNC_AUDIO_MASTER, /* default choice */
184 AV_SYNC_VIDEO_MASTER,
185 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
186};
187
188typedef struct Decoder {
189 AVPacket pkt;
190 AVPacket pkt_temp;
191 PacketQueue *queue;
192 AVCodecContext *avctx;
193 int pkt_serial;
194 int finished;
195 int packet_pending;
196 SDL_cond *empty_queue_cond;
197 int64_t start_pts;
198 AVRational start_pts_tb;
199 int64_t next_pts;
200 AVRational next_pts_tb;
201 SDL_Thread *decoder_tid;
202} Decoder;
203
204typedef struct VideoState {
205 SDL_Thread *read_tid;
206 AVInputFormat *iformat;
207 int abort_request;
208 int force_refresh;
209 int paused;
210 int last_paused;
211 int queue_attachments_req;
212 int seek_req;
213 int seek_flags;
214 int64_t seek_pos;
215 int64_t seek_rel;
216 int read_pause_return;
217 AVFormatContext *ic;
218 int realtime;
219
220 Clock audclk;
221 Clock vidclk;
222 Clock extclk;
223
224 FrameQueue pictq;
225 FrameQueue subpq;
226 FrameQueue sampq;
227
228 Decoder auddec;
229 Decoder viddec;
230 Decoder subdec;
231
232 int audio_stream;
233
234 int av_sync_type;
235
236 double audio_clock;
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;
242 AVStream *audio_st;
243 PacketQueue audioq;
244 int audio_hw_buf_size;
245 uint8_t *audio_buf;
246 uint8_t *audio_buf1;
247 unsigned int audio_buf_size; /* in bytes */
248 unsigned int audio_buf1_size;
249 int audio_buf_index; /* in bytes */
250 int audio_write_buf_size;
251 int audio_volume;
252 int muted;
253 struct AudioParams audio_src;
254#if CONFIG_AVFILTER
255 struct AudioParams audio_filter_src;
256#endif
257 struct AudioParams audio_tgt;
258 struct SwrContext *swr_ctx;
259 int frame_drops_early;
260 int frame_drops_late;
261
262 enum ShowMode {
263 SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
264 } show_mode;
265 int16_t sample_array[SAMPLE_ARRAY_SIZE];
266 int sample_array_index;
267 int last_i_start;
268 RDFTContext *rdft;
269 int rdft_bits;
270 FFTSample *rdft_data;
271 int xpos;
272 double last_vis_time;
273 SDL_Texture *vis_texture;
274 SDL_Texture *sub_texture;
275 SDL_Texture *vid_texture;
276
277 int subtitle_stream;
278 AVStream *subtitle_st;
279 PacketQueue subtitleq;
280
281 double frame_timer;
282 double frame_last_returned_time;
283 double frame_last_filter_delay;
284 int video_stream;
285 AVStream *video_st;
286 PacketQueue videoq;
287 double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
288 struct SwsContext *img_convert_ctx;
289 struct SwsContext *sub_convert_ctx;
290 int eof;
291
292 char *filename;
293 int width, height, xleft, ytop;
294 int step;
295
296#if CONFIG_AVFILTER
297 int vfilter_idx;
298 AVFilterContext *in_video_filter; // the first filter in the video chain
299 AVFilterContext *out_video_filter; // the last filter in the video chain
300 AVFilterContext *in_audio_filter; // the first filter in the audio chain
301 AVFilterContext *out_audio_filter; // the last filter in the audio chain
302 AVFilterGraph *agraph; // audio filter graph
303#endif
304
305 int last_video_stream, last_audio_stream, last_subtitle_stream;
306
307 SDL_cond *continue_read_thread;
308} VideoState;
309
310/* options specified by the user */
311static AVInputFormat *file_iformat;
312static const char *input_filename;
313static const char *window_title;
314static int default_width = 640;
315static int default_height = 480;
316static int screen_width = 0;
317static int screen_height = 0;
318static int audio_disable;
319static int video_disable;
320static int subtitle_disable;
321static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
322static int seek_by_bytes = -1;
323static int display_disable;
324static int borderless;
325static int startup_volume = 100;
326static int show_status = 1;
327static int av_sync_type = AV_SYNC_AUDIO_MASTER;
328static int64_t start_time = AV_NOPTS_VALUE;
329static int64_t duration = AV_NOPTS_VALUE;
330static int fast = 0;
331static int genpts = 0;
332static int lowres = 0;
333static int decoder_reorder_pts = -1;
334static int autoexit;
335static int exit_on_keydown;
336static int exit_on_mousedown;
337static int loop = 1;
338static int framedrop = -1;
339static int infinite_buffer = -1;
340static enum ShowMode show_mode = SHOW_MODE_NONE;
341static const char *audio_codec_name;
342static const char *subtitle_codec_name;
343static const char *video_codec_name;
344double rdftspeed = 0.02;
345static int64_t cursor_last_shown;
346static int cursor_hidden = 0;
347#if CONFIG_AVFILTER
348static const char **vfilters_list = NULL;
349static int nb_vfilters = 0;
350static char *afilters = NULL;
351#endif
352static int autorotate = 1;
353
354/* current context */
355static int is_full_screen;
356static int64_t audio_callback_time;
357
358static AVPacket flush_pkt;
359
360#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
361
362static SDL_Window *window;
363static SDL_Renderer *renderer;
364
365#if CONFIG_AVFILTER
366static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
367{
368 GROW_ARRAY(vfilters_list, nb_vfilters);
369 vfilters_list[nb_vfilters - 1] = arg;
370 return 0;
371}
372#endif
373
374static inline
375int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
376 enum AVSampleFormat fmt2, int64_t channel_count2)
377{
378 /* If channel count == 1, planar and non-planar formats are the same */
379 if (channel_count1 == 1 && channel_count2 == 1)
380 return av_get_packed_sample_fmt(fmt1) != av_get_packed_sample_fmt(fmt2);
381 else
382 return channel_count1 != channel_count2 || fmt1 != fmt2;
383}
384
385static inline
386int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
387{
388 if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
389 return channel_layout;
390 else
391 return 0;
392}
393
394static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
395{
396 MyAVPacketList *pkt1;
397
398 if (q->abort_request)
399 return -1;
400
401 pkt1 = av_malloc(sizeof(MyAVPacketList));
402 if (!pkt1)
403 return -1;
404 pkt1->pkt = *pkt;
405 pkt1->next = NULL;
406 if (pkt == &flush_pkt)
407 q->serial++;
408 pkt1->serial = q->serial;
409
410 if (!q->last_pkt)
411 q->first_pkt = pkt1;
412 else
413 q->last_pkt->next = pkt1;
414 q->last_pkt = pkt1;
415 q->nb_packets++;
416 q->size += pkt1->pkt.size + sizeof(*pkt1);
417 q->duration += pkt1->pkt.duration;
418 /* XXX: should duplicate packet data in DV case */
419 SDL_CondSignal(q->cond);
420 return 0;
421}
422
423static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
424{
425 int ret;
426
427 SDL_LockMutex(q->mutex);
428 ret = packet_queue_put_private(q, pkt);
429 SDL_UnlockMutex(q->mutex);
430
431 if (pkt != &flush_pkt && ret < 0)
432 av_packet_unref(pkt);
433
434 return ret;
435}
436
437static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
438{
439 AVPacket pkt1, *pkt = &pkt1;
440 av_init_packet(pkt);
441 pkt->data = NULL;
442 pkt->size = 0;
443 pkt->stream_index = stream_index;
444 return packet_queue_put(q, pkt);
445}
446
447/* packet queue handling */
448static int packet_queue_init(PacketQueue *q)
449{
450 memset(q, 0, sizeof(PacketQueue));
451 q->mutex = SDL_CreateMutex();
452 if (!q->mutex) {
453 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
454 return AVERROR(ENOMEM);
455 }
456 q->cond = SDL_CreateCond();
457 if (!q->cond) {
458 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
459 return AVERROR(ENOMEM);
460 }
461 q->abort_request = 1;
462 return 0;
463}
464
465static void packet_queue_flush(PacketQueue *q)
466{
467 MyAVPacketList *pkt, *pkt1;
468
469 SDL_LockMutex(q->mutex);
470 for (pkt = q->first_pkt; pkt; pkt = pkt1) {
471 pkt1 = pkt->next;
472 av_packet_unref(&pkt->pkt);
473 av_freep(&pkt);
474 }
475 q->last_pkt = NULL;
476 q->first_pkt = NULL;
477 q->nb_packets = 0;
478 q->size = 0;
479 q->duration = 0;
480 SDL_UnlockMutex(q->mutex);
481}
482
483static void packet_queue_destroy(PacketQueue *q)
484{
485 packet_queue_flush(q);
486 SDL_DestroyMutex(q->mutex);
487 SDL_DestroyCond(q->cond);
488}
489
490static void packet_queue_abort(PacketQueue *q)
491{
492 SDL_LockMutex(q->mutex);
493
494 q->abort_request = 1;
495
496 SDL_CondSignal(q->cond);
497
498 SDL_UnlockMutex(q->mutex);
499}
500
501static void packet_queue_start(PacketQueue *q)
502{
503 SDL_LockMutex(q->mutex);
504 q->abort_request = 0;
505 packet_queue_put_private(q, &flush_pkt);
506 SDL_UnlockMutex(q->mutex);
507}
508
509/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
510static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
511{
512 MyAVPacketList *pkt1;
513 int ret;
514
515 SDL_LockMutex(q->mutex);
516
517 for (;;) {
518 if (q->abort_request) {
519 ret = -1;
520 break;
521 }
522
523 pkt1 = q->first_pkt;
524 if (pkt1) {
525 q->first_pkt = pkt1->next;
526 if (!q->first_pkt)
527 q->last_pkt = NULL;
528 q->nb_packets--;
529 q->size -= pkt1->pkt.size + sizeof(*pkt1);
530 q->duration -= pkt1->pkt.duration;
531 *pkt = pkt1->pkt;
532 if (serial)
533 *serial = pkt1->serial;
534 av_free(pkt1);
535 ret = 1;
536 break;
537 } else if (!block) {
538 ret = 0;
539 break;
540 } else {
541 SDL_CondWait(q->cond, q->mutex);
542 }
543 }
544 SDL_UnlockMutex(q->mutex);
545 return ret;
546}
547
548static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
549 memset(d, 0, sizeof(Decoder));
550 d->avctx = avctx;
551 d->queue = queue;
552 d->empty_queue_cond = empty_queue_cond;
553 d->start_pts = AV_NOPTS_VALUE;
554}
555
556static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
557 int got_frame = 0;
558
559 do {
560 int ret = -1;
561
562 if (d->queue->abort_request)
563 return -1;
564
565 if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
566 AVPacket pkt;
567 do {
568 if (d->queue->nb_packets == 0)
569 SDL_CondSignal(d->empty_queue_cond);
570 if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
571 return -1;
572 if (pkt.data == flush_pkt.data) {
573 avcodec_flush_buffers(d->avctx);
574 d->finished = 0;
575 d->next_pts = d->start_pts;
576 d->next_pts_tb = d->start_pts_tb;
577 }
578 } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
579 av_packet_unref(&d->pkt);
580 d->pkt_temp = d->pkt = pkt;
581 d->packet_pending = 1;
582 }
583
584 switch (d->avctx->codec_type) {
585 case AVMEDIA_TYPE_VIDEO:
586 ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
587 if (got_frame) {
588 if (decoder_reorder_pts == -1) {
589 frame->pts = av_frame_get_best_effort_timestamp(frame);
590 } else if (!decoder_reorder_pts) {
591 frame->pts = frame->pkt_dts;
592 }
593 }
594 break;
595 case AVMEDIA_TYPE_AUDIO:
596 ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
597 if (got_frame) {
598 AVRational tb = (AVRational){1, frame->sample_rate};
599 if (frame->pts != AV_NOPTS_VALUE)
600 frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb);
601 else if (d->next_pts != AV_NOPTS_VALUE)
602 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
603 if (frame->pts != AV_NOPTS_VALUE) {
604 d->next_pts = frame->pts + frame->nb_samples;
605 d->next_pts_tb = tb;
606 }
607 }
608 break;
609 case AVMEDIA_TYPE_SUBTITLE:
610 ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
611 break;
612 }
613
614 if (ret < 0) {
615 d->packet_pending = 0;
616 } else {
617 d->pkt_temp.dts =
618 d->pkt_temp.pts = AV_NOPTS_VALUE;
619 if (d->pkt_temp.data) {
620 if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
621 ret = d->pkt_temp.size;
622 d->pkt_temp.data += ret;
623 d->pkt_temp.size -= ret;
624 if (d->pkt_temp.size <= 0)
625 d->packet_pending = 0;
626 } else {
627 if (!got_frame) {
628 d->packet_pending = 0;
629 d->finished = d->pkt_serial;
630 }
631 }
632 }
633 } while (!got_frame && !d->finished);
634
635 return got_frame;
636}
637
638static void decoder_destroy(Decoder *d) {
639 av_packet_unref(&d->pkt);
640 avcodec_free_context(&d->avctx);
641}
642
643static void frame_queue_unref_item(Frame *vp)
644{
645 av_frame_unref(vp->frame);
646 avsubtitle_free(&vp->sub);
647}
648
649static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
650{
651 int i;
652 memset(f, 0, sizeof(FrameQueue));
653 if (!(f->mutex = SDL_CreateMutex())) {
654 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
655 return AVERROR(ENOMEM);
656 }
657 if (!(f->cond = SDL_CreateCond())) {
658 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
659 return AVERROR(ENOMEM);
660 }
661 f->pktq = pktq;
662 f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
663 f->keep_last = !!keep_last;
664 for (i = 0; i < f->max_size; i++)
665 if (!(f->queue[i].frame = av_frame_alloc()))
666 return AVERROR(ENOMEM);
667 return 0;
668}
669
670static void frame_queue_destory(FrameQueue *f)
671{
672 int i;
673 for (i = 0; i < f->max_size; i++) {
674 Frame *vp = &f->queue[i];
675 frame_queue_unref_item(vp);
676 av_frame_free(&vp->frame);
677 }
678 SDL_DestroyMutex(f->mutex);
679 SDL_DestroyCond(f->cond);
680}
681
682static void frame_queue_signal(FrameQueue *f)
683{
684 SDL_LockMutex(f->mutex);
685 SDL_CondSignal(f->cond);
686 SDL_UnlockMutex(f->mutex);
687}
688
689static Frame *frame_queue_peek(FrameQueue *f)
690{
691 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
692}
693
694static Frame *frame_queue_peek_next(FrameQueue *f)
695{
696 return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
697}
698
699static Frame *frame_queue_peek_last(FrameQueue *f)
700{
701 return &f->queue[f->rindex];
702}
703
704static Frame *frame_queue_peek_writable(FrameQueue *f)
705{
706 /* wait until we have space to put a new frame */
707 SDL_LockMutex(f->mutex);
708 while (f->size >= f->max_size &&
709 !f->pktq->abort_request) {
710 SDL_CondWait(f->cond, f->mutex);
711 }
712 SDL_UnlockMutex(f->mutex);
713
714 if (f->pktq->abort_request)
715 return NULL;
716
717 return &f->queue[f->windex];
718}
719
720static Frame *frame_queue_peek_readable(FrameQueue *f)
721{
722 /* wait until we have a readable a new frame */
723 SDL_LockMutex(f->mutex);
724 while (f->size - f->rindex_shown <= 0 &&
725 !f->pktq->abort_request) {
726 SDL_CondWait(f->cond, f->mutex);
727 }
728 SDL_UnlockMutex(f->mutex);
729
730 if (f->pktq->abort_request)
731 return NULL;
732
733 return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
734}
735
736static void frame_queue_push(FrameQueue *f)
737{
738 if (++f->windex == f->max_size)
739 f->windex = 0;
740 SDL_LockMutex(f->mutex);
741 f->size++;
742 SDL_CondSignal(f->cond);
743 SDL_UnlockMutex(f->mutex);
744}
745
746static void frame_queue_next(FrameQueue *f)
747{
748 if (f->keep_last && !f->rindex_shown) {
749 f->rindex_shown = 1;
750 return;
751 }
752 frame_queue_unref_item(&f->queue[f->rindex]);
753 if (++f->rindex == f->max_size)
754 f->rindex = 0;
755 SDL_LockMutex(f->mutex);
756 f->size--;
757 SDL_CondSignal(f->cond);
758 SDL_UnlockMutex(f->mutex);
759}
760
761/* return the number of undisplayed frames in the queue */
762static int frame_queue_nb_remaining(FrameQueue *f)
763{
764 return f->size - f->rindex_shown;
765}
766
767/* return last shown position */
768static int64_t frame_queue_last_pos(FrameQueue *f)
769{
770 Frame *fp = &f->queue[f->rindex];
771 if (f->rindex_shown && fp->serial == f->pktq->serial)
772 return fp->pos;
773 else
774 return -1;
775}
776
777static void decoder_abort(Decoder *d, FrameQueue *fq)
778{
779 packet_queue_abort(d->queue);
780 frame_queue_signal(fq);
781 SDL_WaitThread(d->decoder_tid, NULL);
782 d->decoder_tid = NULL;
783 packet_queue_flush(d->queue);
784}
785
786static inline void fill_rectangle(int x, int y, int w, int h)
787{
788 SDL_Rect rect;
789 rect.x = x;
790 rect.y = y;
791 rect.w = w;
792 rect.h = h;
793 if (w && h)
794 SDL_RenderFillRect(renderer, &rect);
795}
796
797static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
798{
799 Uint32 format;
800 int access, w, h;
801 if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
802 void *pixels;
803 int pitch;
804 SDL_DestroyTexture(*texture);
805 if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
806 return -1;
807 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
808 return -1;
809 if (init_texture) {
810 if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
811 return -1;
812 memset(pixels, 0, pitch * new_height);
813 SDL_UnlockTexture(*texture);
814 }
815 }
816 return 0;
817}
818
819static void calculate_display_rect(SDL_Rect *rect,
820 int scr_xleft, int scr_ytop, int scr_width, int scr_height,
821 int pic_width, int pic_height, AVRational pic_sar)
822{
823 float aspect_ratio;
824 int width, height, x, y;
825
826 if (pic_sar.num == 0)
827 aspect_ratio = 0;
828 else
829 aspect_ratio = av_q2d(pic_sar);
830
831 if (aspect_ratio <= 0.0)
832 aspect_ratio = 1.0;
833 aspect_ratio *= (float)pic_width / (float)pic_height;
834
835 /* XXX: we suppose the screen has a 1.0 pixel ratio */
836 height = scr_height;
837 width = lrint(height * aspect_ratio) & ~1;
838 if (width > scr_width) {
839 width = scr_width;
840 height = lrint(width / aspect_ratio) & ~1;
841 }
842 x = (scr_width - width) / 2;
843 y = (scr_height - height) / 2;
844 rect->x = scr_xleft + x;
845 rect->y = scr_ytop + y;
846 rect->w = FFMAX(width, 1);
847 rect->h = FFMAX(height, 1);
848}
849
850static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
851 int ret = 0;
852 switch (frame->format) {
853 case AV_PIX_FMT_YUV420P:
854 if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
855 av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
856 return -1;
857 }
858 ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
859 frame->data[1], frame->linesize[1],
860 frame->data[2], frame->linesize[2]);
861 break;
862 case AV_PIX_FMT_BGRA:
863 if (frame->linesize[0] < 0) {
864 ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
865 } else {
866 ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
867 }
868 break;
869 default:
870 /* This should only happen if we are not using avfilter... */
871 *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
872 frame->width, frame->height, frame->format, frame->width, frame->height,
873 AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
874 if (*img_convert_ctx != NULL) {
875 uint8_t *pixels[4];
876 int pitch[4];
877 if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) {
878 sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
879 0, frame->height, pixels, pitch);
880 SDL_UnlockTexture(tex);
881 }
882 } else {
883 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
884 ret = -1;
885 }
886 break;
887 }
888 return ret;
889}
890
891static void video_image_display(VideoState *is)
892{
893 Frame *vp;
894 Frame *sp = NULL;
895 SDL_Rect rect;
896
897 vp = frame_queue_peek_last(&is->pictq);
898 if (is->subtitle_st) {
899 if (frame_queue_nb_remaining(&is->subpq) > 0) {
900 sp = frame_queue_peek(&is->subpq);
901
902 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
903 if (!sp->uploaded) {
904 uint8_t* pixels[4];
905 int pitch[4];
906 int i;
907 if (!sp->width || !sp->height) {
908 sp->width = vp->width;
909 sp->height = vp->height;
910 }
911 if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
912 return;
913
914 for (i = 0; i < sp->sub.num_rects; i++) {
915 AVSubtitleRect *sub_rect = sp->sub.rects[i];
916
917 sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
918 sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
919 sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
920 sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
921
922 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
923 sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
924 sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
925 0, NULL, NULL, NULL);
926 if (!is->sub_convert_ctx) {
927 av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
928 return;
929 }
930 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
931 sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
932 0, sub_rect->h, pixels, pitch);
933 SDL_UnlockTexture(is->sub_texture);
934 }
935 }
936 sp->uploaded = 1;
937 }
938 } else
939 sp = NULL;
940 }
941 }
942
943 calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
944
945 if (!vp->uploaded) {
946 int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
947 if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
948 return;
949 if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
950 return;
951 vp->uploaded = 1;
952 vp->flip_v = vp->frame->linesize[0] < 0;
953 }
954
955 SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
956 if (sp) {
957#if USE_ONEPASS_SUBTITLE_RENDER
958 SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
959#else
960 int i;
961 double xratio = (double)rect.w / (double)sp->width;
962 double yratio = (double)rect.h / (double)sp->height;
963 for (i = 0; i < sp->sub.num_rects; i++) {
964 SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
965 SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
966 .y = rect.y + sub_rect->y * yratio,
967 .w = sub_rect->w * xratio,
968 .h = sub_rect->h * yratio};
969 SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
970 }
971#endif
972 }
973}
974
975static inline int compute_mod(int a, int b)
976{
977 return a < 0 ? a%b + b : a%b;
978}
979
980static void video_audio_display(VideoState *s)
981{
982 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
983 int ch, channels, h, h2;
984 int64_t time_diff;
985 int rdft_bits, nb_freq;
986
987 for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
988 ;
989 nb_freq = 1 << (rdft_bits - 1);
990
991 /* compute display index : center on currently output samples */
992 channels = s->audio_tgt.channels;
993 nb_display_channels = channels;
994 if (!s->paused) {
995 int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
996 n = 2 * channels;
997 delay = s->audio_write_buf_size;
998 delay /= n;
999
1000 /* to be more precise, we take into account the time spent since
1001 the last buffer computation */
1002 if (audio_callback_time) {
1003 time_diff = av_gettime_relative() - audio_callback_time;
1004 delay -= (time_diff * s->audio_tgt.freq) / 1000000;
1005 }
1006
1007 delay += 2 * data_used;
1008 if (delay < data_used)
1009 delay = data_used;
1010
1011 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
1012 if (s->show_mode == SHOW_MODE_WAVES) {
1013 h = INT_MIN;
1014 for (i = 0; i < 1000; i += channels) {
1015 int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
1016 int a = s->sample_array[idx];
1017 int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
1018 int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
1019 int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
1020 int score = a - d;
1021 if (h < score && (b ^ c) < 0) {
1022 h = score;
1023 i_start = idx;
1024 }
1025 }
1026 }
1027
1028 s->last_i_start = i_start;
1029 } else {
1030 i_start = s->last_i_start;
1031 }
1032
1033 if (s->show_mode == SHOW_MODE_WAVES) {
1034 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
1035
1036 /* total height for one channel */
1037 h = s->height / nb_display_channels;
1038 /* graph height / 2 */
1039 h2 = (h * 9) / 20;
1040 for (ch = 0; ch < nb_display_channels; ch++) {
1041 i = i_start + ch;
1042 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
1043 for (x = 0; x < s->width; x++) {
1044 y = (s->sample_array[i] * h2) >> 15;
1045 if (y < 0) {
1046 y = -y;
1047 ys = y1 - y;
1048 } else {
1049 ys = y1;
1050 }
1051 fill_rectangle(s->xleft + x, ys, 1, y);
1052 i += channels;
1053 if (i >= SAMPLE_ARRAY_SIZE)
1054 i -= SAMPLE_ARRAY_SIZE;
1055 }
1056 }
1057
1058 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
1059
1060 for (ch = 1; ch < nb_display_channels; ch++) {
1061 y = s->ytop + ch * h;
1062 fill_rectangle(s->xleft, y, s->width, 1);
1063 }
1064 } else {
1065 if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
1066 return;
1067
1068 nb_display_channels= FFMIN(nb_display_channels, 2);
1069 if (rdft_bits != s->rdft_bits) {
1070 av_rdft_end(s->rdft);
1071 av_free(s->rdft_data);
1072 s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
1073 s->rdft_bits = rdft_bits;
1074 s->rdft_data = av_malloc_array(nb_freq, 4 *sizeof(*s->rdft_data));
1075 }
1076 if (!s->rdft || !s->rdft_data){
1077 av_log(NULL, AV_LOG_ERROR, "Failed to allocate buffers for RDFT, switching to waves display\n");
1078 s->show_mode = SHOW_MODE_WAVES;
1079 } else {
1080 FFTSample *data[2];
1081 SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
1082 uint32_t *pixels;
1083 int pitch;
1084 for (ch = 0; ch < nb_display_channels; ch++) {
1085 data[ch] = s->rdft_data + 2 * nb_freq * ch;
1086 i = i_start + ch;
1087 for (x = 0; x < 2 * nb_freq; x++) {
1088 double w = (x-nb_freq) * (1.0 / nb_freq);
1089 data[ch][x] = s->sample_array[i] * (1.0 - w * w);
1090 i += channels;
1091 if (i >= SAMPLE_ARRAY_SIZE)
1092 i -= SAMPLE_ARRAY_SIZE;
1093 }
1094 av_rdft_calc(s->rdft, data[ch]);
1095 }
1096 /* Least efficient way to do this, we should of course
1097 * directly access it but it is more than fast enough. */
1098 if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
1099 pitch >>= 2;
1100 pixels += pitch * s->height;
1101 for (y = 0; y < s->height; y++) {
1102 double w = 1 / sqrt(nb_freq);
1103 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]));
1104 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
1105 : a;
1106 a = FFMIN(a, 255);
1107 b = FFMIN(b, 255);
1108 pixels -= pitch;
1109 *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
1110 }
1111 SDL_UnlockTexture(s->vis_texture);
1112 }
1113 SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
1114 }
1115 if (!s->paused)
1116 s->xpos++;
1117 if (s->xpos >= s->width)
1118 s->xpos= s->xleft;
1119 }
1120}
1121
1122static void stream_component_close(VideoState *is, int stream_index)
1123{
1124 AVFormatContext *ic = is->ic;
1125 AVCodecParameters *codecpar;
1126
1127 if (stream_index < 0 || stream_index >= ic->nb_streams)
1128 return;
1129 codecpar = ic->streams[stream_index]->codecpar;
1130
1131 switch (codecpar->codec_type) {
1132 case AVMEDIA_TYPE_AUDIO:
1133 decoder_abort(&is->auddec, &is->sampq);
1134 SDL_CloseAudio();
1135 decoder_destroy(&is->auddec);
1136 swr_free(&is->swr_ctx);
1137 av_freep(&is->audio_buf1);
1138 is->audio_buf1_size = 0;
1139 is->audio_buf = NULL;
1140
1141 if (is->rdft) {
1142 av_rdft_end(is->rdft);
1143 av_freep(&is->rdft_data);
1144 is->rdft = NULL;
1145 is->rdft_bits = 0;
1146 }
1147 break;
1148 case AVMEDIA_TYPE_VIDEO:
1149 decoder_abort(&is->viddec, &is->pictq);
1150 decoder_destroy(&is->viddec);
1151 break;
1152 case AVMEDIA_TYPE_SUBTITLE:
1153 decoder_abort(&is->subdec, &is->subpq);
1154 decoder_destroy(&is->subdec);
1155 break;
1156 default:
1157 break;
1158 }
1159
1160 ic->streams[stream_index]->discard = AVDISCARD_ALL;
1161 switch (codecpar->codec_type) {
1162 case AVMEDIA_TYPE_AUDIO:
1163 is->audio_st = NULL;
1164 is->audio_stream = -1;
1165 break;
1166 case AVMEDIA_TYPE_VIDEO:
1167 is->video_st = NULL;
1168 is->video_stream = -1;
1169 break;
1170 case AVMEDIA_TYPE_SUBTITLE:
1171 is->subtitle_st = NULL;
1172 is->subtitle_stream = -1;
1173 break;
1174 default:
1175 break;
1176 }
1177}
1178
1179static void stream_close(VideoState *is)
1180{
1181 /* XXX: use a special url_shutdown call to abort parse cleanly */
1182 is->abort_request = 1;
1183 SDL_WaitThread(is->read_tid, NULL);
1184
1185 /* close each stream */
1186 if (is->audio_stream >= 0)
1187 stream_component_close(is, is->audio_stream);
1188 if (is->video_stream >= 0)
1189 stream_component_close(is, is->video_stream);
1190 if (is->subtitle_stream >= 0)
1191 stream_component_close(is, is->subtitle_stream);
1192
1193 avformat_close_input(&is->ic);
1194
1195 packet_queue_destroy(&is->videoq);
1196 packet_queue_destroy(&is->audioq);
1197 packet_queue_destroy(&is->subtitleq);
1198
1199 /* free all pictures */
1200 frame_queue_destory(&is->pictq);
1201 frame_queue_destory(&is->sampq);
1202 frame_queue_destory(&is->subpq);
1203 SDL_DestroyCond(is->continue_read_thread);
1204 sws_freeContext(is->img_convert_ctx);
1205 sws_freeContext(is->sub_convert_ctx);
1206 av_free(is->filename);
1207 if (is->vis_texture)
1208 SDL_DestroyTexture(is->vis_texture);
1209 if (is->vid_texture)
1210 SDL_DestroyTexture(is->vid_texture);
1211 if (is->sub_texture)
1212 SDL_DestroyTexture(is->sub_texture);
1213 av_free(is);
1214}
1215
1216static void do_exit(VideoState *is)
1217{
1218 if (is) {
1219 stream_close(is);
1220 }
1221 if (renderer)
1222 SDL_DestroyRenderer(renderer);
1223 if (window)
1224 SDL_DestroyWindow(window);
1225 av_lockmgr_register(NULL);
1226 uninit_opts();
1227#if CONFIG_AVFILTER
1228 av_freep(&vfilters_list);
1229#endif
1230 avformat_network_deinit();
1231 if (show_status)
1232 printf("\n");
1233 SDL_Quit();
1234 av_log(NULL, AV_LOG_QUIET, "%s", "");
1235 exit(0);
1236}
1237
1238static void sigterm_handler(int sig)
1239{
1240 exit(123);
1241}
1242
1243static void set_default_window_size(int width, int height, AVRational sar)
1244{
1245 SDL_Rect rect;
1246 calculate_display_rect(&rect, 0, 0, INT_MAX, height, width, height, sar);
1247 default_width = rect.w;
1248 default_height = rect.h;
1249}
1250
1251static int video_open(VideoState *is)
1252{
1253 int w,h;
1254
1255 if (screen_width) {
1256 w = screen_width;
1257 h = screen_height;
1258 } else {
1259 w = default_width;
1260 h = default_height;
1261 }
1262
1263 if (!window) {
1264 int flags = SDL_WINDOW_SHOWN;
1265 if (!window_title)
1266 window_title = input_filename;
1267 if (is_full_screen)
1268 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1269 if (borderless)
1270 flags |= SDL_WINDOW_BORDERLESS;
1271 else
1272 flags |= SDL_WINDOW_RESIZABLE;
1273 window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
1274 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
1275 if (window) {
1276 SDL_RendererInfo info;
1277 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1278 if (!renderer) {
1279 av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
1280 renderer = SDL_CreateRenderer(window, -1, 0);
1281 }
1282 if (renderer) {
1283 if (!SDL_GetRendererInfo(renderer, &info))
1284 av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
1285 }
1286 }
1287 } else {
1288 SDL_SetWindowSize(window, w, h);
1289 }
1290
1291 if (!window || !renderer) {
1292 av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
1293 do_exit(is);
1294 }
1295
1296 is->width = w;
1297 is->height = h;
1298
1299 return 0;
1300}
1301
1302/* display the current picture, if any */
1303static void video_display(VideoState *is)
1304{
1305 if (!window)
1306 video_open(is);
1307
1308 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
1309 SDL_RenderClear(renderer);
1310 if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
1311 video_audio_display(is);
1312 else if (is->video_st)
1313 video_image_display(is);
1314 SDL_RenderPresent(renderer);
1315}
1316
1317static double get_clock(Clock *c)
1318{
1319 if (*c->queue_serial != c->serial)
1320 return NAN;
1321 if (c->paused) {
1322 return c->pts;
1323 } else {
1324 double time = av_gettime_relative() / 1000000.0;
1325 return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
1326 }
1327}
1328
1329static void set_clock_at(Clock *c, double pts, int serial, double time)
1330{
1331 c->pts = pts;
1332 c->last_updated = time;
1333 c->pts_drift = c->pts - time;
1334 c->serial = serial;
1335}
1336
1337static void set_clock(Clock *c, double pts, int serial)
1338{
1339 double time = av_gettime_relative() / 1000000.0;
1340 set_clock_at(c, pts, serial, time);
1341}
1342
1343static void set_clock_speed(Clock *c, double speed)
1344{
1345 set_clock(c, get_clock(c), c->serial);
1346 c->speed = speed;
1347}
1348
1349static void init_clock(Clock *c, int *queue_serial)
1350{
1351 c->speed = 1.0;
1352 c->paused = 0;
1353 c->queue_serial = queue_serial;
1354 set_clock(c, NAN, -1);
1355}
1356
1357static void sync_clock_to_slave(Clock *c, Clock *slave)
1358{
1359 double clock = get_clock(c);
1360 double slave_clock = get_clock(slave);
1361 if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
1362 set_clock(c, slave_clock, slave->serial);
1363}
1364
1365static int get_master_sync_type(VideoState *is) {
1366 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1367 if (is->video_st)
1368 return AV_SYNC_VIDEO_MASTER;
1369 else
1370 return AV_SYNC_AUDIO_MASTER;
1371 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1372 if (is->audio_st)
1373 return AV_SYNC_AUDIO_MASTER;
1374 else
1375 return AV_SYNC_EXTERNAL_CLOCK;
1376 } else {
1377 return AV_SYNC_EXTERNAL_CLOCK;
1378 }
1379}
1380
1381/* get the current master clock value */
1382static double get_master_clock(VideoState *is)
1383{
1384 double val;
1385
1386 switch (get_master_sync_type(is)) {
1387 case AV_SYNC_VIDEO_MASTER:
1388 val = get_clock(&is->vidclk);
1389 break;
1390 case AV_SYNC_AUDIO_MASTER:
1391 val = get_clock(&is->audclk);
1392 break;
1393 default:
1394 val = get_clock(&is->extclk);
1395 break;
1396 }
1397 return val;
1398}
1399
1400static void check_external_clock_speed(VideoState *is) {
1401 if (is->video_stream >= 0 && is->videoq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES ||
1402 is->audio_stream >= 0 && is->audioq.nb_packets <= EXTERNAL_CLOCK_MIN_FRAMES) {
1403 set_clock_speed(&is->extclk, FFMAX(EXTERNAL_CLOCK_SPEED_MIN, is->extclk.speed - EXTERNAL_CLOCK_SPEED_STEP));
1404 } else if ((is->video_stream < 0 || is->videoq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES) &&
1405 (is->audio_stream < 0 || is->audioq.nb_packets > EXTERNAL_CLOCK_MAX_FRAMES)) {
1406 set_clock_speed(&is->extclk, FFMIN(EXTERNAL_CLOCK_SPEED_MAX, is->extclk.speed + EXTERNAL_CLOCK_SPEED_STEP));
1407 } else {
1408 double speed = is->extclk.speed;
1409 if (speed != 1.0)
1410 set_clock_speed(&is->extclk, speed + EXTERNAL_CLOCK_SPEED_STEP * (1.0 - speed) / fabs(1.0 - speed));
1411 }
1412}
1413
1414/* seek in the stream */
1415static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1416{
1417 if (!is->seek_req) {
1418 is->seek_pos = pos;
1419 is->seek_rel = rel;
1420 is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1421 if (seek_by_bytes)
1422 is->seek_flags |= AVSEEK_FLAG_BYTE;
1423 is->seek_req = 1;
1424 SDL_CondSignal(is->continue_read_thread);
1425 }
1426}
1427
1428/* pause or resume the video */
1429static void stream_toggle_pause(VideoState *is)
1430{
1431 if (is->paused) {
1432 is->frame_timer += av_gettime_relative() / 1000000.0 - is->vidclk.last_updated;
1433 if (is->read_pause_return != AVERROR(ENOSYS)) {
1434 is->vidclk.paused = 0;
1435 }
1436 set_clock(&is->vidclk, get_clock(&is->vidclk), is->vidclk.serial);
1437 }
1438 set_clock(&is->extclk, get_clock(&is->extclk), is->extclk.serial);
1439 is->paused = is->audclk.paused = is->vidclk.paused = is->extclk.paused = !is->paused;
1440}
1441
1442static void toggle_pause(VideoState *is)
1443{
1444 stream_toggle_pause(is);
1445 is->step = 0;
1446}
1447
1448static void toggle_mute(VideoState *is)
1449{
1450 is->muted = !is->muted;
1451}
1452
1453static void update_volume(VideoState *is, int sign, double step)
1454{
1455 double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1456 int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
1457 is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1458}
1459
1460static void step_to_next_frame(VideoState *is)
1461{
1462 /* if the stream is paused unpause it, then step */
1463 if (is->paused)
1464 stream_toggle_pause(is);
1465 is->step = 1;
1466}
1467
1468static double compute_target_delay(double delay, VideoState *is)
1469{
1470 double sync_threshold, diff = 0;
1471
1472 /* update delay to follow master synchronisation source */
1473 if (get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER) {
1474 /* if video is slave, we try to correct big delays by
1475 duplicating or deleting a frame */
1476 diff = get_clock(&is->vidclk) - get_master_clock(is);
1477
1478 /* skip or repeat frame. We take into account the
1479 delay to compute the threshold. I still don't know
1480 if it is the best guess */
1481 sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN, FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
1482 if (!isnan(diff) && fabs(diff) < is->max_frame_duration) {
1483 if (diff <= -sync_threshold)
1484 delay = FFMAX(0, delay + diff);
1485 else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD)
1486 delay = delay + diff;
1487 else if (diff >= sync_threshold)
1488 delay = 2 * delay;
1489 }
1490 }
1491
1492 av_log(NULL, AV_LOG_TRACE, "video: delay=%0.3f A-V=%f\n",
1493 delay, -diff);
1494
1495 return delay;
1496}
1497
1498static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
1499 if (vp->serial == nextvp->serial) {
1500 double duration = nextvp->pts - vp->pts;
1501 if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
1502 return vp->duration;
1503 else
1504 return duration;
1505 } else {
1506 return 0.0;
1507 }
1508}
1509
1510static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
1511 /* update current video pts */
1512 set_clock(&is->vidclk, pts, serial);
1513 sync_clock_to_slave(&is->extclk, &is->vidclk);
1514}
1515
1516/* called to display each frame */
1517static void video_refresh(void *opaque, double *remaining_time)
1518{
1519 VideoState *is = opaque;
1520 double time;
1521
1522 Frame *sp, *sp2;
1523
1524 if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
1525 check_external_clock_speed(is);
1526
1527 if (!display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
1528 time = av_gettime_relative() / 1000000.0;
1529 if (is->force_refresh || is->last_vis_time + rdftspeed < time) {
1530 video_display(is);
1531 is->last_vis_time = time;
1532 }
1533 *remaining_time = FFMIN(*remaining_time, is->last_vis_time + rdftspeed - time);
1534 }
1535
1536 if (is->video_st) {
1537retry:
1538 if (frame_queue_nb_remaining(&is->pictq) == 0) {
1539 // nothing to do, no picture to display in the queue
1540 } else {
1541 double last_duration, duration, delay;
1542 Frame *vp, *lastvp;
1543
1544 /* dequeue the picture */
1545 lastvp = frame_queue_peek_last(&is->pictq);
1546 vp = frame_queue_peek(&is->pictq);
1547
1548 if (vp->serial != is->videoq.serial) {
1549 frame_queue_next(&is->pictq);
1550 goto retry;
1551 }
1552
1553 if (lastvp->serial != vp->serial)
1554 is->frame_timer = av_gettime_relative() / 1000000.0;
1555
1556 if (is->paused)
1557 goto display;
1558
1559 /* compute nominal last_duration */
1560 last_duration = vp_duration(is, lastvp, vp);
1561 delay = compute_target_delay(last_duration, is);
1562
1563 time= av_gettime_relative()/1000000.0;
1564 if (time < is->frame_timer + delay) {
1565 *remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
1566 goto display;
1567 }
1568
1569 is->frame_timer += delay;
1570 if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
1571 is->frame_timer = time;
1572
1573 SDL_LockMutex(is->pictq.mutex);
1574 if (!isnan(vp->pts))
1575 update_video_pts(is, vp->pts, vp->pos, vp->serial);
1576 SDL_UnlockMutex(is->pictq.mutex);
1577
1578 if (frame_queue_nb_remaining(&is->pictq) > 1) {
1579 Frame *nextvp = frame_queue_peek_next(&is->pictq);
1580 duration = vp_duration(is, vp, nextvp);
1581 if(!is->step && (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
1582 is->frame_drops_late++;
1583 frame_queue_next(&is->pictq);
1584 goto retry;
1585 }
1586 }
1587
1588 if (is->subtitle_st) {
1589 while (frame_queue_nb_remaining(&is->subpq) > 0) {
1590 sp = frame_queue_peek(&is->subpq);
1591
1592 if (frame_queue_nb_remaining(&is->subpq) > 1)
1593 sp2 = frame_queue_peek_next(&is->subpq);
1594 else
1595 sp2 = NULL;
1596
1597 if (sp->serial != is->subtitleq.serial
1598 || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1599 || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1600 {
1601 if (sp->uploaded) {
1602 int i;
1603 for (i = 0; i < sp->sub.num_rects; i++) {
1604 AVSubtitleRect *sub_rect = sp->sub.rects[i];
1605 uint8_t *pixels;
1606 int pitch, j;
1607
1608 if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
1609 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1610 memset(pixels, 0, sub_rect->w << 2);
1611 SDL_UnlockTexture(is->sub_texture);
1612 }
1613 }
1614 }
1615 frame_queue_next(&is->subpq);
1616 } else {
1617 break;
1618 }
1619 }
1620 }
1621
1622 frame_queue_next(&is->pictq);
1623 is->force_refresh = 1;
1624
1625 if (is->step && !is->paused)
1626 stream_toggle_pause(is);
1627 }
1628display:
1629 /* display picture */
1630 if (!display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
1631 video_display(is);
1632 }
1633 is->force_refresh = 0;
1634 if (show_status) {
1635 static int64_t last_time;
1636 int64_t cur_time;
1637 int aqsize, vqsize, sqsize;
1638 double av_diff;
1639
1640 cur_time = av_gettime_relative();
1641 if (!last_time || (cur_time - last_time) >= 30000) {
1642 aqsize = 0;
1643 vqsize = 0;
1644 sqsize = 0;
1645 if (is->audio_st)
1646 aqsize = is->audioq.size;
1647 if (is->video_st)
1648 vqsize = is->videoq.size;
1649 if (is->subtitle_st)
1650 sqsize = is->subtitleq.size;
1651 av_diff = 0;
1652 if (is->audio_st && is->video_st)
1653 av_diff = get_clock(&is->audclk) - get_clock(&is->vidclk);
1654 else if (is->video_st)
1655 av_diff = get_master_clock(is) - get_clock(&is->vidclk);
1656 else if (is->audio_st)
1657 av_diff = get_master_clock(is) - get_clock(&is->audclk);
1658 av_log(NULL, AV_LOG_INFO,
1659 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
1660 get_master_clock(is),
1661 (is->audio_st && is->video_st) ? "A-V" : (is->video_st ? "M-V" : (is->audio_st ? "M-A" : " ")),
1662 av_diff,
1663 is->frame_drops_early + is->frame_drops_late,
1664 aqsize / 1024,
1665 vqsize / 1024,
1666 sqsize,
1667 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1668 is->video_st ? is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1669 fflush(stdout);
1670 last_time = cur_time;
1671 }
1672 }
1673}
1674
1675static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
1676{
1677 Frame *vp;
1678
1679#if defined(DEBUG_SYNC)
1680 printf("frame_type=%c pts=%0.3f\n",
1681 av_get_picture_type_char(src_frame->pict_type), pts);
1682#endif
1683
1684 if (!(vp = frame_queue_peek_writable(&is->pictq)))
1685 return -1;
1686
1687 vp->sar = src_frame->sample_aspect_ratio;
1688 vp->uploaded = 0;
1689
1690 vp->width = src_frame->width;
1691 vp->height = src_frame->height;
1692 vp->format = src_frame->format;
1693
1694 vp->pts = pts;
1695 vp->duration = duration;
1696 vp->pos = pos;
1697 vp->serial = serial;
1698
1699 set_default_window_size(vp->width, vp->height, vp->sar);
1700
1701 av_frame_move_ref(vp->frame, src_frame);
1702 frame_queue_push(&is->pictq);
1703 return 0;
1704}
1705
1706static int get_video_frame(VideoState *is, AVFrame *frame)
1707{
1708 int got_picture;
1709
1710 if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
1711 return -1;
1712
1713 if (got_picture) {
1714 double dpts = NAN;
1715
1716 if (frame->pts != AV_NOPTS_VALUE)
1717 dpts = av_q2d(is->video_st->time_base) * frame->pts;
1718
1719 frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
1720
1721 if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
1722 if (frame->pts != AV_NOPTS_VALUE) {
1723 double diff = dpts - get_master_clock(is);
1724 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
1725 diff - is->frame_last_filter_delay < 0 &&
1726 is->viddec.pkt_serial == is->vidclk.serial &&
1727 is->videoq.nb_packets) {
1728 is->frame_drops_early++;
1729 av_frame_unref(frame);
1730 got_picture = 0;
1731 }
1732 }
1733 }
1734 }
1735
1736 return got_picture;
1737}
1738
1739#if CONFIG_AVFILTER
1740static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
1741 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
1742{
1743 int ret, i;
1744 int nb_filters = graph->nb_filters;
1745 AVFilterInOut *outputs = NULL, *inputs = NULL;
1746
1747 if (filtergraph) {
1748 outputs = avfilter_inout_alloc();
1749 inputs = avfilter_inout_alloc();
1750 if (!outputs || !inputs) {
1751 ret = AVERROR(ENOMEM);
1752 goto fail;
1753 }
1754
1755 outputs->name = av_strdup("in");
1756 outputs->filter_ctx = source_ctx;
1757 outputs->pad_idx = 0;
1758 outputs->next = NULL;
1759
1760 inputs->name = av_strdup("out");
1761 inputs->filter_ctx = sink_ctx;
1762 inputs->pad_idx = 0;
1763 inputs->next = NULL;
1764
1765 if ((ret = avfilter_graph_parse_ptr(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
1766 goto fail;
1767 } else {
1768 if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
1769 goto fail;
1770 }
1771
1772 /* Reorder the filters to ensure that inputs of the custom filters are merged first */
1773 for (i = 0; i < graph->nb_filters - nb_filters; i++)
1774 FFSWAP(AVFilterContext*, graph->filters[i], graph->filters[i + nb_filters]);
1775
1776 ret = avfilter_graph_config(graph, NULL);
1777fail:
1778 avfilter_inout_free(&outputs);
1779 avfilter_inout_free(&inputs);
1780 return ret;
1781}
1782
1783static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
1784{
1785 static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
1786 char sws_flags_str[512] = "";
1787 char buffersrc_args[256];
1788 int ret;
1789 AVFilterContext *filt_src = NULL, *filt_out = NULL, *last_filter = NULL;
1790 AVCodecParameters *codecpar = is->video_st->codecpar;
1791 AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL);
1792 AVDictionaryEntry *e = NULL;
1793
1794 while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
1795 if (!strcmp(e->key, "sws_flags")) {
1796 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", "flags", e->value);
1797 } else
1798 av_strlcatf(sws_flags_str, sizeof(sws_flags_str), "%s=%s:", e->key, e->value);
1799 }
1800 if (strlen(sws_flags_str))
1801 sws_flags_str[strlen(sws_flags_str)-1] = '\0';
1802
1803 graph->scale_sws_opts = av_strdup(sws_flags_str);
1804
1805 snprintf(buffersrc_args, sizeof(buffersrc_args),
1806 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1807 frame->width, frame->height, frame->format,
1808 is->video_st->time_base.num, is->video_st->time_base.den,
1809 codecpar->sample_aspect_ratio.num, FFMAX(codecpar->sample_aspect_ratio.den, 1));
1810 if (fr.num && fr.den)
1811 av_strlcatf(buffersrc_args, sizeof(buffersrc_args), ":frame_rate=%d/%d", fr.num, fr.den);
1812
1813 if ((ret = avfilter_graph_create_filter(&filt_src,
1814 avfilter_get_by_name("buffer"),
1815 "ffplay_buffer", buffersrc_args, NULL,
1816 graph)) < 0)
1817 goto fail;
1818
1819 ret = avfilter_graph_create_filter(&filt_out,
1820 avfilter_get_by_name("buffersink"),
1821 "ffplay_buffersink", NULL, NULL, graph);
1822 if (ret < 0)
1823 goto fail;
1824
1825 if ((ret = av_opt_set_int_list(filt_out, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1826 goto fail;
1827
1828 last_filter = filt_out;
1829
1830/* Note: this macro adds a filter before the lastly added filter, so the
1831 * processing order of the filters is in reverse */
1832#define INSERT_FILT(name, arg) do { \
1833 AVFilterContext *filt_ctx; \
1834 \
1835 ret = avfilter_graph_create_filter(&filt_ctx, \
1836 avfilter_get_by_name(name), \
1837 "ffplay_" name, arg, NULL, graph); \
1838 if (ret < 0) \
1839 goto fail; \
1840 \
1841 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1842 if (ret < 0) \
1843 goto fail; \
1844 \
1845 last_filter = filt_ctx; \
1846} while (0)
1847
1848 if (autorotate) {
1849 double theta = get_rotation(is->video_st);
1850
1851 if (fabs(theta - 90) < 1.0) {
1852 INSERT_FILT("transpose", "clock");
1853 } else if (fabs(theta - 180) < 1.0) {
1854 INSERT_FILT("hflip", NULL);
1855 INSERT_FILT("vflip", NULL);
1856 } else if (fabs(theta - 270) < 1.0) {
1857 INSERT_FILT("transpose", "cclock");
1858 } else if (fabs(theta) > 1.0) {
1859 char rotate_buf[64];
1860 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1861 INSERT_FILT("rotate", rotate_buf);
1862 }
1863 }
1864
1865 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
1866 goto fail;
1867
1868 is->in_video_filter = filt_src;
1869 is->out_video_filter = filt_out;
1870
1871fail:
1872 return ret;
1873}
1874
1875static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
1876{
1877 static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
1878 int sample_rates[2] = { 0, -1 };
1879 int64_t channel_layouts[2] = { 0, -1 };
1880 int channels[2] = { 0, -1 };
1881 AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
1882 char aresample_swr_opts[512] = "";
1883 AVDictionaryEntry *e = NULL;
1884 char asrc_args[256];
1885 int ret;
1886
1887 avfilter_graph_free(&is->agraph);
1888 if (!(is->agraph = avfilter_graph_alloc()))
1889 return AVERROR(ENOMEM);
1890
1891 while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
1892 av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
1893 if (strlen(aresample_swr_opts))
1894 aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
1895 av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
1896
1897 ret = snprintf(asrc_args, sizeof(asrc_args),
1898 "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
1899 is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
1900 is->audio_filter_src.channels,
1901 1, is->audio_filter_src.freq);
1902 if (is->audio_filter_src.channel_layout)
1903 snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
1904 ":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
1905
1906 ret = avfilter_graph_create_filter(&filt_asrc,
1907 avfilter_get_by_name("abuffer"), "ffplay_abuffer",
1908 asrc_args, NULL, is->agraph);
1909 if (ret < 0)
1910 goto end;
1911
1912
1913 ret = avfilter_graph_create_filter(&filt_asink,
1914 avfilter_get_by_name("abuffersink"), "ffplay_abuffersink",
1915 NULL, NULL, is->agraph);
1916 if (ret < 0)
1917 goto end;
1918
1919 if ((ret = av_opt_set_int_list(filt_asink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
1920 goto end;
1921 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN)) < 0)
1922 goto end;
1923
1924 if (force_output_format) {
1925 channel_layouts[0] = is->audio_tgt.channel_layout;
1926 channels [0] = is->audio_tgt.channels;
1927 sample_rates [0] = is->audio_tgt.freq;
1928 if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
1929 goto end;
1930 if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1931 goto end;
1932 if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1933 goto end;
1934 if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
1935 goto end;
1936 }
1937
1938
1939 if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
1940 goto end;
1941
1942 is->in_audio_filter = filt_asrc;
1943 is->out_audio_filter = filt_asink;
1944
1945end:
1946 if (ret < 0)
1947 avfilter_graph_free(&is->agraph);
1948 return ret;
1949}
1950#endif /* CONFIG_AVFILTER */
1951
1952static int audio_thread(void *arg)
1953{
1954 VideoState *is = arg;
1955 AVFrame *frame = av_frame_alloc();
1956 Frame *af;
1957#if CONFIG_AVFILTER
1958 int last_serial = -1;
1959 int64_t dec_channel_layout;
1960 int reconfigure;
1961#endif
1962 int got_frame = 0;
1963 AVRational tb;
1964 int ret = 0;
1965
1966 if (!frame)
1967 return AVERROR(ENOMEM);
1968
1969 do {
1970 if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
1971 goto the_end;
1972
1973 if (got_frame) {
1974 tb = (AVRational){1, frame->sample_rate};
1975
1976#if CONFIG_AVFILTER
1977 dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
1978
1979 reconfigure =
1980 cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
1981 frame->format, av_frame_get_channels(frame)) ||
1982 is->audio_filter_src.channel_layout != dec_channel_layout ||
1983 is->audio_filter_src.freq != frame->sample_rate ||
1984 is->auddec.pkt_serial != last_serial;
1985
1986 if (reconfigure) {
1987 char buf1[1024], buf2[1024];
1988 av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
1989 av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
1990 av_log(NULL, AV_LOG_DEBUG,
1991 "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
1992 is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
1993 frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
1994
1995 is->audio_filter_src.fmt = frame->format;
1996 is->audio_filter_src.channels = av_frame_get_channels(frame);
1997 is->audio_filter_src.channel_layout = dec_channel_layout;
1998 is->audio_filter_src.freq = frame->sample_rate;
1999 last_serial = is->auddec.pkt_serial;
2000
2001 if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
2002 goto the_end;
2003 }
2004
2005 if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
2006 goto the_end;
2007
2008 while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
2009 tb = av_buffersink_get_time_base(is->out_audio_filter);
2010#endif
2011 if (!(af = frame_queue_peek_writable(&is->sampq)))
2012 goto the_end;
2013
2014 af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2015 af->pos = av_frame_get_pkt_pos(frame);
2016 af->serial = is->auddec.pkt_serial;
2017 af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
2018
2019 av_frame_move_ref(af->frame, frame);
2020 frame_queue_push(&is->sampq);
2021
2022#if CONFIG_AVFILTER
2023 if (is->audioq.serial != is->auddec.pkt_serial)
2024 break;
2025 }
2026 if (ret == AVERROR_EOF)
2027 is->auddec.finished = is->auddec.pkt_serial;
2028#endif
2029 }
2030 } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
2031 the_end:
2032#if CONFIG_AVFILTER
2033 avfilter_graph_free(&is->agraph);
2034#endif
2035 av_frame_free(&frame);
2036 return ret;
2037}
2038
2039static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
2040{
2041 packet_queue_start(d->queue);
2042 d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
2043 if (!d->decoder_tid) {
2044 av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
2045 return AVERROR(ENOMEM);
2046 }
2047 return 0;
2048}
2049
2050static int video_thread(void *arg)
2051{
2052 VideoState *is = arg;
2053 AVFrame *frame = av_frame_alloc();
2054 double pts;
2055 double duration;
2056 int ret;
2057 AVRational tb = is->video_st->time_base;
2058 AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
2059
2060#if CONFIG_AVFILTER
2061 AVFilterGraph *graph = avfilter_graph_alloc();
2062 AVFilterContext *filt_out = NULL, *filt_in = NULL;
2063 int last_w = 0;
2064 int last_h = 0;
2065 enum AVPixelFormat last_format = -2;
2066 int last_serial = -1;
2067 int last_vfilter_idx = 0;
2068 if (!graph) {
2069 av_frame_free(&frame);
2070 return AVERROR(ENOMEM);
2071 }
2072
2073#endif
2074
2075 if (!frame) {
2076#if CONFIG_AVFILTER
2077 avfilter_graph_free(&graph);
2078#endif
2079 return AVERROR(ENOMEM);
2080 }
2081
2082 for (;;) {
2083 ret = get_video_frame(is, frame);
2084 if (ret < 0)
2085 goto the_end;
2086 if (!ret)
2087 continue;
2088
2089#if CONFIG_AVFILTER
2090 if ( last_w != frame->width
2091 || last_h != frame->height
2092 || last_format != frame->format
2093 || last_serial != is->viddec.pkt_serial
2094 || last_vfilter_idx != is->vfilter_idx) {
2095 av_log(NULL, AV_LOG_DEBUG,
2096 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2097 last_w, last_h,
2098 (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
2099 frame->width, frame->height,
2100 (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
2101 avfilter_graph_free(&graph);
2102 graph = avfilter_graph_alloc();
2103 if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
2104 SDL_Event event;
2105 event.type = FF_QUIT_EVENT;
2106 event.user.data1 = is;
2107 SDL_PushEvent(&event);
2108 goto the_end;
2109 }
2110 filt_in = is->in_video_filter;
2111 filt_out = is->out_video_filter;
2112 last_w = frame->width;
2113 last_h = frame->height;
2114 last_format = frame->format;
2115 last_serial = is->viddec.pkt_serial;
2116 last_vfilter_idx = is->vfilter_idx;
2117 frame_rate = av_buffersink_get_frame_rate(filt_out);
2118 }
2119
2120 ret = av_buffersrc_add_frame(filt_in, frame);
2121 if (ret < 0)
2122 goto the_end;
2123
2124 while (ret >= 0) {
2125 is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
2126
2127 ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
2128 if (ret < 0) {
2129 if (ret == AVERROR_EOF)
2130 is->viddec.finished = is->viddec.pkt_serial;
2131 ret = 0;
2132 break;
2133 }
2134
2135 is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
2136 if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
2137 is->frame_last_filter_delay = 0;
2138 tb = av_buffersink_get_time_base(filt_out);
2139#endif
2140 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
2141 pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
2142 ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
2143 av_frame_unref(frame);
2144#if CONFIG_AVFILTER
2145 }
2146#endif
2147
2148 if (ret < 0)
2149 goto the_end;
2150 }
2151 the_end:
2152#if CONFIG_AVFILTER
2153 avfilter_graph_free(&graph);
2154#endif
2155 av_frame_free(&frame);
2156 return 0;
2157}
2158
2159static int subtitle_thread(void *arg)
2160{
2161 VideoState *is = arg;
2162 Frame *sp;
2163 int got_subtitle;
2164 double pts;
2165
2166 for (;;) {
2167 if (!(sp = frame_queue_peek_writable(&is->subpq)))
2168 return 0;
2169
2170 if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
2171 break;
2172
2173 pts = 0;
2174
2175 if (got_subtitle && sp->sub.format == 0) {
2176 if (sp->sub.pts != AV_NOPTS_VALUE)
2177 pts = sp->sub.pts / (double)AV_TIME_BASE;
2178 sp->pts = pts;
2179 sp->serial = is->subdec.pkt_serial;
2180 sp->width = is->subdec.avctx->width;
2181 sp->height = is->subdec.avctx->height;
2182 sp->uploaded = 0;
2183
2184 /* now we can update the picture count */
2185 frame_queue_push(&is->subpq);
2186 } else if (got_subtitle) {
2187 avsubtitle_free(&sp->sub);
2188 }
2189 }
2190 return 0;
2191}
2192
2193/* copy samples for viewing in editor window */
2194static void update_sample_display(VideoState *is, short *samples, int samples_size)
2195{
2196 int size, len;
2197
2198 size = samples_size / sizeof(short);
2199 while (size > 0) {
2200 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
2201 if (len > size)
2202 len = size;
2203 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
2204 samples += len;
2205 is->sample_array_index += len;
2206 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
2207 is->sample_array_index = 0;
2208 size -= len;
2209 }
2210}
2211
2212/* return the wanted number of samples to get better sync if sync_type is video
2213 * or external master clock */
2214static int synchronize_audio(VideoState *is, int nb_samples)
2215{
2216 int wanted_nb_samples = nb_samples;
2217
2218 /* if not master, then we try to remove or add samples to correct the clock */
2219 if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {
2220 double diff, avg_diff;
2221 int min_nb_samples, max_nb_samples;
2222
2223 diff = get_clock(&is->audclk) - get_master_clock(is);
2224
2225 if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD) {
2226 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2227 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2228 /* not enough measures to have a correct estimate */
2229 is->audio_diff_avg_count++;
2230 } else {
2231 /* estimate the A-V difference */
2232 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2233
2234 if (fabs(avg_diff) >= is->audio_diff_threshold) {
2235 wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
2236 min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2237 max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));
2238 wanted_nb_samples = av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2239 }
2240 av_log(NULL, AV_LOG_TRACE, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",
2241 diff, avg_diff, wanted_nb_samples - nb_samples,
2242 is->audio_clock, is->audio_diff_threshold);
2243 }
2244 } else {
2245 /* too big difference : may be initial PTS errors, so
2246 reset A-V filter */
2247 is->audio_diff_avg_count = 0;
2248 is->audio_diff_cum = 0;
2249 }
2250 }
2251
2252 return wanted_nb_samples;
2253}
2254
2255/**
2256 * Decode one audio frame and return its uncompressed size.
2257 *
2258 * The processed audio frame is decoded, converted if required, and
2259 * stored in is->audio_buf, with size in bytes given by the return
2260 * value.
2261 */
2262static int audio_decode_frame(VideoState *is)
2263{
2264 int data_size, resampled_data_size;
2265 int64_t dec_channel_layout;
2266 av_unused double audio_clock0;
2267 int wanted_nb_samples;
2268 Frame *af;
2269
2270 if (is->paused)
2271 return -1;
2272
2273 do {
2274#if defined(_WIN32)
2275 while (frame_queue_nb_remaining(&is->sampq) == 0) {
2276 if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
2277 return -1;
2278 av_usleep (1000);
2279 }
2280#endif
2281 if (!(af = frame_queue_peek_readable(&is->sampq)))
2282 return -1;
2283 frame_queue_next(&is->sampq);
2284 } while (af->serial != is->audioq.serial);
2285
2286 data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
2287 af->frame->nb_samples,
2288 af->frame->format, 1);
2289
2290 dec_channel_layout =
2291 (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
2292 af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
2293 wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
2294
2295 if (af->frame->format != is->audio_src.fmt ||
2296 dec_channel_layout != is->audio_src.channel_layout ||
2297 af->frame->sample_rate != is->audio_src.freq ||
2298 (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
2299 swr_free(&is->swr_ctx);
2300 is->swr_ctx = swr_alloc_set_opts(NULL,
2301 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
2302 dec_channel_layout, af->frame->format, af->frame->sample_rate,
2303 0, NULL);
2304 if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
2305 av_log(NULL, AV_LOG_ERROR,
2306 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2307 af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
2308 is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
2309 swr_free(&is->swr_ctx);
2310 return -1;
2311 }
2312 is->audio_src.channel_layout = dec_channel_layout;
2313 is->audio_src.channels = av_frame_get_channels(af->frame);
2314 is->audio_src.freq = af->frame->sample_rate;
2315 is->audio_src.fmt = af->frame->format;
2316 }
2317
2318 if (is->swr_ctx) {
2319 const uint8_t **in = (const uint8_t **)af->frame->extended_data;
2320 uint8_t **out = &is->audio_buf1;
2321 int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
2322 int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
2323 int len2;
2324 if (out_size < 0) {
2325 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
2326 return -1;
2327 }
2328 if (wanted_nb_samples != af->frame->nb_samples) {
2329 if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
2330 wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
2331 av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
2332 return -1;
2333 }
2334 }
2335 av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
2336 if (!is->audio_buf1)
2337 return AVERROR(ENOMEM);
2338 len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
2339 if (len2 < 0) {
2340 av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
2341 return -1;
2342 }
2343 if (len2 == out_count) {
2344 av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
2345 if (swr_init(is->swr_ctx) < 0)
2346 swr_free(&is->swr_ctx);
2347 }
2348 is->audio_buf = is->audio_buf1;
2349 resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
2350 } else {
2351 is->audio_buf = af->frame->data[0];
2352 resampled_data_size = data_size;
2353 }
2354
2355 audio_clock0 = is->audio_clock;
2356 /* update the audio clock with the pts */
2357 if (!isnan(af->pts))
2358 is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
2359 else
2360 is->audio_clock = NAN;
2361 is->audio_clock_serial = af->serial;
2362#ifdef DEBUG
2363 {
2364 static double last_clock;
2365 printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2366 is->audio_clock - last_clock,
2367 is->audio_clock, audio_clock0);
2368 last_clock = is->audio_clock;
2369 }
2370#endif
2371 return resampled_data_size;
2372}
2373
2374/* prepare a new audio buffer */
2375static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2376{
2377 VideoState *is = opaque;
2378 int audio_size, len1;
2379
2380 audio_callback_time = av_gettime_relative();
2381
2382 while (len > 0) {
2383 if (is->audio_buf_index >= is->audio_buf_size) {
2384 audio_size = audio_decode_frame(is);
2385 if (audio_size < 0) {
2386 /* if error, just output silence */
2387 is->audio_buf = NULL;
2388 is->audio_buf_size = SDL_AUDIO_MIN_BUFFER_SIZE / is->audio_tgt.frame_size * is->audio_tgt.frame_size;
2389 } else {
2390 if (is->show_mode != SHOW_MODE_VIDEO)
2391 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2392 is->audio_buf_size = audio_size;
2393 }
2394 is->audio_buf_index = 0;
2395 }
2396 len1 = is->audio_buf_size - is->audio_buf_index;
2397 if (len1 > len)
2398 len1 = len;
2399 if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
2400 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2401 else {
2402 memset(stream, 0, len1);
2403 if (!is->muted && is->audio_buf)
2404 SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
2405 }
2406 len -= len1;
2407 stream += len1;
2408 is->audio_buf_index += len1;
2409 }
2410 is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
2411 /* Let's assume the audio driver that is used by SDL has two periods. */
2412 if (!isnan(is->audio_clock)) {
2413 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);
2414 sync_clock_to_slave(&is->extclk, &is->audclk);
2415 }
2416}
2417
2418static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
2419{
2420 SDL_AudioSpec wanted_spec, spec;
2421 const char *env;
2422 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2423 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2424 int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
2425
2426 env = SDL_getenv("SDL_AUDIO_CHANNELS");
2427 if (env) {
2428 wanted_nb_channels = atoi(env);
2429 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2430 }
2431 if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
2432 wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
2433 wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
2434 }
2435 wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
2436 wanted_spec.channels = wanted_nb_channels;
2437 wanted_spec.freq = wanted_sample_rate;
2438 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2439 av_log(NULL, AV_LOG_ERROR, "Invalid sample rate or channel count!\n");
2440 return -1;
2441 }
2442 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2443 next_sample_rate_idx--;
2444 wanted_spec.format = AUDIO_S16SYS;
2445 wanted_spec.silence = 0;
2446 wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
2447 wanted_spec.callback = sdl_audio_callback;
2448 wanted_spec.userdata = opaque;
2449 while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2450 av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
2451 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2452 wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
2453 if (!wanted_spec.channels) {
2454 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2455 wanted_spec.channels = wanted_nb_channels;
2456 if (!wanted_spec.freq) {
2457 av_log(NULL, AV_LOG_ERROR,
2458 "No more combinations to try, audio open failed\n");
2459 return -1;
2460 }
2461 }
2462 wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
2463 }
2464 if (spec.format != AUDIO_S16SYS) {
2465 av_log(NULL, AV_LOG_ERROR,
2466 "SDL advised audio format %d is not supported!\n", spec.format);
2467 return -1;
2468 }
2469 if (spec.channels != wanted_spec.channels) {
2470 wanted_channel_layout = av_get_default_channel_layout(spec.channels);
2471 if (!wanted_channel_layout) {
2472 av_log(NULL, AV_LOG_ERROR,
2473 "SDL advised channel count %d is not supported!\n", spec.channels);
2474 return -1;
2475 }
2476 }
2477
2478 audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
2479 audio_hw_params->freq = spec.freq;
2480 audio_hw_params->channel_layout = wanted_channel_layout;
2481 audio_hw_params->channels = spec.channels;
2482 audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
2483 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);
2484 if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
2485 av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
2486 return -1;
2487 }
2488 return spec.size;
2489}
2490
2491/* open a given stream. Return 0 if OK */
2492static int stream_component_open(VideoState *is, int stream_index)
2493{
2494 AVFormatContext *ic = is->ic;
2495 AVCodecContext *avctx;
2496 AVCodec *codec;
2497 const char *forced_codec_name = NULL;
2498 AVDictionary *opts = NULL;
2499 AVDictionaryEntry *t = NULL;
2500 int sample_rate, nb_channels;
2501 int64_t channel_layout;
2502 int ret = 0;
2503 int stream_lowres = lowres;
2504
2505 if (stream_index < 0 || stream_index >= ic->nb_streams)
2506 return -1;
2507
2508 avctx = avcodec_alloc_context3(NULL);
2509 if (!avctx)
2510 return AVERROR(ENOMEM);
2511
2512 ret = avcodec_parameters_to_context(avctx, ic->streams[stream_index]->codecpar);
2513 if (ret < 0)
2514 goto fail;
2515 av_codec_set_pkt_timebase(avctx, ic->streams[stream_index]->time_base);
2516
2517 codec = avcodec_find_decoder(avctx->codec_id);
2518
2519 switch(avctx->codec_type){
2520 case AVMEDIA_TYPE_AUDIO : is->last_audio_stream = stream_index; forced_codec_name = audio_codec_name; break;
2521 case AVMEDIA_TYPE_SUBTITLE: is->last_subtitle_stream = stream_index; forced_codec_name = subtitle_codec_name; break;
2522 case AVMEDIA_TYPE_VIDEO : is->last_video_stream = stream_index; forced_codec_name = video_codec_name; break;
2523 }
2524 if (forced_codec_name)
2525 codec = avcodec_find_decoder_by_name(forced_codec_name);
2526 if (!codec) {
2527 if (forced_codec_name) av_log(NULL, AV_LOG_WARNING,
2528 "No codec could be found with name '%s'\n", forced_codec_name);
2529 else av_log(NULL, AV_LOG_WARNING,
2530 "No codec could be found with id %d\n", avctx->codec_id);
2531 ret = AVERROR(EINVAL);
2532 goto fail;
2533 }
2534
2535 avctx->codec_id = codec->id;
2536 if(stream_lowres > av_codec_get_max_lowres(codec)){
2537 av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
2538 av_codec_get_max_lowres(codec));
2539 stream_lowres = av_codec_get_max_lowres(codec);
2540 }
2541 av_codec_set_lowres(avctx, stream_lowres);
2542
2543#if FF_API_EMU_EDGE
2544 if(stream_lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2545#endif
2546 if (fast)
2547 avctx->flags2 |= AV_CODEC_FLAG2_FAST;
2548#if FF_API_EMU_EDGE
2549 if(codec->capabilities & AV_CODEC_CAP_DR1)
2550 avctx->flags |= CODEC_FLAG_EMU_EDGE;
2551#endif
2552
2553 opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
2554 if (!av_dict_get(opts, "threads", NULL, 0))
2555 av_dict_set(&opts, "threads", "auto", 0);
2556 if (stream_lowres)
2557 av_dict_set_int(&opts, "lowres", stream_lowres, 0);
2558 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2559 av_dict_set(&opts, "refcounted_frames", "1", 0);
2560 if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
2561 goto fail;
2562 }
2563 if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2564 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2565 ret = AVERROR_OPTION_NOT_FOUND;
2566 goto fail;
2567 }
2568
2569 is->eof = 0;
2570 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2571 switch (avctx->codec_type) {
2572 case AVMEDIA_TYPE_AUDIO:
2573#if CONFIG_AVFILTER
2574 {
2575 AVFilterContext *sink;
2576
2577 is->audio_filter_src.freq = avctx->sample_rate;
2578 is->audio_filter_src.channels = avctx->channels;
2579 is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
2580 is->audio_filter_src.fmt = avctx->sample_fmt;
2581 if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
2582 goto fail;
2583 sink = is->out_audio_filter;
2584 sample_rate = av_buffersink_get_sample_rate(sink);
2585 nb_channels = av_buffersink_get_channels(sink);
2586 channel_layout = av_buffersink_get_channel_layout(sink);
2587 }
2588#else
2589 sample_rate = avctx->sample_rate;
2590 nb_channels = avctx->channels;
2591 channel_layout = avctx->channel_layout;
2592#endif
2593
2594 /* prepare audio output */
2595 if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
2596 goto fail;
2597 is->audio_hw_buf_size = ret;
2598 is->audio_src = is->audio_tgt;
2599 is->audio_buf_size = 0;
2600 is->audio_buf_index = 0;
2601
2602 /* init averaging filter */
2603 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2604 is->audio_diff_avg_count = 0;
2605 /* since we do not have a precise anough audio FIFO fullness,
2606 we correct audio sync only if larger than this threshold */
2607 is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
2608
2609 is->audio_stream = stream_index;
2610 is->audio_st = ic->streams[stream_index];
2611
2612 decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
2613 if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
2614 is->auddec.start_pts = is->audio_st->start_time;
2615 is->auddec.start_pts_tb = is->audio_st->time_base;
2616 }
2617 if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
2618 goto out;
2619 SDL_PauseAudio(0);
2620 break;
2621 case AVMEDIA_TYPE_VIDEO:
2622 is->video_stream = stream_index;
2623 is->video_st = ic->streams[stream_index];
2624
2625 decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
2626 if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
2627 goto out;
2628 is->queue_attachments_req = 1;
2629 break;
2630 case AVMEDIA_TYPE_SUBTITLE:
2631 is->subtitle_stream = stream_index;
2632 is->subtitle_st = ic->streams[stream_index];
2633
2634 decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
2635 if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
2636 goto out;
2637 break;
2638 default:
2639 break;
2640 }
2641 goto out;
2642
2643fail:
2644 avcodec_free_context(&avctx);
2645out:
2646 av_dict_free(&opts);
2647
2648 return ret;
2649}
2650
2651static int decode_interrupt_cb(void *ctx)
2652{
2653 VideoState *is = ctx;
2654 return is->abort_request;
2655}
2656
2657static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue) {
2658 return stream_id < 0 ||
2659 queue->abort_request ||
2660 (st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||
2661 queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
2662}
2663
2664static int is_realtime(AVFormatContext *s)
2665{
2666 if( !strcmp(s->iformat->name, "rtp")
2667 || !strcmp(s->iformat->name, "rtsp")
2668 || !strcmp(s->iformat->name, "sdp")
2669 )
2670 return 1;
2671
2672 if(s->pb && ( !strncmp(s->filename, "rtp:", 4)
2673 || !strncmp(s->filename, "udp:", 4)
2674 )
2675 )
2676 return 1;
2677 return 0;
2678}
2679
2680/* this thread gets the stream from the disk or the network */
2681static int read_thread(void *arg)
2682{
2683 VideoState *is = arg;
2684 AVFormatContext *ic = NULL;
2685 int err, i, ret;
2686 int st_index[AVMEDIA_TYPE_NB];
2687 AVPacket pkt1, *pkt = &pkt1;
2688 int64_t stream_start_time;
2689 int pkt_in_play_range = 0;
2690 AVDictionaryEntry *t;
2691 AVDictionary **opts;
2692 int orig_nb_streams;
2693 SDL_mutex *wait_mutex = SDL_CreateMutex();
2694 int scan_all_pmts_set = 0;
2695 int64_t pkt_ts;
2696
2697 if (!wait_mutex) {
2698 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
2699 ret = AVERROR(ENOMEM);
2700 goto fail;
2701 }
2702
2703 memset(st_index, -1, sizeof(st_index));
2704 is->last_video_stream = is->video_stream = -1;
2705 is->last_audio_stream = is->audio_stream = -1;
2706 is->last_subtitle_stream = is->subtitle_stream = -1;
2707 is->eof = 0;
2708
2709 ic = avformat_alloc_context();
2710 if (!ic) {
2711 av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
2712 ret = AVERROR(ENOMEM);
2713 goto fail;
2714 }
2715 ic->interrupt_callback.callback = decode_interrupt_cb;
2716 ic->interrupt_callback.opaque = is;
2717 if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2718 av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2719 scan_all_pmts_set = 1;
2720 }
2721 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
2722 if (err < 0) {
2723 print_error(is->filename, err);
2724 ret = -1;
2725 goto fail;
2726 }
2727 if (scan_all_pmts_set)
2728 av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2729
2730 if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2731 av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2732 ret = AVERROR_OPTION_NOT_FOUND;
2733 goto fail;
2734 }
2735 is->ic = ic;
2736
2737 if (genpts)
2738 ic->flags |= AVFMT_FLAG_GENPTS;
2739
2740 av_format_inject_global_side_data(ic);
2741
2742 opts = setup_find_stream_info_opts(ic, codec_opts);
2743 orig_nb_streams = ic->nb_streams;
2744
2745 err = avformat_find_stream_info(ic, opts);
2746
2747 for (i = 0; i < orig_nb_streams; i++)
2748 av_dict_free(&opts[i]);
2749 av_freep(&opts);
2750
2751 if (err < 0) {
2752 av_log(NULL, AV_LOG_WARNING,
2753 "%s: could not find codec parameters\n", is->filename);
2754 ret = -1;
2755 goto fail;
2756 }
2757
2758 if (ic->pb)
2759 ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
2760
2761 if (seek_by_bytes < 0)
2762 seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
2763
2764 is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
2765
2766 if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))
2767 window_title = av_asprintf("%s - %s", t->value, input_filename);
2768
2769 /* if seeking requested, we execute it */
2770 if (start_time != AV_NOPTS_VALUE) {
2771 int64_t timestamp;
2772
2773 timestamp = start_time;
2774 /* add the stream start time */
2775 if (ic->start_time != AV_NOPTS_VALUE)
2776 timestamp += ic->start_time;
2777 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2778 if (ret < 0) {
2779 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
2780 is->filename, (double)timestamp / AV_TIME_BASE);
2781 }
2782 }
2783
2784 is->realtime = is_realtime(ic);
2785
2786 if (show_status)
2787 av_dump_format(ic, 0, is->filename, 0);
2788
2789 for (i = 0; i < ic->nb_streams; i++) {
2790 AVStream *st = ic->streams[i];
2791 enum AVMediaType type = st->codecpar->codec_type;
2792 st->discard = AVDISCARD_ALL;
2793 if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1)
2794 if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)
2795 st_index[type] = i;
2796 }
2797 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
2798 if (wanted_stream_spec[i] && st_index[i] == -1) {
2799 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));
2800 st_index[i] = INT_MAX;
2801 }
2802 }
2803
2804 if (!video_disable)
2805 st_index[AVMEDIA_TYPE_VIDEO] =
2806 av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2807 st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2808 if (!audio_disable)
2809 st_index[AVMEDIA_TYPE_AUDIO] =
2810 av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2811 st_index[AVMEDIA_TYPE_AUDIO],
2812 st_index[AVMEDIA_TYPE_VIDEO],
2813 NULL, 0);
2814 if (!video_disable && !subtitle_disable)
2815 st_index[AVMEDIA_TYPE_SUBTITLE] =
2816 av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2817 st_index[AVMEDIA_TYPE_SUBTITLE],
2818 (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2819 st_index[AVMEDIA_TYPE_AUDIO] :
2820 st_index[AVMEDIA_TYPE_VIDEO]),
2821 NULL, 0);
2822
2823 is->show_mode = show_mode;
2824 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2825 AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
2826 AVCodecParameters *codecpar = st->codecpar;
2827 AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);
2828 if (codecpar->width)
2829 set_default_window_size(codecpar->width, codecpar->height, sar);
2830 }
2831
2832 /* open the streams */
2833 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2834 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2835 }
2836
2837 ret = -1;
2838 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2839 ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2840 }
2841 if (is->show_mode == SHOW_MODE_NONE)
2842 is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2843
2844 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2845 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2846 }
2847
2848 if (is->video_stream < 0 && is->audio_stream < 0) {
2849 av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",
2850 is->filename);
2851 ret = -1;
2852 goto fail;
2853 }
2854
2855 if (infinite_buffer < 0 && is->realtime)
2856 infinite_buffer = 1;
2857
2858 for (;;) {
2859 if (is->abort_request)
2860 break;
2861 if (is->paused != is->last_paused) {
2862 is->last_paused = is->paused;
2863 if (is->paused)
2864 is->read_pause_return = av_read_pause(ic);
2865 else
2866 av_read_play(ic);
2867 }
2868#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2869 if (is->paused &&
2870 (!strcmp(ic->iformat->name, "rtsp") ||
2871 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
2872 /* wait 10 ms to avoid trying to get another packet */
2873 /* XXX: horrible */
2874 SDL_Delay(10);
2875 continue;
2876 }
2877#endif
2878 if (is->seek_req) {
2879 int64_t seek_target = is->seek_pos;
2880 int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2881 int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2882// FIXME the +-2 is due to rounding being not done in the correct direction in generation
2883// of the seek_pos/seek_rel variables
2884
2885 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2886 if (ret < 0) {
2887 av_log(NULL, AV_LOG_ERROR,
2888 "%s: error while seeking\n", is->ic->filename);
2889 } else {
2890 if (is->audio_stream >= 0) {
2891 packet_queue_flush(&is->audioq);
2892 packet_queue_put(&is->audioq, &flush_pkt);
2893 }
2894 if (is->subtitle_stream >= 0) {
2895 packet_queue_flush(&is->subtitleq);
2896 packet_queue_put(&is->subtitleq, &flush_pkt);
2897 }
2898 if (is->video_stream >= 0) {
2899 packet_queue_flush(&is->videoq);
2900 packet_queue_put(&is->videoq, &flush_pkt);
2901 }
2902 if (is->seek_flags & AVSEEK_FLAG_BYTE) {
2903 set_clock(&is->extclk, NAN, 0);
2904 } else {
2905 set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);
2906 }
2907 }
2908 is->seek_req = 0;
2909 is->queue_attachments_req = 1;
2910 is->eof = 0;
2911 if (is->paused)
2912 step_to_next_frame(is);
2913 }
2914 if (is->queue_attachments_req) {
2915 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
2916 AVPacket copy;
2917 if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)
2918 goto fail;
2919 packet_queue_put(&is->videoq, &copy);
2920 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2921 }
2922 is->queue_attachments_req = 0;
2923 }
2924
2925 /* if the queue are full, no need to read more */
2926 if (infinite_buffer<1 &&
2927 (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2928 || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) &&
2929 stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) &&
2930 stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
2931 /* wait 10 ms */
2932 SDL_LockMutex(wait_mutex);
2933 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2934 SDL_UnlockMutex(wait_mutex);
2935 continue;
2936 }
2937 if (!is->paused &&
2938 (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
2939 (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
2940 if (loop != 1 && (!loop || --loop)) {
2941 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2942 } else if (autoexit) {
2943 ret = AVERROR_EOF;
2944 goto fail;
2945 }
2946 }
2947 ret = av_read_frame(ic, pkt);
2948 if (ret < 0) {
2949 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {
2950 if (is->video_stream >= 0)
2951 packet_queue_put_nullpacket(&is->videoq, is->video_stream);
2952 if (is->audio_stream >= 0)
2953 packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
2954 if (is->subtitle_stream >= 0)
2955 packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
2956 is->eof = 1;
2957 }
2958 if (ic->pb && ic->pb->error)
2959 break;
2960 SDL_LockMutex(wait_mutex);
2961 SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
2962 SDL_UnlockMutex(wait_mutex);
2963 continue;
2964 } else {
2965 is->eof = 0;
2966 }
2967 /* check if packet is in play range specified by user, then queue, otherwise discard */
2968 stream_start_time = ic->streams[pkt->stream_index]->start_time;
2969 pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
2970 pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2971 (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *
2972 av_q2d(ic->streams[pkt->stream_index]->time_base) -
2973 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
2974 <= ((double)duration / 1000000);
2975 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2976 packet_queue_put(&is->audioq, pkt);
2977 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range
2978 && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
2979 packet_queue_put(&is->videoq, pkt);
2980 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2981 packet_queue_put(&is->subtitleq, pkt);
2982 } else {
2983 av_packet_unref(pkt);
2984 }
2985 }
2986
2987 ret = 0;
2988 fail:
2989 if (ic && !is->ic)
2990 avformat_close_input(&ic);
2991
2992 if (ret != 0) {
2993 SDL_Event event;
2994
2995 event.type = FF_QUIT_EVENT;
2996 event.user.data1 = is;
2997 SDL_PushEvent(&event);
2998 }
2999 SDL_DestroyMutex(wait_mutex);
3000 return 0;
3001}
3002
3003static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
3004{
3005 VideoState *is;
3006
3007 is = av_mallocz(sizeof(VideoState));
3008 if (!is)
3009 return NULL;
3010 is->filename = av_strdup(filename);
3011 if (!is->filename)
3012 goto fail;
3013 is->iformat = iformat;
3014 is->ytop = 0;
3015 is->xleft = 0;
3016
3017 /* start video display */
3018 if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
3019 goto fail;
3020 if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
3021 goto fail;
3022 if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
3023 goto fail;
3024
3025 if (packet_queue_init(&is->videoq) < 0 ||
3026 packet_queue_init(&is->audioq) < 0 ||
3027 packet_queue_init(&is->subtitleq) < 0)
3028 goto fail;
3029
3030 if (!(is->continue_read_thread = SDL_CreateCond())) {
3031 av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
3032 goto fail;
3033 }
3034
3035 init_clock(&is->vidclk, &is->videoq.serial);
3036 init_clock(&is->audclk, &is->audioq.serial);
3037 init_clock(&is->extclk, &is->extclk.serial);
3038 is->audio_clock_serial = -1;
3039 if (startup_volume < 0)
3040 av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
3041 if (startup_volume > 100)
3042 av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
3043 startup_volume = av_clip(startup_volume, 0, 100);
3044 startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
3045 is->audio_volume = startup_volume;
3046 is->muted = 0;
3047 is->av_sync_type = av_sync_type;
3048 is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
3049 if (!is->read_tid) {
3050 av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
3051fail:
3052 stream_close(is);
3053 return NULL;
3054 }
3055 return is;
3056}
3057
3058static void stream_cycle_channel(VideoState *is, int codec_type)
3059{
3060 AVFormatContext *ic = is->ic;
3061 int start_index, stream_index;
3062 int old_index;
3063 AVStream *st;
3064 AVProgram *p = NULL;
3065 int nb_streams = is->ic->nb_streams;
3066
3067 if (codec_type == AVMEDIA_TYPE_VIDEO) {
3068 start_index = is->last_video_stream;
3069 old_index = is->video_stream;
3070 } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
3071 start_index = is->last_audio_stream;
3072 old_index = is->audio_stream;
3073 } else {
3074 start_index = is->last_subtitle_stream;
3075 old_index = is->subtitle_stream;
3076 }
3077 stream_index = start_index;
3078
3079 if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
3080 p = av_find_program_from_stream(ic, NULL, is->video_stream);
3081 if (p) {
3082 nb_streams = p->nb_stream_indexes;
3083 for (start_index = 0; start_index < nb_streams; start_index++)
3084 if (p->stream_index[start_index] == stream_index)
3085 break;
3086 if (start_index == nb_streams)
3087 start_index = -1;
3088 stream_index = start_index;
3089 }
3090 }
3091
3092 for (;;) {
3093 if (++stream_index >= nb_streams)
3094 {
3095 if (codec_type == AVMEDIA_TYPE_SUBTITLE)
3096 {
3097 stream_index = -1;
3098 is->last_subtitle_stream = -1;
3099 goto the_end;
3100 }
3101 if (start_index == -1)
3102 return;
3103 stream_index = 0;
3104 }
3105 if (stream_index == start_index)
3106 return;
3107 st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
3108 if (st->codecpar->codec_type == codec_type) {
3109 /* check that parameters are OK */
3110 switch (codec_type) {
3111 case AVMEDIA_TYPE_AUDIO:
3112 if (st->codecpar->sample_rate != 0 &&
3113 st->codecpar->channels != 0)
3114 goto the_end;
3115 break;
3116 case AVMEDIA_TYPE_VIDEO:
3117 case AVMEDIA_TYPE_SUBTITLE:
3118 goto the_end;
3119 default:
3120 break;
3121 }
3122 }
3123 }
3124 the_end:
3125 if (p && stream_index != -1)
3126 stream_index = p->stream_index[stream_index];
3127 av_log(NULL, AV_LOG_INFO, "Switch %s stream from #%d to #%d\n",
3128 av_get_media_type_string(codec_type),
3129 old_index,
3130 stream_index);
3131
3132 stream_component_close(is, old_index);
3133 stream_component_open(is, stream_index);
3134}
3135
3136
3137static void toggle_full_screen(VideoState *is)
3138{
3139 is_full_screen = !is_full_screen;
3140 SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
3141}
3142
3143static void toggle_audio_display(VideoState *is)
3144{
3145 int next = is->show_mode;
3146 do {
3147 next = (next + 1) % SHOW_MODE_NB;
3148 } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
3149 if (is->show_mode != next) {
3150 is->force_refresh = 1;
3151 is->show_mode = next;
3152 }
3153}
3154
3155static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
3156 double remaining_time = 0.0;
3157 SDL_PumpEvents();
3158 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3159 if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
3160 SDL_ShowCursor(0);
3161 cursor_hidden = 1;
3162 }
3163 if (remaining_time > 0.0)
3164 av_usleep((int64_t)(remaining_time * 1000000.0));
3165 remaining_time = REFRESH_RATE;
3166 if (is->show_mode != SHOW_MODE_NONE && (!is->paused || is->force_refresh))
3167 video_refresh(is, &remaining_time);
3168 SDL_PumpEvents();
3169 }
3170}
3171
3172static void seek_chapter(VideoState *is, int incr)
3173{
3174 int64_t pos = get_master_clock(is) * AV_TIME_BASE;
3175 int i;
3176
3177 if (!is->ic->nb_chapters)
3178 return;
3179
3180 /* find the current chapter */
3181 for (i = 0; i < is->ic->nb_chapters; i++) {
3182 AVChapter *ch = is->ic->chapters[i];
3183 if (av_compare_ts(pos, AV_TIME_BASE_Q, ch->start, ch->time_base) < 0) {
3184 i--;
3185 break;
3186 }
3187 }
3188
3189 i += incr;
3190 i = FFMAX(i, 0);
3191 if (i >= is->ic->nb_chapters)
3192 return;
3193
3194 av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i);
3195 stream_seek(is, av_rescale_q(is->ic->chapters[i]->start, is->ic->chapters[i]->time_base,
3196 AV_TIME_BASE_Q), 0, 0);
3197}
3198
3199/* handle an event sent by the GUI */
3200static void event_loop(VideoState *cur_stream)
3201{
3202 SDL_Event event;
3203 double incr, pos, frac;
3204
3205 for (;;) {
3206 double x;
3207 refresh_loop_wait_event(cur_stream, &event);
3208 switch (event.type) {
3209 case SDL_KEYDOWN:
3210 if (exit_on_keydown) {
3211 do_exit(cur_stream);
3212 break;
3213 }
3214 switch (event.key.keysym.sym) {
3215 case SDLK_ESCAPE:
3216 case SDLK_q:
3217 do_exit(cur_stream);
3218 break;
3219 case SDLK_f:
3220 toggle_full_screen(cur_stream);
3221 cur_stream->force_refresh = 1;
3222 break;
3223 case SDLK_p:
3224 case SDLK_SPACE:
3225 toggle_pause(cur_stream);
3226 break;
3227 case SDLK_m:
3228 toggle_mute(cur_stream);
3229 break;
3230 case SDLK_KP_MULTIPLY:
3231 case SDLK_0:
3232 update_volume(cur_stream, 1, SDL_VOLUME_STEP);
3233 break;
3234 case SDLK_KP_DIVIDE:
3235 case SDLK_9:
3236 update_volume(cur_stream, -1, SDL_VOLUME_STEP);
3237 break;
3238 case SDLK_s: // S: Step to next frame
3239 step_to_next_frame(cur_stream);
3240 break;
3241 case SDLK_a:
3242 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3243 break;
3244 case SDLK_v:
3245 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3246 break;
3247 case SDLK_c:
3248 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
3249 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
3250 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3251 break;
3252 case SDLK_t:
3253 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
3254 break;
3255 case SDLK_w:
3256#if CONFIG_AVFILTER
3257 if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
3258 if (++cur_stream->vfilter_idx >= nb_vfilters)
3259 cur_stream->vfilter_idx = 0;
3260 } else {
3261 cur_stream->vfilter_idx = 0;
3262 toggle_audio_display(cur_stream);
3263 }
3264#else
3265 toggle_audio_display(cur_stream);
3266#endif
3267 break;
3268 case SDLK_PAGEUP:
3269 if (cur_stream->ic->nb_chapters <= 1) {
3270 incr = 600.0;
3271 goto do_seek;
3272 }
3273 seek_chapter(cur_stream, 1);
3274 break;
3275 case SDLK_PAGEDOWN:
3276 if (cur_stream->ic->nb_chapters <= 1) {
3277 incr = -600.0;
3278 goto do_seek;
3279 }
3280 seek_chapter(cur_stream, -1);
3281 break;
3282 case SDLK_LEFT:
3283 incr = -10.0;
3284 goto do_seek;
3285 case SDLK_RIGHT:
3286 incr = 10.0;
3287 goto do_seek;
3288 case SDLK_UP:
3289 incr = 60.0;
3290 goto do_seek;
3291 case SDLK_DOWN:
3292 incr = -60.0;
3293 do_seek:
3294 if (seek_by_bytes) {
3295 pos = -1;
3296 if (pos < 0 && cur_stream->video_stream >= 0)
3297 pos = frame_queue_last_pos(&cur_stream->pictq);
3298 if (pos < 0 && cur_stream->audio_stream >= 0)
3299 pos = frame_queue_last_pos(&cur_stream->sampq);
3300 if (pos < 0)
3301 pos = avio_tell(cur_stream->ic->pb);
3302 if (cur_stream->ic->bit_rate)
3303 incr *= cur_stream->ic->bit_rate / 8.0;
3304 else
3305 incr *= 180000.0;
3306 pos += incr;
3307 stream_seek(cur_stream, pos, incr, 1);
3308 } else {
3309 pos = get_master_clock(cur_stream);
3310 if (isnan(pos))
3311 pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
3312 pos += incr;
3313 if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
3314 pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
3315 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
3316 }
3317 break;
3318 default:
3319 break;
3320 }
3321 break;
3322 case SDL_MOUSEBUTTONDOWN:
3323 if (exit_on_mousedown) {
3324 do_exit(cur_stream);
3325 break;
3326 }
3327 if (event.button.button == SDL_BUTTON_LEFT) {
3328 static int64_t last_mouse_left_click = 0;
3329 if (av_gettime_relative() - last_mouse_left_click <= 500000) {
3330 toggle_full_screen(cur_stream);
3331 cur_stream->force_refresh = 1;
3332 last_mouse_left_click = 0;
3333 } else {
3334 last_mouse_left_click = av_gettime_relative();
3335 }
3336 }
3337 case SDL_MOUSEMOTION:
3338 if (cursor_hidden) {
3339 SDL_ShowCursor(1);
3340 cursor_hidden = 0;
3341 }
3342 cursor_last_shown = av_gettime_relative();
3343 if (event.type == SDL_MOUSEBUTTONDOWN) {
3344 if (event.button.button != SDL_BUTTON_RIGHT)
3345 break;
3346 x = event.button.x;
3347 } else {
3348 if (!(event.motion.state & SDL_BUTTON_RMASK))
3349 break;
3350 x = event.motion.x;
3351 }
3352 if (seek_by_bytes || cur_stream->ic->duration <= 0) {
3353 uint64_t size = avio_size(cur_stream->ic->pb);
3354 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
3355 } else {
3356 int64_t ts;
3357 int ns, hh, mm, ss;
3358 int tns, thh, tmm, tss;
3359 tns = cur_stream->ic->duration / 1000000LL;
3360 thh = tns / 3600;
3361 tmm = (tns % 3600) / 60;
3362 tss = (tns % 60);
3363 frac = x / cur_stream->width;
3364 ns = frac * tns;
3365 hh = ns / 3600;
3366 mm = (ns % 3600) / 60;
3367 ss = (ns % 60);
3368 av_log(NULL, AV_LOG_INFO,
3369 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3370 hh, mm, ss, thh, tmm, tss);
3371 ts = frac * cur_stream->ic->duration;
3372 if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
3373 ts += cur_stream->ic->start_time;
3374 stream_seek(cur_stream, ts, 0, 0);
3375 }
3376 break;
3377 case SDL_WINDOWEVENT:
3378 switch (event.window.event) {
3379 case SDL_WINDOWEVENT_RESIZED:
3380 screen_width = cur_stream->width = event.window.data1;
3381 screen_height = cur_stream->height = event.window.data2;
3382 if (cur_stream->vis_texture) {
3383 SDL_DestroyTexture(cur_stream->vis_texture);
3384 cur_stream->vis_texture = NULL;
3385 }
3386 case SDL_WINDOWEVENT_EXPOSED:
3387 cur_stream->force_refresh = 1;
3388 }
3389 break;
3390 case SDL_QUIT:
3391 case FF_QUIT_EVENT:
3392 do_exit(cur_stream);
3393 break;
3394 default:
3395 break;
3396 }
3397 }
3398}
3399
3400static int opt_frame_size(void *optctx, const char *opt, const char *arg)
3401{
3402 av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
3403 return opt_default(NULL, "video_size", arg);
3404}
3405
3406static int opt_width(void *optctx, const char *opt, const char *arg)
3407{
3408 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3409 return 0;
3410}
3411
3412static int opt_height(void *optctx, const char *opt, const char *arg)
3413{
3414 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
3415 return 0;
3416}
3417
3418static int opt_format(void *optctx, const char *opt, const char *arg)
3419{
3420 file_iformat = av_find_input_format(arg);
3421 if (!file_iformat) {
3422 av_log(NULL, AV_LOG_FATAL, "Unknown input format: %s\n", arg);
3423 return AVERROR(EINVAL);
3424 }
3425 return 0;
3426}
3427
3428static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
3429{
3430 av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
3431 return opt_default(NULL, "pixel_format", arg);
3432}
3433
3434static int opt_sync(void *optctx, const char *opt, const char *arg)
3435{
3436 if (!strcmp(arg, "audio"))
3437 av_sync_type = AV_SYNC_AUDIO_MASTER;
3438 else if (!strcmp(arg, "video"))
3439 av_sync_type = AV_SYNC_VIDEO_MASTER;
3440 else if (!strcmp(arg, "ext"))
3441 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
3442 else {
3443 av_log(NULL, AV_LOG_ERROR, "Unknown value for %s: %s\n", opt, arg);
3444 exit(1);
3445 }
3446 return 0;
3447}
3448
3449static int opt_seek(void *optctx, const char *opt, const char *arg)
3450{
3451 start_time = parse_time_or_die(opt, arg, 1);
3452 return 0;
3453}
3454
3455static int opt_duration(void *optctx, const char *opt, const char *arg)
3456{
3457 duration = parse_time_or_die(opt, arg, 1);
3458 return 0;
3459}
3460
3461static int opt_show_mode(void *optctx, const char *opt, const char *arg)
3462{
3463 show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
3464 !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
3465 !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT :
3466 parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
3467 return 0;
3468}
3469
3470static void opt_input_file(void *optctx, const char *filename)
3471{
3472 if (input_filename) {
3473 av_log(NULL, AV_LOG_FATAL,
3474 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3475 filename, input_filename);
3476 exit(1);
3477 }
3478 if (!strcmp(filename, "-"))
3479 filename = "pipe:";
3480 input_filename = filename;
3481}
3482
3483static int opt_codec(void *optctx, const char *opt, const char *arg)
3484{
3485 const char *spec = strchr(opt, ':');
3486 if (!spec) {
3487 av_log(NULL, AV_LOG_ERROR,
3488 "No media specifier was specified in '%s' in option '%s'\n",
3489 arg, opt);
3490 return AVERROR(EINVAL);
3491 }
3492 spec++;
3493 switch (spec[0]) {
3494 case 'a' : audio_codec_name = arg; break;
3495 case 's' : subtitle_codec_name = arg; break;
3496 case 'v' : video_codec_name = arg; break;
3497 default:
3498 av_log(NULL, AV_LOG_ERROR,
3499 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3500 return AVERROR(EINVAL);
3501 }
3502 return 0;
3503}
3504
3505static int dummy;
3506
3507static const OptionDef options[] = {
3508#include "cmdutils_common_opts.h"
3509 { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
3510 { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
3511 { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
3512 { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
3513 { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
3514 { "vn", OPT_BOOL, { &video_disable }, "disable video" },
3515 { "sn", OPT_BOOL, { &subtitle_disable }, "disable subtitling" },
3516 { "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
3517 { "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
3518 { "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
3519 { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
3520 { "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
3521 { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
3522 { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
3523 { "noborder", OPT_BOOL, { &borderless }, "borderless window" },
3524 { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
3525 { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
3526 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
3527 { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
3528 { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
3529 { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
3530 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3531 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
3532 { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
3533 { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
3534 { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
3535 { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
3536 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
3537 { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
3538 { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
3539 { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
3540#if CONFIG_AVFILTER
3541 { "vf", OPT_EXPERT | HAS_ARG, { .func_arg = opt_add_vfilter }, "set video filters", "filter_graph" },
3542 { "af", OPT_STRING | HAS_ARG, { &afilters }, "set audio filters", "filter_graph" },
3543#endif
3544 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
3545 { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
3546 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
3547 { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
3548 { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
3549 { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &audio_codec_name }, "force audio decoder", "decoder_name" },
3550 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
3551 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &video_codec_name }, "force video decoder", "decoder_name" },
3552 { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
3553 { NULL, },
3554};
3555
3556static void show_usage(void)
3557{
3558 av_log(NULL, AV_LOG_INFO, "Simple media player\n");
3559 av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
3560 av_log(NULL, AV_LOG_INFO, "\n");
3561}
3562
3563void show_help_default(const char *opt, const char *arg)
3564{
3565 av_log_set_callback(log_callback_help);
3566 show_usage();
3567 show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
3568 show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
3569 printf("\n");
3570 show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3571 show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3572#if !CONFIG_AVFILTER
3573 show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
3574#else
3575 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
3576#endif
3577 printf("\nWhile playing:\n"
3578 "q, ESC quit\n"
3579 "f toggle full screen\n"
3580 "p, SPC pause\n"
3581 "m toggle mute\n"
3582 "9, 0 decrease and increase volume respectively\n"
3583 "/, * decrease and increase volume respectively\n"
3584 "a cycle audio channel in the current program\n"
3585 "v cycle video channel\n"
3586 "t cycle subtitle channel in the current program\n"
3587 "c cycle program\n"
3588 "w cycle video filters or show modes\n"
3589 "s activate frame-step mode\n"
3590 "left/right seek backward/forward 10 seconds\n"
3591 "down/up seek backward/forward 1 minute\n"
3592 "page down/page up seek backward/forward 10 minutes\n"
3593 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3594 "left double-click toggle full screen\n"
3595 );
3596}
3597
3598static int lockmgr(void **mtx, enum AVLockOp op)
3599{
3600 switch(op) {
3601 case AV_LOCK_CREATE:
3602 *mtx = SDL_CreateMutex();
3603 if(!*mtx) {
3604 av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
3605 return 1;
3606 }
3607 return 0;
3608 case AV_LOCK_OBTAIN:
3609 return !!SDL_LockMutex(*mtx);
3610 case AV_LOCK_RELEASE:
3611 return !!SDL_UnlockMutex(*mtx);
3612 case AV_LOCK_DESTROY:
3613 SDL_DestroyMutex(*mtx);
3614 return 0;
3615 }
3616 return 1;
3617}
3618
3619/* Called from the main */
3620int main(int argc, char **argv)
3621{
3622 int flags;
3623 VideoState *is;
3624
3625 init_dynload();
3626
3627 av_log_set_flags(AV_LOG_SKIP_REPEATED);
3628 parse_loglevel(argc, argv, options);
3629
3630 /* register all codecs, demux and protocols */
3631#if CONFIG_AVDEVICE
3632 avdevice_register_all();
3633#endif
3634#if CONFIG_AVFILTER
3635 avfilter_register_all();
3636#endif
3637 av_register_all();
3638 avformat_network_init();
3639
3640 init_opts();
3641
3642 signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
3643 signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
3644
3645 show_banner(argc, argv, options);
3646
3647 parse_options(NULL, argc, argv, options, opt_input_file);
3648
3649 if (!input_filename) {
3650 show_usage();
3651 av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
3652 av_log(NULL, AV_LOG_FATAL,
3653 "Use -h to get full help or, even better, run 'man %s'\n", program_name);
3654 exit(1);
3655 }
3656
3657 if (display_disable) {
3658 video_disable = 1;
3659 }
3660 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3661 if (audio_disable)
3662 flags &= ~SDL_INIT_AUDIO;
3663 else {
3664 /* Try to work around an occasional ALSA buffer underflow issue when the
3665 * period size is NPOT due to ALSA resampling by forcing the buffer size. */
3666 if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3667 SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
3668 }
3669 if (display_disable)
3670 flags &= ~SDL_INIT_VIDEO;
3671 if (SDL_Init (flags)) {
3672 av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
3673 av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
3674 exit(1);
3675 }
3676
3677 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3678 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3679
3680 if (av_lockmgr_register(lockmgr)) {
3681 av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
3682 do_exit(NULL);
3683 }
3684
3685 av_init_packet(&flush_pkt);
3686 flush_pkt.data = (uint8_t *)&flush_pkt;
3687
3688 is = stream_open(input_filename, file_iformat);
3689 if (!is) {
3690 av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");
3691 do_exit(NULL);
3692 }
3693
3694 event_loop(is);
3695
3696 /* never returns */
3697
3698 return 0;
3699}
3700