SoundSource::OpenResult SoundSourceMediaFoundation::tryOpen(const AudioSourceConfig& audioSrcCfg) {
    if (SUCCEEDED(m_hrCoInitialize)) {
        qWarning() << "Cannot reopen MediaFoundation file" << getUrlString();
        return OpenResult::FAILED;
    }

    const QString fileName(getLocalFileName());

    if (sDebug) {
        qDebug() << "open()" << fileName;
    }

    // Initialize the COM library.
    m_hrCoInitialize = CoInitializeEx(nullptr,
            COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(m_hrCoInitialize)) {
        qWarning() << "SSMF: failed to initialize COM";
        return OpenResult::FAILED;
    }
    // Initialize the Media Foundation platform.
    m_hrMFStartup = MFStartup(MF_VERSION);
    if (FAILED(m_hrCoInitialize)) {
        qWarning() << "SSMF: failed to initialize Media Foundation";
        return OpenResult::FAILED;
    }

    // Create the source reader to read the input file.
    // Note: we cannot use QString::toStdWString since QT 4 is compiled with
    // '/Zc:wchar_t-' flag and QT 5 not
    const ushort* const fileNameUtf16 = fileName.utf16();
    static_assert(sizeof(wchar_t) == sizeof(ushort), "QString::utf16(): wchar_t and ushort have different sizes");
    HRESULT hr = MFCreateSourceReaderFromURL(
            reinterpret_cast<const wchar_t*>(fileNameUtf16),
            nullptr,
            &m_pReader);

    if (FAILED(hr)) {
        qWarning() << "SSMF: Error opening input file:" << fileName;
        return OpenResult::FAILED;
    }

    if (!configureAudioStream(audioSrcCfg)) {
        qWarning() << "SSMF: Error configuring audio stream.";
        return OpenResult::FAILED;
    }

    if (!readProperties()) {
        qWarning() << "SSMF::readProperties failed";
        return OpenResult::FAILED;
    }

    //Seek to position 0, which forces us to skip over all the header frames.
    //This makes sure we're ready to just let the Analyzer rip and it'll
    //get the number of samples it expects (ie. no header frames).
    seekSampleFrame(0);

    return OpenResult::SUCCEEDED;
}
Result SoundSourceMediaFoundation::tryOpen(const Mixxx::AudioSourceConfig& audioSrcCfg) {
    if (SUCCEEDED(m_hrCoInitialize)) {
        qWarning() << "Cannot reopen MediaFoundation file" << getUrlString();
        return ERR;
    }

    const QString fileName(getLocalFileName());

    if (sDebug) {
        qDebug() << "open()" << fileName;
    }

    // Initialize the COM library.
    m_hrCoInitialize = CoInitializeEx(NULL,
            COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(m_hrCoInitialize)) {
        qWarning() << "SSMF: failed to initialize COM";
        return ERR;
    }
    // Initialize the Media Foundation platform.
    m_hrMFStartup = MFStartup(MF_VERSION);
    if (FAILED(m_hrCoInitialize)) {
        qWarning() << "SSMF: failed to initialize Media Foundation";
        return ERR;
    }

    QString qurlStr(fileName);
    // http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/35c6a451-3507-40c8-9d1c-8d4edde7c0cc
    // gives maximum path + file length as 248 + 260, using that -bkgood
    m_wcFilename = new wchar_t[248 + 260];
    int wcFilenameLength(fileName.toWCharArray(m_wcFilename));
    // toWCharArray does not append a null terminator to the string!
    m_wcFilename[wcFilenameLength] = '\0';

    // Create the source reader to read the input file.
    HRESULT hr = MFCreateSourceReaderFromURL(m_wcFilename, NULL, &m_pReader);
    if (FAILED(hr)) {
        qWarning() << "SSMF: Error opening input file:" << fileName;
        return ERR;
    }

    if (!configureAudioStream(audioSrcCfg)) {
        qWarning() << "SSMF: Error configuring audio stream.";
        return ERR;
    }

    //Seek to position 0, which forces us to skip over all the header frames.
    //This makes sure we're ready to just let the Analyser rip and it'll
    //get the number of samples it expects (ie. no header frames).
    seekSampleFrame(0);

    return OK;
}
int SoundSourceMediaFoundation::open()
{
    if (sDebug) {
        qDebug() << "open()" << m_qFilename;
    }

    QString qurlStr(m_qFilename);
    int wcFilenameLength(m_qFilename.toWCharArray(m_wcFilename));
    // toWCharArray does not append a null terminator to the string!
    m_wcFilename[wcFilenameLength] = '\0';

    HRESULT hr(S_OK);
    // Initialize the COM library.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(hr)) {
        qWarning() << "SSMF: failed to initialize COM";
        return ERR;
    }

    // Initialize the Media Foundation platform.
    hr = MFStartup(MF_VERSION);
    if (FAILED(hr)) {
        qWarning() << "SSMF: failed to initialize Media Foundation";
        return ERR;
    }

    // Create the source reader to read the input file.
    hr = MFCreateSourceReaderFromURL(m_wcFilename, NULL, &m_pReader);
    if (FAILED(hr)) {
        qWarning() << "SSMF: Error opening input file:" << m_qFilename;
        return ERR;
    }

    if (!configureAudioStream()) {
        qWarning() << "SSMF: Error configuring audio stream.";
        return ERR;
    }

    if (!readProperties()) {
        qWarning() << "SSMF::readProperties failed";
        return ERR;
    }

    //Seek to position 0, which forces us to skip over all the header frames.
    //This makes sure we're ready to just let the Analyser rip and it'll
    //get the number of samples it expects (ie. no header frames).
    seek(0);

    return OK;
}
int AudioDecoderMediaFoundation::open()
{
    if (sDebug) {
        std::cout << "open() " << m_filename << std::endl;
    }

    //Assumes m_filename is ASCII and converts it to UTF-16 (wide char).
    /*
	int wcFilenameLength = m_filename.size();
	for(std::wstring::size_type i=0; i < m_filename.size(); ++i)
	{
		m_wcFilename[i] = m_filename[i];
	}
	m_wcFilename[wcFilenameLength] = (wchar_t)'\0';

	std::string s;

	std::wstring stemp = s2ws(m_filename); // Temporary buffer is required
	LPCWSTR result = (LPCWSTR)stemp.c_str();
    */
   
    //LPCWSTR result; 
    const char* utf8Str = m_filename.c_str();
    MultiByteToWideChar(CP_ACP, 
                        0, 
                        utf8Str, 
                        -1, //assume utf8Str is NULL terminated and give us back a NULL terminated string
                        (LPWSTR)m_wcFilename,
                        512);
    
    LPCWSTR result = m_wcFilename;

    HRESULT hr(S_OK);
    // Initialize the COM library.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(hr)) {
        std::cerr << "SSMF: failed to initialize COM" << std::endl;
        return AUDIODECODER_ERROR;
    }

    // Initialize the Media Foundation platform.
    hr = MFStartup(MF_VERSION);
    if (FAILED(hr)) {
        std::cerr << "SSMF: failed to initialize Media Foundation" << std::endl;
        return AUDIODECODER_ERROR;
    }

    // Create the source reader to read the input file.
    hr = MFCreateSourceReaderFromURL(/*m_wcFilename*/result, NULL, &m_pReader);
    if (FAILED(hr)) {
        std::cerr << "SSMF: Error opening input file:" << m_filename << ", with error: " << HRESULT_CODE(hr) << std::endl;
        return AUDIODECODER_ERROR;
    }

    if (!configureAudioStream()) {
        std::cerr << "SSMF: Error configuring audio stream." << std::endl;
        return AUDIODECODER_ERROR;
    }

    if (!readProperties()) {
        std::cerr << "SSMF::readProperties failed" << std::endl;
        return AUDIODECODER_ERROR;
    }

    //Seek to position 0, which forces us to skip over all the header frames.
    //This makes sure we're ready to just let the Analyser rip and it'll
    //get the number of samples it expects (ie. no header frames).
    seek(0);

    return AUDIODECODER_OK;
}