summaryrefslogtreecommitdiff
path: root/src/asdcp-wrap.cpp
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2015-03-13 16:18:02 +0000
committerjhurst <>2015-03-13 16:18:02 +0000
commit887003223e52b4fb2b9ca135dcb8a23e1f133cd4 (patch)
tree48041e5c550e6baa5ab1651edb82a4af28b6ad9d /src/asdcp-wrap.cpp
parentcc15da3e3cb47333f92d8701b03b0ef87a88bea4 (diff)
turn on the text
Diffstat (limited to 'src/asdcp-wrap.cpp')
-rwxr-xr-xsrc/asdcp-wrap.cpp159
1 files changed, 150 insertions, 9 deletions
diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp
index 72dbaea..9388d87 100755
--- a/src/asdcp-wrap.cpp
+++ b/src/asdcp-wrap.cpp
@@ -138,6 +138,7 @@ Options:\n\
-3 - Create a stereoscopic image file. Expects two\n\
directories of JP2K codestreams (directories must have\n\
an equal number of frames; the left eye is first)\n\
+ -A <UL> - Set DataEssenceCoding UL value in an Aux Data file\n\
-C <UL> - Set ChannelAssignment UL value in a PCM file\n\
-h | -help - Show help\n\
-V - Show version information\n\
@@ -238,6 +239,7 @@ public:
Kumu::PathList_t filenames; // list of filenames to be processed
UL channel_assignment;
UL picture_coding;
+ UL aux_data_coding;
bool dolby_atmos_sync_flag; // if true, insert a Dolby Atmos Synchronization channel.
ui32_t ffoa; /// first frame of action for atmos wrapping
ui32_t max_channel_count; /// max channel count for atmos wrapping
@@ -319,6 +321,15 @@ public:
{
case '3': stereo_image_flag = true; break;
+ case 'A':
+ TEST_EXTRA_ARG(i, 'A');
+ if ( ! aux_data_coding.DecodeHex(argv[i]) )
+ {
+ fprintf(stderr, "Error decoding UL value: %s\n", argv[i]);
+ return;
+ }
+ break;
+
case 'a':
asset_id_flag = true;
TEST_EXTRA_ARG(i, 'a');
@@ -1475,6 +1486,123 @@ write_dolby_atmos_file(CommandOptions& Options)
return result;
}
+// Write one or more plaintext Aux Data (ST 429-14) bytestreams to a plaintext ASDCP file
+// Write one or more plaintext Aux Data (ST 429-14) bytestreams to a ciphertext ASDCP file
+//
+Result_t
+write_aux_data_file(CommandOptions& Options)
+{
+ AESEncContext* Context = 0;
+ HMACContext* HMAC = 0;
+ DCData::MXFWriter Writer;
+ DCData::FrameBuffer FrameBuffer(Options.fb_size);
+ DCData::DCDataDescriptor DDesc;
+ DCData::SequenceParser Parser;
+ byte_t IV_buf[CBC_BLOCK_SIZE];
+ Kumu::FortunaRNG RNG;
+
+ // set up essence parser
+ Result_t result = Parser.OpenRead(Options.filenames.front());
+
+ // set up MXF writer
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Parser.FillDCDataDescriptor(DDesc);
+ memcpy(DDesc.DataEssenceCoding, Options.aux_data_coding.Value(), Options.aux_data_coding.Size());
+ DDesc.EditRate = Options.PictureRate();
+
+ if ( Options.verbose_flag )
+ {
+ fprintf(stderr, "Aux Data\n");
+ fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size);
+ DCData::DCDataDescriptorDump(DDesc);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ {
+ WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
+ if ( Options.asset_id_flag )
+ memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen);
+ else
+ Kumu::GenRandomUUID(Info.AssetUUID);
+
+ Info.LabelSetType = LS_MXF_SMPTE;
+
+ // configure encryption
+ if( Options.key_flag )
+ {
+ Kumu::GenRandomUUID(Info.ContextID);
+ Info.EncryptedEssence = true;
+
+ if ( Options.key_id_flag )
+ {
+ memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen);
+ }
+ else
+ {
+ create_random_uuid(Info.CryptographicKeyID);
+ }
+
+ Context = new AESEncContext;
+ result = Context->InitKey(Options.key_value);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+
+ if ( ASDCP_SUCCESS(result) && Options.write_hmac )
+ {
+ Info.UsesHMAC = true;
+ HMAC = new HMACContext;
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.OpenWrite(Options.out_file, Info, DDesc);
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t duration = 0;
+ result = Parser.Reset();
+
+ while ( ASDCP_SUCCESS(result) && duration++ < Options.duration )
+ {
+ result = Parser.ReadFrame(FrameBuffer);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+
+ if ( Options.encrypt_header_flag )
+ FrameBuffer.PlaintextOffset(0);
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ {
+ result = Writer.WriteFrame(FrameBuffer, Context, HMAC);
+
+ // The Writer class will forward the last block of ciphertext
+ // to the encryption context for use as the IV for the next
+ // frame. If you want to use non-sequitur IV values, un-comment
+ // the following line of code.
+ // if ( ASDCP_SUCCESS(result) && Options.key_flag )
+ // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+ }
+ }
+
+ if ( result == RESULT_ENDOFFILE )
+ result = RESULT_OK;
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ result = Writer.Finalize();
+
+ return result;
+}
+
//
int
main(int argc, const char** argv)
@@ -1532,16 +1660,16 @@ main(int argc, const char** argv)
case ESS_PCM_24b_48k:
case ESS_PCM_24b_96k:
- if ( Options.dolby_atmos_sync_flag )
- {
- result = write_PCM_with_ATMOS_sync_file(Options);
- }
- else
- {
- result = write_PCM_file(Options);
- }
+ if ( Options.dolby_atmos_sync_flag )
+ {
+ result = write_PCM_with_ATMOS_sync_file(Options);
+ }
+ else
+ {
+ result = write_PCM_file(Options);
+ }
break;
-
+
case ESS_TIMED_TEXT:
result = write_timed_text_file(Options);
break;
@@ -1550,6 +1678,19 @@ main(int argc, const char** argv)
result = write_dolby_atmos_file(Options);
break;
+ case ESS_DCDATA_UNKNOWN:
+ if ( ! Options.aux_data_coding.HasValue() )
+ {
+ fprintf(stderr, "Option \"-A <UL>\" is required for Aux Data essence.\n",
+ Options.filenames.front().c_str());
+ return 3;
+ }
+ else
+ {
+ result = write_aux_data_file(Options);
+ }
+ break;
+
default:
fprintf(stderr, "%s: Unknown file type, not ASDCP-compatible essence.\n",
Options.filenames.front().c_str());