X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fsmoothstreamingenc.c;h=1ed19ebb2f2e03a604ce6d60b56e02a8ce5f9122;hb=d6489ddb7a6cdfb6bd4e5b8095d765e0ba1aba4a;hp=54a1c49caae695e832f5c8962d0b8432d3757c35;hpb=b855b570c811d208bfadeb4e140bee90c1598e72;p=ffmpeg diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 54a1c49caae..1ed19ebb2f2 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -221,8 +221,8 @@ static int write_manifest(AVFormatContext *s, int final) 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); - snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename); + snprintf(filename, sizeof(filename), "%s/Manifest", s->url); + snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->url); ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); @@ -293,9 +293,9 @@ static int ism_write_header(AVFormatContext *s) { SmoothStreamingContext *c = s->priv_data; int ret = 0, i; - AVOutputFormat *oformat; + ff_const59 AVOutputFormat *oformat; - if (mkdir(s->filename, 0777) == -1 && errno != EEXIST) { + if (mkdir(s->url, 0777) == -1 && errno != EEXIST) { ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); goto fail; @@ -320,11 +320,13 @@ static int ism_write_header(AVFormatContext *s) AVDictionary *opts = NULL; if (!s->streams[i]->codecpar->bit_rate) { - av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i); - ret = AVERROR(EINVAL); - goto fail; + av_log(s, AV_LOG_WARNING, "No bit rate set for stream %d\n", i); + // create a tmp name for the directory of fragments + snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(Tmp_%d)", s->url, i); + } else { + snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->url, s->streams[i]->codecpar->bit_rate); } - snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->filename, s->streams[i]->codecpar->bit_rate); + if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) { ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); @@ -519,7 +521,7 @@ static int ism_flush(AVFormatContext *s, int final) for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; - char filename[1024], target_filename[1024], header_filename[1024]; + char filename[1024], target_filename[1024], header_filename[1024], curr_dirname[1024]; int64_t size; int64_t start_ts, duration, moof_size; if (!os->packets_written) @@ -541,6 +543,26 @@ static int ism_flush(AVFormatContext *s, int final) size = os->tail_pos - os->cur_start_pos; if ((ret = parse_fragment(s, filename, &start_ts, &duration, &moof_size, size)) < 0) break; + + if (!s->streams[i]->codecpar->bit_rate) { + int64_t bitrate = (int64_t) size * 8 * AV_TIME_BASE / av_rescale_q(duration, s->streams[i]->time_base, AV_TIME_BASE_Q); + if (!bitrate) { + av_log(s, AV_LOG_ERROR, "calculating bitrate got zero.\n"); + ret = AVERROR(EINVAL); + return ret; + } + + av_log(s, AV_LOG_DEBUG, "calculated bitrate: %"PRId64"\n", bitrate); + s->streams[i]->codecpar->bit_rate = bitrate; + memcpy(curr_dirname, os->dirname, sizeof(os->dirname)); + snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->url, s->streams[i]->codecpar->bit_rate); + snprintf(filename, sizeof(filename), "%s/temp", os->dirname); + + // rename the tmp folder back to the correct name since we now have the bitrate + if ((ret = ff_rename((const char*)curr_dirname, os->dirname, s)) < 0) + return ret; + } + snprintf(header_filename, sizeof(header_filename), "%s/FragmentInfo(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); snprintf(target_filename, sizeof(target_filename), "%s/Fragments(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); copy_moof(s, filename, header_filename, moof_size); @@ -609,9 +631,9 @@ static int ism_write_trailer(AVFormatContext *s) if (c->remove_at_exit) { char filename[1024]; - snprintf(filename, sizeof(filename), "%s/Manifest", s->filename); + snprintf(filename, sizeof(filename), "%s/Manifest", s->url); unlink(filename); - rmdir(s->filename); + rmdir(s->url); } ism_free(s);