예제 #1
0
void PlayMedia(const char *pszFileName) throw(_com_error)
{
	HRESULT hr;
	IGraphBuilderPtr pGraphBuilder;
	IMediaControlPtr pMediaControl;
	IMediaEventPtr pMediaEvent;
	WCHAR wszFileName[MAX_PATH];
	LONG lEventCode;

	CoInitializeEx(NULL, COINIT_MULTITHREADED);

	pGraphBuilder.CreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC);

	wsprintfW(wszFileName, L"%S", pszFileName);
	hr = pGraphBuilder->RenderFile(wszFileName, NULL);
	if (!SUCCEEDED(hr))
		_com_raise_error(hr);

	pMediaControl = pGraphBuilder;
	pMediaEvent = pGraphBuilder;

	hr = pMediaControl->Run();
	if (!SUCCEEDED(hr))
		_com_raise_error(hr);

	hr = pMediaEvent->WaitForCompletion(INFINITE, &lEventCode);
	if (!SUCCEEDED(hr))
		_com_raise_error(hr);
}
예제 #2
0
파일: oggenc.cpp 프로젝트: kazutomi/xiphqt
int wmain(int argc, wchar_t* argv[]) 
{ 
    using namespace dshow; 
    using namespace std; 
 
    if (!ParseCommandlineParameters(argc, argv))
    {
        return 1;
    }
  
    try 
    { 
        IGraphBuilderPtr graphBuilder; 
 
        HRESULT hr = graphBuilder.CreateInstance(CLSID_FilterGraph); 
        ThrowIfError(hr, "ERROR: could not create filter graph object");

        IFilterGraphPtr filterGraph = graphBuilder;
  
        // Add a renderer, which will be replaced by the encoder
        IBaseFilterPtr directSound;
        hr = directSound.CreateInstance(CLSID_DSoundRender);
        ThrowIfError(hr, "ERROR: could not create direct sound renderer");

        filterGraph->AddFilter(directSound, L"Direct Sound Renderer");

        // Render the audio source file using intelligent connect
        hr = graphBuilder->raw_RenderFile(const_cast<wchar_t*>(g_options.sourceFile.c_str()), 0); 
        ThrowIfError(hr, "ERROR: could not render the file");

        // Get the audio decoder output pin
        IPinPtr directSoundRendererInput = FindPin(directSound, dshow::PINDIR_INPUT);

        IPinPtr audioRendererPin;
        hr = directSoundRendererInput->raw_ConnectedTo(&audioRendererPin);
        ThrowIfError(hr, "ERROR: could not get audio renderer output pin");

        // Remove the DirectSound renderer
        audioRendererPin->Disconnect();
        filterGraph->RemoveFilter(directSound);

        // Add the Vorbis Encoder
        IBaseFilterPtr vorbisEncoder;
        hr = vorbisEncoder.CreateInstance(CLSID_VorbisEncoder);
        ThrowIfError(hr, "ERROR: could not create vorbis encoder object");

        filterGraph->AddFilter(vorbisEncoder, L"Vorbis Encoder");

        // Connect the audio decoder to the Vorbis Encoder
        IPinPtr vorbisEncoderInput = FindPin(vorbisEncoder, dshow::PINDIR_INPUT);

        hr = filterGraph->raw_ConnectDirect(audioRendererPin, vorbisEncoderInput, 0);
        ThrowIfError(hr, "ERROR: could not connect audio renderer to vorbis encoder");

        // Add the Ogg Mux Filter
        IBaseFilterPtr oggMuxer;
        hr = oggMuxer.CreateInstance(CLSID_OggMuxFilter);
        ThrowIfError(hr, "ERROR: could not create ogg mux object");

        filterGraph->AddFilter(oggMuxer, L"Ogg Muxer");

        // Connect the Vorbis Encoder to Ogg Muxer
        IPinPtr vorbisEncoderOutput = FindPin(vorbisEncoder, dshow::PINDIR_OUTPUT);
        IPinPtr oggMuxerInput = FindPin(oggMuxer, dshow::PINDIR_INPUT);

        hr = filterGraph->raw_ConnectDirect(vorbisEncoderOutput, oggMuxerInput, 0);
        ThrowIfError(hr, "ERROR: could not connect vorbis encoder to ogg muxer");

        // Get the encoder settings object
        IVorbisEncodeSettingsPtr encodeSettings = vorbisEncoder;

        // Set the name of the Ogg file
        IFileSinkFilterPtr oggSource = oggMuxer;

        hr = oggSource->SetFileName(g_options.oggFile.c_str(), 0);
        ThrowIfError(hr, "ERROR: could not set ogg muxer file");

        // Get the progress from the Ogg Muxer
        IOggMuxProgressPtr oggMuxProgress = oggMuxer;
 
        REFERENCE_TIME audioSourceDuration = GetAudioSourceDuration(g_options.sourceFile);

        wcout << L"Encoding \"" << g_options.sourceFile.c_str() << L"\" to" << endl;
        wcout << L"\t \"" << g_options.oggFile.c_str() << L"\"" << endl;

        if (g_options.bitrate != 0)
        {
            wcout << L"WARNING: oggcodecs build version <= 0.81.15562 do not work correctly!" << endl;
            wcout << L"WARNING: at the end of the encoding, the average bitrate does not" << endl;
            wcout << L"WARNING: have the expected value." << endl;

            encodeSettings->setBitrateQualityMode(g_options.bitrate);
        }
        else if (g_options.managedMinBitrate != 0 && g_options.managedMaxBitrate != 0)
        {
            wcout << L"using bitrate management (min " << g_options.managedMinBitrate << L" kbps, ";
            wcout << L"max " << g_options.managedMaxBitrate << L" kbps)" << endl;

            encodeSettings->setManaged(g_options.bitrate, g_options.managedMinBitrate, 
                g_options.managedMaxBitrate);
        }
        else
        {
            wcout << L"at quality " << fixed << setprecision(1) << g_options.quality << endl;

            encodeSettings->setQuality(static_cast<int>(g_options.quality * 10));
        }

        unsigned long startTime = timeGetTime(); 

        // Start the encoding
        IMediaControlPtr control = graphBuilder; 
        control->Run(); 

        LONGLONG destinationFileSize;
        bool isEncoding = true;
        while (isEncoding)
        {
            LONGLONG muxerProgressTime = oggMuxProgress->getProgressTime();
            destinationFileSize = oggMuxProgress->getBytesWritten();
                                
            // Give a margin of 10 nanoseconds
            if (muxerProgressTime >= audioSourceDuration - 10)
            {
                muxerProgressTime = audioSourceDuration;

                control->Stop();
                isEncoding = false;
            }
            else
            {
                // Sleep 50 milliseconds
                Sleep(50);
            }

            unsigned long currentTime = ::timeGetTime();

            PrintProgress(muxerProgressTime, audioSourceDuration, (currentTime - startTime) * 10000);
        } 

        unsigned long endTime = timeGetTime(); 
        PrintStatistics(g_options.oggFile, audioSourceDuration, (endTime - startTime) * 10000, destinationFileSize);
    } 
    catch(const std::runtime_error& err) 
    { 
        wcout << err.what() << endl; 
    } 
    catch(const _com_error& err)
    {
        wcout << L"Error code: 0x" << hex << err.Error() << L"(" << err.ErrorMessage() << L")" << endl;
    }
    catch (...)
    {
        wcout << "Unknown exception!";
    }
     
    return 0; 
}