Concatenate two AVI files using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C++

#define SOURCE_FILE1  "C:\\Src1.avi" 
#define SOURCE_FILE2  "C:\\Src2.wav" 
#define DEST_FILE     "C:\\Dst.avi" 
 
void ConvertFile(IltmmConvert* pConvert1, IltmmMultiStreamTarget* pSampleTarget, IltmmMultiStreamSource* pSampleSource, long* plStartHi , long *plStartLo); 
 
int Concatenate() 
{ 
   IltmmConvert* pConvert1 = NULL; 
   IltmmConvert* pConvert2 = NULL; 
   IltmmMultiStreamTarget* pSampleTarget = NULL; 
   IltmmMultiStreamSource* pSampleSource = NULL; 
   long lStartLo, lStartHi; 
   IltmmMediaTypeDisp* pmt = NULL; 
   IltmmMediaTypeDisp* pInsertedMediaType; 
   BSTR  bstr; 
   CoInitialize(NULL); 
   HRESULT hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pConvert1); 
   if(FAILED(hr)) 
   { 
      AfxMessageBox(_T("Can't instantiate convert library")); 
      return -1; 
   } 
   hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pConvert2); 
   if(FAILED(hr)) 
   { 
      AfxMessageBox(_T("Can't instantiate convert library")); 
      return -1; 
   } 
   hr = CoCreateInstance(CLSID_ltmmMultiStreamTarget, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMultiStreamTarget, (void**) &pSampleTarget); 
   if(FAILED(hr)) 
   { 
      AfxMessageBox(_T("Can't instantiate convert library")); 
      return -1; 
   } 
   hr = CoCreateInstance(CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMultiStreamSource, (void**) &pSampleSource); 
   if(FAILED(hr)) 
   { 
      AfxMessageBox(_T("Can't instantiate convert library")); 
      return -1; 
   } 
   // set the start time to be 0 
   lStartHi = 0; 
   lStartLo = 0; 
 
   // set the input filename 
   bstr = ::SysAllocString(MAKE_MEDIA_PATH(SOURCE_FILE1)); 
   pConvert1->put_SourceFile(bstr); 
   SysFreeString(bstr); 
    
   // set the output sample to a target object 
   pSampleTarget->put_StreamCount(2); 
    
   hr = CoCreateInstance(CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMediaTypeDisp, (void**) &pmt); 
   if(FAILED(hr)) 
   { 
      AfxMessageBox(_T("Can't instantiate convert library")); 
      return -1; 
   } 
    
   pmt->put_Type(ltmmMEDIATYPE_Video); 
   pSampleTarget->SetAcceptedMediaType(0, pmt); 
   pmt->put_Type(ltmmMEDIATYPE_Audio); 
   pSampleTarget->SetAcceptedMediaType(1, pmt); 
   pmt->Release(); 
   pmt = NULL; 
    
   // get the inserted media type for the first stream 
   pSampleTarget->GetAcceptedMediaType(0, &pInsertedMediaType); 
   pInsertedMediaType->Release(); 
   pInsertedMediaType = NULL; 
   hr = pConvert1->put_TargetObject(pSampleTarget); 
    
   // START the source conversion, so we can get the media sample format 
   hr = pConvert1->StartConvert(); 
    
   //INITIALIZE pConvert2 
   // get the output media sample format and put it into the source object 
   pSampleSource->put_StreamCount(2); 
   hr = pSampleTarget->GetConnectedMediaType(0, &pmt); 
   pSampleSource->SetMediaType(0, pmt); 
   pmt->Release(); 
   pmt = NULL; 
   pSampleTarget->GetConnectedMediaType(1, &pmt); 
   pSampleSource->SetMediaType(1, pmt); 
   pmt->Release(); 
   pmt = NULL; 
    
   // get the inserted media type for the first stream 
   pSampleSource->GetMediaType(0, &pInsertedMediaType); 
   pInsertedMediaType->Release(); 
   pInsertedMediaType = NULL; 
    
   // set the output filename 
   bstr = ::SysAllocString(MAKE_MEDIA_PATH(DEST_FILE)); 
   pConvert2->put_TargetFile(bstr); 
   SysFreeString(bstr); 
   pConvert2->put_SourceObject(pSampleSource); 
    
   // start the dest conversion 
   pConvert2->StartConvert(); 
    
   // convert first file 
   ConvertFile(pConvert1, pSampleTarget, pSampleSource, &lStartHi, &lStartLo); 
    
   /* 
   Restrict the output format to the media type of the source for the first file 
   That is because the two files must have the same media type for both video and audio 
   With video, you have to make sure the files have the same frame rate! Minor changes in 
   the frame rate might make the connection fail! 
   The control will tolerate differences in frame rate if you comment the next line 
   */ 
   pSampleTarget->GetConnectedMediaType(0, &pmt); 
   pSampleTarget->SetAcceptedMediaType(0, pmt); 
   pmt->Release(); 
   pmt = NULL; 
   pSampleTarget->GetConnectedMediaType(1, &pmt); 
   pSampleTarget->SetAcceptedMediaType(1, pmt); 
   pmt->Release(); 
   pmt = NULL; 
    
   // change the source file to second file 
   bstr = ::SysAllocString(MAKE_MEDIA_PATH(SOURCE_FILE2)); 
   pConvert1->put_SourceFile(bstr); 
   SysFreeString(bstr); 
    
   // start converting again 
   pConvert1->StartConvert(); 
    
   // convert second file 
   ConvertFile(pConvert1, pSampleTarget, pSampleSource, &lStartHi, &lStartLo); 
    
   // deliver end of sample to stop the conversion 
   pSampleSource->DeliverEndOfStream(0, 1000); 
   pSampleSource->DeliverEndOfStream(1, 1000); 
   long lState; 
   pConvert2->get_State(&lState); 
   if (lState == ltmmConvert_State_Running) 
      pConvert2->StopConvert(); 
    
   // free the source and target objects 
   pConvert1->ResetTarget(); 
   pConvert2->ResetSource(); 
   if (pConvert1) 
   { 
      pConvert1->Release(); 
      pConvert1 = NULL; 
   } 
   if (pConvert2) 
   { 
      pConvert2->Release(); 
      pConvert2 = NULL; 
   } 
   if (pSampleSource) 
   { 
      pSampleSource->Release(); 
      pSampleSource = NULL; 
   } 
   if (pSampleTarget) 
   { 
      pSampleTarget->Release(); 
      pSampleTarget = NULL; 
   } 
   CoUninitialize(); 
   return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
