2013-02-11 65 views
1

我需要一些幫助創建一個AVI文件的位圖。 問題是,在最後我得到一個損壞的AVI文件。如果我有一個HEX_Editor 整個AVI標頭爲0 ...Bitmaps to Avi使用視頻的Windows,C

讀它,我使用Borland C++ Builder的6和64位Windows 7

AVIINFO結構:

typedef struct 
{ 
    PAVISTREAM aviStream; 
    PAVISTREAM aviStreamCompressed; 
    PAVIFILE aviFile; 
    AVISTREAMINFO avistInfo; 
    AVICOMPRESSOPTIONS avistComprOpts; 
    unsigned long framenumber; // which frame will be added next 
} AVIINFO, *PAVIINFO; 

pstBmpInfo已經填滿像這樣的:

biSize = 40 
biWidth = 800 
biHeight = 600 
biPlanes = 1 
biBitcount = 24 
biSizeImage = 1440000 
others are 0 


int initAvi(AVIINFO *aviInfo, BMPINFOHEADER *pstBmpInfo) 
    { 
      /* AVIFile Library initialisieren */ 
      AVIFileInit(); 

     /* File erstellen */ 
     if (AVIFileOpen(&(aviInfo->aviFile), "avistream.avi", OF_CREATE|OF_WRITE, NULL) != 0) 
     { 
       printf("Error creating AVIFile...\n%s\n", strerror(errno)); 
       return -1; 
     } 

     memset(&(aviInfo->avistInfo), 0, sizeof(aviInfo->avistInfo)); 
     memset(&(aviInfo->avistComprOpts), 0, sizeof(aviInfo->avistComprOpts)); 

     /* AVISTREAMINFO Optionen setzen */ 
     aviInfo->avistInfo.fccType = streamtypeVIDEO; 
     aviInfo->avistInfo.fccHandler = mmioFOURCC('M','S','V','C'); 
     aviInfo->avistInfo.dwRate = STREAM_FPS; // 10 
     aviInfo->avistInfo.dwScale = 1; 
     aviInfo->avistInfo.dwSuggestedBufferSize = pstBmpInfo->biSizeImage; 
     aviInfo->avistInfo.rcFrame.bottom = pstBmpInfo->biHeight; 
     aviInfo->avistInfo.rcFrame.right = pstBmpInfo->biWidth; 
     aviInfo->avistInfo.dwQuality = -1; // default quality 

     /* Stream erstellen */ 
     if (AVIFileCreateStream(aviInfo->aviFile ,&(aviInfo->aviStream), &(aviInfo->avistInfo)) != 0) 
     { 
       printf("Error creating Stream...\nErrorcode: %s\n", strerror(errno)); 
       return -1; 
     } 

     /* AVICOMPRESSOPTIONS Optionen setzen */ 
     aviInfo->avistComprOpts.fccType = streamtypeVIDEO; 
     aviInfo->avistComprOpts.fccHandler = mmioFOURCC('M','S','V','C'); 

     /* */ 
     if (AVIMakeCompressedStream(&(aviInfo->aviStreamCompressed), aviInfo->aviStream, 
       &(aviInfo->avistComprOpts), NULL) != AVIERR_OK) 
     { 
       printf("Error creating compressed Stream...\nErrorcode: %s\n", strerror(errno)); 
       return -1; 
     } 

     /* Streamformat für Bitmaps */ 
     if (AVIStreamSetFormat(aviInfo->aviStreamCompressed, 0, pstBmpInfo, sizeof(*pstBmpInfo)) != 0) 
     { 
       printf("Error setting new Streamformat...\nErrorcode: %s\n", strerror(errno)); 
       return -1; 
     } 

     aviInfo->framenumber = 0; 
     return 0; 
} 

這是我寫的文件:

pucBitmapDataBuffer保持的BitmapData

. 
. 
. 
. 

if ((AVIStreamWrite(aviInfo->aviStreamCompressed, aviInfo->framenumber, 1, pucBitmapDataBuffer, 
         sizeof(pucBitmapDataBuffer), AVIIF_KEYFRAME, NULL, NULL)) != 0) 
       { 
         streamErrorCnt++; 
         printf("Could not write Data to Stream...\n%s", strerror(errno)); 
         aviInfo->framenumber++; 
         free(pucBitmapDataBuffer); 
         fclose(FileSource); 
         stDirEp = readdir(DirSource); 
         continue; // get next BMP 
       } 
       else 
       { 
         streamErrorCnt = 0; 
         aviInfo->framenumber++; 
       } 
. 
. 
. 
. 

我不知道如何填寫AVICOMPRESSOPTIONS,或者如果我使用的funcions是正確的......

PS:這是我的第一篇文章在這裏,如果你需要更多的信息,請讓我知道!

+0

在您的代碼中,您關閉了該文件,並且我認爲您將再次打開該文件。當您重新打開該文件時,是否可以檢查是否以O_APPEND模式而不是O_WRITE模式打開? – Ganesh 2013-02-11 17:13:17

+0

嘿,謝謝你的回覆!你的意思是哪個文件? 「FileSource」在寫入流後關閉文件並轉到目錄「DirSource」中的下一個位圖後,讀取位圖(Headers和Data)。我打開每個位圖,如下所示: FileSource = fopen(sourcepathbuffer,「rb」) 「sourcepathbuffer」包含路徑和文件名稱 – Cittles 2013-02-12 09:15:02

+0

您正逐幀將BMP寫入AVIStream。我的問題與流有關。你關閉並重新打開流?如果是這樣,請在'O_APPEND'模式下打開'AVI'流。 – Ganesh 2013-02-12 16:31:48

回答

1

前一段時間,但這裏是解決方案:

如果流完成後,您必須使用AVIStreamRelease關閉流()。 只有標題將被生成並寫入文件。