I try to write simple code which must copy op1a file without changes.
It works when audio tracks have 1 channel. If audio tracks has 2 channels and more i get exception
ERROR: 'size >= sample_size * num_samples' check failed
ERROR: near OP1AContentPackage.cpp:702
It happens in line "pcm_track->WriteSamples(channel...".
May be you have simple code to understand principle to write op1a mxf files
I tried to base on bmx\apps\bmxtranswrap\bmxtranswrap.cpp
and bmx\apps\raw2bmx\raw2bmx.cpp
Thank you in advance.
My code:
#include<stdio.h>#include<memory>#include"bmx/mxf_reader/MXFFileReader.h"#include"bmx/apps/AppMXFFileFactory.h"#include"bmx/clip_writer/ClipWriter.h"#include<bmx/essence_parser/SoundConversion.h>#include"OutputTrack.h"usingnamespacebmx;usingnamespacemxfpp;intmain(intargc,char*argv[]){if(argc<2){printf("No file specified.\n");return1;}std::stringfileName=argv[1];std::stringoutFileName=fileName+".out";printf("FILE %s\n",fileName.c_str());AppMXFFileFactoryfile_factory;MXFFileReaderfile_reader=MXFFileReader();file_reader.SetFileFactory(&file_factory,false);file_reader.GetPackageResolver()->SetFileFactory(&file_factory,false);MXFFileReader::OpenResultresult;result=file_reader.Open(fileName);intmxfVersion=file_reader.GetMXFVersion();if(result!=MXFFileReader::MXF_RESULT_SUCCESS){printf("Failed to open MXF file '%s': %s\n",fileName.c_str(),MXFFileReader::ResultToString(result).c_str());throwfalse;}MXFFileReader*reader=&file_reader;if(!reader->IsComplete()){printf("Input file is incomplete\n");}Rationalclip_frame_rate=reader->GetEditRate();//createoutputclipandinitializeint16_tmxfFlavour=OP1A_MIN_PARTITIONS_FLAVOUR|OP1A_MP_TRACK_NUMBER_FLAVOUR;if(mxfVersion==MXF_PREFACE_VER(1,2)){mxfFlavour|=OP1A_377_2004_FLAVOUR;}ClipWriter*clip=ClipWriter::OpenNewOP1AClip(mxfFlavour,file_factory.OpenNew(outFileName),clip_frame_rate);OP1AFile*op1a_clip=clip->GetOP1AClip();op1a_clip->SetAddSystemItem(true);//createoutputtracksintaudio_track_index=0;std::shared_ptr<OutputTrack>output_video_track;std::shared_ptr<OutputTrack>output_anc_track;std::map<int,std::shared_ptr<OutputTrack>>output_audio_tracks;for(inti=0;i<reader->GetNumTrackReaders();i++){MXFTrackReader*track_reader=reader->GetTrackReader(i);constMXFTrackInfo*input_track_info=track_reader->GetTrackInfo();printf("%i. %s\n",i,essence_type_to_string(input_track_info->essence_type));switch(input_track_info->essence_type){caseEssenceType::WAVE_PCM:{autooutputTrack=std::make_shared<OutputTrack>(clip->CreateTrack(input_track_info->essence_type));constMXFSoundTrackInfo*input_sound_info=dynamic_cast<constMXFSoundTrackInfo*>(reader->GetTrackReader(i)->GetTrackInfo());OutputTrackSoundInfo*output_sound_info=outputTrack->GetSoundInfo();output_sound_info->sampling_rate=input_sound_info->sampling_rate;output_sound_info->bits_per_sample=input_sound_info->bits_per_sample;output_sound_info->sequence_offset=0;outputTrack->SetPhysSrcTrackIndex(i+1);ClipWriterTrack*clip_track=outputTrack->GetClipTrack();clip_track->SetSamplingRate(output_sound_info->sampling_rate);clip_track->SetQuantizationBits(output_sound_info->bits_per_sample);clip_track->SetChannelCount(input_sound_info->channel_count);clip_track->SetOutputTrackNumber(i+1);printf("create output_audio_tracks[%d]\n",audio_track_index);output_audio_tracks[audio_track_index]=outputTrack;audio_track_index++;}break;caseEssenceType::ANC_DATA:{output_anc_track=std::make_shared<OutputTrack>(clip->CreateTrack(input_track_info->essence_type));}break;caseEssenceType::IEC_DV25:{output_video_track=std::make_shared<OutputTrack>(clip->CreateTrack(input_track_info->essence_type));ClipWriterTrack*clip_track=output_video_track->GetClipTrack();clip_track->SetComponentDepth(8);}break;caseEssenceType::DV100_1080I:{output_video_track=std::make_shared<OutputTrack>(clip->CreateTrack(input_track_info->essence_type));ClipWriterTrack*clip_track=output_video_track->GetClipTrack();clip_track->SetComponentDepth(10);}break;default:printf("Unknown essence type %s\n",essence_type_to_string(input_track_info->essence_type));throwfalse;}}clip->PrepareHeaderMetadata();clip->PrepareWrite();//copytracksuint32_tmax_samples_per_read=1;audio_track_index=0;bmx::ByteArraysound_buffer;while(true){uint32_tnum_read=reader->Read(max_samples_per_read);if(num_read==0){break;}for(inti=0;i<reader->GetNumTrackReaders();i++){MXFTrackReader*track_reader=reader->GetTrackReader(i);constMXFTrackInfo*input_track_info=track_reader->GetTrackInfo();constMXFSoundTrackInfo*sound_info=dynamic_cast<constMXFSoundTrackInfo*>(input_track_info);switch(input_track_info->essence_type){caseEssenceType::WAVE_PCM:{while(true){Frame*frame=track_reader->GetFrameBuffer()->GetLastFrame(true);if(!frame){break;}if(frame->IsEmpty()){continue;}sound_buffer.Grow(frame->GetSize());autopcm_track=output_audio_tracks[audio_track_index];printf("output_audio_tracks[%d] %s\n",audio_track_index,pcm_track?"ok":"== NULL!");autobits_per_sample=sound_info->bits_per_sample;autochannel_block_align=(bits_per_sample+7)/8;for(intchannel=0;channel<sound_info->channel_count;channel++){deinterleave_audio(frame->GetBytes(),frame->GetSize(),sound_info->bits_per_sample,sound_info->channel_count,channel,sound_buffer.GetBytes(),sound_buffer.GetAllocatedSize());sound_buffer.SetSize(frame->GetSize()/sound_info->channel_count);size_tnum_samples=frame->GetSize()/(sound_info->channel_count*channel_block_align);printf("try WriteSamples channel=%d sound_buffer.GetSize()=%"PRId32" num_samples=%zu frame->GetSize()=%"PRId32"\n",channel,sound_buffer.GetSize(),num_samples,frame->GetSize());pcm_track->WriteSamples(channel,sound_buffer.GetBytes(),sound_buffer.GetSize(),//num_samples*channel_block_align,num_samples);}}audio_track_index++;}break;caseEssenceType::ANC_DATA:{Frame*frame=reader->GetTrackReader(i)->GetFrameBuffer()->GetLastFrame(true);output_anc_track->WriteSamples(0,(unsignedchar*)frame->GetBytes(),frame->GetSize(),1);}break;caseEssenceType::IEC_DV25:caseEssenceType::DV100_1080I:{Frame*frame=reader->GetTrackReader(i)->GetFrameBuffer()->GetLastFrame(true);output_video_track->WriteSamples(0,(unsignedchar*)frame->GetBytes(),frame->GetSize(),1);}break;default:printf("Unknown essence type %s\n",essence_type_to_string(input_track_info->essence_type));throwfalse;}}audio_track_index=0;}deleteclip;printf("===== finish =====\n");return0;}
Last edit: Sergey Romashev 2017-07-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The issue is that you haven't registered all the track channels in the OutputTrack, i.e. you need to call OutputTrack::AddInput for each channel. The result is that OutputTrack only thinks 1 channel of audio is present (it needs to know how the channels are mapped and so doesn't query the ClipWriterTrack for the channel count) in the track and calls ClipWriterTrack::WriteSamples after receiving 1 channel of audio samples. This results in the exception because there is insufficient data for >1 channels.
However, given that you want to copy the samples unchanged you should just call ClipWriterTrack::WriteSamples using the Frame data, i.e. no need to use the OutputTrack which is intended to support remapping audio channels.
Philip
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi respected.
I try to write simple code which must copy op1a file without changes.
It works when audio tracks have 1 channel. If audio tracks has 2 channels and more i get exception
ERROR: 'size >= sample_size * num_samples' check failed
ERROR: near OP1AContentPackage.cpp:702
It happens in line "pcm_track->WriteSamples(channel...".
May be you have simple code to understand principle to write op1a mxf files
I tried to base on bmx\apps\bmxtranswrap\bmxtranswrap.cpp
and bmx\apps\raw2bmx\raw2bmx.cpp
Thank you in advance.
My code:
Last edit: Sergey Romashev 2017-07-25
The issue is that you haven't registered all the track channels in the OutputTrack, i.e. you need to call OutputTrack::AddInput for each channel. The result is that OutputTrack only thinks 1 channel of audio is present (it needs to know how the channels are mapped and so doesn't query the ClipWriterTrack for the channel count) in the track and calls ClipWriterTrack::WriteSamples after receiving 1 channel of audio samples. This results in the exception because there is insufficient data for >1 channels.
However, given that you want to copy the samples unchanged you should just call ClipWriterTrack::WriteSamples using the Frame data, i.e. no need to use the OutputTrack which is intended to support remapping audio channels.
Philip
Much Thanks, Philip.
How can i create ClipWriterTrack without OutputTrack?
Using ClipWriter::CreateTrack.
Philip
Thanks.