Recompress an AVI File


Following is sample code to recompress the file c:\Foo.avi to c:\Bar.avi, where the output file will be Cinepak with CD-quality audio. (Maybe foo.avi is currently RGB uncompressed with 22 kilohertz (kHz) sound). The DirectShow Capture sample in \dxmedia\Samples\DS\Capture demonstrates a capture application; this code demonstrates a recompression application.

Note: This sample code introduces concepts only. Don't try to compile it. A real application would perform error checking as well.


    // First we need a graph builder
    hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder,
			NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,
			(void **)&pBuild);

    // next we need a filtergraph, and tell the builder what it is
    hr = CoCreateInstance((REFCLSID)CLSID_FilterGraph,
			NULL, CLSCTX_INPROC, (REFIID)IID_IGraphBuilder,
			(void **)&pFg);
    hr = pBuild->SetFiltergraph(pFg);

    // we need a source for c:\foo.avi
    hr = CoCreateInstance((REFCLSID)CLSID_AsyncReader,
			NULL, CLSCTX_INPROC, (REFIID)IID_IBaseFilter,
			(void **)&pSrc);
    hr = pSrc->QueryInterface(IID_IFileSourceFilter, (void **)&pI);
    hr = pI->Load(L"c:\\foo.avi", NULL);
    pI->Release();
    hr = pFg->AddFilter(pSrc, NULL);

    // we need a rendering section to create c:\bar.avi
    hr = pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, L"c:\\bar.avi", &pRender,
								NULL);

    // make the ACM filter produce CD quality format
    set up a WAVEFORMATEX structure to describe 44.1kHz 16bit stereo, say wfx
    cmt.SetType(&MEDIATYPE_Audio);
    cmt.SetFormatType(&FORMAT_WaveFormatEx);
    cmt.SetTemporalCompression(FALSE);
    cmt.SetSubtype(&GUID_NULL);
    cmt.AllocFormatBuffer(sizeof(w));
    CopyMemory(cmt.Format(), &wfx, sizeof(wfx));
    hr = pBuild->FindCompressorInterface(pCAud, IID_IAMStreamConfig,
							(void **)&pASC);
    hr = pASC->SetFormat(&cmt);
    pASC->Release();

    // Now we render the recompressed audio stream
    hr = pBuild->RenderCompressionStream(pSrc, pCAud, pRender);

    // Now we use device enumeration (see the \sdk\samples\capture sample
    // code to see how) to pick a video compressor. Use the
    "VideoCompressorCategory" for video compression filters
    pCVid = IBaseFilter pointer of the cinepak compressor we picked
    hr = pFg->AddFilter(pCVid, NULL);

    // now tell it to compress at 100k/second data rate
    // to set the data rate we use the current format, but change the data
    // rate item in the media type
    hr = pBuild->FindCompressorInterface(pCVid, IID_IAMStreamConfig,
							(void **)&pVSC);
    hr = pVSC->GetFormat(&cmt);
    ((VIDEOINFOHEADER)(cmt.Format()))->dwBitRate = 100000;
    hr = pVSC->SetFormat(&cmt);
    pVSC->Release();

    // now tell it we want key frames every 4 frames
    hr = pBuild->FindCompressorInterface(pCVid, IID_IAMVideoCompression,
							(void **)&pVC);
    hr = pVC->put_KeyFrameRate(4);
    pVC->Release();

    // Now we render the recompressed video stream
    hr = pBuild->RenderCompressionStream(pSrc, pCVid, pRender);

    // all done with these objects now
    pSrc->Release();
    pRender->Release();
    pCAud->Release();
    pCVid->Release();

    // now run the graph
    hr = FG->QueryInterface(IID_IMediaControl, &MC);
    MC->Run();

    // app now waits for EC_COMPLETE, and it's all done!
    wait for EC_COMPLETE event... see amcap sample

    pFg->Release();
    pBuild->Release();

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.