summaryrefslogtreecommitdiff
path: root/src/lib/dcp_decoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dcp_decoder.cc')
-rw-r--r--src/lib/dcp_decoder.cc123
1 files changed, 80 insertions, 43 deletions
diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc
index 727dcbf26..abbaaf15d 100644
--- a/src/lib/dcp_decoder.cc
+++ b/src/lib/dcp_decoder.cc
@@ -26,19 +26,23 @@
#include "constants.h"
#include "dcp_content.h"
#include "dcp_decoder.h"
+#include "dcpomatic_log.h"
#include "digester.h"
#include "ffmpeg_image_proxy.h"
#include "frame_interval_checker.h"
#include "image.h"
#include "j2k_image_proxy.h"
+#include "raw_image_proxy.h"
#include "text_decoder.h"
+#include "util.h"
#include "video_decoder.h"
#include <dcp/cpl.h>
#include <dcp/dcp.h>
#include <dcp/decrypted_kdm.h>
-#include <dcp/mono_picture_asset.h>
-#include <dcp/mono_picture_asset_reader.h>
-#include <dcp/mono_picture_frame.h>
+#include <dcp/mono_j2k_picture_asset.h>
+#include <dcp/mono_j2k_picture_asset_reader.h>
+#include <dcp/mono_j2k_picture_frame.h>
+#include <dcp/mono_mpeg2_picture_asset.h>
#include <dcp/reel.h>
#include <dcp/reel_atmos_asset.h>
#include <dcp/reel_closed_caption_asset.h>
@@ -48,9 +52,9 @@
#include <dcp/search.h>
#include <dcp/sound_asset_reader.h>
#include <dcp/sound_frame.h>
-#include <dcp/stereo_picture_asset.h>
-#include <dcp/stereo_picture_asset_reader.h>
-#include <dcp/stereo_picture_frame.h>
+#include <dcp/stereo_j2k_picture_asset.h>
+#include <dcp/stereo_j2k_picture_asset_reader.h>
+#include <dcp/stereo_j2k_picture_frame.h>
#include <dcp/subtitle_image.h>
#include <iostream>
@@ -169,43 +173,60 @@ DCPDecoder::pass ()
*/
pass_texts (_next, picture_asset->size());
- if ((_mono_reader || _stereo_reader) && (_decode_referenced || !_dcp_content->reference_video())) {
+ if ((_j2k_mono_reader || _j2k_stereo_reader || _mpeg2_mono_reader) && (_decode_referenced || !_dcp_content->reference_video())) {
auto const entry_point = (*_reel)->main_picture()->entry_point().get_value_or(0);
- if (_mono_reader) {
+ if (_j2k_mono_reader) {
video->emit (
film(),
std::make_shared<J2KImageProxy>(
- _mono_reader->get_frame (entry_point + frame),
+ _j2k_mono_reader->get_frame(entry_point + frame),
picture_asset->size(),
AV_PIX_FMT_XYZ12LE,
_forced_reduction
),
- _offset + frame
+ ContentTime::from_frames(_offset + frame, vfr)
);
- } else {
+ } else if (_j2k_stereo_reader) {
video->emit (
film(),
std::make_shared<J2KImageProxy>(
- _stereo_reader->get_frame (entry_point + frame),
+ _j2k_stereo_reader->get_frame (entry_point + frame),
picture_asset->size(),
dcp::Eye::LEFT,
AV_PIX_FMT_XYZ12LE,
_forced_reduction
),
- _offset + frame
+ ContentTime::from_frames(_offset + frame, vfr)
);
video->emit (
film(),
std::make_shared<J2KImageProxy>(
- _stereo_reader->get_frame (entry_point + frame),
+ _j2k_stereo_reader->get_frame (entry_point + frame),
picture_asset->size(),
dcp::Eye::RIGHT,
AV_PIX_FMT_XYZ12LE,
_forced_reduction
),
- _offset + frame
+ ContentTime::from_frames(_offset + frame, vfr)
);
+ } else if (_mpeg2_mono_reader) {
+ /* XXX: got to flush this at some point */
+ try {
+ for (auto const& image: _mpeg2_decompressor->decompress_frame(_mpeg2_mono_reader->get_frame(entry_point + frame))) {
+ video->emit(
+ film(),
+ /* XXX: should this be PADDED? */
+ std::make_shared<RawImageProxy>(std::make_shared<Image>(image.frame(), Image::Alignment::COMPACT)),
+ /* XXX: this will be wrong */
+ ContentTime::from_frames(_offset + frame, vfr)
+ );
+ }
+ } catch (dcp::MPEG2DecompressionError& e) {
+ LOG_ERROR("Failed to decompress MPEG video frame %1 (%2)", entry_point + frame, e.what());
+ } catch (dcp::ReadError& e) {
+ LOG_ERROR("Failed to read MPEG2 video frame %1 (%2)", entry_point + frame, e.what());
+ }
}
}
@@ -214,15 +235,32 @@ DCPDecoder::pass ()
auto sf = _sound_reader->get_frame (entry_point + frame);
auto from = sf->data ();
- int const channels = _dcp_content->audio->stream()->channels ();
- int const frames = sf->size() / (3 * channels);
+ int const channels = _dcp_content->audio->stream()->channels();
+ int const frames = sf->size() / (sf->bits() * channels / 8);
auto data = make_shared<AudioBuffers>(channels, frames);
auto data_data = data->data();
- for (int i = 0; i < frames; ++i) {
- for (int j = 0; j < channels; ++j) {
- data_data[j][i] = static_cast<int> ((from[0] << 8) | (from[1] << 16) | (from[2] << 24)) / static_cast<float> (INT_MAX - 256);
- from += 3;
+
+ switch (sf->bits()) {
+ case 24:
+ {
+ for (int i = 0; i < frames; ++i) {
+ for (int j = 0; j < channels; ++j) {
+ data_data[j][i] = static_cast<int>((from[0] << 8) | (from[1] << 16) | (from[2] << 24)) / static_cast<float> (INT_MAX - 256);
+ from += 3;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ for (int i = 0; i < frames; ++i) {
+ for (int j = 0; j < channels; ++j) {
+ data_data[j][i] = static_cast<int>(from[0] << 16 | (from[1] << 24)) / static_cast<float> (INT_MAX - 256);
+ from += 2;
+ }
}
+ break;
+ }
}
audio->emit (film(), _dcp_content->audio->stream(), data, ContentTime::from_frames (_offset, vfr) + _next);
@@ -367,38 +405,40 @@ DCPDecoder::next_reel ()
void
DCPDecoder::get_readers ()
{
+ _j2k_mono_reader.reset();
+ _j2k_stereo_reader.reset();
+ _mpeg2_mono_reader.reset();
+ _sound_reader.reset();
+ _atmos_reader.reset();
+ _mpeg2_decompressor.reset();
+ _atmos_metadata = boost::none;
+
if (_reel == _reels.end() || !_dcp_content->can_be_played ()) {
- _mono_reader.reset ();
- _stereo_reader.reset ();
- _sound_reader.reset ();
- _atmos_reader.reset ();
return;
}
if (video && !video->ignore() && (*_reel)->main_picture()) {
auto asset = (*_reel)->main_picture()->asset ();
- auto mono = dynamic_pointer_cast<dcp::MonoPictureAsset> (asset);
- auto stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset);
- DCPOMATIC_ASSERT (mono || stereo);
- if (mono) {
- _mono_reader = mono->start_read ();
- _mono_reader->set_check_hmac (false);
- _stereo_reader.reset ();
+ auto j2k_mono = dynamic_pointer_cast<dcp::MonoJ2KPictureAsset>(asset);
+ auto j2k_stereo = dynamic_pointer_cast<dcp::StereoJ2KPictureAsset>(asset);
+ auto mpeg2_mono = dynamic_pointer_cast<dcp::MonoMPEG2PictureAsset>(asset);
+ DCPOMATIC_ASSERT(j2k_mono || j2k_stereo || mpeg2_mono)
+ if (j2k_mono) {
+ _j2k_mono_reader = j2k_mono->start_read();
+ _j2k_mono_reader->set_check_hmac(false);
+ } else if (j2k_stereo) {
+ _j2k_stereo_reader = j2k_stereo->start_read();
+ _j2k_stereo_reader->set_check_hmac(false);
} else {
- _stereo_reader = stereo->start_read ();
- _stereo_reader->set_check_hmac (false);
- _mono_reader.reset ();
+ _mpeg2_mono_reader = mpeg2_mono->start_read();
+ _mpeg2_mono_reader->set_check_hmac(false);
+ _mpeg2_decompressor = std::make_shared<dcp::MPEG2Decompressor>();
}
- } else {
- _mono_reader.reset ();
- _stereo_reader.reset ();
}
if (audio && !audio->ignore() && (*_reel)->main_sound()) {
_sound_reader = (*_reel)->main_sound()->asset()->start_read ();
_sound_reader->set_check_hmac (false);
- } else {
- _sound_reader.reset ();
}
if ((*_reel)->atmos()) {
@@ -406,9 +446,6 @@ DCPDecoder::get_readers ()
_atmos_reader = asset->start_read();
_atmos_reader->set_check_hmac (false);
_atmos_metadata = AtmosMetadata (asset);
- } else {
- _atmos_reader.reset ();
- _atmos_metadata = boost::none;
}
}