/* return -1 if no image found */ static int find_image_range(int *pfirst_index, int *plast_index, const char *path) { char buf[1024]; int range, last_index, range1, first_index; /* find the first image */ for(first_index = 0; first_index < 5; first_index++) { if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { *pfirst_index = *plast_index = 1; if(url_exist(buf)) return 0; return -1; } if (url_exist(buf)) break; } if (first_index == 5) goto fail; /* find the last image */ last_index = first_index; for(;;) { range = 0; for(;;) { if (!range) range1 = 1; else range1 = 2 * range; if (av_get_frame_filename(buf, sizeof(buf), path, last_index + range1) < 0) goto fail; if (!url_exist(buf)) break; range = range1; /* just in case... */ if (range >= (1 << 30)) goto fail; } /* we are sure than image last_index + range exists */ if (!range) break; last_index += range; } *pfirst_index = first_index; *plast_index = last_index; return 0; fail: return -1; }
/** * Get index range of image files matched by path. * * @param pfirst_index pointer to index updated with the first number in the range * @param plast_index pointer to index updated with the last number in the range * @param path path which has to be matched by the image files in the range * @param start_index minimum accepted value for the first index in the range * @return -1 if no image file could be found */ static int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index, const char *path, int start_index, int start_index_range) { char buf[1024]; int range, last_index, range1, first_index; /* find the first image */ for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { *pfirst_index = *plast_index = 1; if (pb || avio_check(buf, AVIO_FLAG_READ) > 0) return 0; return -1; } if (avio_check(buf, AVIO_FLAG_READ) > 0) break; } if (first_index == start_index + start_index_range) goto fail; /* find the last image */ last_index = first_index; for (;;) { range = 0; for (;;) { if (!range) range1 = 1; else range1 = 2 * range; if (av_get_frame_filename(buf, sizeof(buf), path, last_index + range1) < 0) goto fail; if (avio_check(buf, AVIO_FLAG_READ) <= 0) break; range = range1; /* just in case... */ if (range >= (1 << 30)) goto fail; } /* we are sure than image last_index + range exists */ if (!range) break; last_index += range; } *pfirst_index = first_index; *plast_index = last_index; return 0; fail: return -1; }
static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoData *s = s1->priv_data; char filename[1024]; int i; int size[3]={0}, ret[3]={0}; ByteIOContext f1[3], *f[3]= {&f1[0], &f1[1], &f1[2]}; AVCodecContext *codec= s1->streams[0]->codec; if (!s->is_pipe) { /* loop over input */ if (s1->loop_input && s->img_number > s->img_last) { s->img_number = s->img_first; } if (av_get_frame_filename(filename, sizeof(filename), s->path, s->img_number)<0 && s->img_number > 1) return AVERROR_IO; for(i=0; i<3; i++){ if (url_fopen(f[i], filename, URL_RDONLY) < 0) return AVERROR_IO; size[i]= url_fsize(f[i]); if(codec->codec_id != CODEC_ID_RAWVIDEO) break; filename[ strlen(filename) - 1 ]= 'U' + i; } if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width) infer_size(&codec->width, &codec->height, size[0]); } else { f[0] = &s1->pb; if (url_feof(f[0])) return AVERROR_IO; size[0]= 4096; } av_new_packet(pkt, size[0] + size[1] + size[2]); pkt->stream_index = 0; pkt->flags |= PKT_FLAG_KEY; pkt->size= 0; for(i=0; i<3; i++){ if(size[i]){ ret[i]= get_buffer(f[i], pkt->data + pkt->size, size[i]); if (!s->is_pipe) url_fclose(f[i]); if(ret[i]>0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) { av_free_packet(pkt); return AVERROR_IO; /* signal EOF */ } else { s->img_count++; s->img_number++; return 0; } }
static int segment_start(AVFormatContext *s, int write_header) { SegmentContext *c = s->priv_data; AVFormatContext *oc = c->avf; int err = 0; if (write_header) { avformat_free_context(oc); c->avf = NULL; if ((err = segment_mux_init(s)) < 0) return err; oc = c->avf; } if (c->wrap) c->number %= c->wrap; if (av_get_frame_filename(oc->filename, sizeof(oc->filename), s->filename, c->number++) < 0) return AVERROR(EINVAL); if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) return err; if (oc->oformat->priv_class && oc->priv_data) av_opt_set(oc->priv_data, "resend_headers", "1", 0); /* mpegts specific */ if (write_header) { if ((err = avformat_write_header(oc, NULL)) < 0) return err; } return 0; }
static int img_write_packet(AVFormatContext *s, AVPacket *pkt) { VideoData *img = s->priv_data; ByteIOContext pb1[3], *pb[3]= {&pb1[0], &pb1[1], &pb1[2]}; char filename[1024]; AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; int i; if (!img->is_pipe) { if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number>1) return AVERROR_IO; for(i=0; i<3; i++){ if (url_fopen(pb[i], filename, URL_WRONLY) < 0) return AVERROR_IO; if(codec->codec_id != CODEC_ID_RAWVIDEO) break; filename[ strlen(filename) - 1 ]= 'U' + i; } } else { pb[0] = &s->pb; } if(codec->codec_id == CODEC_ID_RAWVIDEO){ int ysize = codec->width * codec->height; put_buffer(pb[0], pkt->data , ysize); put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); put_flush_packet(pb[1]); put_flush_packet(pb[2]); url_fclose(pb[1]); url_fclose(pb[2]); }else{ put_buffer(pb[0], pkt->data, pkt->size); } put_flush_packet(pb[0]); if (!img->is_pipe) { url_fclose(pb[0]); } img->img_number++; return 0; }
static int get_chunk_filename(AVFormatContext *s, int is_header, char *filename) { WebMChunkContext *wc = s->priv_data; AVFormatContext *oc = wc->avf; if (!filename) { return AVERROR(EINVAL); } if (is_header) { if (!wc->header_filename) { return AVERROR(EINVAL); } av_strlcpy(filename, wc->header_filename, strlen(wc->header_filename) + 1); } else { if (av_get_frame_filename(filename, MAX_FILENAME_SIZE, s->filename, wc->chunk_index - 1) < 0) { av_log(oc, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->filename); return AVERROR(EINVAL); } } return 0; }
static int segment_hls_window(AVFormatContext *s, int last) { SegmentContext *seg = s->priv_data; int i, ret = 0; char buf[1024]; if ((ret = s->io_open(s, &seg->pb, seg->list, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; avio_printf(seg->pb, "#EXTM3U\n"); avio_printf(seg->pb, "#EXT-X-VERSION:3\n"); avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time); avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", FFMAX(0, seg->number - seg->size)); av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%d\n", FFMAX(0, seg->number - seg->size)); for (i = FFMAX(0, seg->number - seg->size); i < seg->number; i++) { avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time); if (seg->entry_prefix) { avio_printf(seg->pb, "%s", seg->entry_prefix); } ret = av_get_frame_filename(buf, sizeof(buf), s->filename, i); if (ret < 0) { ret = AVERROR(EINVAL); goto fail; } avio_printf(seg->pb, "%s\n", buf); } if (last) avio_printf(seg->pb, "#EXT-X-ENDLIST\n"); fail: ff_format_io_close(s, &seg->pb); return ret; }
int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; char filename_bytes[1024]; char *filename = filename_bytes; int i, res; int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecParameters *par = s1->streams[0]->codecpar; if (!s->is_pipe) { /* loop over input */ if (s->loop && s->img_number > s->img_last) { s->img_number = s->img_first; } if (s->img_number > s->img_last) return AVERROR_EOF; if (s->pattern_type == PT_NONE) { av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes)); } else if (s->use_glob) { #if HAVE_GLOB filename = s->globstate.gl_pathv[s->img_number]; #endif } else { if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), s->path, s->img_number) < 0 && s->img_number > 1) return AVERROR(EIO); } for (i = 0; i < 3; i++) { if (s1->pb && !strcmp(filename_bytes, s->path) && !s->loop && !s->split_planes) { f[i] = s1->pb; } else if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", filename); return AVERROR(EIO); } size[i] = avio_size(f[i]); if (!s->split_planes) break; filename[strlen(filename) - 1] = 'U' + i; } if (par->codec_id == AV_CODEC_ID_NONE) { AVProbeData pd = { 0 }; AVInputFormat *ifmt; uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE]; int ret; int score = 0; ret = avio_read(f[0], header, PROBE_BUF_MIN); if (ret < 0) return ret; memset(header + ret, 0, sizeof(header) - ret); avio_skip(f[0], -ret); pd.buf = header; pd.buf_size = ret; pd.filename = filename; ifmt = av_probe_input_format3(&pd, 1, &score); if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id) par->codec_id = ifmt->raw_codec_id; } if (par->codec_id == AV_CODEC_ID_RAWVIDEO && !par->width) infer_size(&par->width, &par->height, size[0]); } else { f[0] = s1->pb; if (avio_feof(f[0]) && s->loop && s->is_pipe) avio_seek(f[0], 0, SEEK_SET); if (avio_feof(f[0])) return AVERROR_EOF; if (s->frame_size > 0) { size[0] = s->frame_size; } else if (!s1->streams[0]->parser) { size[0] = avio_size(s1->pb); } else { size[0] = 4096; } } res = av_new_packet(pkt, size[0] + size[1] + size[2]); if (res < 0) { goto fail; } pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; if (stat(filename, &img_stat)) { res = AVERROR(EIO); goto fail; } pkt->pts = (int64_t)img_stat.st_mtime; #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC if (s->ts_from_file == 2) pkt->pts = 1000000000*pkt->pts + img_stat.st_mtim.tv_nsec; #endif av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME); } else if (!s->is_pipe) { pkt->pts = s->pts; } if (s->is_pipe) pkt->pos = avio_tell(f[0]); pkt->size = 0; for (i = 0; i < 3; i++) { if (f[i]) { ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); if (s->loop && s->is_pipe && ret[i] == AVERROR_EOF) { if (avio_seek(f[i], 0, SEEK_SET) >= 0) { pkt->pos = 0; ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); } } if (!s->is_pipe && f[i] != s1->pb) ff_format_io_close(s1, &f[i]); if (ret[i] > 0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { av_packet_unref(pkt); if (ret[0] < 0) { res = ret[0]; } else if (ret[1] < 0) { res = ret[1]; } else if (ret[2] < 0) { res = ret[2]; } else { res = AVERROR_EOF; } goto fail; } else { s->img_count++; s->img_number++; s->pts++; return 0; } fail: if (!s->is_pipe) { for (i = 0; i < 3; i++) { if (f[i] != s1->pb) ff_format_io_close(s1, &f[i]); } } return res; }
static int img_write_packet(AVFormatContext *s, AVPacket *pkt) { VideoData *img = s->priv_data; ByteIOContext *pb[3]; char filename[1024]; AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; int i; if (!img->is_pipe) { if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number>1) { av_log(s, AV_LOG_ERROR, "Could not get frame filename from pattern\n"); return AVERROR(EIO); } for(i=0; i<3; i++){ if (url_fopen(&pb[i], filename, URL_WRONLY) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } if(codec->codec_id != CODEC_ID_RAWVIDEO) break; filename[ strlen(filename) - 1 ]= 'U' + i; } } else { pb[0] = s->pb; } if(codec->codec_id == CODEC_ID_RAWVIDEO){ int ysize = codec->width * codec->height; put_buffer(pb[0], pkt->data , ysize); put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); put_flush_packet(pb[1]); put_flush_packet(pb[2]); url_fclose(pb[1]); url_fclose(pb[2]); }else{ if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){ AVStream *st = s->streams[0]; if(st->codec->extradata_size > 8 && AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){ if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c')) goto error; put_be32(pb[0], 12); put_tag (pb[0], "jP "); put_be32(pb[0], 0x0D0A870A); // signature put_be32(pb[0], 20); put_tag (pb[0], "ftyp"); put_tag (pb[0], "jp2 "); put_be32(pb[0], 0); put_tag (pb[0], "jp2 "); put_buffer(pb[0], st->codec->extradata, st->codec->extradata_size); }else if(pkt->size < 8 || (!st->codec->extradata_size && AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature error: av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n"); return -1; } } put_buffer(pb[0], pkt->data, pkt->size); } put_flush_packet(pb[0]); if (!img->is_pipe) { url_fclose(pb[0]); } img->img_number++; return 0; }
static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; char filename[1024]; int i, res; int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecContext *codec = s1->streams[0]->codec; if (!s->is_pipe) { /* loop over input */ if (s->loop && s->img_number > s->img_last) { s->img_number = s->img_first; } if (s->img_number > s->img_last) return AVERROR_EOF; if (av_get_frame_filename(filename, sizeof(filename), s->path, s->img_number) < 0 && s->img_number > 1) return AVERROR(EIO); for (i = 0; i < 3; i++) { if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", filename); return AVERROR(EIO); } size[i] = avio_size(f[i]); if (codec->codec_id != AV_CODEC_ID_RAWVIDEO) break; filename[strlen(filename) - 1] = 'U' + i; } if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width) infer_size(&codec->width, &codec->height, size[0]); } else { f[0] = s1->pb; if (f[0]->eof_reached) return AVERROR(EIO); size[0] = 4096; } res = av_new_packet(pkt, size[0] + size[1] + size[2]); if (res < 0) return res; pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; pkt->size = 0; for (i = 0; i < 3; i++) { if (f[i]) { ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); if (!s->is_pipe) ff_format_io_close(s1, &f[i]); if (ret[i] > 0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { av_packet_unref(pkt); return AVERROR(EIO); /* signal EOF */ } else { s->img_count++; s->img_number++; return 0; } }
static int write_packet(AVFormatContext *s, AVPacket *pkt) { VideoMuxData *img = s->priv_data; AVIOContext *pb[4]; char filename[1024]; AVCodecContext *codec = s->streams[pkt->stream_index]->codec; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(codec->pix_fmt); int i; int nb_renames = 0; if (!img->is_pipe) { if (img->update) { av_strlcpy(filename, img->path, sizeof(filename)); } else if (img->use_strftime) { time_t now0; struct tm *tm, tmpbuf; time(&now0); tm = localtime_r(&now0, &tmpbuf); if (!strftime(filename, sizeof(filename), img->path, tm)) { av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n"); return AVERROR(EINVAL); } } else if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number > 1) { av_log(s, AV_LOG_ERROR, "Could not get frame filename number %d from pattern '%s' (either set updatefirst or use a pattern like %%03d within the filename pattern)\n", img->img_number, img->path); return AVERROR(EINVAL); } for (i = 0; i < 4; i++) { snprintf(img->tmp[i], sizeof(img->tmp[i]), "%s.tmp", filename); av_strlcpy(img->target[i], filename, sizeof(img->target[i])); if (avio_open2(&pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", img->use_rename ? img->tmp[i] : filename); return AVERROR(EIO); } if (!img->split_planes || i+1 >= desc->nb_components) break; filename[strlen(filename) - 1] = "UVAx"[i]; } if (img->use_rename) nb_renames = i + 1; } else { pb[0] = s->pb; } if (img->split_planes) { int ysize = codec->width * codec->height; int usize = AV_CEIL_RSHIFT(codec->width, desc->log2_chroma_w) * AV_CEIL_RSHIFT(codec->height, desc->log2_chroma_h); if (desc->comp[0].depth >= 9) { ysize *= 2; usize *= 2; } avio_write(pb[0], pkt->data , ysize); avio_write(pb[1], pkt->data + ysize , usize); avio_write(pb[2], pkt->data + ysize + usize, usize); avio_closep(&pb[1]); avio_closep(&pb[2]); if (desc->nb_components > 3) { avio_write(pb[3], pkt->data + ysize + 2*usize, ysize); avio_closep(&pb[3]); } } else if (img->muxer) { int ret; AVStream *st; AVPacket pkt2 = {0}; AVFormatContext *fmt = NULL; av_assert0(!img->split_planes); ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->filename); if (ret < 0) return ret; st = avformat_new_stream(fmt, NULL); if (!st) { avformat_free_context(fmt); return AVERROR(ENOMEM); } st->id = pkt->stream_index; fmt->pb = pb[0]; if ((ret = av_copy_packet(&pkt2, pkt)) < 0 || (ret = av_dup_packet(&pkt2)) < 0 || (ret = avcodec_copy_context(st->codec, s->streams[0]->codec)) < 0 || (ret = avformat_write_header(fmt, NULL)) < 0 || (ret = av_interleaved_write_frame(fmt, &pkt2)) < 0 || (ret = av_write_trailer(fmt)) < 0) { av_packet_unref(&pkt2); avformat_free_context(fmt); return ret; } av_packet_unref(&pkt2); avformat_free_context(fmt); } else { avio_write(pb[0], pkt->data, pkt->size); } avio_flush(pb[0]); if (!img->is_pipe) { avio_closep(&pb[0]); for (i = 0; i < nb_renames; i++) { ff_rename(img->tmp[i], img->target[i], s); } } img->img_number++; return 0; }
static int write_packet(AVFormatContext *s, AVPacket *pkt) { VideoMuxData *img = s->priv_data; AVIOContext *pb[3]; char filename[1024]; AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; int i; if (!img->is_pipe) { if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number>1) { av_log(s, AV_LOG_ERROR, "Could not get frame filename number %d from pattern '%s'\n", img->img_number, img->path); return AVERROR(EIO); } for(i=0; i<3; i++){ if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } if(codec->codec_id != CODEC_ID_RAWVIDEO) break; filename[ strlen(filename) - 1 ]= 'U' + i; } } else { pb[0] = s->pb; } if(codec->codec_id == CODEC_ID_RAWVIDEO){ int ysize = codec->width * codec->height; avio_write(pb[0], pkt->data , ysize); avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); avio_write(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); avio_flush(pb[1]); avio_flush(pb[2]); avio_close(pb[1]); avio_close(pb[2]); }else{ if(ff_guess_image2_codec(s->filename) == CODEC_ID_JPEG2000){ AVStream *st = s->streams[0]; if(st->codec->extradata_size > 8 && AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){ if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c')) goto error; avio_wb32(pb[0], 12); ffio_wfourcc(pb[0], "jP "); avio_wb32(pb[0], 0x0D0A870A); // signature avio_wb32(pb[0], 20); ffio_wfourcc(pb[0], "ftyp"); ffio_wfourcc(pb[0], "jp2 "); avio_wb32(pb[0], 0); ffio_wfourcc(pb[0], "jp2 "); avio_write(pb[0], st->codec->extradata, st->codec->extradata_size); }else if(pkt->size < 8 || (!st->codec->extradata_size && AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature error: av_log(s, AV_LOG_ERROR, "malformed JPEG 2000 codestream\n"); return -1; } } avio_write(pb[0], pkt->data, pkt->size); } avio_flush(pb[0]); if (!img->is_pipe) { avio_close(pb[0]); } img->img_number++; return 0; }
static int seg_write_header(AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = NULL; int ret, i; seg->number = 0; seg->offset_time = 0; seg->recording_time = seg->time * 1000000; if (!seg->write_header_trailer) seg->individual_header_trailer = 0; if (seg->list && seg->list_type != LIST_HLS) if ((ret = s->io_open(s, &seg->pb, seg->list, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; for (i = 0; i < s->nb_streams; i++) seg->has_video += (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO); if (seg->has_video > 1) av_log(s, AV_LOG_WARNING, "More than a single video stream present, " "expect issues decoding it.\n"); seg->oformat = av_guess_format(seg->format, s->filename, NULL); if (!seg->oformat) { ret = AVERROR_MUXER_NOT_FOUND; goto fail; } if (seg->oformat->flags & AVFMT_NOFILE) { av_log(s, AV_LOG_ERROR, "format %s not supported.\n", seg->oformat->name); ret = AVERROR(EINVAL); goto fail; } if ((ret = segment_mux_init(s)) < 0) goto fail; oc = seg->avf; if (av_get_frame_filename(oc->filename, sizeof(oc->filename), s->filename, seg->number++) < 0) { ret = AVERROR(EINVAL); goto fail; } if (seg->write_header_trailer) { if ((ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } else { if ((ret = open_null_ctx(&oc->pb)) < 0) goto fail; } if ((ret = avformat_write_header(oc, NULL)) < 0) { ff_format_io_close(oc, &oc->pb); goto fail; } if (!seg->write_header_trailer) { close_null_ctx(oc->pb); if ((ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } if (seg->list) { if (seg->list_type == LIST_HLS) { if ((ret = segment_hls_window(s, 0)) < 0) goto fail; } else { avio_printf(seg->pb, "%s\n", oc->filename); avio_flush(seg->pb); } } fail: if (ret < 0) seg_free_context(seg); return ret; }