X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdcp_video_frame.cc;h=3e5c4b3aaa4cb5b7433712d8215ea14351a7b1a2;hb=129afab72bfc026b5704c41a6bfc0f4b3a2c4033;hp=da7133c4ba2a7f6552d76819dd7acc01ab22cac8;hpb=82af50304f55a961cba6afefbfa7edd5440bfcc4;p=dcpomatic.git diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index da7133c4b..3e5c4b3aa 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -55,6 +55,7 @@ #include "scaler.h" #include "image.h" #include "log.h" +#include "subtitle.h" using namespace std; using namespace boost; @@ -72,10 +73,16 @@ using namespace boost; * @param l Log to write to. */ DCPVideoFrame::DCPVideoFrame ( - shared_ptr yuv, Size out, int p, Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l) + shared_ptr yuv, shared_ptr sub, + Size out, int p, int subtitle_offset, float subtitle_scale, + Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l + ) : _input (yuv) + , _subtitle (sub) , _out_size (out) , _padding (p) + , _subtitle_offset (subtitle_offset) + , _subtitle_scale (subtitle_scale) , _scaler (s) , _frame (f) /* we round here; not sure if this is right */ @@ -147,18 +154,28 @@ DCPVideoFrame::~DCPVideoFrame () shared_ptr DCPVideoFrame::encode_locally () { - shared_ptr prepared = _input; - if (!_post_process.empty ()) { - prepared = prepared->post_process (_post_process); + _input = _input->post_process (_post_process); } - prepared = prepared->scale_and_convert_to_rgb (_out_size, _padding, _scaler); + shared_ptr prepared = _input->scale_and_convert_to_rgb (_out_size, _padding, _scaler); + + if (_subtitle) { + list > subs = _subtitle->images (); + for (list >::iterator i = subs.begin(); i != subs.end(); ++i) { + Rectangle tx = transformed_subtitle_area ( + float (_out_size.width) / _input->size().width, + float (_out_size.height) / _input->size().height, + (*i)->area(), _subtitle_offset, _subtitle_scale + ); + + shared_ptr im = (*i)->image()->scale (Size (tx.w, tx.h), _scaler); + prepared->alpha_blend (im, Position (tx.x, tx.y)); + } + } create_openjpeg_container (); - int const size = _out_size.width * _out_size.height; - struct { double r, g, b; } s; @@ -169,27 +186,41 @@ DCPVideoFrame::encode_locally () /* Copy our RGB into the openjpeg container, converting to XYZ in the process */ - uint8_t* p = prepared->data()[0]; - for (int i = 0; i < size; ++i) { - /* In gamma LUT (converting 8-bit input to 12-bit) */ - s.r = lut_in[_colour_lut_index][*p++ << 4]; - s.g = lut_in[_colour_lut_index][*p++ << 4]; - s.b = lut_in[_colour_lut_index][*p++ << 4]; - - /* RGB to XYZ Matrix */ - d.x = ((s.r * color_matrix[_colour_lut_index][0][0]) + (s.g * color_matrix[_colour_lut_index][0][1]) + (s.b * color_matrix[_colour_lut_index][0][2])); - d.y = ((s.r * color_matrix[_colour_lut_index][1][0]) + (s.g * color_matrix[_colour_lut_index][1][1]) + (s.b * color_matrix[_colour_lut_index][1][2])); - d.z = ((s.r * color_matrix[_colour_lut_index][2][0]) + (s.g * color_matrix[_colour_lut_index][2][1]) + (s.b * color_matrix[_colour_lut_index][2][2])); - - /* DCI companding */ - d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - d.y = d.y * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - d.z = d.z * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); - - /* Out gamma LUT */ - _image->comps[0].data[i] = lut_out[LO_DCI][(int) d.x]; - _image->comps[1].data[i] = lut_out[LO_DCI][(int) d.y]; - _image->comps[2].data[i] = lut_out[LO_DCI][(int) d.z]; + int jn = 0; + for (int y = 0; y < _out_size.height; ++y) { + uint8_t* p = prepared->data()[0] + y * prepared->line_size()[0]; + for (int x = 0; x < _out_size.width; ++x) { + + /* In gamma LUT (converting 8-bit input to 12-bit) */ + s.r = lut_in[_colour_lut_index][*p++ << 4]; + s.g = lut_in[_colour_lut_index][*p++ << 4]; + s.b = lut_in[_colour_lut_index][*p++ << 4]; + + /* RGB to XYZ Matrix */ + d.x = ((s.r * color_matrix[_colour_lut_index][0][0]) + + (s.g * color_matrix[_colour_lut_index][0][1]) + + (s.b * color_matrix[_colour_lut_index][0][2])); + + d.y = ((s.r * color_matrix[_colour_lut_index][1][0]) + + (s.g * color_matrix[_colour_lut_index][1][1]) + + (s.b * color_matrix[_colour_lut_index][1][2])); + + d.z = ((s.r * color_matrix[_colour_lut_index][2][0]) + + (s.g * color_matrix[_colour_lut_index][2][1]) + + (s.b * color_matrix[_colour_lut_index][2][2])); + + /* DCI companding */ + d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + d.y = d.y * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + d.z = d.z * DCI_COEFFICENT * (DCI_LUT_SIZE - 1); + + /* Out gamma LUT */ + _image->comps[0].data[jn] = lut_out[LO_DCI][(int) d.x]; + _image->comps[1].data[jn] = lut_out[LO_DCI][(int) d.y]; + _image->comps[2].data[jn] = lut_out[LO_DCI][(int) d.z]; + + ++jn; + } } /* Set the max image and component sizes based on frame_rate */ @@ -262,11 +293,7 @@ DCPVideoFrame::encode_locally () throw EncodeError ("jpeg2000 encoding failed"); } - { - stringstream s; - s << "Finished locally-encoded frame " << _frame; - _log->log (s.str ()); - } + _log->log (String::compose ("Finished locally-encoded frame %1", _frame)); return shared_ptr (new LocallyEncodedData (_cio->buffer, cio_tell (_cio))); } @@ -293,6 +320,8 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) << _input->pixel_format() << " " << _out_size.width << " " << _out_size.height << " " << _padding << " " + << _subtitle_offset << " " + << _subtitle_scale << " " << _scaler->id () << " " << _frame << " " << _frames_per_second << " " @@ -300,10 +329,6 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) << Config::instance()->colour_lut_index () << " " << Config::instance()->j2k_bandwidth () << " "; - for (int i = 0; i < _input->components(); ++i) { - s << _input->line_size()[i] << " "; - } - socket.write ((uint8_t *) s.str().c_str(), s.str().length() + 1, 30); for (int i = 0; i < _input->components(); ++i) { @@ -318,11 +343,7 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) /* now read the rest */ socket.read_definite_and_consume (e->data(), e->size(), 30); - { - stringstream s; - s << "Finished remotely-encoded frame " << _frame; - _log->log (s.str ()); - } + _log->log (String::compose ("Finished remotely-encoded frame %1", _frame)); return e; }