|
|
hi all,
please do not leave this topic by thinking that its too long to read, atleast go through the problem defination. I was asking the solution for converting set of images into video using media SDK. Chris told me to go through the IWMWriter. Ap per the SDK help, i have written a program. But dont know why its not working. Here is thet program you can just copy the same and try it. please
requirement is that, need a BitmapSet1.bmp file in D drive, try to take a small one.
issue: WriteSample method is returning NS_E_NOT_CONFIGURED when i set the value 0(zero) to this variable vihVideoInfo.bmiHeader.biSizeImage. And if i change it to the value (pBmiHdr->biHeight * pBmiHdr->biWidth * pBmiHdr->biBitCount) / 8 (as given in help file) then AddStream is returning NS_E_INVALID_STREAM (The specified stream does not exist).
I am not finding any clue for this please help me members
int main(void) { HRESULT hr = NULL; //char *szInputFile = ; char *szOutFile = "D:\\vishy.wmv"; HANDLE hFile;
hr = CoInitialize(NULL);
hFile = (HANDLE)CreateFile("D:\\BitmapSet1.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); DWORD size = GetFileSize(hFile, &size); BYTE *buffer = (BYTE *)malloc(size); DWORD read; if(ReadFile(hFile, buffer, size, &read, NULL) == 0) { printf("ReadFile(D:\\BitmapSet1.bmp) Failed\n"); return 1; } int cbFileHeader = sizeof(BITMAPFILEHEADER); printf("BITMAPFILEHEADER : %d\n", cbFileHeader);
// Store the size of the BITMAPINFO BITMAPFILEHEADER *pBm = (BITMAPFILEHEADER*)buffer; DWORD cbBitmapInfo = pBm->bfOffBits - cbFileHeader;
// Store a pointer to the BITMAPINFO BITMAPINFO *pBmi = (BITMAPINFO*)(buffer + cbFileHeader); BITMAPINFOHEADER *pBmiHdr = (BITMAPINFOHEADER*)(buffer + cbFileHeader);
// Store a pointer to the starting address of the pixel bits BYTE * Image = buffer + cbFileHeader + cbBitmapInfo;
// Close and invalidate the file handle, since we have copied its bitmap data CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
// create a profo mamger IWMProfileManager* pProfileManager; IWMProfile* pProfile; hr = WMCreateProfileManager(&pProfileManager ); // create a profile if(pProfileManager) { hr = pProfileManager->CreateEmptyProfile(WMT_VER_9_0, &pProfile); if(FAILED(hr)) { SAFE_RELEASE(pProfileManager ); return 1; } }
IWMStreamConfig* pConfig; // create a stream for the profile: hr = pProfile->CreateNewStream(WMMEDIATYPE_Image,&pConfig); if( FAILED(hr)) return 1; //set stream name and all the connection name: if(pConfig) { hr = pConfig->SetStreamName(L"bitmapImageStream"); } if(FAILED(hr)) return 1; // configure a connect name for the stream hr = pConfig-> SetConnectionName(L"VideoImg"); if(FAILED(hr)) return 1; /// configure a strean number s from 1 - 63 hr = pConfig->SetStreamNumber(1); if(FAILED(hr)) return 1;
// set bit rate hr=pConfig->SetBitrate(50000); if(FAILED(hr)) return 1;
// set window size hr =pConfig->SetBufferWindow(50000); if(FAILED(hr)) return 1;
//******************* configure media type for image **************//
WM_MEDIA_TYPE *wmtMediaType = new WM_MEDIA_TYPE; ZeroMemory( wmtMediaType, sizeof( wmtMediaType ) ); WMVIDEOINFOHEADER vihVideoInfo;
IWMMediaProps* pMediaProps = NULL;
hr = pConfig->QueryInterface( IID_IWMMediaProps, (void**) &pMediaProps ); if ( FAILED( hr ) ) { return 1; } // Set up the WMVIDEOINFOHEADER structure ZeroMemory( &vihVideoInfo, sizeof( vihVideoInfo ) ); vihVideoInfo.rcSource.left = 0; vihVideoInfo.rcSource.top = 0; vihVideoInfo.rcSource.bottom = pBmiHdr->biHeight; vihVideoInfo.rcSource.right = pBmiHdr->biWidth; // it seems stream of image doesn't // accept width <200 vihVideoInfo.rcTarget = vihVideoInfo.rcSource; vihVideoInfo.dwBitRate=100; // same value as above vihVideoInfo.dwBitErrorRate = 0; vihVideoInfo.AvgTimePerFrame = 0; vihVideoInfo.dwBitErrorRate = 0;
vihVideoInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); vihVideoInfo.bmiHeader.biWidth = pBmiHdr->biWidth; vihVideoInfo.bmiHeader.biHeight = pBmiHdr->biHeight; vihVideoInfo.bmiHeader.biPlanes = 1; vihVideoInfo.bmiHeader.biBitCount = pBmiHdr->biBitCount; vihVideoInfo.bmiHeader.biCompression = BI_RGB; vihVideoInfo.bmiHeader.biSizeImage = (pBmiHdr->biHeight * pBmiHdr-
[Quoted Text] >biWidth * pBmiHdr->biBitCount) / 8;
vihVideoInfo.bmiHeader.biXPelsPerMeter = 0; vihVideoInfo.bmiHeader.biYPelsPerMeter = 0; vihVideoInfo.bmiHeader.biClrUsed = 0; vihVideoInfo.bmiHeader.biClrImportant = 0;
printf("%d, %d\n", vihVideoInfo.bmiHeader.biSizeImage, pBmiHdr- >biSizeImage); // Set up the WM_MEDIA_TYPE structure wmtMediaType->majortype = WMMEDIATYPE_Image; wmtMediaType->subtype = WMMEDIASUBTYPE_RGB24; wmtMediaType->bFixedSizeSamples = FALSE; wmtMediaType->bTemporalCompression = FALSE; wmtMediaType->lSampleSize = 0; wmtMediaType->formattype = WMFORMAT_VideoInfo; wmtMediaType->pUnk = NULL; wmtMediaType->cbFormat = sizeof( WMVIDEOINFOHEADER ); wmtMediaType->pbFormat = (unsigned char *)new WMVIDEOINFOHEADER; wmtMediaType->pbFormat = (BYTE *) &vihVideoInfo;
// set media type hr = pMediaProps->SetMediaType( wmtMediaType );
if( hr==E_OUTOFMEMORY) { printf("outofMemory"); }
if( hr== E_INVALIDARG) { printf(" pValue is null"); }
if( FAILED( hr ) ) { return hr; }
// add stream profile hr = pProfile->AddStream(pConfig); if( FAILED( hr ) ) { return hr; }
SAFE_RELEASE(pConfig); SAFE_RELEASE(pMediaProps);
/// create a writer IWMWriter * m_pWriter=NULL; hr = WMCreateWriter( NULL, &m_pWriter ); if( FAILED( hr ) ) { return( hr ); } /// set writer profile hr = m_pWriter->SetProfile( pProfile ); if( FAILED( hr ) ) { return( hr ); }
SAFE_RELEASE(pProfile);
// working with the input: set the input properties the same as
IWMInputMediaProps * pInputProps = NULL; WCHAR* pwszConnectionName = NULL; DWORD cInputs = 0; WORD cchName = 0; hr = m_pWriter->GetInputCount( &cInputs ); // verify if the input name match with the stream name: for( DWORD i = 0; i < cInputs; i++ ) // here cInputs= 1; { hr = m_pWriter->GetInputProps( i, &pInputProps ); if( FAILED( hr ) ) return( hr );
hr = pInputProps->GetConnectionName(0, &cchName); if(cchName<=0) return 1; pwszConnectionName= new WCHAR [cchName]; /// get connection name of the stream hr = pInputProps->GetConnectionName(pwszConnectionName, &cchName); printf("Input # %d = %S\n", cchName, pwszConnectionName); if( FAILED( hr ) ) { break; }
if(pwszConnectionName) { delete pwszConnectionName; pwszConnectionName=NULL; }
/*WM_MEDIA_TYPE *wmmType; DWORD psType;
hr = pInputProps->GetMediaType(NULL, &psType); if( FAILED( hr ) ) { printf("GetMediaType failed\n"); return( hr ); }
wmmType = (WM_MEDIA_TYPE*)new BYTE[psType];
hr = pInputProps->GetMediaType(wmmType, &psType); if( FAILED( hr ) ) { printf("GetMediaType failed\n"); return( hr ); }*/
SAFE_RELEASE(pInputProps);
// g_wszJPEGCompressionQuality for still image IWMWriterAdvanced2 *pWMWA2 = NULL; hr = m_pWriter->QueryInterface(IID_IWMWriterAdvanced2, (void**)&pWMWA2); if (SUCCEEDED(hr)) { DWORD value = 75; WMT_ATTR_DATATYPE wmt_type = WMT_TYPE_WORD; hr = pWMWA2->SetInputSetting(i, g_wszJPEGCompressionQuality, wmt_type , (BYTE*)&value,sizeof(WORD)); }
}
// Set the output file of the writer hr = m_pWriter->SetOutputFilename(L"D:\\vishy.wmv"); if( FAILED( hr ) ) { return( hr ); } // before feed the sample call hr = m_pWriter->BeginWriting(); if( FAILED(hr)) return 1;
DWORD cnsSampleTime = 1000; for( int k=0; k<10; k++) { // pass a sample to the writer
/// Allocate a buffer and retrieve a pointer to the INSSBuffer interface //DWORD dwSampleSize=pBmiHdr->biHeight*pBmiHdr->biWidth*3 ; DWORD dwSampleSize = size - cbFileHeader;
// when we have the image then we can have it INSSBuffer* pSample =NULL; // buffer to contain the image to pass hr = m_pWriter->AllocateSample(dwSampleSize,&pSample); if(FAILED(hr) || !pSample) return 1; ///Retrieve the address of the buffer created in step above BYTE* pdwBuffer=NULL; DWORD dwLeng; hr = pSample->GetBufferAndLength(&pdwBuffer,&dwLeng); if(FAILED(hr)) return 1; ///Copy sample data to the buffer location, making sure that the sample memcpy( pdwBuffer, pBmi, dwLeng); hr = pSample->SetLength(dwLeng);
printf("Size = %d dwLeng = %d\n", dwSampleSize, dwLeng); //printf("Size = %s\n%s\n", Image, Image+strlen((char *)Image)+4);
hr = m_pWriter->WriteSample(i-1 ,cnsSampleTime,0,pSample);
if( hr == S_OK) printf("Sample written\n");
else if( hr == E_INVALIDARG) printf("The dwInputNum value is greater than the highest index number %d\n", k);
else if( hr== E_UNEXPECTED) printf(" The method failed for an unspecified reason\n");
else if( hr== NS_E_NOT_CONFIGURED) printf(" Not configured properly %d, %d\n", k, i-1);
else if( hr == NS_E_INVALID_DATA) printf("The sample is not valid \n");
else if( hr == NS_E_INVALID_NUM_PASSES) printf("The wrong number of preprocessing passes\n");
else if( hr == NS_E_TOO_MUCH_DATA ) printf("Samples from a real-time source are arriving\n ");
cnsSampleTime+=1000; SAFE_RELEASE(pSample); }
hr = m_pWriter->EndWriting();
SAFE_RELEASE(m_pWriter);
return 0; }
|
|
hi,
I think you all got bored with my silly questions. But what to do i am new to this media sdk, don't know much. so taking help from you guys.
Thanx Vishy
|
|
|