Message ID | 20190314182158.16464-1-junli1026@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Thu, Mar 14, 2019 at 11:22 AM Jun Li <junli1026@gmail.com> wrote: > Calculate bitrate based on fragment size, only applied when > bitrate is not set, for example rtsp source. > > Signed-off-by: Jun Li <junli1026@gmail.com> > --- > libavformat/smoothstreamingenc.c | 32 +++++++++++++++++++++++++++----- > 1 file changed, 27 insertions(+), 5 deletions(-) > > diff --git a/libavformat/smoothstreamingenc.c > b/libavformat/smoothstreamingenc.c > index 094712af27..30bb188aa2 100644 > --- a/libavformat/smoothstreamingenc.c > +++ b/libavformat/smoothstreamingenc.c > @@ -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_%"PRId64")", 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->url, 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 get zero."); > + ret = AVERROR(EINVAL); > + return ret; > + } > + > + av_log(s, AV_LOG_WARNING, "calculated bitrate: %ld\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); > -- > 2.17.1 Ping. Some information about this patch, I met this bit-rate zero issue when trying to saving RTSP to Smooth. The current behavior is to exit with EINVAL if bit-rate is not set. Dash muxer overcome this by calculating from first fragment size: https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/dashenc.c#L1545 Since smooth and dash share many common, the patch follows the same path to solve the issue. Could someone please take a review ? Thanks. Best Regards, -Jun
On Thu, Mar 14, 2019 at 11:21:58AM -0700, Jun Li wrote: > Calculate bitrate based on fragment size, only applied when > bitrate is not set, for example rtsp source. > > Signed-off-by: Jun Li <junli1026@gmail.com> > --- > libavformat/smoothstreamingenc.c | 32 +++++++++++++++++++++++++++----- > 1 file changed, 27 insertions(+), 5 deletions(-) > > diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c > index 094712af27..30bb188aa2 100644 > --- a/libavformat/smoothstreamingenc.c > +++ b/libavformat/smoothstreamingenc.c > @@ -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_%"PRId64")", s->url, i); "i" cannot be "%d" and %"PRId64" at the same time [...]
On Fri, Mar 15, 2019 at 4:15 PM Michael Niedermayer <michael@niedermayer.cc> wrote: > On Thu, Mar 14, 2019 at 11:21:58AM -0700, Jun Li wrote: > > Calculate bitrate based on fragment size, only applied when > > bitrate is not set, for example rtsp source. > > > > Signed-off-by: Jun Li <junli1026@gmail.com> > > --- > > libavformat/smoothstreamingenc.c | 32 +++++++++++++++++++++++++++----- > > 1 file changed, 27 insertions(+), 5 deletions(-) > > > > diff --git a/libavformat/smoothstreamingenc.c > b/libavformat/smoothstreamingenc.c > > index 094712af27..30bb188aa2 100644 > > --- a/libavformat/smoothstreamingenc.c > > +++ b/libavformat/smoothstreamingenc.c > > @@ -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_%"PRId64")", s->url, i); > > "i" cannot be "%d" and %"PRId64" at the same time > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Into a blind darkness they enter who follow after the Ignorance, > they as if into a greater darkness enter who devote themselves > to the Knowledge alone. -- Isha Upanishad > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1 > > iEYEARECAAYFAlyMMh0ACgkQYR7HhwQLD6uHZACeOiKsIs38O9VjpdvfRUAe5cV7 > U7sAn0RBbjZJsvqX+IlR284ZYytZ4j5u > =qYmJ > -----END PGP SIGNATURE----- > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel Thanks, version 4 is sent out to address this: https://patchwork.ffmpeg.org/patch/12318/
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 094712af27..30bb188aa2 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -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_%"PRId64")", 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->url, 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 get zero."); + ret = AVERROR(EINVAL); + return ret; + } + + av_log(s, AV_LOG_WARNING, "calculated bitrate: %ld\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);
Calculate bitrate based on fragment size, only applied when bitrate is not set, for example rtsp source. Signed-off-by: Jun Li <junli1026@gmail.com> --- libavformat/smoothstreamingenc.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)