+//------------------------------------------------------------------------------------------
+// TimedText essence
+
+// Read one or more timed text streams from a plaintext AS-02 file
+//
+Result_t
+read_timed_text_file(CommandOptions& Options)
+{
+ AESDecContext* Context = 0;
+ HMACContext* HMAC = 0;
+ AS_02::TimedText::MXFReader Reader;
+ TimedText::FrameBuffer FrameBuffer(Options.fb_size);
+ //ASDCP::TimedText::FrameBuffer FrameBuffer(Options.fb_size);
+ AS_02::TimedText::TimedTextDescriptor TDesc;
+ ASDCP::MXF::TimedTextDescriptor *tt_descriptor = 0;
+
+ Result_t result = Reader.OpenRead(Options.input_filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_TimedTextDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&tt_descriptor));
+ if ( Options.verbose_flag ) {
+ tt_descriptor->Dump();
+ }
+
+
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
+ std::string XMLDoc;
+ std::string out_path = Kumu::PathDirname(Options.file_prefix);
+ ui32_t write_count;
+ char buf[64];
+ TimedText::ResourceList_t::const_iterator ri;
+
+ result = Reader.ReadTimedTextResource(XMLDoc);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Reader.FillTimedTextDescriptor(TDesc);
+ FrameBuffer.Capacity(Options.fb_size);
+
+ if ( Options.verbose_flag )
+ TimedText::DescriptorDump(TDesc);
+ }
+
+ if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) )
+ {
+ Kumu::FileWriter Writer;
+ result = Writer.OpenWrite(Options.file_prefix);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.Write(reinterpret_cast<const byte_t*>(XMLDoc.c_str()), XMLDoc.size(), &write_count);
+ }
+
+ for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ )
+ {
+ result = Reader.ReadAncillaryResource(ri->ResourceID, FrameBuffer, Context, HMAC);
+
+ if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) )
+ {
+ Kumu::FileWriter Writer;
+ if (out_path != "") {
+ result = Writer.OpenWrite(Kumu::PathJoin(out_path, Kumu::UUID(ri->ResourceID).EncodeHex(buf, 64)).c_str());
+ } else {
+ // Workaround for a bug in Kumu::PathJoin
+ result = Writer.OpenWrite(Kumu::UUID(ri->ResourceID).EncodeHex(buf, 64));
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count);
+
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+ }
+ }
+ }
+ return result;
+}
+
+//
+Result_t
+read_isxd_file(CommandOptions& Options)
+{
+ AESDecContext* Context = 0;
+ HMACContext* HMAC = 0;
+ AS_02::ISXD::MXFReader Reader;
+ ASDCP::FrameBuffer FrameBuffer;
+ ui32_t frame_count = 0;
+
+ Result_t result = Reader.OpenRead(Options.input_filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ result = FrameBuffer.Capacity(Options.fb_size);
+ frame_count = Reader.AS02IndexReader().GetDuration();
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ std::list<MXF::InterchangeObject*> object_list;
+ Reader.OP1aHeader().GetMDObjectsByType(DefaultSMPTEDict().ul(MDD_GenericStreamTextBasedSet), object_list);
+
+ std::list<MXF::InterchangeObject*>::iterator i;
+ for ( i = object_list.begin(); i != object_list.end(); ++i )
+ {
+ MXF::GenericStreamTextBasedSet *text_object = dynamic_cast<MXF::GenericStreamTextBasedSet*>(*i);
+ assert(text_object);
+ text_object->Dump(stderr);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) && Options.key_flag )
+ {
+ Context = new AESDecContext;
+ result = Context->InitKey(Options.key_value);
+
+ if ( ASDCP_SUCCESS(result) && Options.read_hmac )
+ {
+ WriterInfo Info;
+ Reader.FillWriterInfo(Info);
+
+ if ( Info.UsesHMAC )
+ {
+ HMAC = new HMACContext;
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
+ }
+ else
+ {
+ fputs("File does not contain HMAC values, ignoring -m option.\n", stderr);
+ }
+ }
+ }
+
+ ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count);
+ if ( last_frame > frame_count )
+ last_frame = frame_count;
+
+ char name_format[64];
+ snprintf(name_format, 64, "%%s%%0%du.%s", Options.number_width, Options.extension);
+
+ for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ )
+ {
+ result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( ! Options.no_write_flag )
+ {
+ Kumu::FileWriter OutFile;
+ char filename[256];
+ ui32_t write_count;
+ snprintf(filename, 256, name_format, Options.file_prefix, i);
+ result = OutFile.OpenWrite(filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count);
+ }
+ }
+ }
+
+ return result;
+}
+
+Result_t
+extract_generic_stream_partition_payload(const std::string& in_filename, const ui32_t sid, const std::string& out_filename)
+{
+ ASDCP::FrameBuffer payload;
+ AS_02::ISXD::MXFReader reader;
+
+ Result_t result = reader.OpenRead(in_filename);
+
+ if ( KM_SUCCESS(result) )
+ {
+ result = reader.ReadGenericStreamPartitionPayload(sid, payload);
+ }
+
+ if ( KM_SUCCESS(result) )
+ {
+ Kumu::FileWriter writer;
+ ui32_t write_count = 0;
+ result = writer.OpenWrite(out_filename);
+
+ if ( KM_SUCCESS(result) )
+ {
+ result = writer.Write(payload.RoData(), payload.Size(), &write_count);
+ }
+ }
+
+ return result;
+}
+
+