diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp index e98ce05fea..e1b7121033 100644 --- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp @@ -3,6 +3,7 @@ #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/lv2/sys_sync.h" +#include "util/media_utils.h" #ifdef _MSC_VER #pragma warning(push, 0) @@ -489,16 +490,29 @@ public: else if (just_started) // deferred initialization { AVDictionary* opts = nullptr; - av_dict_set(&opts, "probesize", "96", 0); + err = av_dict_set(&opts, "probesize", "96", 0); + if (err < 0) + { + fmt::throw_exception("av_dict_set(probesize, 96) failed (err=0x%x='%s')", err, utils::av_error_to_string(err)); + } err = avformat_open_input(&fmt, nullptr, input_format, &opts); if (err || opts) { - fmt::throw_exception("avformat_open_input() failed (err=0x%x, opts=%d)", err, opts ? 1 : 0); + std::string dict_content; + if (opts) + { + AVDictionaryEntry* tag = nullptr; + while ((tag = av_dict_get(opts, "", tag, AV_DICT_IGNORE_SUFFIX))) + { + fmt::append(dict_content, "['%s': '%s']", tag->key, tag->value); + } + } + fmt::throw_exception("avformat_open_input() failed (err=0x%x='%s', opts=%s)", err, utils::av_error_to_string(err), dict_content); } //err = avformat_find_stream_info(fmt, NULL); //if (err || !fmt->nb_streams) //{ - // ADEC_ERROR("adecDecodeAu: avformat_find_stream_info() failed (err=0x%x, nb_streams=%d)", err, fmt->nb_streams); + // fmt::throw_exception("avformat_find_stream_info() failed (err=0x%x='%s', nb_streams=%d)", err, utils::av_error_to_string(err), fmt->nb_streams); //} if (!avformat_new_stream(fmt, codec)) { @@ -507,7 +521,11 @@ public: //ctx = fmt->streams[0]->codec; // TODO: check data opts = nullptr; - av_dict_set(&opts, "refcounted_frames", "1", 0); + err = av_dict_set(&opts, "refcounted_frames", "1", 0); + if (err < 0) + { + fmt::throw_exception("av_dict_set(refcounted_frames, 1) failed (err=0x%x='%s')", err, utils::av_error_to_string(err)); + } { std::lock_guard lock(g_mutex_avcodec_open2); // not multithread-safe (???) @@ -515,7 +533,16 @@ public: } if (err || opts) { - fmt::throw_exception("avcodec_open2() failed (err=0x%x, opts=%d)", err, opts ? 1 : 0); + std::string dict_content; + if (opts) + { + AVDictionaryEntry* tag = nullptr; + while ((tag = av_dict_get(opts, "", tag, AV_DICT_IGNORE_SUFFIX))) + { + fmt::append(dict_content, "['%s': '%s']", tag->key, tag->value); + } + } + fmt::throw_exception("avcodec_open2() failed (err=0x%x='%s', opts=%s)", err, utils::av_error_to_string(err), dict_content); } just_started = false; } diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 1e8290fc55..7578bc3d02 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -6,6 +6,7 @@ #include "Emu/Cell/lv2/sys_ppu_thread.h" #include "Emu/Cell/lv2/sys_process.h" #include "sysPrxForUser.h" +#include "util/media_utils.h" #ifdef _MSC_VER #pragma warning(push, 0) @@ -172,15 +173,29 @@ struct vdec_context final } AVDictionary* opts{}; - av_dict_set(&opts, "refcounted_frames", "1", 0); + int err = av_dict_set(&opts, "refcounted_frames", "1", 0); + if (err < 0) + { + avcodec_free_context(&ctx); + fmt::throw_exception("av_dict_set(refcounted_frames, 1) failed (err=0x%x='%s')", err, utils::av_error_to_string(err)); + } std::lock_guard lock(g_mutex_avcodec_open2); - int err = avcodec_open2(ctx, codec, &opts); + err = avcodec_open2(ctx, codec, &opts); if (err || opts) { avcodec_free_context(&ctx); - fmt::throw_exception("avcodec_open2() failed (err=0x%x, opts=%d)", err, opts ? 1 : 0); + std::string dict_content; + if (opts) + { + AVDictionaryEntry* tag = nullptr; + while ((tag = av_dict_get(opts, "", tag, AV_DICT_IGNORE_SUFFIX))) + { + fmt::append(dict_content, "['%s': '%s']", tag->key, tag->value); + } + } + fmt::throw_exception("avcodec_open2() failed (err=0x%x='%s', opts=%s)", err, utils::av_error_to_string(err), dict_content); } } diff --git a/rpcs3/util/media_utils.cpp b/rpcs3/util/media_utils.cpp index 97a6abc8a2..c1f3524c5e 100644 --- a/rpcs3/util/media_utils.cpp +++ b/rpcs3/util/media_utils.cpp @@ -55,7 +55,7 @@ namespace utils return def; } - std::string error_to_string(int error) + std::string av_error_to_string(int error) { char av_error[AV_ERROR_MAX_STRING_SIZE]; av_make_error_string(av_error, AV_ERROR_MAX_STRING_SIZE, error); @@ -73,7 +73,7 @@ namespace utils AVDictionary* av_dict_opts = nullptr; if (int err = av_dict_set(&av_dict_opts, "probesize", "96", 0); err < 0) { - media_log.error("av_dict_set: returned with error=%d='%s'", err, error_to_string(err)); + media_log.error("av_dict_set: returned with error=%d='%s'", err, av_error_to_string(err)); return { false, std::move(info) }; } @@ -85,7 +85,7 @@ namespace utils // Failed to open file av_dict_free(&av_dict_opts); avformat_free_context(av_format_ctx); - media_log.notice("avformat_open_input: could not open file. error=%d='%s' file='%s'", err, error_to_string(err), path); + media_log.notice("avformat_open_input: could not open file. error=%d='%s' file='%s'", err, av_error_to_string(err), path); return { false, std::move(info) }; } av_dict_free(&av_dict_opts); @@ -96,7 +96,7 @@ namespace utils // Failed to load stream information avformat_close_input(&av_format_ctx); avformat_free_context(av_format_ctx); - media_log.notice("avformat_find_stream_info: could not load stream information. error=%d='%s' file='%s'", err, error_to_string(err), path); + media_log.notice("avformat_find_stream_info: could not load stream information. error=%d='%s' file='%s'", err, av_error_to_string(err), path); return { false, std::move(info) }; } @@ -233,13 +233,13 @@ namespace utils av.format = avformat_alloc_context(); if (int err = avformat_open_input(&av.format, path.c_str(), nullptr, nullptr); err < 0) { - media_log.error("audio_decoder: Could not open file '%s'. Error: %d='%s'", path, err, error_to_string(err)); + media_log.error("audio_decoder: Could not open file '%s'. Error: %d='%s'", path, err, av_error_to_string(err)); has_error = true; return; } if (int err = avformat_find_stream_info(av.format, nullptr); err < 0) { - media_log.error("audio_decoder: Could not retrieve stream info from file '%s'. Error: %d='%s'", path, err, error_to_string(err)); + media_log.error("audio_decoder: Could not retrieve stream info from file '%s'. Error: %d='%s'", path, err, av_error_to_string(err)); has_error = true; return; } @@ -283,7 +283,7 @@ namespace utils // Open decoder if (int err = avcodec_open2(av.context, av.codec, nullptr); err < 0) { - media_log.error("audio_decoder: Failed to open decoder for stream #%u in file '%s'. Error: %d='%s'", stream_index, path, err, error_to_string(err)); + media_log.error("audio_decoder: Failed to open decoder for stream #%u in file '%s'. Error: %d='%s'", stream_index, path, err, av_error_to_string(err)); has_error = true; return; } @@ -311,14 +311,14 @@ namespace utils (set_err = av_opt_set_sample_fmt(av.swr, "in_sample_fmt", static_cast(stream->codecpar->format), 0)) || (set_err = av_opt_set_sample_fmt(av.swr, "out_sample_fmt", dst_format, 0))) { - media_log.error("audio_decoder: Failed to set resampler options: Error: %d='%s'", set_err, error_to_string(set_err)); + media_log.error("audio_decoder: Failed to set resampler options: Error: %d='%s'", set_err, av_error_to_string(set_err)); has_error = true; return; } if (int err = swr_init(av.swr); err < 0 || !swr_is_initialized(av.swr)) { - media_log.error("audio_decoder: Resampler has not been properly initialized: %d='%s'", err, error_to_string(err)); + media_log.error("audio_decoder: Resampler has not been properly initialized: %d='%s'", err, av_error_to_string(err)); has_error = true; return; } @@ -341,7 +341,7 @@ namespace utils { if (int err = avcodec_send_packet(av.context, &packet); err < 0) { - media_log.error("audio_decoder: Queuing error: %d='%s'", err, error_to_string(err)); + media_log.error("audio_decoder: Queuing error: %d='%s'", err, av_error_to_string(err)); has_error = true; return; } @@ -353,7 +353,7 @@ namespace utils if (err == AVERROR(EAGAIN) || err == averror_eof) break; - media_log.error("audio_decoder: Decoding error: %d='%s'", err, error_to_string(err)); + media_log.error("audio_decoder: Decoding error: %d='%s'", err, av_error_to_string(err)); has_error = true; return; } @@ -364,7 +364,7 @@ namespace utils const int buffer_size = av_samples_alloc(&buffer, nullptr, dst_channels, av.frame->nb_samples, dst_format, align); if (buffer_size < 0) { - media_log.error("audio_decoder: Error allocating buffer: %d='%s'", buffer_size, error_to_string(buffer_size)); + media_log.error("audio_decoder: Error allocating buffer: %d='%s'", buffer_size, av_error_to_string(buffer_size)); has_error = true; return; } @@ -372,7 +372,7 @@ namespace utils const int frame_count = swr_convert(av.swr, &buffer, av.frame->nb_samples, const_cast(av.frame->data), av.frame->nb_samples); if (frame_count < 0) { - media_log.error("audio_decoder: Error converting frame: %d='%s'", frame_count, error_to_string(frame_count)); + media_log.error("audio_decoder: Error converting frame: %d='%s'", frame_count, av_error_to_string(frame_count)); has_error = true; if (buffer) av_free(buffer); diff --git a/rpcs3/util/media_utils.h b/rpcs3/util/media_utils.h index 7e7c1e1bad..58c49f3129 100644 --- a/rpcs3/util/media_utils.h +++ b/rpcs3/util/media_utils.h @@ -10,6 +10,8 @@ namespace utils { + std::string av_error_to_string(int error); + struct media_info { std::string path;