diff --git a/src/ffmpeg/avcodec.cpp b/src/ffmpeg/avcodec.cpp index f1d4fdf..848a229 100644 --- a/src/ffmpeg/avcodec.cpp +++ b/src/ffmpeg/avcodec.cpp @@ -6,6 +6,25 @@ extern "C" { #include namespace mgs::ffmpeg { +namespace { +::AVPixelFormat get_favourite_format_ifp (::AVCodecContext* s, const ::AVPixelFormat* fmt) { + ::AVPixelFormat fav_format; + std::copy( + reinterpret_cast(&s->opaque), + reinterpret_cast(&s->opaque) + sizeof(::AVPixelFormat), + reinterpret_cast(&fav_format) + ); + + const ::AVPixelFormat* curr_fmt = fmt; + while (*curr_fmt != -1) { + if (*curr_fmt == fav_format) + return fav_format; + ++curr_fmt; + } + return ::avcodec_default_get_format(s, fmt); +} +} //unnamed namespace + AVCodec::AVCodec (::AVCodecID id) : m_avcodec(::avcodec_find_decoder(id)) { @@ -27,7 +46,17 @@ Decoder AVCodec::make_decoder (unsigned int width, unsigned int height, ::AVPixe context->width = width; context->height = height; - context->codec = codec; + context->get_format = &get_favourite_format_ifp; + + static_assert(sizeof(void*) >= sizeof(::AVPixelFormat)); + std::copy( + reinterpret_cast(&dst_format), + reinterpret_cast(&dst_format) + sizeof(::AVPixelFormat), + reinterpret_cast(&context->opaque) + ); + + if (::avcodec_open2(context.get(), codec, nullptr) < 0) + throw std::runtime_error("Could not open codec"); return {std::move(context), dst_format}; } diff --git a/src/ffmpeg/decoder.cpp b/src/ffmpeg/decoder.cpp index 288bd72..e6ff0be 100644 --- a/src/ffmpeg/decoder.cpp +++ b/src/ffmpeg/decoder.cpp @@ -13,19 +13,6 @@ namespace mgs::ffmpeg { namespace { constexpr int Align = 32; -::AVPixelFormat get_favourite_format_ifp (::AVCodecContext* s, const ::AVPixelFormat* fmt) { - assert(s->opaque); - - const ::AVPixelFormat* curr_fmt = fmt; - const auto fav_format = static_cast(s->opaque)->destination_format(); - while (*curr_fmt != -1) { - if (*curr_fmt == fav_format) - return fav_format; - ++curr_fmt; - } - return ::avcodec_default_get_format(s, fmt); -} - } //unnamed namespace Decoder::Decoder (UniqueAVCodecContext&& context, ::AVPixelFormat dst_format) : @@ -35,13 +22,6 @@ Decoder::Decoder (UniqueAVCodecContext&& context, ::AVPixelFormat dst_format) : m_frame2(::av_frame_alloc()), m_dst_format(dst_format) { - assert(not m_context->opaque); - assert(m_context->codec); - m_context->opaque = this; - m_context->get_format = &get_favourite_format_ifp; - - if (::avcodec_open2(m_context.get(), m_context->codec, nullptr) < 0) - throw std::runtime_error("Could not open codec"); } Decoder::~Decoder() noexcept = default;