Convert DVD with Subtitles for C++

This example shows how to convert only one chapter in a DVD title and how to enable DVD subtitles during conversion when you use the DVD Source object

#define MAKE_MEDIA_PATH(pFileName) (TEXT("C:\\LEADTOOLS 17.5\\Media\\")TEXT(pFileName))



// include the LEAD Multimedia TOOLKIT header
#include "ltmm.h"

// This function will select one chapter in a certain title
void SelectChapter(IltmmDVDTitle *pTitle, int nChapterIndex)
{
   long nCount;
   pTitle->get_ChapterCount(&nCount);
   for(int i = 0; i < nCount; i++)
   {
      IltmmDVDChapter *pChapter;
      if(pTitle->GetChapter(i, &pChapter) == S_OK)
      {
         pChapter->put_Selected(i == nChapterIndex ? VARIANT_TRUE : VARIANT_FALSE);
         pChapter->Release();
      }
   }
}

   //This function will select the main title for conversion.
   //Within the main title, it will select only the second chapter.
   //It will also select the first subtitle stream.

void SelectOneChapterAndSubtitles(IltmmConvert *pConvert)
{
   IUnknown *punk;
   IltmmDVDSource* pDVDSource;
   // Get the DVD source interface
   pConvert->GetSubObject(ltmmConvert_Object_SourceFilter, &punk);
   if (punk)
   {
      punk->QueryInterface(IID_IltmmDVDSource, (void**)&pDVDSource);
      if (pDVDSource)
      {
         IltmmDVDTitle *pTitle;
         long lCount;
         long lVal;

         // Select the main title
         pDVDSource->put_Selected(ltmmDVDSource_Main_Selected);
         // We now need to select one chapter and enable subtitles for this title
         // For that, we will loop through the titles and find out which one was selected above
         // Get the title count in the disc
         pDVDSource->get_TitleCount(&lCount);
         for (int i = 0; i < lCount; i++)
         {
            // Get the title interface
            pDVDSource->GetTitle(i, &pTitle);
            if (pTitle)
            {
               long bSelected;
               pTitle->get_Selected(&bSelected);
               if(bSelected)
               {
                  // we found the main title
                  // (Optional step). We will convert only one chapter to speed up the conversion. 
                  // We will select the 2nd chapte, because the first chapter will sometimes have movie credits and little dialogue
                  // Chapters are 0-based, so the second chapter has index 1
                  SelectChapter(pTitle, 1);
                  // Get the subpicture stream count
                  pTitle->get_SubpictureStreamCount(&lVal);
                  if(lVal > 0)
                     // Select the first subpicture stream
                     pTitle->put_SelectedSubpictureStream(0);
               }
               pTitle->Release();
            }
         }
         pDVDSource->Release();
      }
      punk->Release();
   }
}

#define LEAD_MPEG2_ENCODER L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MPEG2 Encoder (3.0)"
#define LEAD_MPEG_AUDIO_ENCODER L"@device:sw:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\LEAD MPEG Audio Encoder (2.0)"

// select a certain encoder
void SelectCompressor(IltmmCompressors *pCompressors, LPCWSTR pszCompressorName)
{
   long index;
   BSTR bstrCompressorName = SysAllocString(pszCompressorName);
   pCompressors->Find(bstrCompressorName, &index);
   pCompressors->put_Selection(index);
   SysFreeString(bstrCompressorName);
}

// helper function to wait for conversion to complete
void WaitForCompletion(IltmmConvert *pConvert)
{
   long lState = ltmmConvert_State_Running;
   MSG msg;

   pConvert->get_State(&lState);

   while(lState != ltmmConvert_State_Stopped)
   { 
      if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
      
      pConvert->get_State(&lState);
   }
}

// convert one chapter with subtitles (close captioning)
HRESULT ConvertOneChapterWithSubtitles()
{
   IltmmConvert *pConvert;
   HRESULT hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pConvert);
   if(FAILED(hr))
      return hr;

   // use the DVD source for greater control over the DVD conversion process
   pConvert->put_UseDVDSource(VARIANT_TRUE);

   // set the source, compressors and target format
   BSTR bstr = ::SysAllocString(MAKE_MEDIA_PATH("video_ts.ifo"));
   pConvert->put_SourceFile(bstr);
   SysFreeString(bstr);

   pConvert->put_TargetFormat(ltmmConvert_TargetFormat_MPEG2_PROGRAM);
   IltmmCompressors *pCompressors;

   // select mpeg2 encoder
   pConvert->get_VideoCompressors(&pCompressors);
   SelectCompressor(pCompressors, LEAD_MPEG2_ENCODER);
   pCompressors->Release();

   // select mpeg audio encoder
   pConvert->get_AudioCompressors(&pCompressors);
   SelectCompressor(pCompressors, LEAD_MPEG_AUDIO_ENCODER);
   pCompressors->Release();
   bstr = ::SysAllocString(MAKE_MEDIA_PATH("1.mpg"));
   pConvert->put_TargetFile(bstr);
   SysFreeString(bstr);

   // this function is the interesting part of the example
   SelectOneChapterAndSubtitles(pConvert);
   hr = pConvert->StartConvert();

   // wait for conversion to finish
   WaitForCompletion(pConvert);

   pConvert->Release();
   return hr;
}