2012-05-02 37 views
2

我有一個製作AVI電影的Delphi 6應用程序。我已經到了可以編寫具有未壓縮視頻幀的AVI文件的程度。當我嘗試創建一個壓縮的視頻流,我碰到一個錯誤AVIERR_MEMORY當我叫AVIStreamSetFormat():在AVIStreamSetFormat()調用期間發生AVIERR_MEMORY錯誤

hr := AVIStreamSetFormat(
     FAvi_.thePsCompressed, 
     0, 
     @dsBmih, 
     dsBmih.biSize + dsBmih.biClrUsed * sizeof(RGBQUAD)); 

爲什麼會出現這個錯誤,我能做些什麼來解決這個問題?

這是我選擇Cinepak Code by Radius壓縮器​​後,使用AVISaveOptions()調用後的壓縮選項數據結構的內容。請注意,如果我選擇一個不同的壓縮機我還是得到錯誤:

fccType: 0 
fccHandler: 1684633187 
dwKeyFrameEvery: 0 
dwQuality: 8800 
dwBytesPerSecond: 0 
dwFlags: 8 
lpFormat: nil 
cbFormat: 0 
lpParms: nil 
cbParms: 4 
dwInterleaveEvery: 0 

這裏是TBitmapHeaderInfo數據結構的內容:

biSize: 40 
biWidth: 320 
biHeight: -240 
biPlanes: 1 
biBitcount: 32 
biCompression: 0 
biSizeImage: 307200 
biXPelsPerMeter: 0 
biYPelsPerMeter: 0 
biClrUsed: 0 
biClrImportant: 0 

這裏是一個包含調用AVIStreamSetFormat方法():

function TAviWriterWithCompression.compressionDirect(
           opts: PAVICOMPRESSOPTIONS; 
           bShowDialog: boolean; 
           hparent: HWND; 
           dsBmih: TBitmapInfoHeader; 
           sizeImage: integer; 
           DIBValues: Pointer; 
           framesPerSecond: integer): HRESULT; 
var 
    lastErr: string; 
    hr: HRESULT; 
    myopts: TAVICOMPRESSOPTIONS; 
    aopts: array[0..0] of PAVICOMPRESSOPTIONS; 
    res: Bool; 
begin 
    if not FIsVirginFile then 
    begin 
     // The output file already has at least one audio or video frame so 
     // setting or changing the compression format is not allowed. 
     Result := LongInt(AVIERR_ERROR); 

     // =========================== EXIT POINT ============== 
     exit; 
    end; // if not Assigned(FAvi_) then 

    if not Assigned(FAvi_) then 
    begin 
     Result := LongInt(AVIERR_BADHANDLE); 

     // =========================== EXIT POINT ============== 
     exit; 
    end; // if not Assigned(FAvi_) then 

    // Check the utility object for an error. 
    if (FAvi_.iserr) then 
    begin 
     Result := LongInt(AVIERR_ERROR); 
     // =========================== EXIT POINT ============== 
     exit; 
    end; // if (FAvi_.iserr) then 

    // Make sure the compressor has not already been selected. 
    if Assigned(FAvi_.thePsCompressed) then 
    begin 
     Result := LongInt(AVIERR_COMPRESSOR); 
     // =========================== EXIT POINT ============== 
     exit; 
    end; // if (FAvi_.iserr) then 

    // create the stream, if it wasn't there before 
    if not Assigned(FAvi_.thePs) then 
    begin 
     hr := createVideoStream(dsBmih, framesPerSecond); 

     if hr <> AVIERR_OK then 
     begin 
      Result := hr; 

      // Set the error flag in our utility object. 
      FAvi_.iserr := true; 

      // =========================== EXIT POINT ============== 
      exit; 
     end; // if hr <> AVIERR_OK then 
    end; // if not Assigned(FAvi_.thePs) then 

    // set the compression, prompting dialog if necessary 
    if not Assigned(FAvi_.thePsCompressed) then 
    begin 
     ZeroMemory(@myopts, sizeof(myopts)); 

     if Assigned(opts) then 
      // Use the provided compressor options 
      aopts[0] := opts 
     else 
      // Use our initialized (empty) variable. 
      aopts[0] := @myopts; 

     // Does the caller want to show the compressor dialog box? 
     if (bShowDialog) then 
     begin 
      res := AVISaveOptions(hparent, 0, 1, FAvi_.thePs, aopts[0]); 

      if not res then 
      begin 
       AVISaveOptionsFree(1, aopts[0]); 

       // Set the error flag. 
       FAvi_.iserr := true; 

       Result := LongInt(AVIERR_USERABORT); 

       // =========================== EXIT POINT ============== 
       exit; 
      end; // if res = 0 then 
     end; // if (bShowDialog) then 

     hr := AVIMakeCompressedStream(FAvi_.thePsCompressed, FAvi_.thePs, aopts[0], nil); 

     if hr <> AVIERR_OK then 
     begin 
      Result := hr; 

      // Set the error flag in our utility object. 
      FAvi_.iserr := true; 

      // =========================== EXIT POINT ============== 
      exit; 
     end; // if hr <> AVIERR_OK then 

     AVISaveOptionsFree(1, aopts[0]); 
     postDiagMsg('Avi::compression after AVISaveOptionsFree()'); 

     // >>>> This is where I get the AVIERR_MEMORY error. 
     hr := AVIStreamSetFormat(FAvi_.thePsCompressed, 0, @dsBmih, dsBmih.biSize + dsBmih.biClrUsed * sizeof(RGBQUAD)); 

     if hr <> AVIERR_OK then 
     begin 
      Result := hr; 

      // Set the error flag in our utility object. 
      FAvi_.iserr := true; 

      // =========================== EXIT POINT ============== 
      exit; 
     end; // if hr <> AVIERR_OK then 
    end; // if not Assigned(FAvi_.thePsCompressed) then 

    Result := AVIERR_OK; 
end; 

回答

3

它可能由biHeightTBitmapHeaderInfo負值引起結構,這意味着存儲在DIB部分中的位值表示垂直翻轉的圖像。

某些編解碼器可能無法解決此問題。因此,請儘量確保圖像標題的大小和位深度可以由您選擇的視頻流壓縮器處理。您必須僅使用支持的圖像格式,並且如果您的編解碼器不支持翻轉的圖像,則必須翻轉DIB圖像數據並由您自己手動修改圖像標題。

相關問題