Copying ltmmMediaSample Attributes and Data for C

The following code demonstrates how to copy a media sample's attributes and data to another media sample.

// define helper macros for using interfaces under C
#ifndef COBJMACROS
   #define COBJMACROS
#endif

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

/////////////////////////////////////////////////////////////////
// CopyMediaSampleAttributes
// copies data and attributes from one sample to another
// pDest - destination sample interface
// pSource - source sample interface
//
HRESULT CopyMediaSampleAttributesExample (IltmmMediaSampleDisp* pDest, IltmmMediaSampleDisp* pSource)
{
   HRESULT hr;
   VARIANT_BOOL f;
   LARGE_INTEGER starttime;
   LARGE_INTEGER stoptime;
   VARIANT var;
   long cbData;
   long cbBuffer;
   IltmmMediaTypeDisp* pMediaType;

   // return error if NULL
   if(!pSource || !pDest)
      return E_POINTER;

   // get the source actual data length
   hr = IltmmMediaSampleDisp_get_ActualDataLength (pSource, &cbData);
   if(FAILED(hr))
      return hr;

   // now the dest maximum buffer size
   hr = IltmmMediaSampleDisp_get_BufferSize(pDest, &cbBuffer);
   if(FAILED(hr))
      return hr;

   // if no room for the data, return an error
   if(cbData > cbBuffer)
      return E_OUTOFMEMORY;

   // any data to copy?
   if(cbData)
   {
      // yes, then copy away
      hr = IltmmMediaSampleDisp_GetData (pSource, cbData, &var);
      if(FAILED(hr))
         return hr;
      hr = IltmmMediaSampleDisp_SetData (pDest, cbData, var);
      VariantClear(&var);
      if(FAILED(hr))
         return hr;
   }
   else
   {
      // no, just set the dest data length to 0
      IltmmMediaSampleDisp_put_ActualDataLength (pDest, 0);
   }

   // copy the the media type, if there is one
   pMediaType = NULL;
   IltmmMediaSampleDisp_GetMediaType (pSource, &pMediaType);
   if(pMediaType)
   {
      IltmmMediaSampleDisp_SetMediaType (pDest, pMediaType);
      IUnknown_Release(pMediaType);
   }

   // copy discontinuity
   f = VARIANT_FALSE;
   IltmmMediaSampleDisp_get_Discontinuity(pSource, &f);
   IltmmMediaSampleDisp_put_Discontinuity (pDest, f);

   // copy preroll
   f = VARIANT_FALSE;
   IltmmMediaSampleDisp_get_Preroll(pSource, &f);
   IltmmMediaSampleDisp_put_Preroll (pDest, f);

   // copy syncpoint
   f = VARIANT_FALSE;
   IltmmMediaSampleDisp_get_SyncPoint(pSource, &f);
   IltmmMediaSampleDisp_put_SyncPoint (pDest, f);

   // is the time available?
   hr = IltmmMediaSampleDisp_GetTime (pSource, &starttime.HighPart, (long*) &starttime.LowPart, &stoptime.HighPart, (long*) &stoptime.LowPart);
   if(FAILED(hr))
   {
      // no, then reset the dest time
      IltmmMediaSampleDisp_ResetTime (pDest);
   }
   else
   {
      // yes, copy to the dest
      IltmmMediaSampleDisp_SetTime (pDest, starttime.HighPart, starttime.LowPart, stoptime.HighPart, stoptime.LowPart);
   }

   // is the media time available?
   hr = IltmmMediaSampleDisp_GetMediaTime (pSource, &starttime.HighPart, (long*) &starttime.LowPart, &stoptime.HighPart, (long*) &stoptime.LowPart);
   if(FAILED(hr))
   {
      // no, then reset the dest media time
      IltmmMediaSampleDisp_ResetMediaTime (pDest);
   }
   else
   {
      // yes, copy to the dest
      IltmmMediaSampleDisp_SetMediaTime (pDest, starttime.HighPart, starttime.LowPart, stoptime.HighPart, stoptime.LowPart);
   }

   return S_OK;
}