Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Mpeg2 ts with VBI Data

rippi
Beginner
409 Views
I am trying to pack a H.264 video steam into a mpeg2 transport stream. It works very well. Now I have to add some further information (mata data) to that stream. My first idea was to put these information as vbi data. Unfortunately my application does not work properly and I cannot locate the errors. I also looked for some examples, but I could not find anything about vbi data in mpeg2ts. Can anybody help me with maybe some hints or examples?
0 Kudos
3 Replies
Ali_Gökalp_P_
Beginner
409 Views
Same problem here, we 're also trying to pack MPEG4 video stream with private elementary stream that is neither video nor audio.We are trying to put into VBI_TRACK but we haven't succeeded yet.
0 Kudos
rippi
Beginner
409 Views

Hello,

there are some new ideas from me about transporting video and private elementary streams with Mpeg2Ts.

Now I can write the private streams as VBI-data (UMC::TrackType==UMC::TRACK_VBI_TXT) into the TS. Important to mention is, that the MPEG2TsChunkWriter does not work correctly for VBI-Data. So I have to overwrite the methods PrepareChunk() and WriteChunk():

Status VbiMPEG2TSChunkWriter::PrepareChunk(void) {
[...]
//old version
//if (m_uiStartIndicator && m_ESType != MPEG2MUX_ES_VBI_DATA)
//new version
if (m_uiStartIndicator) {
[...]
}

Status VbiMPEG2TSChunkWriter::WriteChunk(void) {
[...]
//old version
//if (m_uiStartIndicator && m_ESType != MPEG2MUX_ES_VBI_DATA)
//new version
if (m_uiStartIndicator) {
[...]
}

Now the Pes-Header will be written for VBI-data, too. This is necessary, because the Splitter looks for it while extracting the data.
The muxer has to be modified like this:

UMC::TrackParams &param = muxerParams->pTrackParams[trackNumberVbi];
param.type = UMC::VBI_TRACK;

//PID is a struct containing the private data
param.bufferParams.m_prefInputBufferSize = sizeof( PID );

//m_lpVbiParams is an object of a class, which is derived from UMC::BaseCodecParams
//info is an object from a class, which is derived from UMC::StreamInfo
param.info.undef = &m_lpVbiParams->info;

The data can be put into the TS like this:

//VbiData is derived from UMC::MediaData
VbiData mux_data( 2 * sizeof(PID) + 1 );
PID pid;
while (!bStopFlag) {
mux_data.setPrivateData(pid);
mux_data.SetDataSize(sizeof(PID));
memcpy(mux_data.GetDataPointer(), &mux_data.getMetadata(), sizeof(PID));

//IMPORTANT: Timestamps have to be set!
mux_data.SetTime(m_pts_Video_start, m_pts_Video_ende );
umcRes = m_lpMuxer->PutData(&mux_data, 1);
if (UMC::UMC_ERR_NOT_ENOUGH_BUFFER == umcRes){
vm_time_sleep(TIME_TO_SLEEP);
}
}
m_lpMuxer->PutEndOfStream(1);
m_lpMuxer->Flush();

When I tried to extract the VBI-data I realized, that the Demuxer has to be modified, too, because the UMC::Mpeg2PesParser is not able to ident ify VBI-data.
So I overwrote the method ParsePmtInfo():

Status VbiMpeg2PesParser::ParsePmtInfo(Mpeg2TsPmt &pmt) {
[...]
//old version
/*} else if (0x06 == pmt.pESs.uiType) {
// we should wait for decriptor to determine type
m_pInfo[iTrack]->m_Type = TRACK_UNKNOWN;
}*/
//new version
} else if (0x06 == pmt.pESs.uiType) {
//new for VBI
m_pInfo[iTrack]->m_Type = TRACK_VBI_TXT;
}
[...]
}

The next step is to define some rules for the UMC::ThreadedDemuxer and to start the demuxer:

UMC::Splitter m_pSplitter = new VbiThreadedDemuxer;
UMC::DemuxerParams m_lpDemuxerParams= new DemuxerParams;

m_lpDemuxerParams->m_pDataReader = m_pDataReader;
m_lpDemuxerParams->m_uiRules = 2;
m_lpDemuxerParams->m_pRules = new TrackRule[m_lpDemuxerParams->m_uiRules];

//one rule for video
m_lpDemuxerParams->m_pRules[0].m_TypeMask = TRACK_ANY_VIDEO;
m_lpDemuxerParams->m_pRules[0].m_iPID = -1;
m_lpDemuxerParams->m_pRules[0].m_iLimit = 1;
m_lpDemuxerParams->m_pRules[0].m_bValidAfterInit = true;

//one rule for vbi
m_lpDemuxerParams->m_pRules[1].m_TypeMask = TRACK_ANY_VBI;
m_lpDemuxerParams->m_pRules[1].m_iPID = -1;
m_lpDemuxerParams->m_pRules[1].m_iLimit = 1;
m_lpDemuxerParams->m_pRules[1].m_bValidAfterInit = true;

m_pSplitter->Init(*m_lpDemuxerParams);
m_pSplitter->Run();

Now the Splitter is able to identify VBI-data and videos and I could start to work on the data.
First look for the number of the VBI-track and save it in m_nVbiTrack:

Ipp32u i;
Ipp32u m_nVbiTrack;
UMC::SplitterInfo* pSplitterInfo = NULL;

m_pSplitter->GetInfo(&pSplitterInfo);

for (i=0; i< pSplitterInfo->m_nOfTracks; i++) {
if (pSplitterInfo->m_ppTrackInfo->m_isSelected) {
if (pSplitterInfo->m_ppTrackInfo->m_Type & UMC::TRACK_ANY_VBI) {
m_nVbiTrack = i;
vm_string_printf("VBI found... ");
}
}
}

Then extract the data of track number m_nVbiTrack out of the datastream:

UMC::MediaData vbiData;
PID pid;
size_t sizePid = sizeof(pid);

while(!bStopFlag) {
while(UMC::UMC_ERR_NOT_ENOUGH_DATA == m_pSplitter->GetNextData(&vbiData, m_nVbiTrack)) {
vm_time_sleep(5);
}
memcpy(&pid, vbiData.GetDataPointer(), sizePid);
pid.process();
}

0 Kudos
Ali_Gökalp_P_
Beginner
409 Views
Thanks for the info... We've changed UMC in a different way , but this seems as a better one.
0 Kudos
Reply