Reading a Table of Contents from a Video File

This topic demonstrates how to read a table of contents that has already been embedded in a video file.

Start by calling CoCreateInstance to create a TOC Parser object and obtain an ITocParser interface. Then obtain the following interfaces by calling methods.

Use the methods of ITocEntry to inspect an individual entry in the table of contents. For example, you can inspect the title, the start time, and the end time of the entry.

The following list gives the steps in more detail.

  1. Call CoCreateInstance to create a TOC Parser object and obtain an ITocParser interface on it.
  2. Call ITocParser::Init to initialize the TOC parser and associate it with a video file.
  3. Obtain an IToc interface by calling ITocParser::GetTocByIndex.
  4. Obtain an ITocEntryList interface by calling IToc::GetEntryListByIndex.
  5. Obtain an ITocEntry interface by calling ITocEntryList::GetEntryByIndex.
  6. Allocate a TOC_ENTRY_DESCRIPTOR structure.
  7. Populate the TOC_ENTRY_DESCRIPTOR structure by calling ITocEntry::GetDescriptor.

The following code demonstrates the steps in the preceding list.

#include <stdio.h>
#include <wmcodecdsp.h>

HRESULT ShowEntryInfo(ITocEntry* pEntry);

void main()
{
   HRESULT hr = CoInitialize(NULL);
   
   if(SUCCEEDED(hr))
   {    
      ITocParser* pTocParser = NULL;

      hr = CoCreateInstance(CLSID_CTocParser, NULL, CLSCTX_INPROC_SERVER, 
         IID_ITocParser, (VOID**)&pTocParser);  
      
      if(SUCCEEDED(hr))
      {  
         hr = pTocParser->Init(L"\\\\?\\c:\\experiment\\seattle.wmv");

         if(SUCCEEDED(hr))
         {
            IToc* pToc = NULL;
            hr = pTocParser->GetTocByIndex(TOC_POS_TOPLEVELOBJECT, 0, &pToc);

            if(SUCCEEDED(hr))
            {
               ITocEntryList* pEntryList = NULL;
               hr = pToc->GetEntryListByIndex(0, &pEntryList);

               if(SUCCEEDED(hr))
               {
                  ITocEntry* pEntry = NULL;
                  hr = pEntryList->GetEntryByIndex(0, &pEntry);

                  if(SUCCEEDED(hr))
                  {
                     hr = ShowEntryInfo(pEntry);
                     pEntry->Release();
                     pEntry = NULL;
                  }

                  pEntryList->Release();
                  pEntryList = NULL;
               }

               pToc->Release();
               pToc = NULL;
            }
         }

         pTocParser->Release();
         pTocParser = NULL;  
      }
                   
      CoUninitialize();
   }
}

HRESULT ShowEntryInfo(ITocEntry* pEntry)
{
   HRESULT hr = E_FAIL;

   TOC_ENTRY_DESCRIPTOR entryDesc = {0};
   hr = pEntry->GetDescriptor(&entryDesc);

   if(SUCCEEDED(hr))
   {
      printf_s("qwStartTime: %x\n", entryDesc.qwStartTime);
      printf_s("qwEndTime: %x\n", entryDesc.qwEndTime);
      printf_s("qwStartStartPacketOffset: %x\n", entryDesc.qwStartPacketOffset);
      printf_s("qwEndPacketOffset: %x\n", entryDesc.qwEndPacketOffset);
      printf_s("qwRepresentativeFrameTime: %x\n", entryDesc.qwRepresentativeFrameTime);
   }

   return hr;
}

Embedding a Table of Contents in a Video File

Table of Contents Parser Objects

Table of Contents Parser Programming Guide