Go to the documentation of this file.
27 #include "config_components.h"
58 #include <SDL_thread.h>
66 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
68 #define EXTERNAL_CLOCK_MIN_FRAMES 2
69 #define EXTERNAL_CLOCK_MAX_FRAMES 10
72 #define SDL_AUDIO_MIN_BUFFER_SIZE 512
74 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
77 #define SDL_VOLUME_STEP (0.75)
80 #define AV_SYNC_THRESHOLD_MIN 0.04
82 #define AV_SYNC_THRESHOLD_MAX 0.1
84 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
86 #define AV_NOSYNC_THRESHOLD 10.0
89 #define SAMPLE_CORRECTION_PERCENT_MAX 10
92 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
93 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
94 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
97 #define AUDIO_DIFF_AVG_NB 20
100 #define REFRESH_RATE 0.01
104 #define SAMPLE_ARRAY_SIZE (8 * 65536)
106 #define CURSOR_HIDE_DELAY 1000000
108 #define USE_ONEPASS_SUBTITLE_RENDER 1
126 #define VIDEO_PICTURE_QUEUE_SIZE 3
127 #define SUBPICTURE_QUEUE_SIZE 16
128 #define SAMPLE_QUEUE_SIZE 9
129 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
356 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
401 if (channel_count1 == 1 && channel_count2 == 1)
404 return channel_count1 != channel_count2 || fmt1 != fmt2;
426 SDL_CondSignal(q->
cond);
442 SDL_LockMutex(q->
mutex);
444 SDL_UnlockMutex(q->
mutex);
465 q->
mutex = SDL_CreateMutex();
470 q->
cond = SDL_CreateCond();
483 SDL_LockMutex(q->
mutex);
490 SDL_UnlockMutex(q->
mutex);
497 SDL_DestroyMutex(q->
mutex);
498 SDL_DestroyCond(q->
cond);
503 SDL_LockMutex(q->
mutex);
507 SDL_CondSignal(q->
cond);
509 SDL_UnlockMutex(q->
mutex);
514 SDL_LockMutex(q->
mutex);
517 SDL_UnlockMutex(q->
mutex);
526 SDL_LockMutex(q->
mutex);
551 SDL_UnlockMutex(q->
mutex);
562 d->empty_queue_cond = empty_queue_cond;
572 if (
d->queue->serial ==
d->pkt_serial) {
574 if (
d->queue->abort_request)
577 switch (
d->avctx->codec_type) {
604 d->finished =
d->pkt_serial;
614 if (
d->queue->nb_packets == 0)
615 SDL_CondSignal(
d->empty_queue_cond);
616 if (
d->packet_pending) {
617 d->packet_pending = 0;
619 int old_serial =
d->pkt_serial;
622 if (old_serial !=
d->pkt_serial) {
625 d->next_pts =
d->start_pts;
626 d->next_pts_tb =
d->start_pts_tb;
629 if (
d->queue->serial ==
d->pkt_serial)
640 if (got_frame && !
d->pkt->data) {
641 d->packet_pending = 1;
647 if (
d->pkt->buf && !
d->pkt->opaque_ref) {
651 if (!
d->pkt->opaque_ref)
658 av_log(
d->avctx,
AV_LOG_ERROR,
"Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
659 d->packet_pending = 1;
682 if (!(
f->mutex = SDL_CreateMutex())) {
686 if (!(
f->cond = SDL_CreateCond())) {
692 f->keep_last = !!keep_last;
693 for (
i = 0;
i <
f->max_size;
i++)
702 for (
i = 0;
i <
f->max_size;
i++) {
707 SDL_DestroyMutex(
f->mutex);
708 SDL_DestroyCond(
f->cond);
713 SDL_LockMutex(
f->mutex);
714 SDL_CondSignal(
f->cond);
715 SDL_UnlockMutex(
f->mutex);
720 return &
f->queue[(
f->rindex +
f->rindex_shown) %
f->max_size];
725 return &
f->queue[(
f->rindex +
f->rindex_shown + 1) %
f->max_size];
730 return &
f->queue[
f->rindex];
736 SDL_LockMutex(
f->mutex);
737 while (
f->size >=
f->max_size &&
738 !
f->pktq->abort_request) {
739 SDL_CondWait(
f->cond,
f->mutex);
741 SDL_UnlockMutex(
f->mutex);
743 if (
f->pktq->abort_request)
746 return &
f->queue[
f->windex];
752 SDL_LockMutex(
f->mutex);
753 while (
f->size -
f->rindex_shown <= 0 &&
754 !
f->pktq->abort_request) {
755 SDL_CondWait(
f->cond,
f->mutex);
757 SDL_UnlockMutex(
f->mutex);
759 if (
f->pktq->abort_request)
762 return &
f->queue[(
f->rindex +
f->rindex_shown) %
f->max_size];
767 if (++
f->windex ==
f->max_size)
769 SDL_LockMutex(
f->mutex);
771 SDL_CondSignal(
f->cond);
772 SDL_UnlockMutex(
f->mutex);
777 if (
f->keep_last && !
f->rindex_shown) {
782 if (++
f->rindex ==
f->max_size)
784 SDL_LockMutex(
f->mutex);
786 SDL_CondSignal(
f->cond);
787 SDL_UnlockMutex(
f->mutex);
793 return f->size -
f->rindex_shown;
800 if (
f->rindex_shown &&
fp->serial ==
f->pktq->serial)
810 SDL_WaitThread(
d->decoder_tid,
NULL);
811 d->decoder_tid =
NULL;
826 static int realloc_texture(SDL_Texture **texture, Uint32 new_format,
int new_width,
int new_height, SDL_BlendMode blendmode,
int init_texture)
830 if (!*texture || SDL_QueryTexture(*texture, &
format, &access, &
w, &
h) < 0 || new_width !=
w || new_height !=
h || new_format !=
format) {
834 SDL_DestroyTexture(*texture);
835 if (!(*texture = SDL_CreateTexture(
renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
837 if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
840 if (SDL_LockTexture(*texture,
NULL, &pixels, &pitch) < 0)
842 memset(pixels, 0, pitch * new_height);
843 SDL_UnlockTexture(*texture);
845 av_log(
NULL,
AV_LOG_VERBOSE,
"Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format));
851 int scr_xleft,
int scr_ytop,
int scr_width,
int scr_height,
852 int pic_width,
int pic_height,
AVRational pic_sar)
865 if (
width > scr_width) {
869 x = (scr_width -
width) / 2;
870 y = (scr_height -
height) / 2;
871 rect->
x = scr_xleft + x;
872 rect->
y = scr_ytop + y;
880 *sdl_blendmode = SDL_BLENDMODE_NONE;
881 *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN;
886 *sdl_blendmode = SDL_BLENDMODE_BLEND;
899 SDL_BlendMode sdl_blendmode;
901 if (
realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt,
frame->width,
frame->height, sdl_blendmode, 0) < 0)
903 switch (sdl_pix_fmt) {
904 case SDL_PIXELFORMAT_IYUV:
905 if (
frame->linesize[0] > 0 &&
frame->linesize[1] > 0 &&
frame->linesize[2] > 0) {
909 }
else if (
frame->linesize[0] < 0 &&
frame->linesize[1] < 0 &&
frame->linesize[2] < 0) {
919 if (
frame->linesize[0] < 0) {
931 #if SDL_VERSION_ATLEAST(2,0,8)
932 SDL_YUV_CONVERSION_MODE
mode = SDL_YUV_CONVERSION_AUTOMATIC;
935 mode = SDL_YUV_CONVERSION_JPEG;
937 mode = SDL_YUV_CONVERSION_BT709;
939 mode = SDL_YUV_CONVERSION_BT601;
941 SDL_SetYUVConversionMode(
mode);
952 if (
is->subtitle_st) {
956 if (vp->
pts >=
sp->pts + ((
float)
sp->sub.start_display_time / 1000)) {
961 if (!
sp->width || !
sp->height) {
965 if (
realloc_texture(&
is->sub_texture, SDL_PIXELFORMAT_ARGB8888,
sp->width,
sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
968 for (
i = 0;
i <
sp->sub.num_rects;
i++) {
973 sub_rect->
w =
av_clip(sub_rect->
w, 0,
sp->width - sub_rect->
x);
974 sub_rect->
h =
av_clip(sub_rect->
h, 0,
sp->height - sub_rect->
y);
980 if (!
is->sub_convert_ctx) {
984 if (!SDL_LockTexture(
is->sub_texture, (SDL_Rect *)sub_rect, (
void **)pixels, pitch)) {
985 sws_scale(
is->sub_convert_ctx, (
const uint8_t *
const *)sub_rect->data, sub_rect->linesize,
986 0, sub_rect->h, pixels, pitch);
987 SDL_UnlockTexture(
is->sub_texture);
1012 #if USE_ONEPASS_SUBTITLE_RENDER
1018 for (
i = 0;
i <
sp->sub.num_rects;
i++) {
1019 SDL_Rect *sub_rect = (SDL_Rect*)
sp->sub.rects[
i];
1020 SDL_Rect target = {.x =
rect.
x + sub_rect->x * xratio,
1021 .y =
rect.
y + sub_rect->y * yratio,
1022 .w = sub_rect->w * xratio,
1023 .h = sub_rect->h * yratio};
1024 SDL_RenderCopy(
renderer,
is->sub_texture, sub_rect, &target);
1032 return a < 0 ?
a%
b +
b :
a%
b;
1037 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
1040 int rdft_bits, nb_freq;
1042 for (rdft_bits = 1; (1 << rdft_bits) < 2 *
s->height; rdft_bits++)
1044 nb_freq = 1 << (rdft_bits - 1);
1047 channels =
s->audio_tgt.ch_layout.nb_channels;
1050 int data_used=
s->show_mode == SHOW_MODE_WAVES ?
s->width : (2*nb_freq);
1052 delay =
s->audio_write_buf_size;
1059 delay -= (time_diff *
s->audio_tgt.freq) / 1000000;
1062 delay += 2 * data_used;
1063 if (delay < data_used)
1067 if (
s->show_mode == SHOW_MODE_WAVES) {
1071 int a =
s->sample_array[idx];
1076 if (
h < score && (
b ^
c) < 0) {
1083 s->last_i_start = i_start;
1085 i_start =
s->last_i_start;
1088 if (
s->show_mode == SHOW_MODE_WAVES) {
1089 SDL_SetRenderDrawColor(
renderer, 255, 255, 255, 255);
1092 h =
s->height / nb_display_channels;
1095 for (ch = 0; ch < nb_display_channels; ch++) {
1097 y1 =
s->ytop + ch *
h + (
h / 2);
1098 for (x = 0; x <
s->width; x++) {
1099 y = (
s->sample_array[
i] * h2) >> 15;
1113 SDL_SetRenderDrawColor(
renderer, 0, 0, 255, 255);
1115 for (ch = 1; ch < nb_display_channels; ch++) {
1116 y =
s->ytop + ch *
h;
1120 if (
realloc_texture(&
s->vis_texture, SDL_PIXELFORMAT_ARGB8888,
s->width,
s->height, SDL_BLENDMODE_NONE, 1) < 0)
1123 if (
s->xpos >=
s->width)
1125 nb_display_channels=
FFMIN(nb_display_channels, 2);
1126 if (rdft_bits !=
s->rdft_bits) {
1130 s->rdft_bits = rdft_bits;
1133 if (!
s->rdft || !
s->rdft_data){
1135 s->show_mode = SHOW_MODE_WAVES;
1138 SDL_Rect
rect = {.
x =
s->xpos, .y = 0, .w = 1, .h =
s->height};
1141 for (ch = 0; ch < nb_display_channels; ch++) {
1142 data[ch] =
s->rdft_data + 2 * nb_freq * ch;
1144 for (x = 0; x < 2 * nb_freq; x++) {
1145 double w = (x-nb_freq) * (1.0 / nb_freq);
1146 data[ch][x] =
s->sample_array[
i] * (1.0 -
w *
w);
1155 if (!SDL_LockTexture(
s->vis_texture, &
rect, (
void **)&pixels, &pitch)) {
1157 pixels += pitch *
s->height;
1158 for (y = 0; y <
s->height; y++) {
1159 double w = 1 / sqrt(nb_freq);
1160 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]));
1161 int b = (nb_display_channels == 2 ) ? sqrt(
w *
hypot(
data[1][2 * y + 0],
data[1][2 * y + 1]))
1166 *pixels = (
a << 16) + (
b << 8) + ((
a+
b) >> 1);
1168 SDL_UnlockTexture(
s->vis_texture);
1182 if (stream_index < 0 || stream_index >= ic->
nb_streams)
1193 is->audio_buf1_size = 0;
1219 is->audio_stream = -1;
1223 is->video_stream = -1;
1227 is->subtitle_stream = -1;
1237 is->abort_request = 1;
1238 SDL_WaitThread(
is->read_tid,
NULL);
1241 if (
is->audio_stream >= 0)
1243 if (
is->video_stream >= 0)
1245 if (
is->subtitle_stream >= 0)
1258 SDL_DestroyCond(
is->continue_read_thread);
1261 if (
is->vis_texture)
1262 SDL_DestroyTexture(
is->vis_texture);
1263 if (
is->vid_texture)
1264 SDL_DestroyTexture(
is->vid_texture);
1265 if (
is->sub_texture)
1266 SDL_DestroyTexture(
is->sub_texture);
1278 SDL_DestroyWindow(
window);
1299 if (max_width == INT_MAX && max_height == INT_MAX)
1320 SDL_SetWindowFullscreen(
window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1335 SDL_SetRenderDrawColor(
renderer, 0, 0, 0, 255);
1337 if (
is->audio_st &&
is->show_mode != SHOW_MODE_VIDEO)
1339 else if (
is->video_st)
1346 if (*
c->queue_serial !=
c->serial)
1352 return c->pts_drift + time - (time -
c->last_updated) * (1.0 -
c->speed);
1359 c->last_updated = time;
1360 c->pts_drift =
c->pts - time;
1380 c->queue_serial = queue_serial;
1435 double speed =
is->extclk.speed;
1444 if (!
is->seek_req) {
1451 SDL_CondSignal(
is->continue_read_thread);
1460 if (
is->read_pause_return !=
AVERROR(ENOSYS)) {
1461 is->vidclk.paused = 0;
1466 is->paused =
is->audclk.paused =
is->vidclk.paused =
is->extclk.paused = !
is->paused;
1477 is->muted = !
is->muted;
1482 double volume_level =
is->audio_volume ? (20 * log(
is->audio_volume / (
double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
1483 int new_volume =
lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign *
step) / 20.0));
1484 is->audio_volume =
av_clip(
is->audio_volume == new_volume ? (
is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
1497 double sync_threshold,
diff = 0;
1510 if (
diff <= -sync_threshold)
1513 delay = delay +
diff;
1514 else if (
diff >= sync_threshold)
1528 if (
isnan(
duration) || duration <= 0 || duration >
is->max_frame_duration)
1557 if (
is->force_refresh ||
is->last_vis_time +
rdftspeed < time) {
1559 is->last_vis_time = time;
1561 *remaining_time =
FFMIN(*remaining_time,
is->last_vis_time +
rdftspeed - time);
1569 double last_duration,
duration, delay;
1576 if (vp->
serial !=
is->videoq.serial) {
1592 if (time < is->frame_timer + delay) {
1593 *remaining_time =
FFMIN(
is->frame_timer + delay - time, *remaining_time);
1597 is->frame_timer += delay;
1599 is->frame_timer = time;
1601 SDL_LockMutex(
is->pictq.mutex);
1604 SDL_UnlockMutex(
is->pictq.mutex);
1610 is->frame_drops_late++;
1616 if (
is->subtitle_st) {
1625 if (
sp->serial !=
is->subtitleq.serial
1626 || (
is->vidclk.pts > (
sp->pts + ((
float)
sp->sub.end_display_time / 1000)))
1631 for (
i = 0;
i <
sp->sub.num_rects;
i++) {
1636 if (!SDL_LockTexture(
is->sub_texture, (SDL_Rect *)sub_rect, (
void **)&pixels, &pitch)) {
1637 for (j = 0; j < sub_rect->h; j++, pixels += pitch)
1638 memset(pixels, 0, sub_rect->w << 2);
1639 SDL_UnlockTexture(
is->sub_texture);
1651 is->force_refresh = 1;
1653 if (
is->step && !
is->paused)
1658 if (!
display_disable &&
is->force_refresh &&
is->show_mode == SHOW_MODE_VIDEO &&
is->pictq.rindex_shown)
1661 is->force_refresh = 0;
1664 static int64_t last_time;
1666 int aqsize, vqsize, sqsize;
1670 if (!last_time || (cur_time - last_time) >= 30000) {
1675 aqsize =
is->audioq.size;
1677 vqsize =
is->videoq.size;
1678 if (
is->subtitle_st)
1679 sqsize =
is->subtitleq.size;
1681 if (
is->audio_st &&
is->video_st)
1683 else if (
is->video_st)
1685 else if (
is->audio_st)
1690 "%7.2f %s:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64
"/%"PRId64
" \r",
1692 (
is->audio_st &&
is->video_st) ?
"A-V" : (
is->video_st ?
"M-V" : (
is->audio_st ?
"M-A" :
" ")),
1694 is->frame_drops_early +
is->frame_drops_late,
1698 is->video_st ?
is->viddec.avctx->pts_correction_num_faulty_dts : 0,
1699 is->video_st ?
is->viddec.avctx->pts_correction_num_faulty_pts : 0);
1702 fprintf(stderr,
"%s", buf.str);
1709 last_time = cur_time;
1718 #if defined(DEBUG_SYNC)
1719 printf(
"frame_type=%c pts=%0.3f\n",
1764 diff -
is->frame_last_filter_delay < 0 &&
1765 is->viddec.pkt_serial ==
is->vidclk.serial &&
1766 is->videoq.nb_packets) {
1767 is->frame_drops_early++;
1794 outputs->filter_ctx = source_ctx;
1799 inputs->filter_ctx = sink_ctx;
1824 char sws_flags_str[512] =
"";
1825 char buffersrc_args[256];
1831 int nb_pix_fmts = 0;
1845 if (!strcmp(e->
key,
"sws_flags")) {
1846 av_strlcatf(sws_flags_str,
sizeof(sws_flags_str),
"%s=%s:",
"flags", e->
value);
1850 if (strlen(sws_flags_str))
1851 sws_flags_str[strlen(sws_flags_str)-1] =
'\0';
1855 snprintf(buffersrc_args,
sizeof(buffersrc_args),
1856 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
1858 is->video_st->time_base.num,
is->video_st->time_base.den,
1861 av_strlcatf(buffersrc_args,
sizeof(buffersrc_args),
":frame_rate=%d/%d", fr.
num, fr.
den);
1865 "ffplay_buffer", buffersrc_args,
NULL,
1871 "ffplay_buffersink",
NULL,
NULL, graph);
1878 last_filter = filt_out;
1882 #define INSERT_FILT(name, arg) do { \
1883 AVFilterContext *filt_ctx; \
1885 ret = avfilter_graph_create_filter(&filt_ctx, \
1886 avfilter_get_by_name(name), \
1887 "ffplay_" name, arg, NULL, graph); \
1891 ret = avfilter_link(filt_ctx, 0, last_filter, 0); \
1895 last_filter = filt_ctx; \
1908 if (
fabs(theta - 90) < 1.0) {
1910 }
else if (
fabs(theta - 180) < 1.0) {
1913 }
else if (
fabs(theta - 270) < 1.0) {
1915 }
else if (
fabs(theta) > 1.0) {
1916 char rotate_buf[64];
1917 snprintf(rotate_buf,
sizeof(rotate_buf),
"%f*PI/180", theta);
1925 is->in_video_filter = filt_src;
1926 is->out_video_filter = filt_out;
1937 char aresample_swr_opts[512] =
"";
1940 char asrc_args[256];
1952 if (strlen(aresample_swr_opts))
1953 aresample_swr_opts[strlen(aresample_swr_opts)-1] =
'\0';
1954 av_opt_set(
is->agraph,
"aresample_swr_opts", aresample_swr_opts, 0);
1959 "sample_rate=%d:sample_fmt=%s:time_base=%d/%d:channel_layout=%s",
1961 1,
is->audio_filter_src.freq, bp.str);
1965 asrc_args,
NULL,
is->agraph);
1981 if (force_output_format) {
1995 is->in_audio_filter = filt_asrc;
1996 is->out_audio_filter = filt_asink;
2011 int last_serial = -1;
2029 frame->format,
frame->ch_layout.nb_channels) ||
2031 is->audio_filter_src.freq !=
frame->sample_rate ||
2032 is->auddec.pkt_serial != last_serial;
2035 char buf1[1024], buf2[1024];
2039 "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",
2040 is->audio_filter_src.freq,
is->audio_filter_src.ch_layout.nb_channels,
av_get_sample_fmt_name(
is->audio_filter_src.fmt), buf1, last_serial,
2043 is->audio_filter_src.fmt =
frame->format;
2047 is->audio_filter_src.freq =
frame->sample_rate;
2048 last_serial =
is->auddec.pkt_serial;
2065 af->
serial =
is->auddec.pkt_serial;
2071 if (
is->audioq.serial !=
is->auddec.pkt_serial)
2075 is->auddec.finished =
is->auddec.pkt_serial;
2087 d->decoder_tid = SDL_CreateThread(
fn, thread_name,
arg);
2088 if (!
d->decoder_tid) {
2110 int last_serial = -1;
2111 int last_vfilter_idx = 0;
2123 if ( last_w !=
frame->width
2124 || last_h !=
frame->height
2125 || last_format !=
frame->format
2126 || last_serial !=
is->viddec.pkt_serial
2127 || last_vfilter_idx !=
is->vfilter_idx) {
2129 "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
2144 event.user.data1 =
is;
2145 SDL_PushEvent(&event);
2148 filt_in =
is->in_video_filter;
2149 filt_out =
is->out_video_filter;
2150 last_w =
frame->width;
2151 last_h =
frame->height;
2152 last_format =
frame->format;
2153 last_serial =
is->viddec.pkt_serial;
2154 last_vfilter_idx =
is->vfilter_idx;
2170 is->viddec.finished =
is->viddec.pkt_serial;
2179 is->frame_last_filter_delay = 0;
2185 if (
is->videoq.serial !=
is->viddec.pkt_serial)
2214 if (got_subtitle &&
sp->sub.format == 0) {
2218 sp->serial =
is->subdec.pkt_serial;
2219 sp->width =
is->subdec.avctx->width;
2220 sp->height =
is->subdec.avctx->height;
2225 }
else if (got_subtitle) {
2242 memcpy(
is->sample_array +
is->sample_array_index,
samples,
len *
sizeof(
short));
2244 is->sample_array_index +=
len;
2246 is->sample_array_index = 0;
2255 int wanted_nb_samples = nb_samples;
2259 double diff, avg_diff;
2260 int min_nb_samples, max_nb_samples;
2265 is->audio_diff_cum =
diff +
is->audio_diff_avg_coef *
is->audio_diff_cum;
2268 is->audio_diff_avg_count++;
2271 avg_diff =
is->audio_diff_cum * (1.0 -
is->audio_diff_avg_coef);
2273 if (
fabs(avg_diff) >=
is->audio_diff_threshold) {
2274 wanted_nb_samples = nb_samples + (
int)(
diff *
is->audio_src.freq);
2277 wanted_nb_samples =
av_clip(wanted_nb_samples, min_nb_samples, max_nb_samples);
2280 diff, avg_diff, wanted_nb_samples - nb_samples,
2281 is->audio_clock,
is->audio_diff_threshold);
2286 is->audio_diff_avg_count = 0;
2287 is->audio_diff_cum = 0;
2291 return wanted_nb_samples;
2303 int data_size, resampled_data_size;
2305 int wanted_nb_samples;
2322 }
while (af->
serial !=
is->audioq.serial);
2336 &
is->audio_tgt.ch_layout,
is->audio_tgt.fmt,
is->audio_tgt.freq,
2341 "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
2355 uint8_t **
out = &
is->audio_buf1;
2356 int out_count = (int64_t)wanted_nb_samples *
is->audio_tgt.freq / af->
frame->
sample_rate + 256;
2371 if (!
is->audio_buf1)
2378 if (len2 == out_count) {
2383 is->audio_buf =
is->audio_buf1;
2387 resampled_data_size = data_size;
2390 audio_clock0 =
is->audio_clock;
2395 is->audio_clock =
NAN;
2396 is->audio_clock_serial = af->
serial;
2399 static double last_clock;
2400 printf(
"audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
2401 is->audio_clock - last_clock,
2402 is->audio_clock, audio_clock0);
2403 last_clock =
is->audio_clock;
2406 return resampled_data_size;
2413 int audio_size, len1;
2418 if (
is->audio_buf_index >=
is->audio_buf_size) {
2420 if (audio_size < 0) {
2425 if (
is->show_mode != SHOW_MODE_VIDEO)
2427 is->audio_buf_size = audio_size;
2429 is->audio_buf_index = 0;
2431 len1 =
is->audio_buf_size -
is->audio_buf_index;
2434 if (!
is->muted &&
is->audio_buf &&
is->audio_volume == SDL_MIX_MAXVOLUME)
2435 memcpy(stream, (uint8_t *)
is->audio_buf +
is->audio_buf_index, len1);
2437 memset(stream, 0, len1);
2438 if (!
is->muted &&
is->audio_buf)
2439 SDL_MixAudioFormat(stream, (uint8_t *)
is->audio_buf +
is->audio_buf_index, AUDIO_S16SYS, len1,
is->audio_volume);
2443 is->audio_buf_index += len1;
2445 is->audio_write_buf_size =
is->audio_buf_size -
is->audio_buf_index;
2447 if (!
isnan(
is->audio_clock)) {
2455 SDL_AudioSpec wanted_spec, spec;
2457 static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
2458 static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
2459 int next_sample_rate_idx =
FF_ARRAY_ELEMS(next_sample_rates) - 1;
2460 int wanted_nb_channels = wanted_channel_layout->
nb_channels;
2462 env = SDL_getenv(
"SDL_AUDIO_CHANNELS");
2464 wanted_nb_channels = atoi(env);
2472 wanted_nb_channels = wanted_channel_layout->
nb_channels;
2473 wanted_spec.channels = wanted_nb_channels;
2474 wanted_spec.freq = wanted_sample_rate;
2475 if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
2479 while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
2480 next_sample_rate_idx--;
2481 wanted_spec.format = AUDIO_S16SYS;
2482 wanted_spec.silence = 0;
2485 wanted_spec.userdata = opaque;
2486 while (!(
audio_dev = SDL_OpenAudioDevice(
NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
2488 wanted_spec.channels, wanted_spec.freq, SDL_GetError());
2489 wanted_spec.channels = next_nb_channels[
FFMIN(7, wanted_spec.channels)];
2490 if (!wanted_spec.channels) {
2491 wanted_spec.freq = next_sample_rates[next_sample_rate_idx--];
2492 wanted_spec.channels = wanted_nb_channels;
2493 if (!wanted_spec.freq) {
2495 "No more combinations to try, audio open failed\n");
2501 if (spec.format != AUDIO_S16SYS) {
2503 "SDL advised audio format %d is not supported!\n", spec.format);
2506 if (spec.channels != wanted_spec.channels) {
2511 "SDL advised channel count %d is not supported!\n", spec.channels);
2517 audio_hw_params->
freq = spec.freq;
2535 const char *forced_codec_name =
NULL;
2541 int stream_lowres =
lowres;
2543 if (stream_index < 0 || stream_index >= ic->
nb_streams)
2562 if (forced_codec_name)
2566 "No codec could be found with name '%s'\n", forced_codec_name);
2579 avctx->
lowres = stream_lowres;
2615 sink =
is->out_audio_filter;
2625 is->audio_hw_buf_size =
ret;
2626 is->audio_src =
is->audio_tgt;
2627 is->audio_buf_size = 0;
2628 is->audio_buf_index = 0;
2632 is->audio_diff_avg_count = 0;
2635 is->audio_diff_threshold = (
double)(
is->audio_hw_buf_size) /
is->audio_tgt.bytes_per_sec;
2637 is->audio_stream = stream_index;
2638 is->audio_st = ic->
streams[stream_index];
2643 is->auddec.start_pts =
is->audio_st->start_time;
2644 is->auddec.start_pts_tb =
is->audio_st->time_base;
2651 is->video_stream = stream_index;
2652 is->video_st = ic->
streams[stream_index];
2658 is->queue_attachments_req = 1;
2661 is->subtitle_stream = stream_index;
2662 is->subtitle_st = ic->
streams[stream_index];
2686 return is->abort_request;
2690 return stream_id < 0 ||
2698 if( !strcmp(
s->iformat->name,
"rtp")
2699 || !strcmp(
s->iformat->name,
"rtsp")
2700 || !strcmp(
s->iformat->name,
"sdp")
2704 if(
s->pb && ( !strncmp(
s->url,
"rtp:", 4)
2705 || !strncmp(
s->url,
"udp:", 4)
2720 int64_t stream_start_time;
2721 int pkt_in_play_range = 0;
2723 SDL_mutex *wait_mutex = SDL_CreateMutex();
2724 int scan_all_pmts_set = 0;
2733 memset(st_index, -1,
sizeof(st_index));
2752 scan_all_pmts_set = 1;
2760 if (scan_all_pmts_set)
2781 for (
i = 0;
i < orig_nb_streams;
i++)
2787 "%s: could not find codec parameters\n",
is->filename);
2837 st_index[
i] = INT_MAX;
2865 if (codecpar->
width)
2878 if (
is->show_mode == SHOW_MODE_NONE)
2879 is->show_mode =
ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
2885 if (
is->video_stream < 0 &&
is->audio_stream < 0) {
2892 if (infinite_buffer < 0 && is->realtime)
2896 if (
is->abort_request)
2898 if (
is->paused !=
is->last_paused) {
2899 is->last_paused =
is->paused;
2905 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
2916 int64_t seek_target =
is->seek_pos;
2917 int64_t seek_min =
is->seek_rel > 0 ? seek_target -
is->seek_rel + 2: INT64_MIN;
2918 int64_t seek_max =
is->seek_rel < 0 ? seek_target -
is->seek_rel - 2: INT64_MAX;
2925 "%s: error while seeking\n",
is->ic->url);
2927 if (
is->audio_stream >= 0)
2929 if (
is->subtitle_stream >= 0)
2931 if (
is->video_stream >= 0)
2940 is->queue_attachments_req = 1;
2945 if (
is->queue_attachments_req) {
2952 is->queue_attachments_req = 0;
2962 SDL_LockMutex(wait_mutex);
2963 SDL_CondWaitTimeout(
is->continue_read_thread, wait_mutex, 10);
2964 SDL_UnlockMutex(wait_mutex);
2980 if (
is->video_stream >= 0)
2982 if (
is->audio_stream >= 0)
2984 if (
is->subtitle_stream >= 0)
2994 SDL_LockMutex(wait_mutex);
2995 SDL_CondWaitTimeout(
is->continue_read_thread, wait_mutex, 10);
2996 SDL_UnlockMutex(wait_mutex);
3005 (pkt_ts - (stream_start_time !=
AV_NOPTS_VALUE ? stream_start_time : 0)) *
3031 event.user.data1 =
is;
3032 SDL_PushEvent(&event);
3034 SDL_DestroyMutex(wait_mutex);
3046 is->last_video_stream =
is->video_stream = -1;
3047 is->last_audio_stream =
is->audio_stream = -1;
3048 is->last_subtitle_stream =
is->subtitle_stream = -1;
3069 if (!(
is->continue_read_thread = SDL_CreateCond())) {
3077 is->audio_clock_serial = -1;
3088 if (!
is->read_tid) {
3100 int start_index, stream_index;
3107 start_index =
is->last_video_stream;
3108 old_index =
is->video_stream;
3110 start_index =
is->last_audio_stream;
3111 old_index =
is->audio_stream;
3113 start_index =
is->last_subtitle_stream;
3114 old_index =
is->subtitle_stream;
3116 stream_index = start_index;
3122 for (start_index = 0; start_index <
nb_streams; start_index++)
3127 stream_index = start_index;
3137 is->last_subtitle_stream = -1;
3140 if (start_index == -1)
3144 if (stream_index == start_index)
3146 st =
is->ic->streams[p ? p->
stream_index[stream_index] : stream_index];
3164 if (p && stream_index != -1)
3184 int next =
is->show_mode;
3186 next = (next + 1) % SHOW_MODE_NB;
3187 }
while (next !=
is->show_mode && (next == SHOW_MODE_VIDEO && !
is->video_st || next != SHOW_MODE_VIDEO && !
is->audio_st));
3188 if (
is->show_mode != next) {
3189 is->force_refresh = 1;
3190 is->show_mode = next;
3195 double remaining_time = 0.0;
3197 while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
3202 if (remaining_time > 0.0)
3203 av_usleep((int64_t)(remaining_time * 1000000.0));
3205 if (
is->show_mode != SHOW_MODE_NONE && (!
is->paused ||
is->force_refresh))
3216 if (!
is->ic->nb_chapters)
3220 for (
i = 0;
i <
is->ic->nb_chapters;
i++) {
3230 if (
i >=
is->ic->nb_chapters)
3242 double incr,
pos, frac;
3247 switch (event.type) {
3249 if (
exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
3254 if (!cur_stream->
width)
3256 switch (event.key.keysym.sym) {
3268 case SDLK_KP_MULTIPLY:
3272 case SDLK_KP_DIVIDE:
3356 case SDL_MOUSEBUTTONDOWN:
3361 if (event.button.button == SDL_BUTTON_LEFT) {
3362 static int64_t last_mouse_left_click = 0;
3366 last_mouse_left_click = 0;
3371 case SDL_MOUSEMOTION:
3377 if (event.type == SDL_MOUSEBUTTONDOWN) {
3378 if (event.button.button != SDL_BUTTON_RIGHT)
3382 if (!(event.motion.state & SDL_BUTTON_RMASK))
3392 int tns, thh, tmm, tss;
3395 tmm = (tns % 3600) / 60;
3397 frac = x / cur_stream->
width;
3400 mm = (
ns % 3600) / 60;
3403 "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
3404 hh, mm,
ss, thh, tmm, tss);
3411 case SDL_WINDOWEVENT:
3412 switch (event.window.event) {
3413 case SDL_WINDOWEVENT_SIZE_CHANGED:
3420 case SDL_WINDOWEVENT_EXPOSED:
3458 if (!strcmp(
arg,
"audio"))
3460 else if (!strcmp(
arg,
"video"))
3462 else if (!strcmp(
arg,
"ext"))
3486 !strcmp(
arg,
"waves") ? SHOW_MODE_WAVES :
3487 !strcmp(
arg,
"rdft" ) ? SHOW_MODE_RDFT :
3496 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3500 if (!strcmp(filename,
"-"))
3507 const char *spec = strchr(opt,
':');
3510 "No media specifier was specified in '%s' in option '%s'\n",
3521 "Invalid media specifier '%s' in option '%s'\n", spec, opt);
3531 {
"x",
HAS_ARG, { .func_arg =
opt_width },
"force displayed width",
"width" },
3532 {
"y",
HAS_ARG, { .func_arg =
opt_height },
"force displayed height",
"height" },
3540 {
"ss",
HAS_ARG, { .func_arg =
opt_seek },
"seek to a given position in seconds",
"pos" },
3541 {
"t",
HAS_ARG, { .func_arg =
opt_duration },
"play \"duration\" seconds of audio/video",
"duration" },
3554 {
"sync",
HAS_ARG |
OPT_EXPERT, { .func_arg =
opt_sync },
"set audio-video sync. type (type=audio/video/ext)",
"type" },
3567 {
"showmode",
HAS_ARG, { .func_arg =
opt_show_mode},
"select show mode (0 = video, 1 = waves, 2 = RDFT)",
"mode" },
3568 {
"i",
OPT_BOOL, { &
dummy},
"read specified file",
"input_file"},
3569 {
"codec",
HAS_ARG, { .func_arg =
opt_codec},
"force decoder",
"decoder_name" },
3575 "read and decode the streams to fill missing information with heuristics" },
3597 printf(
"\nWhile playing:\n"
3599 "f toggle full screen\n"
3602 "9, 0 decrease and increase volume respectively\n"
3603 "/, * decrease and increase volume respectively\n"
3604 "a cycle audio channel in the current program\n"
3605 "v cycle video channel\n"
3606 "t cycle subtitle channel in the current program\n"
3608 "w cycle video filters or show modes\n"
3609 "s activate frame-step mode\n"
3610 "left/right seek backward/forward 10 seconds or to custom interval if -seek_interval is set\n"
3611 "down/up seek backward/forward 1 minute\n"
3612 "page down/page up seek backward/forward 10 minutes\n"
3613 "right mouse click seek to percentage in file corresponding to fraction of width\n"
3614 "left double-click toggle full screen\n"
3646 "Use -h to get full help or, even better, run 'man %s'\n",
program_name);
3653 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3655 flags &= ~SDL_INIT_AUDIO;
3659 if (!SDL_getenv(
"SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
3660 SDL_setenv(
"SDL_AUDIO_ALSA_SET_BUFFER_SIZE",
"1", 1);
3663 flags &= ~SDL_INIT_VIDEO;
3664 if (SDL_Init (
flags)) {
3670 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3671 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3674 int flags = SDL_WINDOW_HIDDEN;
3676 #if SDL_VERSION_ATLEAST(2,0,5)
3677 flags |= SDL_WINDOW_ALWAYS_ON_TOP;
3679 av_log(
NULL,
AV_LOG_WARNING,
"Your SDL version doesn't support SDL_WINDOW_ALWAYS_ON_TOP. Feature will be inactive.\n");
3682 flags |= SDL_WINDOW_BORDERLESS;
3684 flags |= SDL_WINDOW_RESIZABLE;
3686 #ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
3687 SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,
"0");
3690 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
"linear");
3692 renderer = SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
struct SwsContext * sws_getCachedContext(struct SwsContext *context, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Check if context can be reused, otherwise reallocate a new one.
static void do_exit(VideoState *is)
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
#define AV_LOG_WARNING
Something somehow does not look correct.
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
AVPixelFormat
Pixel format.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static SDL_RendererInfo renderer_info
static int frame_queue_nb_remaining(FrameQueue *f)
static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format)
static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
static void frame_queue_next(FrameQueue *f)
enum AVMediaType codec_type
General type of the encoded data.
int nb_threads
Maximum number of threads used by filters in this graph.
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
unsigned int nb_stream_indexes
static int64_t frame_queue_last_pos(FrameQueue *f)
int sample_rate
samples per second
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
static int video_thread(void *arg)
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
The official guide to swscale for confused that is
static void set_default_window_size(int width, int height, AVRational sar)
#define AV_NOSYNC_THRESHOLD
unsigned int nb_chapters
Number of chapters in AVChapter array.
This struct describes the properties of an encoded stream.
#define AV_LOG_QUIET
Print no output.
static float sub(float src0, float src1)
static enum AVSampleFormat sample_fmts[]
static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub)
#define AVERROR_EOF
End of file.
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Get a frame with filtered data from sink and put it in frame.
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
AVProgram * av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
Find the programs which belong to a given stream.
static int display_disable
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance)
Activate resampling compensation ("soft" compensation).
#define SAMPLE_ARRAY_SIZE
static void update_volume(VideoState *is, int sign, double step)
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define av_opt_set_int_list(obj, name, val, term, flags)
Set a binary option to an integer list.
char * av_asprintf(const char *fmt,...)
static int decoder_start(Decoder *d, int(*fn)(void *), const char *thread_name, void *arg)
const AVClass * avformat_get_class(void)
Get the AVClass for AVFormatContext.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
SDL_Texture * vis_texture
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
This structure describes decoded (raw) audio or video data.
struct AudioParams audio_filter_src
AVStream ** streams
A list of all streams in the file.
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
double frame_last_filter_delay
@ AVCOL_RANGE_JPEG
Full range content.
static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
static const char * subtitle_codec_name
#define EXTERNAL_CLOCK_MIN_FRAMES
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
Add a frame to the buffer source.
static void frame_queue_destory(FrameQueue *f)
#define SAMPLE_QUEUE_SIZE
const char program_name[]
program name, defined by the program for show_version().
AVDictionary * format_opts
int error
contains the error code or 0 if no error happened
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
#define AV_PIX_FMT_RGB32_1
double audio_diff_avg_coef
#define AV_LOG_VERBOSE
Detailed information.
#define CURSOR_HIDE_DELAY
void show_help_children(const AVClass *class, int flags)
Show help for all options with given flags in class and all its children.
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
enum AVChannelOrder order
Channel order used in this layout.
static double compute_target_delay(double delay, VideoState *is)
static void stream_close(VideoState *is)
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
#define SDL_AUDIO_MAX_CALLBACKS_PER_SEC
int nb_channels
Number of channels in this layout.
static void init_clock(Clock *c, int *queue_serial)
enum AVMediaType codec_type
#define AV_OPT_FLAG_FILTERING_PARAM
a generic parameter which can be set by the user for filtering
static int opt_seek(void *optctx, const char *opt, const char *arg)
int64_t avio_size(AVIOContext *s)
Get the filesize.
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
static double get_master_clock(VideoState *is)
static const AVInputFormat * file_iformat
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
static int subtitle_thread(void *arg)
int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, AVBPrint *bp)
bprint variant of av_channel_layout_describe().
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
void avfilter_graph_free(AVFilterGraph **graph)
Free a graph, destroy its links, and set *graph to NULL.
static int audio_decode_frame(VideoState *is)
Decode one audio frame and return its uncompressed size.
static int subtitle_disable
struct SwrContext * swr_ctx
static int opt_sync(void *optctx, const char *opt, const char *arg)
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, const AVCodec **decoder_ret, int flags)
Find the "best" stream in the file.
static void step_to_next_frame(VideoState *is)
static int upload_texture(SDL_Texture **tex, AVFrame *frame)
enum AVPixelFormat format
static void video_display(VideoState *is)
uint8_t max_lowres
maximum value for lowres supported by the decoder
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
Parse a string and return its corresponding value as a double.
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
#define SDL_AUDIO_MIN_BUFFER_SIZE
void print_error(const char *filename, int err)
Print an error message to stderr, indicating filename and a human readable description of the error c...
static int startup_volume
static SDL_Window * window
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)
Create and add a filter instance into an existing graph.
static void toggle_full_screen(VideoState *is)
static int packet_queue_init(PacketQueue *q)
#define AUDIO_DIFF_AVG_NB
AVChannelLayout ch_layout
Audio channel layout.
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
AVFilterGraph * avfilter_graph_alloc(void)
Allocate a filter graph.
static int opt_duration(void *optctx, const char *opt, const char *arg)
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
int x
top left corner of pict, undefined when pict is not set
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
#define AVERROR_OPTION_NOT_FOUND
Option not found.
#define AV_BPRINT_SIZE_AUTOMATIC
static void video_image_display(VideoState *is)
static double val(void *priv, double ch)
AVChannelLayout ch_layout
Channel layout of the audio data.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
static int opt_show_mode(void *optctx, const char *opt, const char *arg)
SDL_cond * empty_queue_cond
static void set_clock_speed(Clock *c, double speed)
double audio_diff_threshold
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
#define ss(width, name, subs,...)
int avformat_network_init(void)
Do global initialization of network libraries.
static int opt_height(void *optctx, const char *opt, const char *arg)
void avsubtitle_free(AVSubtitle *sub)
Free all allocated data in the given subtitle struct.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static const struct TextureFormatEntry sdl_texture_format_map[]
int64_t bit_rate
Total stream bitrate in bit/s, 0 if not available.
static int is_full_screen
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, const AVPacket *avpkt)
Decode a subtitle message.
void avfilter_inout_free(AVFilterInOut **inout)
Free the supplied list of AVFilterInOut and set *inout to NULL.
static void set_sdl_yuv_conversion_mode(AVFrame *frame)
AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
Guess the sample aspect ratio of a frame, based on both the stream and the frame aspect ratio.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVDictionary * metadata
Metadata that applies to the whole file.
#define FF_ARRAY_ELEMS(a)
static int audio_thread(void *arg)
static void set_clock(Clock *c, double pts, int serial)
void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)
Print detailed information about the input or output format, such as duration, bitrate,...
static Frame * frame_queue_peek_next(FrameQueue *f)
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
static void sync_clock_to_slave(Clock *c, Clock *slave)
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
static void opt_input_file(void *optctx, const char *filename)
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
static void frame_queue_signal(FrameQueue *f)
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
void show_help_default(const char *opt, const char *arg)
Per-fftool specific help handler.
#define AV_CEIL_RSHIFT(a, b)
static int default_height
int flags
Flags modifying the (de)muxer behaviour.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVRational sample_aspect_ratio
Video only.
const struct AVInputFormat * iformat
The input container format.
#define AV_PIX_FMT_0BGR32
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
int y
top left corner of pict, undefined when pict is not set
static AVStream * video_stream
static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, int pic_width, int pic_height, AVRational pic_sar)
static double av_q2d(AVRational a)
Convert an AVRational to a double.
#define EXTERNAL_CLOCK_SPEED_STEP
static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder or encoder (when the AV_CODEC_FLAG_RECON_FRAME flag is used...
AVRational av_buffersink_get_time_base(const AVFilterContext *ctx)
static const AVFilterPad outputs[]
static enum AVPixelFormat pix_fmts[]
int av_read_play(AVFormatContext *s)
Start playing a network-based stream (e.g.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static int opt_codec(void *optctx, const char *opt, const char *arg)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
static double get_clock(Clock *c)
#define EXTERNAL_CLOCK_SPEED_MIN
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, void(*parse_arg_function)(void *, const char *))
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
static SDL_Renderer * renderer
int av_usleep(unsigned usec)
Sleep for a period of time.
The libswresample context.
static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp)
#define AV_PIX_FMT_BGR32_1
void av_rdft_calc(RDFTContext *s, FFTSample *data)
static int synchronize_audio(VideoState *is, int nb_samples)
static const char * window_title
@ AVDISCARD_ALL
discard all
int av_log_get_level(void)
Get the current log level.
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
void init_dynload(void)
Initialize dynamic library loading.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int w
width of pict, undefined when pict is not set
static void seek_chapter(VideoState *is, int incr)
static int get_master_sync_type(VideoState *is)
const AVClass * avcodec_get_class(void)
Get the AVClass for AVCodecContext.
static __device__ float fabs(float a)
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
const AVCodec * avcodec_find_decoder_by_name(const char *name)
Find a registered decoder with the specified name.
#define AV_DICT_MULTIKEY
Allow to store several equal keys in the dictionary.
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Rational number (pair of numerator and denominator).
AVChannelLayout ch_layout
static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int wanted_sample_rate, struct AudioParams *audio_hw_params)
AVFilterContext ** filters
static void stream_cycle_channel(VideoState *is, int codec_type)
#define AV_CODEC_FLAG2_FAST
Allow non spec compliant speedup tricks.
AVIOContext * pb
I/O context.
void av_log_set_flags(int arg)
static void frame_queue_unref_item(Frame *vp)
Frame queue[FRAME_QUEUE_SIZE]
static int64_t cursor_last_shown
unsigned int * stream_index
static Frame * frame_queue_peek(FrameQueue *f)
AVFilterInOut * avfilter_inout_alloc(void)
Allocate a single AVFilterInOut entry.
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
double frame_last_returned_time
static void set_clock_at(Clock *c, double pts, int serial, double time)
static void toggle_pause(VideoState *is)
static int stream_component_open(VideoState *is, int stream_index)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.