从视频采集卡上采集了一段视频保存成avi格式,如何知道这段视频是按每秒多少桢采集的呢?

解决方案 »

  1.   

    unit UFm_Main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, Buttons;function Hex(InChar:Char):String;Type TAVIMAINHEADER=Packed record
    fcc:DWORD;
    cb:DWORD;
    dwMicroSecPerFrame:DWORD;
    dwMaxBytesPerSec:DWORD;
    dwPaddingGranularity:DWORD;
    dwFlags:DWORD;
    dwTotalFrames:DWORD;
    dwInitialFrames:DWORD;
    dwStreams:DWORD;
    dwSuggestedBufferSize:DWORD;
    dwWidth:DWORD;
    dwHeight:DWORD;
    dwReserved:array [0..3] of DWORD;
    end;Type TAVISTREAMHEADER=Packed Record
    fcc:DWORD;
    cb:DWORD;
    fccType:DWORD;
    fccHandler:DWORD;
    dwFlags:DWORD;
    wPriority:DWORD;
    wLanguage:DWORD;
    dwInitialFrames:DWORD;
    dwScale:DWORD;
    dwRate:DWORD;
    dwStart:DWORD;
    dwLength:DWORD;
    dwSuggestedBufferSize:DWORD;
    dwQuality:DWORD;
    dwSampleSize:DWORD;
    left:ShortInt;
    top:ShortInt;
    right:ShortInt;
    bottom:ShortInt;
    end;type
      TFm_Main = class(TForm)
        BitBtn1: TBitBtn;
        RE_Info: TRichEdit;
        OD_AVI: TOpenDialog;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Fm_Main: TFm_Main;
      AVIHeader:TAVIMAINHEADER;
      AVIStreamHeader:TAVISTREAMHEADER;implementation{$R *.dfm}
    function DWToString(dwInput:DWORD):String;
    begin
      Result:=Char(dwInput and $000000FF)
            +Char((dwInput shr 8) and $000000FF)
            +Char((dwInput shr 16) and $000000FF)
            +Char((dwInput shr 24) and $000000FF);
    end;function GetAVIHeaderInfo():String;
    var sTemp:String;
    begin
      sTemp:='AVI Header Info:(64)*************************';
      sTemp:=sTemp+#13#10+'fcc:'+DWToString(AVIHeader.fcc);
      sTemp:=sTemp+#13#10+'cb:'+IntToStr(AVIHeader.cb);
      sTemp:=sTemp+#13#10+'dwMicroSecPerFrame:'+IntToStr(AVIHeader.dwMicroSecPerFrame);
      sTemp:=sTemp+#13#10+'dwMaxBytesPerSec:'+IntToStr(AVIHeader.dwMaxBytesPerSec);
      sTemp:=sTemp+#13#10+'dwPaddingGranularity:'+IntToStr(AVIHeader.dwPaddingGranularity);
      sTemp:=sTemp+#13#10+'dwFlags:'+IntToStr(AVIHeader.dwFlags);
      sTemp:=sTemp+#13#10+'dwTotalFrames:'+IntToStr(AVIHeader.dwTotalFrames);
      sTemp:=sTemp+#13#10+'dwInitialFrames:'+IntToStr(AVIHeader.dwInitialFrames);
      sTemp:=sTemp+#13#10+'dwStreams:'+IntToStr(AVIHeader.dwStreams);
      sTemp:=sTemp+#13#10+'dwSuggestedBufferSize:'+IntToStr(AVIHeader.dwSuggestedBufferSize);
      sTemp:=sTemp+#13#10+'dwWidth:'+IntToStr(AVIHeader.dwWidth);
      sTemp:=sTemp+#13#10+'dwHeight:'+IntToStr(AVIHeader.dwHeight);
      sTemp:=sTemp+#13#10+'dwReserved:'+IntToStr(AVIHeader.dwReserved[0])
                                   +','+IntToStr(AVIHeader.dwReserved[1])
                                   +','+IntToStr(AVIHeader.dwReserved[2])
                                   +','+IntToStr(AVIHeader.dwReserved[3]);
      sTemp:=sTemp+#13#10+'AVI Header Info:(64)*************************';
      Result:=sTemp;
    end;function GetAVIStreamHeaderInfo():String;
    var sTemp:String;
    begin
      sTemp:='AVI Stream Header Info:(64)***********************';
      sTemp:=sTemp+#13#10+'fcc:'+DWToString(AVIStreamHeader.fcc);
      sTemp:=sTemp+#13#10+'cb:'+IntToStr(AVIStreamHeader.cb);
      sTemp:=sTemp+#13#10+'fccType:'+IntToStr(AVIStreamHeader.fccType);
      sTemp:=sTemp+#13#10+'fccHandle:'+IntToStr(AVIStreamHeader.fccHandler);
      sTemp:=sTemp+#13#10+'dwFlags:'+IntToStr(AVIStreamHeader.dwFlags);
      sTemp:=sTemp+#13#10+'wPriority:'+IntToStr(AVIStreamHeader.wPriority);
      sTemp:=sTemp+#13#10+'wLanguage:'+IntToStr(AVIStreamHeader.wLanguage);
      sTemp:=sTemp+#13#10+'dwInitialFrames:'+IntToStr(AVIStreamHeader.dwInitialFrames);
      sTemp:=sTemp+#13#10+'dwScale:'+IntToStr(AVIStreamHeader.dwScale);
      sTemp:=sTemp+#13#10+'dwRate:'+IntToStr(AVIStreamHeader.dwRate);
      sTemp:=sTemp+#13#10+'dwStart:'+IntToStr(AVIStreamHeader.dwStart);
      sTemp:=sTemp+#13#10+'dwLength:'+IntToStr(AVIStreamHeader.dwLength);
      sTemp:=sTemp+#13#10+'dwSuggestedBufferSize:'+IntToStr(AVIStreamHeader.dwSuggestedBufferSize);
      sTemp:=sTemp+#13#10+'dwSampleSize:'+IntToStr(AVIStreamHeader.dwSampleSize);
      sTemp:=sTemp+#13#10+'Left:'+IntToStr(AVIStreamHeader.left);
      sTemp:=sTemp+#13#10+'Top:'+IntToStr(AVIStreamHeader.top);
      sTemp:=sTemp+#13#10+'Right:'+IntToStr(AVIStreamHeader.right);
      sTemp:=sTemp+#13#10+'Bottom:'+IntToStr(AVIStreamHeader.bottom);
      sTemp:=sTemp+#13#10+'AVI Stream Header Info:(64)*************************';
      Result:=sTemp;
    end;
      

  2.   

    procedure TFm_Main.BitBtn1Click(Sender: TObject);
    var
      iFileHandle: Integer;
      Buf: PChar;
      BufSize:DWORD;
      ChunkSize:DWORD;
      i,j,k:Integer;
      seqCount:Integer;
      sTemp:String;
      F: TextFile;
      SubCodePos:Integer;
      iDay,iMonth,iYear,iSec,iMin,iHour:Integer;
    begin
      if not OD_AVI.Execute then Exit;
      iFileHandle := FileOpen(OD_AVI.FileName, fmOpenRead+fmShareDenyNone);
      //AVI文件关头信息
      BufSize:=4;
      Buf := PChar(AllocMem(BufSize + 1));
      sTemp:='';
      repeat
        FileRead(iFileHandle, Buf^, BufSize);
        sTemp:=Buf[0]+Buf[1]+Buf[2]+Buf[3];
      until sTemp='hdrl';
      FreeMem(Buf);
      FileRead(iFileHandle, AVIHeader, SizeOf(TAVIMAINHEADER));
      RE_Info.Lines.Add(GetAVIHeaderInfo());  //AVI文件流信
      BufSize:=4;
      Buf := PChar(AllocMem(BufSize + 1));
      sTemp:='';
      repeat
        FileRead(iFileHandle, Buf^, BufSize);
        sTemp:=Buf[0]+Buf[1]+Buf[2]+Buf[3];
      until sTemp='strl';
      FreeMem(Buf);
      FileRead(iFileHandle, AVIStreamHeader, SizeOf(TAVISTREAMHEADER));
      RE_Info.Lines.Add(GetAVIStreamHeaderInfo());  //找到AVI文件电影片段开始处
      BufSize:=4;
      Buf := PChar(AllocMem(BufSize + 1));
      sTemp:='';
      repeat
        FileRead(iFileHandle, Buf^, BufSize);
        sTemp:=Buf[0]+Buf[1]+Buf[2]+Buf[3];
      until sTemp='movi';
      FreeMem(Buf);  //开始处理帧
      BufSize:=4;
      Buf := PChar(AllocMem(BufSize + 1));
      sTemp:='';
      repeat
        FileRead(iFileHandle, Buf^, BufSize);
        sTemp:=Buf[0]+Buf[1]+Buf[2]+Buf[3];
      until sTemp='00db';
      //取段大小
      FileRead(iFileHandle, ChunkSize, BufSize);
      FreeMem(Buf);
      BufSize:=ChunkSize;
      Buf := PChar(AllocMem(BufSize + 1));
      FileRead(iFileHandle, Buf^, BufSize);  seqCount := 12;
      //  /* process all DIF sequences */
      for i:=0 to seqCount-1 do begin
        //* there are two DIF blocks in the subcode section */
        for j:=0 to 1 do begin
          //* each block has 6 packets */
          for k:=0 to 5 do begin
            {/* calculate address: 150 DIF blocks per sequence, 80 bytes
               per DIF block, subcode blocks start at block 1, block and
               packet have 3 bytes header, packet is 8 bytes long
               (including header) */}
             SubCodePos:=i * 150 * 80 + 1 * 80 + j * 80 + 3 + k * 8 + 3;
             if Hex(Buf[SubCodePos])='62' then begin//年月日
               iDay:=Ord(Buf[SubCodePos+2]);
               iMonth:=Ord(Buf[SubCodePos+3]);
               iYear:=Ord(Buf[SubCodePos+4]);
               iDay:=(iDay and $F)+10*((iDay shr 4) and $3);
               iMonth:=(iMonth and $F)+10*((iMonth shr 4) and $1);
               iYear:=(iYear and $F)+10*((iYear shr 4) and $F);
               if iYear<25 then
                 iYear:=iYear+2000
               else
                 iYear:=iYear+1900;
               RE_Info.Lines.Add(Hex(Buf[SubCodePos])+' '
                                +Hex(Buf[SubCodePos+1])+' '
                                +Hex(Buf[SubCodePos+2])+' '
                                +Hex(Buf[SubCodePos+3])+' '
                                +Hex(Buf[SubCodePos+4]));
               RE_Info.Lines.Add('Date:'+IntToStr(iYear)+'-'
                                        +IntToStr(iMonth)+'-'
                                        +IntToStr(iDay));
             end;
             if Hex(Buf[SubCodePos])='63' then begin//秒分时
               iSec:=Ord(Buf[SubCodePos+2]);
               iMin:=Ord(Buf[SubCodePos+3]);
               iHour:=Ord(Buf[SubCodePos+4]);
               iSec:=(iSec and $F)+10*((iSec shr 4) and $7);
               iMin:=(iMin and $F)+10*((iMin shr 4) and $7);
               iHour:=(iHour and $F)+10*((iHour shr 4) and $3);
               RE_Info.Lines.Add(Hex(Buf[SubCodePos])+' '
                                +Hex(Buf[SubCodePos+1])+' '
                                +Hex(Buf[SubCodePos+2])+' '
                                +Hex(Buf[SubCodePos+3])+' '
                                +Hex(Buf[SubCodePos+4]));
               RE_Info.Lines.Add('Time:'+IntToStr(iHour)+':'
                                        +IntToStr(iMin)+':'
                                        +IntToStr(iSec));
             end;
          end;//end for k
        end;//end for j
      end;//end for i  AssignFile(F, 'OffSet.txt');
      FileMode:=fmOpenReadWrite ;
      Reset(F);
      Append(F);
      //for i:=0 to BufSize-1 do
      //  WriteLn(F,IntToHex(Ord(Buf[i]),2));
      CloseFile(F);  FreeMem(Buf);  FileClose(iFileHandle);
    end;function Hex(InChar:Char):String;
    begin
      Result:=IntToHex(Ord(InChar),2);
    end;end.
      

  3.   

    实际上它的信息是在头内
    00000000 RIFF (103E2920) 'AVI '
    0000000C     LIST (00000146) 'hdrl'
    00000018         avih (00000038)
                         dwMicroSecPerFrame    : 33367
                         dwMaxBytesPerSec      : 3728000
                         dwPaddingGranularity  : 0
                         dwFlags               : 0x810 HASINDEX | TRUSTCKTYPE
                         dwTotalFrames         : 2192
                         dwInitialFrames       : 0
                         dwStreams             : 2
                         dwSuggestedBufferSize : 120000
                         dwWidth               : 720
                         dwHeight              : 480
                         dwReserved            : 0x0
    00000058         LIST (00000094) 'strl'
    00000064             strh (00000038)
                             fccType               : 'vids'
                             fccHandler            : 'dvsd'
                             dwFlags               : 0x0
                             wPriority             : 0
                             wLanguage             : 0x0 undefined
                             dwInitialFrames       : 0
                             dwScale               : 100 (29.970 Frames/Sec)
                             dwRate                : 2997
                             dwStart               : 0
                             dwLength              : 2192
                             dwSuggestedBufferSize : 120000
                             dwQuality             : 0
                             dwSampleSize          : 0
                             rcFrame               : 0,0,720,480
    000000A4             strf (00000048)
                             biSize          : 40
                             biWidth         : 720
                             biHeight        : 480
                             biPlanes        : 1
                             biBitCount      : 24
                             biCompression   : 0x64737664 'dvsd'
                             biSizeImage     : 120000
                             biXPelsPerMeter : 0
                             biYPelsPerMeter : 0
                             biClrUsed       : 0
                             biClrImportant  : 0
                             dwDVAAuxSrc     : 0x........
                             dwDVAAuxCtl     : 0x........
                             dwDVAAuxSrc1    : 0x........
                             dwDVAAuxCtl1    : 0x........
                             dwDVVAuxSrc     : 0x........
                             dwDVVAuxCtl     : 0x........
                             dwDVReserved[2] : 0,0
    000000F4         LIST (0000005E) 'strl'
    00000100             strh (00000038)
                             fccType               : 'auds'
                             fccHandler            : '    '
                             dwFlags               : 0x0
                             wPriority             : 0
                             wLanguage             : 0x0 undefined
                             dwInitialFrames       : 0
                             dwScale               : 1 (32000.000 Samples/Sec)
                             dwRate                : 32000
                             dwStart               : 0
                             dwLength              : 2340474
                             dwSuggestedBufferSize : 4272
                             dwQuality             : 0
                             dwSampleSize          : 4
                             rcFrame               : 0,0,0,0
    00000140             strf (00000012)
                             wFormatTag      : 1 PCM
                             nChannels       : 2
                             nSamplesPerSec  : 32000
                             nAvgBytesPerSec : 128000
                             nBlockAlign     : 4
                             wBitsPerSample  : 16
                             cbSize          : 0
    00000814     LIST (103D0EF4) 'movi'
    103D1710     idx1 (00011210)
      

  4.   

    你只要看取AVI头的部分就行了,其它是用来取拍摄时间的,还没完全写完
      

  5.   

    说明一下,拍摄时间只针对采集的DV AVI有效
      

  6.   

    谢谢,你belllab,不过如果是mpg4文件呢?可以再开个帖子给你分。谢谢!
      

  7.   

    mpeg我倒还没有研究过,我研究AVI是因为我想从DV中取拍摄时间,估计MPEG也应该有相关的资料吧
      

  8.   

    如果只是要mpg4的帧数的话,你看一下他的文件头,应该有的