diff options
| author | Carl Hetherington <cth@carlh.net> | 2023-11-14 22:01:07 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2024-04-22 01:42:00 +0200 |
| commit | 066471f69400fc72e9c126ab36f5427329f30220 (patch) | |
| tree | dd15f6b6aa7a74b5cca2ce5f300723b1b72d2f11 | |
| parent | 0fbfe3d2dd5de9eab299f2ff569bff29cc6f8e19 (diff) | |
Support MPEG2 decompression.
| -rw-r--r-- | benchmark/wscript | 2 | ||||
| -rw-r--r-- | cscript | 15 | ||||
| -rw-r--r-- | examples/wscript | 2 | ||||
| -rw-r--r-- | libdcp-1.0.pc.in | 2 | ||||
| -rw-r--r-- | src/asset_factory.cc | 4 | ||||
| -rw-r--r-- | src/asset_reader.h | 1 | ||||
| -rw-r--r-- | src/dcp.cc | 2 | ||||
| -rw-r--r-- | src/exceptions.h | 18 | ||||
| -rw-r--r-- | src/ffmpeg_image.h | 86 | ||||
| -rw-r--r-- | src/mono_mpeg2_picture_asset.cc | 77 | ||||
| -rw-r--r-- | src/mono_mpeg2_picture_asset.h | 64 | ||||
| -rw-r--r-- | src/mono_mpeg2_picture_asset_reader.h | 58 | ||||
| -rw-r--r-- | src/mono_mpeg2_picture_frame.cc | 83 | ||||
| -rw-r--r-- | src/mono_mpeg2_picture_frame.h | 76 | ||||
| -rw-r--r-- | src/mpeg2_picture_asset.cc | 74 | ||||
| -rw-r--r-- | src/mpeg2_picture_asset.h | 77 | ||||
| -rw-r--r-- | src/mpeg2_transcode.cc | 143 | ||||
| -rw-r--r-- | src/mpeg2_transcode.h | 89 | ||||
| -rw-r--r-- | src/reel.cc | 2 | ||||
| -rw-r--r-- | src/reel_mono_picture_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_mono_picture_asset.h | 19 | ||||
| -rw-r--r-- | src/reel_picture_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_picture_asset.h | 32 | ||||
| -rw-r--r-- | src/wscript | 14 | ||||
| -rw-r--r-- | test/dcp_test.cc | 6 | ||||
| -rw-r--r-- | test/kdm_test.cc | 2 | ||||
| -rw-r--r-- | test/mono_mpeg2_picture_read_test.cc | 62 | ||||
| -rw-r--r-- | test/wscript | 7 | ||||
| -rw-r--r-- | tools/wscript | 2 | ||||
| -rw-r--r-- | wscript | 3 |
30 files changed, 998 insertions, 28 deletions
diff --git a/benchmark/wscript b/benchmark/wscript index f3e2d660..7305bdaa 100644 --- a/benchmark/wscript +++ b/benchmark/wscript @@ -35,7 +35,7 @@ def build(bld): for p in ['rgb_to_xyz', 'j2k_transcode']: obj = bld(features='cxx cxxprogram') obj.name = p - obj.uselib = 'BOOST_FILESYSTEM ASDCPLIB_DCPOMATIC CXML' + obj.uselib = 'BOOST_FILESYSTEM ASDCPLIB_DCPOMATIC CXML AVCODEC AVUTIL' obj.cppflags = ['-g', '-O2'] obj.use = 'libdcp%s' % bld.env.API_VERSION obj.source = "%s.cc" % p @@ -35,11 +35,22 @@ import os import shutil def dependencies(target, options): - return ( + deps = [ ('libcxml', 'v0.17.9', options), ('openjpeg', 'ad8edaacd54a862940d0a77c41ecda5858b54d6e'), ('asdcplib', '4b5d6e8d27dfd5fb282590538068662f4dbbf1c9') - ) + ] + + if target.platform == 'linux': + ffmpeg_options = { 'shared': False } + else: + ffmpeg_options = {} + + if target.platform != 'linux' or target.distro != 'arch': + # Use distro-provided FFmpeg on Arch, otherwise our own + deps.append(('ffmpeg', '0b73d2f5e70a04a67aa902902c42e3025ef3bb77', ffmpeg_options)) + + return deps def build(target, options): cmd = './waf configure --disable-examples --disable-dumpimage --disable-benchmarks --prefix=%s' % target.directory diff --git a/examples/wscript b/examples/wscript index faaa3e9a..68cd79ee 100644 --- a/examples/wscript +++ b/examples/wscript @@ -21,7 +21,7 @@ def build(bld): obj = bld(features='cxx cxxprogram') obj.name = example obj.use = 'libdcp%s' % bld.env.API_VERSION - obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC BOOST_FILESYSTEM OPENSSL XMLSEC1 MAGICK' + obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC BOOST_FILESYSTEM OPENSSL XMLSEC1 MAGICK AVCODEC AVUTIL' obj.source = example + '.cc' obj.target = example obj.install_path = '' diff --git a/libdcp-1.0.pc.in b/libdcp-1.0.pc.in index b838487e..a8d1007f 100644 --- a/libdcp-1.0.pc.in +++ b/libdcp-1.0.pc.in @@ -5,6 +5,6 @@ includedir=@includedir@ Name: libdcp Description: DCP reading and writing library Version: @version@ -Requires: openssl libxml++-@xmlpp_api@ xmlsec1 libasdcp-dcpomatic xerces-c +Requires: openssl libxml++-@xmlpp_api@ xmlsec1 libasdcp-dcpomatic xerces-c libavutil libavcodec Libs: @libs@ Cflags: -I${includedir} diff --git a/src/asset_factory.cc b/src/asset_factory.cc index 240b7685..26811366 100644 --- a/src/asset_factory.cc +++ b/src/asset_factory.cc @@ -41,6 +41,7 @@ #include "atmos_asset.h" #include "compose.hpp" #include "mono_j2k_picture_asset.h" +#include "mono_mpeg2_picture_asset.h" #include "smpte_subtitle_asset.h" #include "sound_asset.h" #include "stereo_j2k_picture_asset.h" @@ -68,8 +69,9 @@ dcp::asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_ } switch (type) { case ASDCP::ESS_UNKNOWN: + throw ReadError("Unknown asset type"); case ASDCP::ESS_MPEG2_VES: - throw ReadError ("MPEG2 video essences are not supported"); + return make_shared<MonoMPEG2PictureAsset>(path); case ASDCP::ESS_JPEG_2000: try { return make_shared<MonoJ2KPictureAsset>(path); diff --git a/src/asset_reader.h b/src/asset_reader.h index 3bf9b8b9..091ac915 100644 --- a/src/asset_reader.h +++ b/src/asset_reader.h @@ -91,6 +91,7 @@ protected: private: friend class AtmosAsset; friend class MonoJ2KPictureAsset; + friend class MonoMPEG2PictureAsset; friend class SoundAsset; friend class StereoJ2KPictureAsset; @@ -52,6 +52,7 @@ #include "interop_subtitle_asset.h" #include "metadata.h" #include "mono_j2k_picture_asset.h" +#include "mono_mpeg2_picture_asset.h" #include "j2k_picture_asset.h" #include "pkl.h" #include "raw_convert.h" @@ -247,6 +248,7 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m } } else if ( *pkl_type == remove_parameters(J2KPictureAsset::static_pkl_type(standard)) || + *pkl_type == remove_parameters(MPEG2PictureAsset::static_pkl_type(standard)) || *pkl_type == remove_parameters(SoundAsset::static_pkl_type(standard)) || *pkl_type == remove_parameters(AtmosAsset::static_pkl_type(standard)) || *pkl_type == remove_parameters(SMPTESubtitleAsset::static_pkl_type(standard)) diff --git a/src/exceptions.h b/src/exceptions.h index 8d85f02a..88ec253c 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -140,6 +140,24 @@ public: }; +class MPEG2CodecError : public MiscError +{ +public: + explicit MPEG2CodecError(std::string message) + : MiscError(message) + {} +}; + + +class MPEG2DecompressionError : public ReadError +{ +public: + explicit MPEG2DecompressionError(std::string message) + : ReadError(message) + {} +}; + + class BadContentKindError : public ReadError { public: diff --git a/src/ffmpeg_image.h b/src/ffmpeg_image.h new file mode 100644 index 00000000..56b68574 --- /dev/null +++ b/src/ffmpeg_image.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_FFMPEG_IMAGE_H +#define LIBDCP_FFMPEG_IMAGE_H + + +extern "C" { +#include <libavutil/frame.h> +} +#include <algorithm> +#include <vector> + + +namespace dcp { + + +class FFmpegImage +{ +public: + explicit FFmpegImage(AVFrame* frame) + : _frame(frame) + {} + + FFmpegImage(FFmpegImage const& other) = delete; + FFmpegImage& operator=(FFmpegImage const& other) = delete; + + FFmpegImage(FFmpegImage&& other) { + std::swap(_frame, other._frame); + } + + FFmpegImage& operator=(FFmpegImage&& other) { + std::swap(_frame, other._frame); + return *this; + } + + ~FFmpegImage() + { + av_frame_free(&_frame); + } + + AVFrame const * frame() const { + return _frame; + } + +private: + AVFrame* _frame = nullptr; +}; + + +} + + +#endif + diff --git a/src/mono_mpeg2_picture_asset.cc b/src/mono_mpeg2_picture_asset.cc new file mode 100644 index 00000000..548e936a --- /dev/null +++ b/src/mono_mpeg2_picture_asset.cc @@ -0,0 +1,77 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "filesystem.h" +#include "mono_mpeg2_picture_asset.h" +#include "mono_mpeg2_picture_asset_reader.h" +#include <asdcp/AS_DCP.h> + + +using std::shared_ptr; +using namespace dcp; + + +MonoMPEG2PictureAsset::MonoMPEG2PictureAsset(boost::filesystem::path file) + : MPEG2PictureAsset(file) +{ + Kumu::FileReaderFactory factory; + ASDCP::MPEG2::MXFReader reader(factory); + auto const result = reader.OpenRead(dcp::filesystem::fix_long_path(file).string().c_str()); + if (ASDCP_FAILURE(result)) { + boost::throw_exception(MXFFileError("could not open MXF file for reading", file.string(), result)); + } + + ASDCP::MPEG2::VideoDescriptor desc; + if (ASDCP_FAILURE(reader.FillVideoDescriptor(desc))) { + boost::throw_exception(ReadError("could not read video MXF information")); + } + + read_video_descriptor(desc); + + ASDCP::WriterInfo info; + if (ASDCP_FAILURE(reader.FillWriterInfo(info))) { + boost::throw_exception(ReadError("could not read video MXF information")); + } + + _id = read_writer_info(info); +} + + +shared_ptr<MonoMPEG2PictureAssetReader> +MonoMPEG2PictureAsset::start_read () const +{ + /* Can't use make_shared here as the MonoMPEG2PictureAssetReader constructor is private */ + return shared_ptr<MonoMPEG2PictureAssetReader>(new MonoMPEG2PictureAssetReader(this, key(), standard())); + +} diff --git a/src/mono_mpeg2_picture_asset.h b/src/mono_mpeg2_picture_asset.h new file mode 100644 index 00000000..a740cc6c --- /dev/null +++ b/src/mono_mpeg2_picture_asset.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_MONO_MPEG2_PICTURE_ASSET_H +#define LIBDCP_MONO_MPEG2_PICTURE_ASSET_H + + +/** @file src/mono_mpeg2_picture_asset.h + * @brief MonoMPEG2PictureAsset class + */ + + +#include "mpeg2_picture_asset.h" +#include "mono_mpeg2_picture_asset_reader.h" + + +namespace dcp { + + +class MonoMPEG2PictureAsset : public MPEG2PictureAsset +{ +public: + explicit MonoMPEG2PictureAsset(boost::filesystem::path file); + + std::shared_ptr<MonoMPEG2PictureAssetReader> start_read() const; +}; + + + +} + + +#endif diff --git a/src/mono_mpeg2_picture_asset_reader.h b/src/mono_mpeg2_picture_asset_reader.h new file mode 100644 index 00000000..75155f40 --- /dev/null +++ b/src/mono_mpeg2_picture_asset_reader.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +/** @file src/mono_mpeg2_picture_asset_reader.h + * @brief MonoJ2KPictureAssetReader typedef + */ + + +#ifndef LIBDCP_MONO_MPEG2_PICTURE_ASSET_READER_H +#define LIBDCP_MONO_MPEG2_PICTURE_ASSET_READER_H + + +#include "asset_reader.h" +#include "mono_mpeg2_picture_frame.h" + + +namespace dcp { + + +typedef AssetReader<ASDCP::MPEG2::MXFReader, MonoMPEG2PictureFrame> MonoMPEG2PictureAssetReader; + + +} + + +#endif + diff --git a/src/mono_mpeg2_picture_frame.cc b/src/mono_mpeg2_picture_frame.cc new file mode 100644 index 00000000..3da67212 --- /dev/null +++ b/src/mono_mpeg2_picture_frame.cc @@ -0,0 +1,83 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "compose.hpp" +#include "mono_mpeg2_picture_frame.h" + + +using std::make_shared; +using std::shared_ptr; +using namespace dcp; + + + +/** Make a picture frame from a 2D (monoscopic) asset. + * @param reader Reader for the asset's MXF file. + * @param n Frame within the asset, not taking EntryPoint into account. + * @param c Context for decryption, or 0. + * @param check_hmac true to check the HMAC and give an error if it is not as expected. + */ +MonoMPEG2PictureFrame::MonoMPEG2PictureFrame(ASDCP::MPEG2::MXFReader* reader, int n, shared_ptr<DecryptionContext> context, bool check_hmac) +{ + /* XXX: unfortunate guesswork on this buffer size */ + _buffer = make_shared<ASDCP::MPEG2::FrameBuffer>(4 * Kumu::Megabyte); + + auto const r = reader->ReadFrame(n, *_buffer, context->context(), check_hmac ? context->hmac() : nullptr); + + if (ASDCP_FAILURE(r)) { + boost::throw_exception(ReadError(String::compose("could not read video frame %1 (%2)", n, static_cast<int>(r)))); + } +} + + +uint8_t const * +MonoMPEG2PictureFrame::data() const +{ + return _buffer->RoData(); +} + + +uint8_t * +MonoMPEG2PictureFrame::data() +{ + return _buffer->Data(); +} + + +int +MonoMPEG2PictureFrame::size() const +{ + return _buffer->Size(); +} + diff --git a/src/mono_mpeg2_picture_frame.h b/src/mono_mpeg2_picture_frame.h new file mode 100644 index 00000000..13853a4e --- /dev/null +++ b/src/mono_mpeg2_picture_frame.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_MONO_MPEG2_PICTURE_FRAME_H +#define LIBDCP_MONO_MPEG2_PICTURE_FRAME_H + + +#include "asset_reader.h" +#include "data.h" + + +namespace dcp { + + +class MonoMPEG2PictureFrame : public Data +{ +public: + MonoMPEG2PictureFrame(MonoMPEG2PictureFrame const&) = delete; + MonoMPEG2PictureFrame& operator=(MonoMPEG2PictureFrame const&) = delete; + + /** @return Pointer to MPEG2 data */ + uint8_t const * data() const override; + + /** @return Pointer to MPEG2 data */ + uint8_t* data () override; + + /** @return Size of MPEG2 data in bytes */ + int size() const override; + +private: + /* XXX: this is a bit of a shame, but I tried friend MonoMPEG2PictureAssetReader and it's + rejected by some (seemingly older) GCCs. + */ + friend class AssetReader<ASDCP::MPEG2::MXFReader, MonoMPEG2PictureFrame>; + + MonoMPEG2PictureFrame(ASDCP::MPEG2::MXFReader* reader, int n, std::shared_ptr<DecryptionContext>, bool check_hmac); + + std::shared_ptr<ASDCP::MPEG2::FrameBuffer> _buffer; +}; + + +} + + +#endif diff --git a/src/mpeg2_picture_asset.cc b/src/mpeg2_picture_asset.cc new file mode 100644 index 00000000..6cd0b428 --- /dev/null +++ b/src/mpeg2_picture_asset.cc @@ -0,0 +1,74 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "mpeg2_picture_asset.h" + + +using std::string; +using namespace dcp; + + +MPEG2PictureAsset::MPEG2PictureAsset(boost::filesystem::path file) + : PictureAsset(file) +{ + +} + + +void +MPEG2PictureAsset::read_video_descriptor(ASDCP::MPEG2::VideoDescriptor const& descriptor) +{ + _size.width = descriptor.StoredWidth; + _size.height = descriptor.StoredHeight; + _edit_rate = Fraction(descriptor.EditRate.Numerator, descriptor.EditRate.Denominator); + _intrinsic_duration = descriptor.ContainerDuration; + _frame_rate = Fraction(descriptor.SampleRate.Numerator, descriptor.SampleRate.Denominator); + _screen_aspect_ratio = Fraction(descriptor.AspectRatio.Numerator, descriptor.AspectRatio.Denominator); +} + + +string +MPEG2PictureAsset::pkl_type (Standard standard) const +{ + DCP_ASSERT(standard == Standard::INTEROP); + return "application/x-smpte-mxf;asdcpKind=Picture"; +} + + +string +MPEG2PictureAsset::static_pkl_type(Standard standard) +{ + DCP_ASSERT(standard == Standard::INTEROP); + return "application/x-smpte-mxf;asdcpKind=Picture"; +} diff --git a/src/mpeg2_picture_asset.h b/src/mpeg2_picture_asset.h new file mode 100644 index 00000000..df882202 --- /dev/null +++ b/src/mpeg2_picture_asset.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_MPEG2_PICTURE_ASSET_H +#define LIBDCP_MPEG2_PICTURE_ASSET_H + + +/** @file src/mpeg2_picture_asset.h + * @brief MPEG2PictureAsset class + */ + + +#include "picture_asset.h" +#include <boost/filesystem/path.hpp> + + +namespace ASDCP { + namespace MPEG2 { + struct VideoDescriptor; + } +} + + +namespace dcp { + + +class MPEG2PictureAsset : public PictureAsset +{ +public: + explicit MPEG2PictureAsset(boost::filesystem::path file); + + static std::string static_pkl_type(Standard standard); + +protected: + void read_video_descriptor(ASDCP::MPEG2::VideoDescriptor const& descriptor); + +private: + std::string pkl_type(Standard standard) const override; +}; + + +} + + +#endif + diff --git a/src/mpeg2_transcode.cc b/src/mpeg2_transcode.cc new file mode 100644 index 00000000..ab77f0e1 --- /dev/null +++ b/src/mpeg2_transcode.cc @@ -0,0 +1,143 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "compose.hpp" +#include "exceptions.h" +#include "mono_mpeg2_picture_frame.h" +#include "mpeg2_transcode.h" +extern "C" { +#include <libavcodec/avcodec.h> +} + + +using std::shared_ptr; +using std::vector; +using namespace dcp; + + +MPEG2Codec::~MPEG2Codec() +{ + avcodec_free_context(&_context); +} + + + +MPEG2Decompressor::MPEG2Decompressor() +{ + _codec = avcodec_find_decoder_by_name("mpeg2video"); + if (!_codec) { + throw MPEG2CodecError("could not find codec"); + } + + _context = avcodec_alloc_context3(_codec); + if (!_context) { + throw MPEG2CodecError("could not allocate codec context"); + } + + int const r = avcodec_open2(_context, _codec, nullptr); + if (r < 0) { + avcodec_free_context(&_context); + throw MPEG2CodecError("could not open codec"); + } + + _decompressed_frame = av_frame_alloc(); + if (!_decompressed_frame) { + throw std::bad_alloc(); + } +} + + +MPEG2Decompressor::~MPEG2Decompressor() +{ + av_frame_free(&_decompressed_frame); +} + + +vector<FFmpegImage> +MPEG2Decompressor::decompress_frame(shared_ptr<const MonoMPEG2PictureFrame> frame) +{ + /* XXX: can we avoid this? */ + auto copy = av_malloc(frame->size() + AV_INPUT_BUFFER_PADDING_SIZE); + if (!copy) { + throw std::bad_alloc(); + } + memcpy(copy, frame->data(), frame->size()); + + AVPacket packet; + av_init_packet(&packet); + av_packet_from_data(&packet, reinterpret_cast<uint8_t*>(copy), frame->size()); + + auto images = decompress_packet(&packet); + + av_packet_unref(&packet); + + return images; +} + + +vector<FFmpegImage> +MPEG2Decompressor::flush() +{ + return decompress_packet(nullptr); +} + + +vector<FFmpegImage> +MPEG2Decompressor::decompress_packet(AVPacket* packet) +{ + int const r = avcodec_send_packet(_context, packet); + if (r < 0) { + throw MPEG2DecompressionError(String::compose("avcodec_send_packet failed (%1)", r)); + } + + vector<FFmpegImage> images; + while (true) { + int const r = avcodec_receive_frame(_context, _decompressed_frame); + if (r == AVERROR(EAGAIN) || r == AVERROR_EOF) { + break; + } else if (r < 0) { + throw MPEG2DecompressionError("avcodec_receive_frame failed"); + } + + auto clone = av_frame_clone(_decompressed_frame); + if (!clone) { + throw std::bad_alloc(); + } + + images.push_back(FFmpegImage(clone)); + } + + return images; +} + diff --git a/src/mpeg2_transcode.h b/src/mpeg2_transcode.h new file mode 100644 index 00000000..ef5c8351 --- /dev/null +++ b/src/mpeg2_transcode.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_MPEG2_TRANSCODE_H +#define LIBDCP_MPEG2_TRANSCODE_H + + +#include "ffmpeg_image.h" +#include <memory> + + +struct AVCodec; +struct AVCodecContext; +struct AVFrame; +struct AVPacket; + + +namespace dcp { + + +class MonoMPEG2PictureFrame; + + +class MPEG2Codec +{ +public: + MPEG2Codec() = default; + virtual ~MPEG2Codec(); + + MPEG2Codec(MPEG2Codec const&) = delete; + MPEG2Codec& operator=(MPEG2Codec const&) = delete; + +protected: + AVCodec const* _codec; + AVCodecContext* _context; +}; + + +class MPEG2Decompressor : public MPEG2Codec +{ +public: + MPEG2Decompressor(); + ~MPEG2Decompressor(); + + std::vector<FFmpegImage> decompress_frame(std::shared_ptr<const MonoMPEG2PictureFrame> frame); + std::vector<FFmpegImage> flush(); + +private: + std::vector<FFmpegImage> decompress_packet(AVPacket* packet); + + AVFrame* _decompressed_frame; +}; + + +} + + +#endif diff --git a/src/reel.cc b/src/reel.cc index fc47239d..acd7c7fc 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -327,7 +327,7 @@ Reel::give_kdm_to_assets (DecryptedKDM const & kdm) { for (auto const& i: kdm.keys()) { if (_main_picture && i.id() == _main_picture->key_id() && _main_picture->asset_ref().resolved()) { - _main_picture->asset()->set_key (i.key()); + _main_picture->j2k_asset()->set_key(i.key()); } if (_main_sound && i.id() == _main_sound->key_id() && _main_sound->asset_ref().resolved()) { _main_sound->asset()->set_key (i.key()); diff --git a/src/reel_mono_picture_asset.cc b/src/reel_mono_picture_asset.cc index 04c16d25..81eb4df9 100644 --- a/src/reel_mono_picture_asset.cc +++ b/src/reel_mono_picture_asset.cc @@ -47,7 +47,7 @@ using std::shared_ptr; using namespace dcp; -ReelMonoPictureAsset::ReelMonoPictureAsset (std::shared_ptr<MonoJ2KPictureAsset> asset, int64_t entry_point) +ReelMonoPictureAsset::ReelMonoPictureAsset(std::shared_ptr<PictureAsset> asset, int64_t entry_point) : ReelPictureAsset (asset, entry_point) { diff --git a/src/reel_mono_picture_asset.h b/src/reel_mono_picture_asset.h index 54429ad4..13c6545e 100644 --- a/src/reel_mono_picture_asset.h +++ b/src/reel_mono_picture_asset.h @@ -43,6 +43,7 @@ #include "reel_picture_asset.h" #include "mono_j2k_picture_asset.h" +#include "mono_mpeg2_picture_asset.h" namespace dcp { @@ -57,19 +58,29 @@ class MonoJ2KPictureAsset; class ReelMonoPictureAsset : public ReelPictureAsset { public: - ReelMonoPictureAsset (std::shared_ptr<MonoJ2KPictureAsset> asset, int64_t entry_point); + ReelMonoPictureAsset(std::shared_ptr<PictureAsset> asset, int64_t entry_point); explicit ReelMonoPictureAsset (std::shared_ptr<const cxml::Node>); - /** @return the MonoJ2KPictureAsset that this object refers to */ - std::shared_ptr<const MonoJ2KPictureAsset> mono_asset () const { + /** @return the MonoJ2KPictureAsset that this object refers to, if applicable */ + std::shared_ptr<const MonoJ2KPictureAsset> mono_j2k_asset() const { return asset_of_type<const MonoJ2KPictureAsset>(); } /** @return the MonoJ2KPictureAsset that this object refers to */ - std::shared_ptr<MonoJ2KPictureAsset> mono_asset () { + std::shared_ptr<MonoJ2KPictureAsset> mono_j2k_asset() { return asset_of_type<MonoJ2KPictureAsset>(); } + /** @return the MonoMPEG2PictureAsset that this object refers to, if applicable */ + std::shared_ptr<const MonoMPEG2PictureAsset> mono_mpeg2_asset() const { + return asset_of_type<const MonoMPEG2PictureAsset>(); + } + + /** @return the MonoMPEG2PictureAsset that this object refers to */ + std::shared_ptr<MonoMPEG2PictureAsset> mono_mpeg2_asset() { + return asset_of_type<MonoMPEG2PictureAsset>(); + } + private: std::string cpl_node_name (Standard standard) const override; }; diff --git a/src/reel_picture_asset.cc b/src/reel_picture_asset.cc index ca22b6fc..37a6bfcc 100644 --- a/src/reel_picture_asset.cc +++ b/src/reel_picture_asset.cc @@ -59,7 +59,7 @@ using boost::optional; using namespace dcp; -ReelPictureAsset::ReelPictureAsset (shared_ptr<J2KPictureAsset> asset, int64_t entry_point) +ReelPictureAsset::ReelPictureAsset(shared_ptr<PictureAsset> asset, int64_t entry_point) : ReelFileAsset (asset, asset->key_id(), asset->id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point) , _frame_rate (asset->frame_rate ()) , _screen_aspect_ratio (asset->screen_aspect_ratio ()) diff --git a/src/reel_picture_asset.h b/src/reel_picture_asset.h index 6185f3dd..9f42a5b6 100644 --- a/src/reel_picture_asset.h +++ b/src/reel_picture_asset.h @@ -43,6 +43,7 @@ #include "reel_file_asset.h" #include "j2k_picture_asset.h" +#include "mpeg2_picture_asset.h" namespace dcp { @@ -54,20 +55,41 @@ namespace dcp { class ReelPictureAsset : public ReelFileAsset { public: - ReelPictureAsset (std::shared_ptr<J2KPictureAsset> asset, int64_t entry_point); + ReelPictureAsset(std::shared_ptr<PictureAsset> asset, int64_t entry_point); explicit ReelPictureAsset (std::shared_ptr<const cxml::Node>); - /** @return the J2KPictureAsset that this object refers to */ - std::shared_ptr<const J2KPictureAsset> asset () const { + /** @return the PictureAsset that this object refers to, if applicable */ + std::shared_ptr<const PictureAsset> asset() const { + return asset_of_type<const PictureAsset>(); + } + + /** @return the PictureAsset that this object refers to, if applicable */ + std::shared_ptr<PictureAsset> asset() { + return asset_of_type<PictureAsset>(); + } + + /** @return the J2KPictureAsset that this object refers to, if applicable */ + std::shared_ptr<const J2KPictureAsset> j2k_asset() const { return asset_of_type<const J2KPictureAsset>(); } - /** @return the J2KPictureAsset that this object refers to */ - std::shared_ptr<J2KPictureAsset> asset () { + /** @return the J2KPictureAsset that this object refers to, if applicable */ + std::shared_ptr<J2KPictureAsset> j2k_asset() { return asset_of_type<J2KPictureAsset>(); } + /** @return the MPEG2PictureAsset that this object refers to, if applicable */ + std::shared_ptr<const MPEG2PictureAsset> mpeg2_asset() const { + return asset_of_type<const MPEG2PictureAsset>(); + } + + /** @return the MPEG2PictureAsset that this object refers to, if applicable */ + std::shared_ptr<MPEG2PictureAsset> mpeg2_asset() { + return asset_of_type<MPEG2PictureAsset>(); + } + virtual xmlpp::Element* write_to_cpl(xmlpp::Element* node, Standard standard) const override; + bool equals(std::shared_ptr<const ReelPictureAsset>, EqualityOptions const&, NoteHandler) const; /** @return picture frame rate */ diff --git a/src/wscript b/src/wscript index 2ce8e556..47b716cf 100644 --- a/src/wscript +++ b/src/wscript @@ -77,6 +77,10 @@ def build(bld): mono_j2k_picture_asset.cc mono_j2k_picture_asset_writer.cc mono_j2k_picture_frame.cc + mono_mpeg2_picture_asset.cc + mono_mpeg2_picture_frame.cc + mpeg2_picture_asset.cc + mpeg2_transcode.cc mxf.cc name_format.cc object.cc @@ -171,6 +175,7 @@ def build(bld): identity_transfer_function.h interop_load_font_node.h interop_subtitle_asset.h + ffmpeg_image.h j2k_picture_asset.h j2k_picture_asset_writer.h j2k_transcode.h @@ -185,6 +190,11 @@ def build(bld): mono_j2k_picture_asset_reader.h mono_j2k_picture_asset_writer.h mono_j2k_picture_frame.h + mono_mpeg2_picture_asset.h + mono_mpeg2_picture_asset_reader.h + mono_mpeg2_picture_frame.h + mpeg2_picture_asset.h + mpeg2_transcode.h mxf.h name_format.h object.h @@ -250,7 +260,7 @@ def build(bld): obj.name = 'libdcp%s' % bld.env.API_VERSION obj.target = 'dcp%s' % bld.env.API_VERSION obj.export_includes = ['.'] - obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_DCPOMATIC XERCES' + obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_DCPOMATIC XERCES AVCODEC AVUTIL' obj.source = source # Library for gcov @@ -262,7 +272,7 @@ def build(bld): obj.name = 'libdcp%s_gcov' % bld.env.API_VERSION obj.target = 'dcp%s_gcov' % bld.env.API_VERSION obj.export_includes = ['.'] - obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_DCPOMATIC XERCES' + obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1 ASDCPLIB_DCPOMATIC XERCES AVCODEC AVUTIL' obj.use = 'libkumu-libdcp%s libasdcp-libdcp%s' % (bld.env.API_VERSION, bld.env.API_VERSION) obj.source = source obj.cppflags = ['-fprofile-arcs', '-ftest-coverage', '-fno-inline', '-fno-default-inline', '-fno-elide-constructors', '-g', '-O0'] diff --git a/test/dcp_test.cc b/test/dcp_test.cc index 4647d8ae..63de990f 100644 --- a/test/dcp_test.cc +++ b/test/dcp_test.cc @@ -203,9 +203,9 @@ test_rewriting_sound(string name, bool modify) dcp::DCP B ("build/test/" + name); auto reel = make_shared<dcp::Reel>(); - BOOST_REQUIRE (A_picture->mono_asset()); - BOOST_REQUIRE (A_picture->mono_asset()->file()); - copy_file (A_picture->mono_asset()->file().get(), path("build") / "test" / name / picture); + BOOST_REQUIRE(A_picture->mono_j2k_asset()); + BOOST_REQUIRE(A_picture->mono_j2k_asset()->file()); + copy_file(A_picture->mono_j2k_asset()->file().get(), path("build") / "test" / name / picture); reel->add(make_shared<dcp::ReelMonoPictureAsset>(make_shared<dcp::MonoJ2KPictureAsset>(path("build") / "test" / name / picture), 0)); auto reader = A_sound->asset()->start_read(); diff --git a/test/kdm_test.cc b/test/kdm_test.cc index 4b261d48..75a6019e 100644 --- a/test/kdm_test.cc +++ b/test/kdm_test.cc @@ -320,7 +320,7 @@ BOOST_AUTO_TEST_CASE (vf_kdm_test) ov->write_xml (); auto ov_reel = ov->cpls()[0]->reels()[0]; - auto ov_reel_picture = make_shared<dcp::ReelMonoPictureAsset>(dynamic_pointer_cast<dcp::ReelMonoPictureAsset>(ov_reel->main_picture())->mono_asset(), 0); + auto ov_reel_picture = make_shared<dcp::ReelMonoPictureAsset>(dynamic_pointer_cast<dcp::ReelMonoPictureAsset>(ov_reel->main_picture())->mono_j2k_asset(), 0); auto ov_reel_sound = make_shared<dcp::ReelSoundAsset>(ov_reel->main_sound()->asset(), 0); /* Make VF */ diff --git a/test/mono_mpeg2_picture_read_test.cc b/test/mono_mpeg2_picture_read_test.cc new file mode 100644 index 00000000..f0d4aac0 --- /dev/null +++ b/test/mono_mpeg2_picture_read_test.cc @@ -0,0 +1,62 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "mono_mpeg2_picture_asset.h" +#include "mpeg2_transcode.h" +#include "test.h" +#include <boost/test/unit_test.hpp> + +extern "C" { +#include <libavcodec/avcodec.h> +} + + +BOOST_AUTO_TEST_CASE(mpeg_mono_picture_read_test) +{ + dcp::MonoMPEG2PictureAsset asset(private_test / "data" / "mas" / "r2.mxf" ); + std::cout << "frame rate " << asset.frame_rate().numerator << "\n"; + std::cout << "duration " << asset.intrinsic_duration() << "\n"; + + auto reader = asset.start_read(); + + dcp::MPEG2Decompressor decompressor; + for (auto i = 0; i < asset.intrinsic_duration(); ++i) { + auto images = decompressor.decompress_frame(reader->get_frame(i)); + BOOST_CHECK_EQUAL(images.size(), i == 0 ? 0U : 1U); + } + + auto images = decompressor.flush(); + BOOST_CHECK_EQUAL(images.size(), 1U); +} + diff --git a/test/wscript b/test/wscript index 92c83598..ee5b754b 100644 --- a/test/wscript +++ b/test/wscript @@ -53,7 +53,7 @@ def configure(conf): def build(bld): obj = bld(features='cxx cxxprogram') obj.name = 'tests' - obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM BOOST_DATETIME OPENJPEG CXML XMLSEC1 SNDFILE OPENMP ASDCPLIB_DCPOMATIC LIBXML++ OPENSSL XERCES DL' + obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM BOOST_DATETIME OPENJPEG CXML XMLSEC1 SNDFILE OPENMP ASDCPLIB_DCPOMATIC LIBXML++ OPENSSL XERCES DL AVCODEC AVUTIL' obj.cppflags = ['-fno-inline', '-fno-elide-constructors', '-g', '-O0'] if bld.env['CXX_NAME'] == 'gcc': obj.cppflags.append('-fno-default-inline') @@ -94,6 +94,7 @@ def build(bld): make_digest_test.cc markers_test.cc mca_test.cc + mono_mpeg2_picture_read_test.cc kdm_test.cc key_test.cc language_tag_test.cc @@ -124,7 +125,7 @@ def build(bld): obj = bld(features='cxx cxxprogram') obj.name = 'subs_in_out' - obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC XMLSEC1 OPENSSL DL LIBXML++' + obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC XMLSEC1 OPENSSL DL LIBXML++ AVCODEC AVUTIL' obj.cppflags = ['-fno-inline', '-fno-elide-constructors', '-g', '-O0'] if bld.env['CXX_NAME'] == 'gcc': obj.cppflags.append('-fno-default-inline') @@ -141,7 +142,7 @@ def build(bld): obj = bld(features='cxx cxxprogram') obj.name = 'rewrite_subs' - obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC XMLSEC1 OPENSSL DL LIBXML++' + obj.uselib = 'BOOST_TEST BOOST_FILESYSTEM OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC XMLSEC1 OPENSSL DL LIBXML++ AVCODEC AVUTIL' obj.cppflags = ['-fno-inline', '-fno-elide-constructors', '-g', '-O0'] if bld.env['CXX_NAME'] == 'gcc': obj.cppflags.append('-fno-default-inline') diff --git a/tools/wscript b/tools/wscript index 53b74e70..d282c88c 100644 --- a/tools/wscript +++ b/tools/wscript @@ -32,7 +32,7 @@ # def build(bld): - uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC BOOST_FILESYSTEM LIBXML++ XMLSEC1 OPENSSL XERCES DL MAGICK' + uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_DCPOMATIC BOOST_FILESYSTEM LIBXML++ XMLSEC1 OPENSSL XERCES DL MAGICK AVCODEC AVUTIL' for f in ['diff', 'info', 'verify']: obj = bld(features='cxx cxxprogram') @@ -248,6 +248,9 @@ def configure(conf): lib=['boost_date_time%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix], uselib_store='BOOST_DATETIME') + conf.check_cfg(package='libavcodec', args='--cflags --libs', uselib_store='AVCODEC', mandatory=True) + conf.check_cfg(package='libavutil', args='--cflags --libs', uselib_store='AVUTIL', mandatory=True) + if not conf.env.DISABLE_TESTS: conf.recurse('test') if conf.options.enable_gcov: |
