locked
create wmv files from images RRS feed

  • Question

  • i want to create wmv file from images.

    i make some change on a example from msdn.but the result is not good.all of frames  are black-white and fuzzy.

    codes as follow:

    const UINT32 VIDEO_WIDTH = 640;
    const UINT32 VIDEO_HEIGHT = 480;
    const UINT32 VIDEO_FPS = 25;
    const UINT32 VIDEO_BIT_RATE = 800000;
    const GUID   VIDEO_ENCODING_FORMAT = MFVideoFormat_WMV3;
    const GUID   VIDEO_INPUT_FORMAT = MFVideoFormat_RGB32;
    const UINT32 VIDEO_PELS = VIDEO_WIDTH * VIDEO_HEIGHT;
    const UINT32 VIDEO_FRAME_COUNT = 20 * VIDEO_FPS;

    HRESULT InitializeSinkWriter(IMFSinkWriter **ppWriter, DWORD *pStreamIndex)
    {
     *ppWriter = NULL;
     *pStreamIndex = NULL;

     IMFSinkWriter   *pSinkWriter = NULL;
     IMFMediaType    *pMediaTypeOut = NULL;  
     IMFMediaType    *pMediaTypeIn = NULL;  
     DWORD           streamIndex;    

     HRESULT hr = MFCreateSinkWriterFromURL(L"output.wmv", NULL, NULL, &pSinkWriter);

     // Set the output media type.
     if (SUCCEEDED(hr))
     {
      hr = MFCreateMediaType(&pMediaTypeOut);  
     }
     if (SUCCEEDED(hr))
     {
     hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);    
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, VIDEO_ENCODING_FORMAT);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, VIDEO_BIT_RATE);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);  
     }
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT);  
     }
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1);  
     }
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pSinkWriter->AddStream(pMediaTypeOut, &streamIndex);  
     }

     // Set the input media type.
     if (SUCCEEDED(hr))
     {
      hr = MFCreateMediaType(&pMediaTypeIn);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT);    
     }
     if (SUCCEEDED(hr))
     {
      hr = pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);  
     }

     
     
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT);  
     }
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, VIDEO_FPS, 1);  
     }
     if (SUCCEEDED(hr))
     {
      hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);  
     }
     if (SUCCEEDED(hr))
     {
      hr = pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);  
     }

     // Tell the sink writer to start accepting data.
     if (SUCCEEDED(hr))
     {
      hr = pSinkWriter->BeginWriting();
     }

     // Return the pointer to the caller.
     if (SUCCEEDED(hr))
     {
      *ppWriter = pSinkWriter;
      (*ppWriter)->AddRef();
      *pStreamIndex = streamIndex;
     }

     SafeRelease(&pSinkWriter);
     SafeRelease(&pMediaTypeOut);
     SafeRelease(&pMediaTypeIn);
     return hr;
    }

    HRESULT WriteFrame(
           IMFSinkWriter *pWriter,
           DWORD streamIndex,
           const LONGLONG& rtStart,        // Time stamp.
           const LONGLONG& rtDuration      // Frame duration.
           )
    {
     IMFSample *pSample = NULL;
     IMFMediaBuffer *pBuffer = NULL;

     const LONG cbWidth = 4 * VIDEO_WIDTH;
     const DWORD cbBuffer = cbWidth * VIDEO_HEIGHT;

     BYTE *pData = NULL;

     // Create a new memory buffer.
     HRESULT hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer);

     // Lock the buffer and copy the video frame to the buffer.
     if (SUCCEEDED(hr))
     {
      hr = pBuffer->Lock(&pData, NULL, NULL);
     }

     ////  [4/17/2012 Lenovo]
     ifstream ifstr;
     static int nCounter = 0;
     char *pszFileName;
     if (nCounter%2==0)
     {
      pszFileName="11.bmp";
     }
     else
     {
      pszFileName="untitled.bmp";
     }
     ifstr.open(pszFileName, ios::binary|ios::in);
     nCounter++;
     BITMAPFILEHEADER bitmaphed;
     BYTE pHeader[sizeof(BITMAPFILEHEADER)];

     ifstr.read((char*)pHeader,sizeof(BITMAPFILEHEADER));

     memcpy((void*)&bitmaphed, (void*)pHeader,sizeof(pHeader));
     UINT32 dd=bitmaphed.bfSize;
     BYTE *pByteData = new BYTE[dd];
     
     ifstr.read((char*)pByteData, bitmaphed.bfSize);
    //  [4/17/2012 Lenovo]
     if (SUCCEEDED(hr))
     {
      hr = MFCopyImage(
       pData,                      // Destination buffer.
       cbWidth,                    // Destination stride.
       (BYTE*)pByteData,    // First row in source image.
       cbWidth,                    // Source stride.
       cbWidth,                    // Image width in bytes.
       VIDEO_HEIGHT                // Image height in pixels.
       );
     }
     if (pBuffer)
     {
      pBuffer->Unlock();
     }
     ifstr.close();
     // Set the data length of the buffer.
     if (SUCCEEDED(hr))
     {
      hr = pBuffer->SetCurrentLength(cbBuffer);
     }

     // Create a media sample and add the buffer to the sample.
     if (SUCCEEDED(hr))
     {
      hr = MFCreateSample(&pSample);
     }
     if (SUCCEEDED(hr))
     {
      hr = pSample->AddBuffer(pBuffer);
     }

     // Set the time stamp and the duration.
     if (SUCCEEDED(hr))
     {
      hr = pSample->SetSampleTime(rtStart);
     }
     if (SUCCEEDED(hr))
     {
      hr = pSample->SetSampleDuration(rtDuration);
     }

     // Send the sample to the Sink Writer.
     if (SUCCEEDED(hr))
     {
      hr = pWriter->WriteSample(streamIndex, pSample);
     }

     delete pByteData;
     SafeRelease(&pSample);
     SafeRelease(&pBuffer);
     return hr;
    }

    void main()
    {
     // Set all pixels to green
     for (DWORD i = 0; i < VIDEO_PELS; ++i)
     {
      videoFrameBuffer[i] = 0x00FF00F0;
     }

     HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
     if (SUCCEEDED(hr))
     {
      hr = MFStartup(MF_VERSION);
      if (SUCCEEDED(hr))
      {
       IMFSinkWriter *pSinkWriter = NULL;
       DWORD stream;

       hr = InitializeSinkWriter(&pSinkWriter, &stream);
       if (SUCCEEDED(hr))
       {
        // Send frames to the sink writer.
        LONGLONG rtStart = 0;
        UINT64 rtDuration;

        MFFrameRateToAverageTimePerFrame(VIDEO_FPS, 1, &rtDuration);

        for (DWORD i = 0; i < VIDEO_FRAME_COUNT; ++i)
        {
         hr = WriteFrame(pSinkWriter, stream, rtStart, rtDuration);
         if (FAILED(hr))
         {
          break;
         }
         rtStart += rtDuration;
        }
       }
       if (SUCCEEDED(hr))
       {
        hr = pSinkWriter->Finalize();
       }
       SafeRelease(&pSinkWriter);
       MFShutdown();
      }
      CoUninitialize();
     }
    }

    thank you!

    Sunday, April 22, 2012 11:43 AM

All replies