char dirname[1024];
uint8_t iobuf[32768];
URLContext *out; // Current output stream where all output is written
- URLContext *out2; // Auxillary output stream where all output also is written
+ URLContext *out2; // Auxiliary output stream where all output is also written
URLContext *tail_out; // The actual main output stream, if we're currently seeked back to write elsewhere
int64_t tail_pos, cur_pos, cur_start_pos;
int packets_written;
if (!ptr)
return;
os->private_str = av_mallocz(2*size + 1);
+ if (!os->private_str)
+ goto fail;
for (i = 0; i < size; i++)
snprintf(&os->private_str[2*i], 3, "%02x", ptr[i]);
+fail:
if (ptr != codec->extradata)
av_free(ptr);
}
{
SmoothStreamingContext *c = s->priv_data;
AVIOContext *out;
- char filename[1024];
+ char filename[1024], temp_filename[1024];
int ret, i, video_chunks = 0, audio_chunks = 0, video_streams = 0, audio_streams = 0;
int64_t duration = 0;
snprintf(filename, sizeof(filename), "%s/Manifest", s->filename);
- ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
- if (ret < 0)
+ snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename);
+ ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
return ret;
+ }
avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
for (i = 0; i < s->nb_streams; i++) {
OutputStream *os = &c->streams[i];
avio_printf(out, "</SmoothStreamingMedia>\n");
avio_flush(out);
avio_close(out);
+ rename(temp_filename, filename);
return 0;
}
int ret = 0, i;
AVOutputFormat *oformat;
- ret = mkdir(s->filename, 0777);
- if (ret) {
- av_log(s, AV_LOG_ERROR, "mkdir(%s): %s\n", s->filename, strerror(errno));
- return AVERROR(errno);
- }
- ret = 0;
+ mkdir(s->filename, 0777);
oformat = av_guess_format("ismv", NULL, NULL);
if (!oformat) {
av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n");
ret = AVERROR(EINVAL);
}
+ ret = write_manifest(s, 0);
fail:
if (ret)
static int add_fragment(OutputStream *os, const char *file, const char *infofile, int64_t start_time, int64_t duration, int64_t start_pos, int64_t size)
{
+ int err;
Fragment *frag;
if (os->nb_fragments >= os->fragments_size) {
os->fragments_size = (os->fragments_size + 1) * 2;
- os->fragments = av_realloc(os->fragments, sizeof(*os->fragments)*os->fragments_size);
- if (!os->fragments)
- return AVERROR(ENOMEM);
+ if ((err = av_reallocp(&os->fragments, sizeof(*os->fragments) *
+ os->fragments_size)) < 0) {
+ os->fragments_size = 0;
+ os->nb_fragments = 0;
+ return err;
+ }
}
frag = av_mallocz(sizeof(*frag));
if (!frag)
SmoothStreamingContext *c = s->priv_data;
AVStream *st = s->streams[pkt->stream_index];
OutputStream *os = &c->streams[pkt->stream_index];
- int64_t end_pts = (c->nb_fragments + 1) * c->min_frag_duration;
+ int64_t end_dts = (c->nb_fragments + 1) * c->min_frag_duration;
int ret;
+ if (st->first_dts == AV_NOPTS_VALUE)
+ st->first_dts = pkt->dts;
+
if ((!c->has_video || st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
- av_compare_ts(pkt->pts, st->time_base,
- end_pts, AV_TIME_BASE_Q) >= 0 &&
+ av_compare_ts(pkt->dts - st->first_dts, st->time_base,
+ end_dts, AV_TIME_BASE_Q) >= 0 &&
pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
if ((ret = ism_flush(s, 0)) < 0)