#include "dash.h"
#define INITIAL_BUFFER_SIZE 32768
+#define MAX_MANIFEST_SIZE 50 * 1024
+#define DEFAULT_MANIFEST_SIZE 8 * 1024
struct fragment {
int64_t url_offset;
char *str_end_offset;
char *str_offset = av_strtok(range, "-", &str_end_offset);
seg->url_offset = strtoll(str_offset, NULL, 10);
- seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset;
+ seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset + 1;
}
return seg;
int close_in = 0;
uint8_t *new_url = NULL;
int64_t filesize = 0;
- char *buffer = NULL;
+ AVBPrint buf;
AVDictionary *opts = NULL;
xmlDoc *doc = NULL;
xmlNodePtr root_element = NULL;
}
filesize = avio_size(in);
- if (filesize <= 0) {
- filesize = 8 * 1024;
+ if (filesize > MAX_MANIFEST_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Manifest too large: %"PRId64"\n", filesize);
+ return AVERROR_INVALIDDATA;
}
- buffer = av_mallocz(filesize);
- if (!buffer) {
- av_free(c->base_url);
- return AVERROR(ENOMEM);
- }
+ av_bprint_init(&buf, (filesize > 0) ? filesize + 1 : DEFAULT_MANIFEST_SIZE, AV_BPRINT_SIZE_UNLIMITED);
- filesize = avio_read(in, buffer, filesize);
- if (filesize <= 0) {
- av_log(s, AV_LOG_ERROR, "Unable to read to offset '%s'\n", url);
- ret = AVERROR_INVALIDDATA;
+ if ((ret = avio_read_to_bprint(in, &buf, MAX_MANIFEST_SIZE)) < 0 ||
+ !avio_feof(in) ||
+ (filesize = buf.len) == 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to read to manifest '%s'\n", url);
+ if (ret == 0)
+ ret = AVERROR_INVALIDDATA;
} else {
LIBXML_TEST_VERSION
- doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0);
+ doc = xmlReadMemory(buf.str, filesize, c->base_url, NULL, 0);
root_element = xmlDocGetRootElement(doc);
node = root_element;
}
av_free(new_url);
- av_free(buffer);
+ av_bprint_finalize(&buf, NULL);
if (close_in) {
avio_close(in);
}
pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
+ pls->ctx->interrupt_callback = s->interrupt_callback;
ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
st->id = i;
avcodec_parameters_copy(st->codecpar, ist->codecpar);
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+
+ // copy disposition
+ st->disposition = ist->disposition;
+
+ // copy side data
+ for (int i = 0; i < ist->nb_side_data; i++) {
+ const AVPacketSideData *sd_src = &ist->side_data[i];
+ uint8_t *dst_data;
+
+ dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
+ if (!dst_data)
+ return AVERROR(ENOMEM);
+ memcpy(dst_data, sd_src->data, sd_src->size);
+ }
}
return 0;