diff options
-rw-r--r-- | src/decoder/plugins/FfmpegDecoderPlugin.cxx | 120 |
1 files changed, 63 insertions, 57 deletions
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 825fe3dda..e946f3a15 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -514,46 +514,23 @@ FfmpegCheckTag(Decoder &decoder, InputStream &is, #endif static void -ffmpeg_decode(Decoder &decoder, InputStream &input) +FfmpegDecode(Decoder &decoder, InputStream &input, + AVFormatContext &format_context) { - AVInputFormat *input_format = ffmpeg_probe(&decoder, input); - if (input_format == nullptr) - return; - - FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)", - input_format->name, input_format->long_name); - - AvioStream stream(&decoder, input); - if (!stream.Open()) { - LogError(ffmpeg_domain, "Failed to open stream"); - return; - } - - //ffmpeg works with ours "fileops" helper - AVFormatContext *format_context = nullptr; - if (mpd_ffmpeg_open_input(&format_context, stream.io, - input.GetURI(), - input_format) != 0) { - LogError(ffmpeg_domain, "Open failed"); - return; - } - const int find_result = - avformat_find_stream_info(format_context, nullptr); + avformat_find_stream_info(&format_context, nullptr); if (find_result < 0) { LogError(ffmpeg_domain, "Couldn't find stream info"); - avformat_close_input(&format_context); return; } - int audio_stream = ffmpeg_find_audio_stream(*format_context); + int audio_stream = ffmpeg_find_audio_stream(format_context); if (audio_stream == -1) { LogError(ffmpeg_domain, "No audio stream inside"); - avformat_close_input(&format_context); return; } - AVStream *av_stream = format_context->streams[audio_stream]; + AVStream *av_stream = format_context.streams[audio_stream]; AVCodecContext *codec_context = av_stream->codec; @@ -573,7 +550,6 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) if (!codec) { LogError(ffmpeg_domain, "Unsupported audio codec"); - avformat_close_input(&format_context); return; } @@ -581,7 +557,6 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) ffmpeg_sample_format(codec_context->sample_fmt); if (sample_format == SampleFormat::UNDEFINED) { // (error message already done by ffmpeg_sample_format()) - avformat_close_input(&format_context); return; } @@ -592,7 +567,6 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) sample_format, codec_context->channels, error)) { LogError(error); - avformat_close_input(&format_context); return; } @@ -604,20 +578,19 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) const int open_result = avcodec_open2(codec_context, codec, nullptr); if (open_result < 0) { LogError(ffmpeg_domain, "Could not open codec"); - avformat_close_input(&format_context); return; } const SignedSongTime total_time = - format_context->duration != (int64_t)AV_NOPTS_VALUE - ? SignedSongTime::FromScale<uint64_t>(format_context->duration, + format_context.duration != (int64_t)AV_NOPTS_VALUE + ? SignedSongTime::FromScale<uint64_t>(format_context.duration, AV_TIME_BASE) : SignedSongTime::Negative(); decoder_initialized(decoder, audio_format, input.IsSeekable(), total_time); - FfmpegParseMetaData(decoder, *format_context, audio_stream); + FfmpegParseMetaData(decoder, format_context, audio_stream); #if LIBAVUTIL_VERSION_MAJOR >= 53 AVFrame *frame = av_frame_alloc(); @@ -626,7 +599,6 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) #endif if (!frame) { LogError(ffmpeg_domain, "Could not allocate frame"); - avformat_close_input(&format_context); return; } @@ -635,12 +607,12 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) DecoderCommand cmd; do { AVPacket packet; - if (av_read_frame(format_context, &packet) < 0) + if (av_read_frame(&format_context, &packet) < 0) /* end of file */ break; #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(56, 1, 0) - FfmpegCheckTag(decoder, input, *format_context, audio_stream); + FfmpegCheckTag(decoder, input, format_context, audio_stream); #endif if (packet.stream_index == audio_stream) @@ -660,7 +632,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) av_stream->time_base) + start_time_fallback(*av_stream); - if (av_seek_frame(format_context, audio_stream, where, + if (av_seek_frame(&format_context, audio_stream, where, AVSEEK_FLAG_ANY) < 0) decoder_seek_error(decoder); else { @@ -679,10 +651,60 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) #endif avcodec_close(codec_context); +} + +static void +ffmpeg_decode(Decoder &decoder, InputStream &input) +{ + AVInputFormat *input_format = ffmpeg_probe(&decoder, input); + if (input_format == nullptr) + return; + + FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)", + input_format->name, input_format->long_name); + + AvioStream stream(&decoder, input); + if (!stream.Open()) { + LogError(ffmpeg_domain, "Failed to open stream"); + return; + } + + //ffmpeg works with ours "fileops" helper + AVFormatContext *format_context = nullptr; + if (mpd_ffmpeg_open_input(&format_context, stream.io, + input.GetURI(), + input_format) != 0) { + LogError(ffmpeg_domain, "Open failed"); + return; + } + + FfmpegDecode(decoder, input, *format_context); avformat_close_input(&format_context); } static bool +FfmpegScanStream(AVFormatContext &format_context, + const struct tag_handler &handler, void *handler_ctx) +{ + const int find_result = + avformat_find_stream_info(&format_context, nullptr); + if (find_result < 0) + return false; + + if (format_context.duration != (int64_t)AV_NOPTS_VALUE) { + const auto duration = + SongTime::FromScale<uint64_t>(format_context.duration, + AV_TIME_BASE); + tag_handler_invoke_duration(&handler, handler_ctx, duration); + } + + int idx = ffmpeg_find_audio_stream(format_context); + FfmpegScanMetadata(format_context, idx, handler, handler_ctx); + + return true; +} + +static bool ffmpeg_scan_stream(InputStream &is, const struct tag_handler *handler, void *handler_ctx) { @@ -699,25 +721,9 @@ ffmpeg_scan_stream(InputStream &is, input_format) != 0) return false; - const int find_result = - avformat_find_stream_info(f, nullptr); - if (find_result < 0) { - avformat_close_input(&f); - return false; - } - - if (f->duration != (int64_t)AV_NOPTS_VALUE) { - const auto duration = - SongTime::FromScale<uint64_t>(f->duration, - AV_TIME_BASE); - tag_handler_invoke_duration(handler, handler_ctx, duration); - } - - int idx = ffmpeg_find_audio_stream(*f); - FfmpegScanMetadata(*f, idx, *handler, handler_ctx); - + bool result = FfmpegScanStream(*f, *handler, handler_ctx); avformat_close_input(&f); - return true; + return result; } /** |