Concatenate two AVI files using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C
int Concatenate()
{
IltmmConvert* pConvert1 = NULL;
IltmmConvert* pConvert2 = NULL;
IltmmMultiStreamTarget* pMSTarget = NULL;
IltmmMultiStreamSource* pMSSource = NULL;
long lStartLo, lStartHi;
IltmmMediaTypeDisp* pmt = NULL;
IltmmMediaTypeDisp* pInsertedMediaType;
BSTR bstr;
HRESULT hr;
long lState;
CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pConvert1);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pConvert2);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmMultiStreamTarget, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamTarget, (void**) &pMSTarget);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
hr = CoCreateInstance(&CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamSource, (void**) &pMSSource);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
// set the start time to be 0
lStartHi = 0;
lStartLo = 0;
// set the input filename
bstr = T2OLE("c:\\Src1.avi");
IltmmConvert__put_SourceFile(pConvert1, bstr);
SysFreeString(bstr);
// set the output sample to a target object
IltmmMultiStreamTarget__put_StreamCount(pMSTarget, 2);
hr = CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pmt);
if(FAILED(hr))
{
MessageBox(0, "Can't instantiate convert library", "Error", 0);
return -1;
}
IltmmMediaTypeDisp__put_Type(pmt, ltmmMEDIATYPE_Video);
IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 0, pmt);
IltmmMediaTypeDisp__put_Type(pmt, ltmmMEDIATYPE_Audio);
IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 1, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
// get the inserted media type for the first stream
IltmmMultiStreamTarget__getAcceptedMediaType(pMSTarget, 0, &pInsertedMediaType);
IltmmMediaTypeDisp_Release(pInsertedMediaType);
pInsertedMediaType = NULL;
hr = IltmmConvert__put_TargetObject(pConvert1, pMSTarget);
// START the source conversion, so we can get the media sample format
hr = IltmmConvert_StartConvert(pConvert1);
//INITIALIZE pConvert2
// get the output media sample format and put it into the source object
IltmmMultiStreamSource__put_StreamCount(pMSSource, 2);
hr = IltmmMultiStreamTarget__getConnectedMediaType (pMSTarget, 0, &pmt);
IltmmMultiStreamSource_SetMediaType(pMSSource, 0, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
IltmmMultiStreamTarget__getConnectedMediaType(pMSTarget, 1, &pmt);
IltmmMultiStreamSource_SetMediaType(pMSSource, 1, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
// get the inserted media type for the first stream
IltmmMultiStreamSource__getMediaType(pMSSource, 0, &pInsertedMediaType);
IltmmMediaTypeDisp_Release(pInsertedMediaType);
pInsertedMediaType = NULL;
// set the output filename
bstr = T2OLE("C:\\Dest.avi");
IltmmConvert__put_TargetFile(pConvert2, bstr);
SysFreeString(bstr);
IltmmConvert__put_SourceObject(pConvert2, pMSSource);
// start the dest conversion
IltmmConvert_StartConvert(pConvert2);
// convert first file
ConvertFile(pConvert1, pMSTarget, pMSSource, &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
*/
IltmmMultiStreamTarget__getConnectedMediaType(pMSTarget, 0, &pmt);
IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 0, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
IltmmMultiStreamTarget__getConnectedMediaType(pMSTarget, 1, &pmt);
IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 1, pmt);
IltmmMediaTypeDisp_Release(pmt);
pmt = NULL;
// change the source file to second file
bstr = T2OLE("C:\\Src2.avi");
IltmmConvert__put_SourceFile(pConvert1, bstr);
SysFreeString(bstr);
// start converting again
IltmmConvert_StartConvert(pConvert1);
// convert second file
ConvertFile(pConvert1, pMSTarget, pMSSource, &lStartHi, &lStartLo);
// deliver end of sample to stop the conversion
IltmmMultiStreamSource_DeliverEndOfStream(pMSSource, 0, 1000);
IltmmMultiStreamSource_DeliverEndOfStream(pMSSource, 1, 1000);
IltmmConvert__get_State(pConvert2, &lState);
if (lState = ltmmConvert_State_Running)
IltmmConvert_StopConvert(pConvert2);
// free the source and target objects
IltmmConvert_ResetTarget(pConvert1);
IltmmConvert_ResetSource(pConvert2);
if (pConvert1)
{
IltmmConvert_Release(pConvert1);
pConvert1 = NULL;
}
if (pConvert2)
{
IltmmConvert_Release(pConvert2);
pConvert2 = NULL;
}
if (pMSSource)
{
IltmmMultiStreamSource_Release(pMSSource);
pMSSource = NULL;
}
if (pMSTarget)
{
IltmmMultiStreamTarget_Release(pMSTarget);
pMSTarget = NULL;
}
CoUninitialize();
return 0;
}
void ConvertFile(IltmmConvert* pConvert1, IltmmMultiStreamTarget* pMSTarget, IltmmMultiStreamSource* pMSSource, long* plStartHi , long *plStartLo)
{
IltmmMediaSampleDisp* pmsSrc = NULL;
IltmmMediaSampleDisp* pmsDst = NULL;
long LastStartHi;
long LastStartLo;
long LastStopHi;
long LastStopLo;
long lSampleStream;
HRESULT hr;
long lActualDataLength;
VARIANT vBuffer;
VARIANT_BOOL vBool;
LastStopHi = 0;
LastStopLo = 0;
do
{
// get the sample, allowing 10 s for the operation to complete
hr = IltmmMultiStreamTarget_WaitForSample(pMSTarget, 1000, &lSampleStream);
if (FAILED(hr))
break;
hr = IltmmMultiStreamTarget__getSample(pMSTarget, lSampleStream, 0, &pmsSrc);
if (FAILED(hr))
break;
hr = IltmmMultiStreamSource__getSampleBuffer(pMSSource, lSampleStream, 2000, &pmsDst);
if (FAILED(hr))
break;
// set the sample time
IltmmMediaSampleDisp__getTime(pmsSrc, &LastStartHi, &LastStartLo, &LastStopHi, &LastStopLo);
// get the sample time
IltmmMediaSampleDisp_SetTime(pmsDst, *plStartHi + LastStartHi, *plStartLo + LastStartLo, *plStartHi + LastStopHi, *plStartLo + LastStopLo);
// copy the data
IltmmMediaSampleDisp__get_ActualDataLength(pmsSrc, &lActualDataLength);
IltmmMediaSampleDisp__getData(pmsSrc, lActualDataLength, &vBuffer);
IltmmMediaSampleDisp_SetData(pmsDst, lActualDataLength, vBuffer);
// copy the other flags
hr = IltmmMediaSampleDisp__get_Discontinuity(pmsSrc, &vBool);
if (FAILED(hr))
break;
hr = IltmmMediaSampleDisp__put_Discontinuity(pmsDst, vBool);
if (FAILED(hr))
break;
hr = IltmmMediaSampleDisp__get_Preroll(pmsSrc, &vBool);
if (FAILED(hr))
break;
hr = IltmmMediaSampleDisp__put_Preroll(pmsDst, vBool);
if (FAILED(hr))
break;
hr = IltmmMediaSampleDisp__get_SyncPoint(pmsSrc, &vBool);
if (FAILED(hr))
break;
hr = IltmmMediaSampleDisp__put_SyncPoint(pmsDst, vBool);
if (FAILED(hr))
break;
// release the source sample
IltmmMediaSampleDisp_Release(pmsSrc);
pmsSrc = NULL;
// deliver the destination sample
IltmmMultiStreamSource_DeliverSample(pMSSource, lSampleStream, 1000, pmsDst);
// release the destination sample
IltmmMediaSampleDisp_Release(pmsDst);
pmsDst = NULL;
}
while (1);
IltmmConvert_StopConvert(pConvert1);
*plStartHi = LastStopHi;
*plStartLo = LastStopLo;
}
LPOLESTR T2OLE(LPCTSTR lpt) { static OLECHAR lpw[512]; if(!lpt) return NULL; lpw[0] = L'\0'; MultiByteToWideChar(CP_ACP, 0, lpt, -1, lpw, 512); return lpw; } void ConvertFile(IltmmConvert* pConvert1, IltmmMultiStreamTarget* pMSTarget, IltmmMultiStreamSource* pMSSource, long* plStartHi , long *plStartLo) { IltmmMediaSampleDisp* pmsSrc = NULL; IltmmMediaSampleDisp* pmsDst = NULL; long LastStartHi; long LastStartLo; long LastStopHi; long LastStopLo; long lSampleStream; HRESULT hr; long lActualDataLength; VARIANT vBuffer; VARIANT_BOOL vBool; LastStopHi = 0; LastStopLo = 0; for(;;) { // get the sample, allowing 10 s for the operation to complete hr = IltmmMultiStreamTarget_WaitForSample(pMSTarget, 1000, &lSampleStream); if (FAILED(hr)) break; hr = IltmmMultiStreamTarget_GetSample(pMSTarget, lSampleStream, 0, &pmsSrc); if (FAILED(hr)) break; hr = IltmmMultiStreamSource_GetSampleBuffer(pMSSource, lSampleStream, 2000, &pmsDst); if (FAILED(hr)) break; // set the sample time IltmmMediaSampleDisp_GetTime(pmsSrc, &LastStartHi, &LastStartLo, &LastStopHi, &LastStopLo); // get the sample time IltmmMediaSampleDisp_SetTime(pmsDst, *plStartHi + LastStartHi, *plStartLo + LastStartLo, *plStartHi + LastStopHi, *plStartLo + LastStopLo); // copy the data IltmmMediaSampleDisp_get_ActualDataLength(pmsSrc, &lActualDataLength); IltmmMediaSampleDisp_GetData(pmsSrc, lActualDataLength, &vBuffer); IltmmMediaSampleDisp_SetData(pmsDst, lActualDataLength, vBuffer); // copy the other flags hr = IltmmMediaSampleDisp_get_Discontinuity(pmsSrc, &vBool); if (FAILED(hr)) break; hr = IltmmMediaSampleDisp_put_Discontinuity(pmsDst, vBool); if (FAILED(hr)) break; hr = IltmmMediaSampleDisp_get_Preroll(pmsSrc, &vBool); if (FAILED(hr)) break; hr = IltmmMediaSampleDisp_put_Preroll(pmsDst, vBool); if (FAILED(hr)) break; hr = IltmmMediaSampleDisp_get_SyncPoint(pmsSrc, &vBool); if (FAILED(hr)) break; hr = IltmmMediaSampleDisp_put_SyncPoint(pmsDst, vBool); if (FAILED(hr)) break; // release the source sample IltmmMediaSampleDisp_Release(pmsSrc); pmsSrc = NULL; // deliver the destination sample IltmmMultiStreamSource_DeliverSample(pMSSource, lSampleStream, 1000, pmsDst); // release the destination sample IltmmMediaSampleDisp_Release(pmsDst); pmsDst = NULL; } IltmmConvert_StopConvert(pConvert1); *plStartHi = LastStopHi; *plStartLo = LastStopLo; } L_MULTIMEDIATEX_API int ConcatenateTwoAVIfilesExample ( void ) { IltmmConvert* pConvert1 = NULL; IltmmConvert* pConvert2 = NULL; IltmmMultiStreamTarget* pMSTarget = NULL; IltmmMultiStreamSource* pMSSource = NULL; long lStartLo, lStartHi; IltmmMediaTypeDisp* pmt = NULL; IltmmMediaTypeDisp* pInsertedMediaType; BSTR bstr; HRESULT hr; long lState; CoInitialize(NULL); hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pConvert1); if(FAILED(hr)) { MessageBox(0, "Can't instantiate convert library", "Error", 0); return -1; } hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pConvert2); if(FAILED(hr)) { MessageBox(0, "Can't instantiate convert library", "Error", 0); return -1; } hr = CoCreateInstance(&CLSID_ltmmMultiStreamTarget, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamTarget, (void**) &pMSTarget); if(FAILED(hr)) { MessageBox(0, "Can't instantiate convert library", "Error", 0); return -1; } hr = CoCreateInstance(&CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamSource, (void**) &pMSSource); if(FAILED(hr)) { MessageBox(0, "Can't instantiate convert library", "Error", 0); return -1; } // set the start time to be 0 lStartHi = 0; lStartLo = 0; // set the input filename bstr = T2OLE("c:\\Src1.avi"); IltmmConvert_put_SourceFile(pConvert1, bstr); SysFreeString(bstr); // set the output sample to a target object IltmmMultiStreamTarget_put_StreamCount(pMSTarget, 2); hr = CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pmt); if(FAILED(hr)) { MessageBox(0, "Can't instantiate convert library", "Error", 0); return -1; } IltmmMediaTypeDisp_put_Type(pmt, ltmmMEDIATYPE_Video); IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 0, pmt); IltmmMediaTypeDisp_put_Type(pmt, ltmmMEDIATYPE_Audio); IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 1, pmt); IltmmMediaTypeDisp_Release(pmt); pmt = NULL; // get the inserted media type for the first stream IltmmMultiStreamTarget_GetAcceptedMediaType(pMSTarget, 0, &pInsertedMediaType); IltmmMediaTypeDisp_Release(pInsertedMediaType); pInsertedMediaType = NULL; hr = IltmmConvert_put_TargetObject(pConvert1, pMSTarget); // START the source conversion, so we can get the media sample format hr = IltmmConvert_StartConvert(pConvert1); //INITIALIZE pConvert2 // get the output media sample format and put it into the source object IltmmMultiStreamSource_put_StreamCount(pMSSource, 2); hr = IltmmMultiStreamTarget_GetConnectedMediaType (pMSTarget, 0, &pmt); IltmmMultiStreamSource_SetMediaType(pMSSource, 0, pmt); IltmmMediaTypeDisp_Release(pmt); pmt = NULL; IltmmMultiStreamTarget_GetConnectedMediaType(pMSTarget, 1, &pmt); IltmmMultiStreamSource_SetMediaType(pMSSource, 1, pmt); IltmmMediaTypeDisp_Release(pmt); pmt = NULL; // get the inserted media type for the first stream IltmmMultiStreamSource_GetMediaType(pMSSource, 0, &pInsertedMediaType); IltmmMediaTypeDisp_Release(pInsertedMediaType); pInsertedMediaType = NULL; // set the output filename bstr = T2OLE("C:\\Dest.avi"); IltmmConvert_put_TargetFile(pConvert2, bstr); SysFreeString(bstr); IltmmConvert_put_SourceObject(pConvert2, pMSSource); // start the dest conversion IltmmConvert_StartConvert(pConvert2); // convert first file ConvertFile(pConvert1, pMSTarget, pMSSource, &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 */ IltmmMultiStreamTarget_GetConnectedMediaType(pMSTarget, 0, &pmt); IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 0, pmt); IltmmMediaTypeDisp_Release(pmt); pmt = NULL; IltmmMultiStreamTarget_GetConnectedMediaType(pMSTarget, 1, &pmt); IltmmMultiStreamTarget_SetAcceptedMediaType(pMSTarget, 1, pmt); IltmmMediaTypeDisp_Release(pmt); pmt = NULL; // change the source file to second file bstr = T2OLE("C:\\Src2.avi"); IltmmConvert_put_SourceFile(pConvert1, bstr); SysFreeString(bstr); // start converting again IltmmConvert_StartConvert(pConvert1); // convert second file ConvertFile(pConvert1, pMSTarget, pMSSource, &lStartHi, &lStartLo); // deliver end of sample to stop the conversion IltmmMultiStreamSource_DeliverEndOfStream(pMSSource, 0, 1000); IltmmMultiStreamSource_DeliverEndOfStream(pMSSource, 1, 1000); IltmmConvert_get_State(pConvert2, &lState); if (lState == ltmmConvert_State_Running) IltmmConvert_StopConvert(pConvert2); // free the source and target objects IltmmConvert_ResetTarget(pConvert1); IltmmConvert_ResetSource(pConvert2); if (pConvert1) { IltmmConvert_Release(pConvert1); pConvert1 = NULL; } if (pConvert2) { IltmmConvert_Release(pConvert2); pConvert2 = NULL; } if (pMSSource) { IltmmMultiStreamSource_Release(pMSSource); pMSSource = NULL; } if (pMSTarget) { IltmmMultiStreamTarget_Release(pMSTarget); pMSTarget = NULL; } CoUninitialize(); return 0; }