void ConvertFile(IltmmConvert* pConvert1, IltmmMultiStreamTarget* pSampleTarget, IltmmMultiStreamSource* pSampleSource, long* plStartHi , long *plStartLo) 
{ 
   IltmmMediaSampleDisp* pmsSrc = NULL; 
   IltmmMediaSampleDisp* pmsDst = NULL; 
   long LastStartHi; 
   long LastStartLo; 
   long LastStopHi; 
   long LastStopLo; 
   long lSampleStream; 
   HRESULT hr; 
   LastStopHi = 0; 
   LastStopLo = 0; 
   do 
   { 
      // get the sample, allowing 10 s for the operation to complete 
      hr = pSampleTarget->WaitForSample(1000, &lSampleStream); 
      if (FAILED(hr)) 
         break; 
      hr = pSampleTarget->GetSample(lSampleStream, 0, &pmsSrc); 
      if (FAILED(hr)) 
         break; 
      hr = pSampleSource->GetSampleBuffer(lSampleStream, 2000, &pmsDst); 
      if (FAILED(hr)) 
         break; 
      // set the sample time 
      pmsSrc->GetTime(&LastStartHi, &LastStartLo, &LastStopHi, &LastStopLo); 
      // get the sample time 
      pmsDst->SetTime(*plStartHi + LastStartHi, *plStartLo + LastStartLo, *plStartHi + LastStopHi, *plStartLo + LastStopLo); 
      // copy the data 
      long lActualDataLength; 
      pmsSrc->get_ActualDataLength(&lActualDataLength); 
      VARIANT vBuffer; 
      pmsSrc->GetData(lActualDataLength, &vBuffer); 
      pmsDst->SetData(lActualDataLength, vBuffer); 
      // copy the other flags 
      VARIANT_BOOL vBool; 
      hr = pmsSrc->get_Discontinuity(&vBool); 
      if (FAILED(hr)) 
         break; 
      hr = pmsDst->put_Discontinuity(vBool); 
      if (FAILED(hr)) 
         break; 
      hr = pmsSrc->get_Preroll(&vBool); 
      if (FAILED(hr)) 
         break; 
      hr = pmsDst->put_Preroll(vBool); 
      if (FAILED(hr)) 
         break; 
      hr = pmsSrc->get_SyncPoint(&vBool); 
      if (FAILED(hr)) 
         break; 
      hr = pmsDst->put_SyncPoint(vBool); 
      if (FAILED(hr)) 
         break; 
      // release the source sample 
      pmsSrc->Release(); 
      pmsSrc = NULL; 
      // deliver the destination sample 
      pSampleSource->DeliverSample(lSampleStream, 1000, pmsDst); 
      // release the destination sample 
      pmsDst->Release(); 
      pmsDst = NULL; 
   } 
   while (1); 
 
   pConvert1->StopConvert(); 
   *plStartHi = LastStopHi; 
   *plStartLo = LastStopLo; 
} 
Help Version 20.0.2019.9.19
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2019 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Multimedia C API Help