static int webm_chunk_write_header(AVFormatContext *s) { WebMChunkContext *wc = s->priv_data; AVFormatContext *oc = NULL; int ret; // DASH Streams can only have either one track per file. if (s->nb_streams != 1) { return AVERROR_INVALIDDATA; } wc->chunk_index = wc->chunk_start_index; wc->oformat = av_guess_format("webm", s->filename, "video/webm"); if (!wc->oformat) return AVERROR_MUXER_NOT_FOUND; ret = chunk_mux_init(s); if (ret < 0) return ret; oc = wc->avf; ret = get_chunk_filename(s, 1, oc->filename); if (ret < 0) return ret; ret = ffio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) return ret; oc->pb->seekable = 0; ret = oc->oformat->write_header(oc); if (ret < 0) return ret; avio_close(oc->pb); return 0; }
static int chunk_end(AVFormatContext *s) { WebMChunkContext *wc = s->priv_data; AVFormatContext *oc = wc->avf; int ret; int buffer_size; uint8_t *buffer; AVIOContext *pb; char filename[MAX_FILENAME_SIZE]; if (wc->chunk_start_index == wc->chunk_index) return 0; // Flush the cluster in WebM muxer. oc->oformat->write_packet(oc, NULL); buffer_size = avio_close_dyn_buf(oc->pb, &buffer); ret = get_chunk_filename(s, 0, filename); if (ret < 0) goto fail; ret = ffio_open_whitelist(&pb, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); if (ret < 0) goto fail; avio_write(pb, buffer, buffer_size); ret = avio_close(pb); if (ret < 0) goto fail; oc->pb = NULL; fail: av_free(buffer); return (ret < 0) ? ret : 0; }
static int import_pem(URLContext *h, char *path, CFArrayRef *array) { AVIOContext *s = NULL; CFDataRef data = NULL; int64_t ret = 0; char *buf = NULL; SecExternalFormat format = kSecFormatPEMSequence; SecExternalFormat type = kSecItemTypeAggregate; CFStringRef pathStr = CFStringCreateWithCString(NULL, path, 0x08000100); if (!pathStr) { ret = AVERROR(ENOMEM); goto end; } if ((ret = ffio_open_whitelist(&s, path, AVIO_FLAG_READ, &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist)) < 0) goto end; if ((ret = avio_size(s)) < 0) goto end; if (ret == 0) { ret = AVERROR_INVALIDDATA; goto end; } if (!(buf = av_malloc(ret))) { ret = AVERROR(ENOMEM); goto end; } if ((ret = avio_read(s, buf, ret)) < 0) goto end; data = CFDataCreate(kCFAllocatorDefault, buf, ret); if (SecItemImport(data, pathStr, &format, &type, 0, NULL, NULL, array) != noErr || !array) { ret = AVERROR_UNKNOWN; goto end; } if (CFArrayGetCount(*array) == 0) { ret = AVERROR_INVALIDDATA; goto end; } end: av_free(buf); if (pathStr) CFRelease(pathStr); if (data) CFRelease(data); if (s) avio_close(s); return ret; }
static int parse_playlist(URLContext *h, const char *url) { HLSContext *s = h->priv_data; AVIOContext *in; int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0; int64_t duration = 0; char line[1024]; const char *ptr; if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist)) < 0) return ret; ff_get_chomp_line(in, line, sizeof(line)); if (strcmp(line, "#EXTM3U")) { ret = AVERROR_INVALIDDATA; goto fail; } free_segment_list(s); s->finished = 0; while (!avio_feof(in)) { ff_get_chomp_line(in, line, sizeof(line)); if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) { struct variant_info info = {{0}}; is_variant = 1; ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args, &info); bandwidth = atoi(info.bandwidth); } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { s->target_duration = atoi(ptr) * AV_TIME_BASE; } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { s->start_seq_no = atoi(ptr); } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { s->finished = 1; } else if (av_strstart(line, "#EXTINF:", &ptr)) { is_segment = 1; duration = atof(ptr) * AV_TIME_BASE; } else if (av_strstart(line, "#", NULL)) { continue; } else if (line[0]) { if (is_segment) { struct segment *seg = av_malloc(sizeof(struct segment)); if (!seg) { ret = AVERROR(ENOMEM); goto fail; } seg->duration = duration; ff_make_absolute_url(seg->url, sizeof(seg->url), url, line); dynarray_add(&s->segments, &s->n_segments, seg); is_segment = 0; } else if (is_variant) { struct variant *var = av_malloc(sizeof(struct variant)); if (!var) { ret = AVERROR(ENOMEM); goto fail; } var->bandwidth = bandwidth; ff_make_absolute_url(var->url, sizeof(var->url), url, line); dynarray_add(&s->variants, &s->n_variants, var); is_variant = 0; } } } s->last_load_time = av_gettime_relative(); fail: avio_close(in); return ret; }