filter/ffmpeg: automatically retry with "aformat"
If DetectFilterOutputFormat() fails to determine the output format, insert an "aformat" filter which attempts to force a specific output format. Fixes part 2 of of https://github.com/MusicPlayerDaemon/MPD/issues/1235
This commit is contained in:
parent
b904f8af03
commit
b5b40d8235
1
NEWS
1
NEWS
|
@ -3,6 +3,7 @@ ver 0.22.11 (not yet released)
|
||||||
- fix "albumart" crash
|
- fix "albumart" crash
|
||||||
* filter
|
* filter
|
||||||
- ffmpeg: pass "channel_layout" instead of "channels" to buffersrc
|
- ffmpeg: pass "channel_layout" instead of "channels" to buffersrc
|
||||||
|
- ffmpeg: fix "av_buffersink_get_frame() failed: Resource temporarily unavailable"
|
||||||
* Android
|
* Android
|
||||||
- build with NDK r23
|
- build with NDK r23
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,40 @@ public:
|
||||||
std::unique_ptr<Filter> Open(AudioFormat &af) override;
|
std::unique_ptr<Filter> Open(AudioFormat &af) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback for PreparedFfmpegFilter::Open() just in case the filter's
|
||||||
|
* native output format could not be determined.
|
||||||
|
*
|
||||||
|
* TODO: improve the MPD filter API to allow returning the output
|
||||||
|
* format later, and eliminate this kludge
|
||||||
|
*/
|
||||||
|
static auto
|
||||||
|
OpenWithAformat(const char *graph_string, AudioFormat &in_audio_format)
|
||||||
|
{
|
||||||
|
Ffmpeg::FilterGraph graph;
|
||||||
|
|
||||||
|
auto &buffer_src =
|
||||||
|
Ffmpeg::MakeAudioBufferSource(in_audio_format, *graph);
|
||||||
|
|
||||||
|
auto &buffer_sink = Ffmpeg::MakeAudioBufferSink(*graph);
|
||||||
|
|
||||||
|
AudioFormat out_audio_format = in_audio_format;
|
||||||
|
auto &aformat = Ffmpeg::MakeAformat(out_audio_format, *graph);
|
||||||
|
|
||||||
|
int error = avfilter_link(&aformat, 0, &buffer_sink, 0);
|
||||||
|
if (error < 0)
|
||||||
|
throw MakeFfmpegError(error, "avfilter_link() failed");
|
||||||
|
|
||||||
|
graph.ParseSingleInOut(graph_string, aformat, buffer_src);
|
||||||
|
graph.CheckAndConfigure();
|
||||||
|
|
||||||
|
return std::make_unique<FfmpegFilter>(in_audio_format,
|
||||||
|
out_audio_format,
|
||||||
|
std::move(graph),
|
||||||
|
buffer_src,
|
||||||
|
buffer_sink);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Filter>
|
std::unique_ptr<Filter>
|
||||||
PreparedFfmpegFilter::Open(AudioFormat &in_audio_format)
|
PreparedFfmpegFilter::Open(AudioFormat &in_audio_format)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +89,12 @@ PreparedFfmpegFilter::Open(AudioFormat &in_audio_format)
|
||||||
buffer_sink);
|
buffer_sink);
|
||||||
|
|
||||||
if (!out_audio_format.IsDefined())
|
if (!out_audio_format.IsDefined())
|
||||||
throw std::runtime_error("Unable to determine FFmpeg filter output format");
|
/* the filter's native output format could not be
|
||||||
|
determined yet, but we need to know it now; as a
|
||||||
|
workaround for this MPD API deficiency, try again
|
||||||
|
with an "aformat" filter which forces a specific
|
||||||
|
output format */
|
||||||
|
return OpenWithAformat(graph_string, in_audio_format);
|
||||||
|
|
||||||
return std::make_unique<FfmpegFilter>(in_audio_format,
|
return std::make_unique<FfmpegFilter>(in_audio_format,
|
||||||
out_audio_format,
|
out_audio_format,
|
||||||
|
|
Loading…
Reference in New Issue