1 /* 2 * Copyright 2003-2021 The Music Player Daemon Project 3 * http://www.musicpd.org 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef MPD_FFMPEG_CODEC_HXX 21 #define MPD_FFMPEG_CODEC_HXX 22 23 #include "Error.hxx" 24 25 extern "C" { 26 #include <libavcodec/avcodec.h> 27 } 28 29 #include <new> 30 31 namespace Ffmpeg { 32 33 class CodecContext { 34 AVCodecContext *codec_context = nullptr; 35 36 public: 37 CodecContext() = default; 38 CodecContext(const AVCodec & codec)39 explicit CodecContext(const AVCodec &codec) 40 :codec_context(avcodec_alloc_context3(&codec)) 41 { 42 if (codec_context == nullptr) 43 throw std::bad_alloc(); 44 } 45 ~CodecContext()46 ~CodecContext() noexcept { 47 if (codec_context != nullptr) 48 avcodec_free_context(&codec_context); 49 } 50 CodecContext(CodecContext && src)51 CodecContext(CodecContext &&src) noexcept 52 :codec_context(std::exchange(src.codec_context, nullptr)) {} 53 operator =(CodecContext && src)54 CodecContext &operator=(CodecContext &&src) noexcept { 55 using std::swap; 56 swap(codec_context, src.codec_context); 57 return *this; 58 } 59 operator *()60 AVCodecContext &operator*() noexcept { 61 return *codec_context; 62 } 63 operator ->()64 AVCodecContext *operator->() noexcept { 65 return codec_context; 66 } 67 FillFromParameters(const AVCodecParameters & par)68 void FillFromParameters(const AVCodecParameters &par) { 69 int err = avcodec_parameters_to_context(codec_context, &par); 70 if (err < 0) 71 throw MakeFfmpegError(err, "avcodec_parameters_to_context() failed"); 72 } 73 Open(const AVCodec & codec,AVDictionary ** options)74 void Open(const AVCodec &codec, AVDictionary **options) { 75 int err = avcodec_open2(codec_context, &codec, options); 76 if (err < 0) 77 throw MakeFfmpegError(err, "avcodec_open2() failed"); 78 } 79 FlushBuffers()80 void FlushBuffers() noexcept { 81 avcodec_flush_buffers(codec_context); 82 } 83 }; 84 85 } // namespace Ffmpeg 86 87 #endif 88