No-op; Fix GPL address and mention libdcp by name.
[libdcp.git] / src / stereo_picture_asset_writer.cc
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "stereo_picture_asset_writer.h"
22 #include "exceptions.h"
23 #include "dcp_assert.h"
24 #include "picture_asset.h"
25 #include "AS_DCP.h"
26 #include "KM_fileio.h"
27
28 #include "picture_asset_writer_common.cc"
29
30 using std::istream;
31 using std::ostream;
32 using std::string;
33 using boost::shared_ptr;
34 using namespace dcp;
35
36 struct StereoPictureAssetWriter::ASDCPState : public ASDCPStateBase
37 {
38         ASDCP::JP2K::MXFSWriter mxf_writer;
39 };
40
41 StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* mxf, boost::filesystem::path file, Standard standard, bool overwrite)
42         : PictureAssetWriter (mxf, file, standard, overwrite)
43         , _state (new StereoPictureAssetWriter::ASDCPState)
44         , _next_eye (EYE_LEFT)
45 {
46
47 }
48
49 void
50 StereoPictureAssetWriter::start (uint8_t* data, int size)
51 {
52         dcp::start (this, _state, _standard, _picture_asset, data, size);
53         _picture_asset->set_frame_rate (Fraction (_picture_asset->edit_rate().numerator * 2, _picture_asset->edit_rate().denominator));
54 }
55
56 /** Write a frame for one eye.  Frames must be written left, then right, then left etc.
57  *  @param data JPEG2000 data.
58  *  @param size Size of data.
59  */
60 FrameInfo
61 StereoPictureAssetWriter::write (uint8_t* data, int size)
62 {
63         DCP_ASSERT (!_finalized);
64
65         if (!_started) {
66                 start (data, size);
67         }
68
69         if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
70                 boost::throw_exception (MiscError ("could not parse J2K frame"));
71         }
72
73         uint64_t const before_offset = _state->mxf_writer.Tell ();
74
75         string hash;
76         Kumu::Result_t r = _state->mxf_writer.WriteFrame (
77                 _state->frame_buffer,
78                 _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
79                 _encryption_context,
80                 _hmac_context,
81                 &hash
82                 );
83
84         if (ASDCP_FAILURE (r)) {
85                 boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
86         }
87
88         _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
89
90         if (_next_eye == EYE_LEFT) {
91                 ++_frames_written;
92         }
93
94         return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
95 }
96
97 void
98 StereoPictureAssetWriter::fake_write (int size)
99 {
100         DCP_ASSERT (_started);
101         DCP_ASSERT (!_finalized);
102
103         Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size, _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT);
104         if (ASDCP_FAILURE (r)) {
105                 boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
106         }
107
108         _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
109         if (_next_eye == EYE_LEFT) {
110                 ++_frames_written;
111         }
112 }
113
114 bool
115 StereoPictureAssetWriter::finalize ()
116 {
117         if (_started) {
118                 Kumu::Result_t r = _state->mxf_writer.Finalize();
119                 if (ASDCP_FAILURE (r)) {
120                         boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r));
121                 }
122         }
123
124         _picture_asset->_intrinsic_duration = _frames_written;
125         return PictureAssetWriter::finalize ();
126 }