32 #include "config_components.h"
80 #define EBML_UNKNOWN_LENGTH UINT64_MAX
81 #define NEEDS_CHECKING 2
85 #define SKIP_THRESHOLD 1024 * 1024
88 #define UNKNOWN_EQUIV 50 * 1024
144 typedef struct Ebml {
429 #define CHILD_OF(parent) { .def = { .n = parent } }
826 uint32_t
id, int64_t position)
855 "Seek to desired resync point failed. Seeking to "
856 "earliest point available instead.\n");
858 last_pos + 1), SEEK_SET);
894 int max_size, uint64_t *number,
int eof_forbidden)
908 if (!total ||
read > max_size) {
912 "0x00 at pos %"PRId64
" (0x%"PRIx64
") invalid as first byte "
913 "of an EBML number\n",
pos,
pos);
916 "Length %d indicated by an EBML number's first byte 0x%02x "
917 "at pos %"PRId64
" (0x%"PRIx64
") exceeds max length %d.\n",
926 total = (total << 8) |
avio_r8(pb);
941 "Read error at pos. %"PRIu64
" (0x%"PRIx64
")\n",
947 "at pos. %"PRIu64
" (0x%"PRIx64
")\n",
pos,
pos);
962 if (res > 0 && *number + 1 == 1ULL << (7 * res))
972 uint64_t default_value, uint64_t *num)
977 *num = default_value;
983 *num = (*num << 8) |
avio_r8(pb);
993 int64_t default_value, int64_t *num)
998 *num = default_value;
1005 *num = ((uint64_t)*num << 8) |
avio_r8(pb);
1016 double default_value,
double *num)
1019 *num = default_value;
1021 }
else if (
size == 4) {
1023 }
else if (
size == 8) {
1036 const char *default_value,
char **
str)
1041 if (
size == 0 && default_value) {
1095 uint64_t length, int64_t
pos)
1107 level->length = length;
1127 *num = unum - ((1LL << (7 * res - 1)) - 1);
1158 *(uint64_t *)dst =
syntax[
i].def.u;
1161 *(int64_t *) dst =
syntax[
i].def.i;
1164 *(
double *) dst =
syntax[
i].def.f;
1197 return id && (
bits + 7) / 8 == (8 -
bits % 8);
1205 uint32_t
id, int64_t
pos)
1277 "at pos. %"PRIu64
" (0x%"PRIx64
")\n",
pos,
pos);
1284 pos_alt =
pos + res;
1307 "%"PRId64
"\n",
id,
pos);
1317 if ((
unsigned)
list->nb_elem + 1 >= UINT_MAX /
syntax->list_elem_size)
1320 &
list->alloc_elem_size,
1321 (
list->nb_elem + 1) *
syntax->list_elem_size);
1324 list->elem = newelem;
1341 uint64_t elem_end = pos_alt + length,
1344 if (elem_end < level_end) {
1346 }
else if (elem_end == level_end) {
1350 "Element at 0x%"PRIx64
" ending at 0x%"PRIx64
" exceeds "
1351 "containing master element ending at 0x%"PRIx64
"\n",
1352 pos, elem_end, level_end);
1359 "at 0x%"PRIx64
" inside parent with finite size\n",
pos);
1369 "Found unknown-length element 0x%"PRIX32
" other than "
1370 "a cluster at 0x%"PRIx64
". Spec-incompliant, but "
1371 "parsing will nevertheless be attempted.\n",
id,
pos);
1378 if (max_lengths[
syntax->type] && length > max_lengths[
syntax->type]) {
1381 "Invalid length 0x%"PRIx64
" > 0x%"PRIx64
" for element "
1382 "with ID 0x%"PRIX32
" at 0x%"PRIx64
"\n",
1383 length, max_lengths[
syntax->type],
id,
pos);
1386 "Element with ID 0x%"PRIX32
" at pos. 0x%"PRIx64
" has "
1387 "unknown length, yet the length of an element of its "
1388 "type must be known.\n",
id,
pos);
1391 "Found unknown-length element with ID 0x%"PRIX32
" at "
1392 "pos. 0x%"PRIx64
" for which no syntax for parsing is "
1393 "available.\n",
id,
pos);
1430 "Unknown element %"PRIX32
" at pos. 0x%"PRIx64
" with "
1431 "length 0x%"PRIx64
" considered as invalid data. Last "
1432 "known good position 0x%"PRIx64
", %d unknown elements"
1478 if (!level1_elem->
pos) {
1481 }
else if (level1_elem->
pos !=
pos)
1499 if ((res2 =
avio_skip(pb, length - 1)) >= 0) {
1538 if (elem->
count != UINT_MAX)
1561 void *data_off = (
char *)
data +
syntax[
i].data_offset;
1572 if (
syntax[
i].list_elem_size) {
1574 char *ptr =
list->elem;
1575 for (j = 0; j <
list->nb_elem;
1576 j++, ptr +=
syntax[
i].list_elem_size)
1580 list->alloc_elem_size = 0;
1595 int len_mask = 0x80,
size = 1, n = 1,
i;
1603 while (
size <= 8 && !(total & len_mask)) {
1609 total &= (len_mask - 1);
1611 total = (total << 8) | p->
buf[4 + n++];
1613 if (total + 1 == 1ULL << (7 *
size)){
1628 if (total < probelen)
1630 for (n = 4 +
size; n <= 4 +
size + total - probelen; n++)
1646 if (tracks[
i].num == num)
1657 uint8_t *
data = *buf;
1658 int isize = *buf_size;
1659 uint8_t *pkt_data =
NULL;
1661 int pkt_size = isize;
1665 if (pkt_size >= 10000000
U)
1668 switch (encodings[0].compression.algo) {
1674 if (header_size && !
header) {
1682 pkt_size = isize + header_size;
1687 memcpy(pkt_data,
header, header_size);
1688 memcpy(pkt_data + header_size,
data, isize);
1694 olen = pkt_size *= 3;
1701 pkt_data = newpktdata;
1713 z_stream zstream = { 0 };
1714 if (!pkt_size || inflateInit(&zstream) != Z_OK)
1716 zstream.next_in =
data;
1717 zstream.avail_in = isize;
1722 inflateEnd(&zstream);
1726 pkt_data = newpktdata;
1727 zstream.avail_out = pkt_size - zstream.total_out;
1728 zstream.next_out = pkt_data + zstream.total_out;
1730 }
while (
result == Z_OK && pkt_size < 10000000);
1731 pkt_size = zstream.total_out;
1732 inflateEnd(&zstream);
1733 if (
result != Z_STREAM_END) {
1734 if (
result == Z_MEM_ERROR)
1746 bz_stream bzstream = { 0 };
1747 if (!pkt_size || BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
1749 bzstream.next_in =
data;
1750 bzstream.avail_in = isize;
1755 BZ2_bzDecompressEnd(&bzstream);
1759 pkt_data = newpktdata;
1760 bzstream.avail_out = pkt_size - bzstream.total_out_lo32;
1761 bzstream.next_out = pkt_data + bzstream.total_out_lo32;
1762 result = BZ2_bzDecompress(&bzstream);
1763 }
while (
result == BZ_OK && pkt_size < 10000000);
1764 pkt_size = bzstream.total_out_lo32;
1765 BZ2_bzDecompressEnd(&bzstream);
1766 if (
result != BZ_STREAM_END) {
1767 if (
result == BZ_MEM_ERROR)
1783 *buf_size = pkt_size;
1798 for (
i = 0;
i <
list->nb_elem;
i++) {
1799 const char *lang = tags[
i].
lang &&
1800 strcmp(tags[
i].lang,
"und") ? tags[
i].
lang :
NULL;
1802 if (!tags[
i].
name) {
1810 if (tags[
i].def || !lang) {
1812 if (tags[
i].
sub.nb_elem)
1819 if (tags[
i].
sub.nb_elem)
1833 if (tags[
i].target.attachuid) {
1837 if (attachment[j].
uid == tags[
i].target.attachuid &&
1838 attachment[j].stream) {
1840 &attachment[j].stream->metadata,
NULL);
1846 "The tags at index %d refer to a "
1847 "non-existent attachment %"PRId64
".\n",
1848 i, tags[
i].target.attachuid);
1850 }
else if (tags[
i].target.chapteruid) {
1854 if (chapter[j].
uid == tags[
i].target.chapteruid &&
1855 chapter[j].chapter) {
1857 &chapter[j].chapter->metadata,
NULL);
1863 "The tags at index %d refer to a non-existent chapter "
1865 i, tags[
i].target.chapteruid);
1867 }
else if (tags[
i].target.trackuid) {
1871 if (track[j].
uid == tags[
i].target.trackuid &&
1874 &track[j].stream->metadata,
NULL);
1880 "The tags at index %d refer to a non-existent track "
1882 i, tags[
i].target.trackuid);
1886 tags[
i].target.type);
1905 "Max EBML element depth (%d) reached, "
1938 for (
i = 0;
i < seekhead_list->
nb_elem;
i++) {
1940 uint32_t
id = seekheads[
i].
id;
1948 if (!elem || elem->
parsed)
1971 uint64_t index_scale = 1;
1977 index_list = &matroska->
index;
1988 for (j = 0; j < pos_list->
nb_elem; j++) {
1991 if (track && track->
stream)
2021 static const char *
const aac_profiles[] = {
"MAIN",
"LC",
"SSR" };
2067 int block_last, block_type, block_size;
2073 if (block_size >
size)
2082 chmask =
av_dict_get(dict,
"WAVEFORMATEXTENSIBLE_CHANNEL_MASK",
NULL, 0);
2087 "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
2103 int minor, micro, bttb = 0;
2108 bttb = (
minor >= 36 && minor <= 51 && micro >= 100);
2110 switch (field_order) {
2129 int *h_width,
int *h_height)
2131 switch (stereo_mode) {
2156 int has_mastering_primaries, has_mastering_luminance;
2161 mastering_meta = &
color->mastering_meta;
2163 has_mastering_primaries =
2164 mastering_meta->
r_x > 0 && mastering_meta->
r_y > 0 &&
2165 mastering_meta->
g_x > 0 && mastering_meta->
g_y > 0 &&
2166 mastering_meta->
b_x > 0 && mastering_meta->
b_y > 0 &&
2190 (
color->chroma_siting_vert - 1) << 7);
2199 (uint8_t *)metadata,
size);
2208 if (has_mastering_primaries || has_mastering_luminance) {
2217 if (has_mastering_primaries) {
2228 if (has_mastering_luminance) {
2241 double pitch = proj->
pitch, yaw = proj->
yaw, roll = proj->
roll;
2245 if (pitch == 0.0 && yaw == 0.0 && roll == 0.0)
2250 if (pitch != 0.0 || (yaw != 0.0 && yaw != 180.0 && yaw != -180.0) ||
2253 "projection in stream %u (yaw %f, pitch %f, roll %f)\n",
2254 st->
index, yaw, pitch, roll);
2280 const uint8_t *priv_data = mkv_projection->
private.
data;
2282 size_t spherical_size;
2283 uint32_t l = 0, t = 0,
r = 0,
b = 0;
2284 uint32_t padding = 0;
2287 if (mkv_projection->
private.
size && priv_data[0] != 0) {
2302 if (
b >= UINT_MAX - t ||
r >= UINT_MAX - l) {
2304 "Invalid bounding rectangle coordinates "
2305 "%"PRIu32
",%"PRIu32
",%"PRIu32
",%"PRIu32
"\n",
2314 if (l || t ||
r ||
b)
2327 "Unknown spherical cubemap layout %"PRIu32
"\n",
layout);
2331 padding =
AV_RB32(priv_data + 8);
2339 "Unknown spherical metadata type %"PRIu64
"\n",
2383 for (
int i = 0;
i < mappings_list->
nb_elem;
i++) {
2386 switch (mapping->
type) {
2387 case MKBETAG(
'd',
'v',
'c',
'C'):
2388 case
MKBETAG(
'd',
'v',
'v',
'C'):
2395 "Unknown block additional mapping type 0x%"PRIx64
", value %"PRIu64
", name \"%s\"\n",
2443 uint8_t *extradata =
NULL;
2444 int extradata_size = 0;
2445 int extradata_offset = 0;
2450 char* key_id_base64 =
NULL;
2459 "Unknown or unsupported track type %"PRIu64
"\n",
2478 "Invalid sample rate %f, defaulting to 8000 instead.\n",
2486 if (default_duration > UINT64_MAX || default_duration < 0) {
2488 "Invalid frame rate %e. Cannot calculate default duration.\n",
2504 if (encodings_list->
nb_elem > 1) {
2506 "Multiple combined encodings not supported");
2507 }
else if (encodings_list->
nb_elem == 1) {
2508 if (encodings[0].
type) {
2509 if (encodings[0].encryption.key_id.size > 0) {
2512 const int b64_size =
AV_BASE64_SIZE(encodings[0].encryption.key_id.size);
2514 if (key_id_base64 ==
NULL)
2518 encodings[0].encryption.key_id.data,
2519 encodings[0].encryption.key_id.size);
2521 encodings[0].
scope = 0;
2523 "Unsupported encoding type");
2534 encodings[0].
scope = 0;
2536 "Unsupported encoding type");
2546 "Failed to decode codec private data\n");
2565 encodings[0].
scope & 1 &&
2584 if (key_id_base64) {
2590 if (!strcmp(track->
codec_id,
"V_MS/VFW/FOURCC") &&
2601 extradata_offset = 40;
2602 }
else if (!strcmp(track->
codec_id,
"A_MS/ACM") &&
2616 }
else if (!strcmp(track->
codec_id,
"A_QUICKTIME")
2620 uint16_t sample_size;
2626 if (sample_size == 8) {
2629 }
else if (sample_size == 16) {
2638 }
else if (!strcmp(track->
codec_id,
"V_QUICKTIME") &&
2694 extradata[0] = (
profile << 3) | ((sri & 0x0E) >> 1);
2695 extradata[1] = ((sri & 0x01) << 7) | (track->
audio.
channels << 3);
2696 if (strstr(track->
codec_id,
"SBR")) {
2698 extradata[2] = 0x56;
2699 extradata[3] = 0xE5;
2700 extradata[4] = 0x80 | (sri << 3);
2713 AV_WB32(extradata, extradata_size);
2714 memcpy(&extradata[4],
"alac", 4);
2723 "Too large audio channel number %"PRIu64
2724 " or bitdepth %"PRIu64
". Skipping track.\n",
2733 extradata_size = 22;
2738 bytestream_put_be32(&ptr,
AV_RB32(
"TTA1"));
2739 bytestream_put_le16(&ptr, 1);
2750 extradata_offset = 26;
2765 flavor = bytestream_get_be16(&ptr);
2784 static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
2793 extradata_offset = 78;
2805 "in absence of valid CodecPrivate.\n");
2821 switch (data_component_id) {
2825 if (component_tag >= 0x30 && component_tag <= 0x37) {
2832 if (component_tag == 0x87) {
2842 "Unknown ARIB caption profile utilized: %02x / %04x\n",
2843 component_tag, data_component_id);
2851 "Unknown/unsupported AVCodecID %s.\n", track->
codec_id);
2855 "Track TimestampScale too small %f, assuming 1.0.\n",
2860 1000 * 1000 * 1000);
2869 if (strcmp(track->
language,
"und"))
2902 int display_width_mul = 1;
2903 int display_height_mul = 1;
2937 #if FF_API_R_FRAME_RATE
2957 snprintf(buf,
sizeof(buf),
"%s_%d",
2960 if (
planes[j].
uid == tracks[k].
uid && tracks[k].stream) {
2962 "stereo_mode", buf, 0);
3000 (
AVRational){1, st->codecpar->codec_id == AV_CODEC_ID_OPUS ?
3001 48000 : st->codecpar->sample_rate});
3011 if (!strcmp(track->
codec_id,
"D_WEBVTT/CAPTIONS")) {
3013 }
else if (!strcmp(track->
codec_id,
"D_WEBVTT/DESCRIPTIONS")) {
3015 }
else if (!strcmp(track->
codec_id,
"D_WEBVTT/METADATA")) {
3041 uint64_t max_start = 0;
3056 ebml.
max_size >
sizeof(uint64_t) ||
3060 "EBML version %"PRIu64
", doctype %s, doc version %"PRIu64,
3066 "EBML header using unsupported features\n"
3067 "(EBML version %"PRIu64
", doctype %s, doc version %"PRIu64
")\n",
3119 attachments = attachments_list->
elem;
3120 for (j = 0; j < attachments_list->
nb_elem; j++) {
3121 if (!(attachments[j].filename && attachments[j].mime &&
3122 attachments[j].bin.data && attachments[j].bin.size > 0)) {
3141 attachments[j].
stream = st;
3152 attachments[j].bin.size);
3164 chapters = chapters_list->
elem;
3167 (max_start == 0 || chapters[
i].start > max_start)) {
3173 max_start = chapters[
i].
start;
3221 uint32_t lace_size[256],
int *laces)
3224 uint8_t *
data = *buf;
3228 lace_size[0] =
size;
3244 for (n = 0; n < *laces - 1; n++) {
3252 lace_size[n] +=
temp;
3255 }
while (
temp == 0xff);
3260 lace_size[n] =
size - total;
3265 if (
size % (*laces))
3267 for (n = 0; n < *laces; n++)
3268 lace_size[n] =
size / *laces;
3285 total = lace_size[0] = num;
3287 for (n = 1; n < *laces - 1; n++) {
3293 if (lace_size[n - 1] + snum > (uint64_t)INT_MAX)
3296 lace_size[n] = lace_size[n - 1] + snum;
3297 total += lace_size[n];
3305 lace_size[*laces - 1] =
size - total;
3317 uint8_t *
data,
int size, uint64_t timecode,
3332 if (
size < cfs *
h / 2) {
3334 "Corrupt int4 RM-style audio packet size\n");
3337 for (x = 0; x <
h / 2; x++)
3338 memcpy(track->
audio.
buf + x * 2 *
w + y * cfs,
3339 data + x * cfs, cfs);
3343 "Corrupt sipr RM-style audio packet size\n");
3350 "Corrupt generic RM-style audio packet size\n");
3353 for (x = 0; x <
w /
sps; x++)
3355 sps * (
h * x + ((
h + 1) / 2) * (y & 1) + (y >> 1)),
3396 uint8_t *dst =
NULL;
3414 while (srclen >= 8) {
3424 multiblock = (
flags & 0x1800) != 0x1800;
3436 if (blocksize > srclen) {
3447 dstlen += blocksize + 32;
3458 memcpy(dst +
offset + 32,
src, blocksize);
3461 srclen -= blocksize;
3462 offset += blocksize + 32;
3481 int dstlen = *
size + 8;
3489 memcpy(dst + 8, *
data, dstlen - 8);
3501 uint8_t *
data,
int data_len,
3507 uint8_t *
id, *settings, *text, *buf;
3508 int id_len, settings_len, text_len;
3516 q =
data + data_len;
3521 if (*p ==
'\r' || *p ==
'\n') {
3530 if (p >= q || *p !=
'\n')
3537 if (*p ==
'\r' || *p ==
'\n') {
3538 settings_len = p - settings;
3546 if (p >= q || *p !=
'\n')
3552 while (text_len > 0) {
3553 const int len = text_len - 1;
3554 const uint8_t
c = p[
len];
3555 if (
c !=
'\r' &&
c !=
'\n')
3568 memcpy(
pkt->
data, text, text_len);
3578 memcpy(buf,
id, id_len);
3581 if (settings_len > 0) {
3589 memcpy(buf, settings, settings_len);
3616 uint64_t timecode, uint64_t lace_duration,
3618 uint8_t *additional, uint64_t additional_id,
int additional_size,
3619 int64_t discard_padding)
3621 uint8_t *pkt_data =
data;
3629 "Error parsing a wavpack block.\n");
3642 "Error parsing a prores block.\n");
3650 if (!pkt_size && !additional_size)
3669 if (additional_size > 0) {
3672 additional_size + 8);
3677 AV_WB64(side_data, additional_id);
3678 memcpy(side_data + 8, additional, additional_size);
3681 if (discard_padding) {
3692 if (discard_padding > 0) {
3693 AV_WL32(side_data + 4, discard_padding);
3695 AV_WL32(side_data, -discard_padding);
3722 int size, int64_t
pos, uint64_t cluster_time,
3724 uint8_t *additional, uint64_t additional_id,
int additional_size,
3725 int64_t cluster_pos, int64_t discard_padding)
3733 uint32_t lace_size[256];
3734 int n,
flags, laces = 0;
3736 int trust_default_duration;
3748 if (!track ||
size < 3)
3751 if (!(st = track->
stream)) {
3753 "No stream associated to TrackNumber %"PRIu64
". "
3754 "Ignoring Block with this TrackNumber.\n", num);
3760 if (block_duration > INT64_MAX)
3761 block_duration = INT64_MAX;
3770 if (cluster_time != (uint64_t) -1 &&
3771 (block_time >= 0 || cluster_time >= -block_time)) {
3772 uint64_t timecode_cluster_in_track_tb = (
double) cluster_time / track->
time_scale;
3775 timecode < track->end_timecode)
3793 else if (!
ffstream(st)->skip_to_keyframe) {
3800 &pb.
pub, lace_size, &laces);
3811 trust_default_duration = 0;
3815 if (!block_duration && trust_default_duration)
3818 if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time))
3822 for (n = 0; n < laces; n++) {
3823 int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces;
3824 uint8_t *out_data =
data;
3849 timecode, lace_duration,
3859 additional, additional_id, additional_size,
3866 timecode = lace_duration ? timecode + lace_duration :
AV_NOPTS_VALUE;
3898 if (res >= 0 &&
block->bin.size > 0) {
3900 uint8_t* additional =
block->additional.size > 0 ?
3907 block->additional.size, cluster->
pos,
3908 block->discard_padding);
3918 "end of segment.\n");
3950 int64_t timestamp,
int flags)
3954 AVStream *st =
s->streams[stream_index];
4033 #if CONFIG_WEBM_DASH_MANIFEST_DEMUXER
4035 int64_t start_time_ns;
4036 int64_t end_time_ns;
4037 int64_t start_offset;
4046 static CueDesc get_cue_desc(
AVFormatContext *
s, int64_t ts, int64_t cues_start) {
4055 return (CueDesc) {-1, -1, -1, -1};
4056 for (
i = 1;
i < nb_index_entries;
i++) {
4057 if (index_entries[
i - 1].timestamp * matroska->
time_scale <= ts &&
4058 index_entries[
i].timestamp * matroska->
time_scale > ts) {
4063 if (index_entries[
i].timestamp > matroska->
duration)
4064 return (CueDesc) {-1, -1, -1, -1};
4067 if (
i != nb_index_entries - 1) {
4086 int64_t cluster_pos, before_pos;
4099 uint64_t cluster_id, cluster_length;
4105 if (
read < 0 || cluster_id != 0xF43B675)
4119 cluster_pos += 4 +
read + cluster_length;
4132 static int buffer_size_after_time_downloaded(int64_t time_ns,
double search_sec, int64_t
bps,
4133 double min_buffer,
double*
buffer,
4137 double nano_seconds_per_second = 1000000000.0;
4138 double time_sec = time_ns / nano_seconds_per_second;
4140 int64_t time_to_search_ns = (int64_t)(search_sec * nano_seconds_per_second);
4141 int64_t end_time_ns = time_ns + time_to_search_ns;
4142 double sec_downloaded = 0.0;
4143 CueDesc desc_curr = get_cue_desc(
s, time_ns, cues_start);
4144 if (desc_curr.start_time_ns == -1)
4146 *sec_to_download = 0.0;
4149 if (time_ns > desc_curr.start_time_ns) {
4150 int64_t cue_nano = desc_curr.end_time_ns - time_ns;
4151 double percent = (
double)(cue_nano) / (desc_curr.end_time_ns - desc_curr.start_time_ns);
4152 double cueBytes = (desc_curr.end_offset - desc_curr.start_offset) * percent;
4153 double timeToDownload = (cueBytes * 8.0) /
bps;
4155 sec_downloaded += (cue_nano / nano_seconds_per_second) - timeToDownload;
4156 *sec_to_download += timeToDownload;
4159 if (desc_curr.end_time_ns >= end_time_ns) {
4160 double desc_end_time_sec = desc_curr.end_time_ns / nano_seconds_per_second;
4161 double percent_to_sub = search_sec / (desc_end_time_sec - time_sec);
4162 sec_downloaded = percent_to_sub * sec_downloaded;
4163 *sec_to_download = percent_to_sub * *sec_to_download;
4166 if ((sec_downloaded + *
buffer) <= min_buffer) {
4171 desc_curr = get_cue_desc(
s, desc_curr.end_time_ns, cues_start);
4174 while (desc_curr.start_time_ns != -1) {
4175 int64_t desc_bytes = desc_curr.end_offset - desc_curr.start_offset;
4176 int64_t desc_ns = desc_curr.end_time_ns - desc_curr.start_time_ns;
4177 double desc_sec = desc_ns / nano_seconds_per_second;
4178 double bits = (desc_bytes * 8.0);
4179 double time_to_download =
bits /
bps;
4181 sec_downloaded += desc_sec - time_to_download;
4182 *sec_to_download += time_to_download;
4184 if (desc_curr.end_time_ns >= end_time_ns) {
4185 double desc_end_time_sec = desc_curr.end_time_ns / nano_seconds_per_second;
4186 double percent_to_sub = search_sec / (desc_end_time_sec - time_sec);
4187 sec_downloaded = percent_to_sub * sec_downloaded;
4188 *sec_to_download = percent_to_sub * *sec_to_download;
4190 if ((sec_downloaded + *
buffer) <= min_buffer)
4195 if ((sec_downloaded + *
buffer) <= min_buffer) {
4200 desc_curr = get_cue_desc(
s, desc_curr.end_time_ns, cues_start);
4213 static int64_t webm_dash_manifest_compute_bandwidth(
AVFormatContext *
s, int64_t cues_start)
4218 double bandwidth = 0.0;
4221 int64_t prebuffer_ns = 1000000000;
4223 double nano_seconds_per_second = 1000000000.0;
4224 int64_t prebuffered_ns = time_ns + prebuffer_ns;
4225 double prebuffer_bytes = 0.0;
4226 int64_t temp_prebuffer_ns = prebuffer_ns;
4227 int64_t pre_bytes, pre_ns;
4228 double pre_sec, prebuffer, bits_per_second;
4229 CueDesc desc_beg = get_cue_desc(
s, time_ns, cues_start);
4232 CueDesc desc_end = desc_beg;
4236 while (desc_end.start_time_ns != -1 && desc_end.end_time_ns < prebuffered_ns) {
4238 prebuffer_bytes += desc_end.end_offset - desc_end.start_offset;
4239 temp_prebuffer_ns -= desc_end.end_time_ns - desc_end.start_time_ns;
4240 desc_end = get_cue_desc(
s, desc_end.end_time_ns, cues_start);
4242 if (desc_end.start_time_ns == -1) {
4246 bits_per_second = 0.0;
4250 pre_bytes = desc_end.end_offset - desc_end.start_offset;
4251 pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
4254 pre_sec = pre_ns / nano_seconds_per_second;
4256 pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
4258 prebuffer = prebuffer_ns / nano_seconds_per_second;
4261 bits_per_second = 0.0;
4263 int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
4264 int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
4265 double desc_sec, calc_bits_per_second, percent, mod_bits_per_second;
4266 if (desc_bytes <= 0)
4269 desc_sec = desc_ns / nano_seconds_per_second;
4270 calc_bits_per_second = (desc_bytes * 8) / desc_sec;
4273 percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
4274 mod_bits_per_second = calc_bits_per_second * percent;
4276 if (prebuffer < desc_sec) {
4282 int64_t
bps = (int64_t)(mod_bits_per_second) + 1;
4283 const double min_buffer = 0.0;
4284 double buffer = prebuffer;
4285 double sec_to_download = 0.0;
4287 int rv = buffer_size_after_time_downloaded(prebuffered_ns, search_sec,
bps,
4288 min_buffer, &
buffer, &sec_to_download,
4292 }
else if (rv == 0) {
4298 desc_end = get_cue_desc(
s, desc_end.end_time_ns, cues_start);
4299 }
while (desc_end.start_time_ns != -1);
4301 if (bandwidth < bits_per_second) bandwidth = bits_per_second;
4303 return (int64_t)bandwidth;
4315 int64_t cues_start = -1, cues_end = -1, before_pos, bandwidth;
4324 if (
i >= seekhead_list->
nb_elem)
return -1;
4328 if (
avio_seek(matroska->
ctx->
pb, cues_start, SEEK_SET) == cues_start) {
4332 uint64_t cues_length, cues_id;
4340 cues_end = cues_start + 4 + bytes_read + cues_length - 1;
4343 if (cues_start == -1 || cues_end == -1)
return -1;
4359 if (cues_start <= init_range)
4363 bandwidth = webm_dash_manifest_compute_bandwidth(
s, cues_start);
4364 if (bandwidth < 0)
return -1;
4380 bprint.str[--bprint.len] =
'\0';