使用显式转换解决从‘int’到‘AVRounding’的无效转换

Using explicit casting to solve invalid conversion from ‘int’ to ‘AVRounding’

我正在尝试遵循 github (https://github.com/leandromoreira/ffmpeg-libav-tutorial#chapter-2---remuxing) 上的“艰难地学习 ffmpeg”指南,当我尝试 运行 自己使用 remuxing 代码时C++ 编译器我总是得到错误

invalid conversion from ‘int’ to ‘AVRounding’[-fpermissive]

我的代码与 github 原始代码之间唯一真正的区别是我将输入文件名和输出文件名作为参数。做一些研究我发现 AVRounding 是一个枚举?我认为?因此我需要以某种方式显式地进行转换。但是,我无法理解显式转换的工作原理以及我将如何使用它来解决我的问题。我要把它放在哪里? 这是导致问题的行:

packet.pts =  av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
packet.dts =  av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);

谁能解释一下如何解决这个问题?对不起,如果这是初学者的错误。在此先感谢您的帮助。

AVRounding 确实是一个枚举(确切地说,是一个 unscoped 没有固定基础类型的枚举):

/**
 * Rounding methods.
 */
enum AVRounding {
    AV_ROUND_ZERO     = 0, ///< Round toward zero.
    AV_ROUND_INF      = 1, ///< Round away from zero.
    AV_ROUND_DOWN     = 2, ///< Round toward -infinity.
    AV_ROUND_UP       = 3, ///< Round toward +infinity.
    AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero.
    /**
     * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through
     * unchanged, avoiding special cases for #AV_NOPTS_VALUE.
     *
     * Unlike other values of the enumeration AVRounding, this value is a
     * bitmask that must be used in conjunction with another value of the
     * enumeration through a bitwise OR, in order to set behavior for normal
     * cases.
     *
     * @code{.c}
     * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
     * // Rescaling 3:
     * //     Calculating 3 * 1 / 2
     * //     3 / 2 is rounded up to 2
     * //     => 2
     *
     * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
     * // Rescaling AV_NOPTS_VALUE:
     * //     AV_NOPTS_VALUE == INT64_MIN
     * //     AV_NOPTS_VALUE is passed through
     * //     => AV_NOPTS_VALUE
     * @endcode
     */
    AV_ROUND_PASS_MINMAX = 8192,
};

您尝试传递给 av_rescale_q_rnd() 的值本身不是 int,但它们隐式 可转换为 int。但是,C++ 不允许 int 隐式 转换为 enum,并且 FFmpeg 没有为 AVRounding 定义 operator| ] 在 C++ 中,因此将 AV_ROUND_NEAR_INFAV_ROUND_PASS_MINMAX 的值进行或运算的结果实际上会产生 int,因此需要进行类型转换以返回到 AVRounding,例如:

packet.pts =  av_rescale_q_rnd(..., static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
packet.dts =  av_rescale_q_rnd(..., static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

如果愿意,您可以手动定义 operator| 以避免在调用站点进行类型转换,例如:

inline AVRounding operator|(AVRounding a, AVRounding b)
{
    return static_cast<AVRounding>(static_cast<int>(a) | static_cast<int>(b));
}

...

packet.pts =  av_rescale_q_rnd(..., AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
packet.dts =  av_rescale_q_rnd(..., AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);