[ mucky @ 11.02.2003. 19:25 ] @
Nekada davno sam ovde post-ovao pitanje kako da saznam strukturu AVI fajla.
U međuvremenu sam se bavio drugim stvarima, ali pre neki dan sam našao taj stari
kod i odlučio da ga već jednom završim.

Naime, reč je o delu programa koji treba da iz AVI fajla učita njegov framerate. Našao
sam strukturu AVI fajla, skontao kako treba saznati framerate (učita se scale i data
rate, pa je framerate = datarate / scale) ali veliki problem mi je kako učitati te dve
vrednosti?? One se nalaze jedna do druge, svaka je velika 4 bajta (ili DWORD za C
programere). Prvo što mi nije jasno je, kog su formata te vrednosti? Celobrojne (integer)
ili floating-point (float)?? Svejedno, kako god da ih učitam i podelim, ne dobijem stvaran
ramerate nego neke nenormalno velike vrednosti :(

Koliko se sećam, bilo je par likova ovde koji su se javili na moj pređašnji post, pa se
nadam da barem neko od vas ima iskustva sa ovakvim stvarima i da može da me uputi
šta da mu radim! (programu :)
[ leka @ 19.05.2003. 17:14 ] @
Ako te to toliko interesuje, skini kod od FFMPEG - http://ffmpeg.sf.net i UCI IZ KODA!

Pogledaj sta, izmedju ostalog, "radi" FFMPEG...
Citat:

* libavformat is a library containing parsers and generators for all common audio/video formats.
[ mucky @ 19.05.2003. 17:37 ] @
Hvala ti, pogledaću taj kod u svakom slučaju. Ja sam već našao neki open-source programčić
rađen u Delphi-ju koji takođe "vadi" framerate AVI fajla, međutim, kad sam preveo taj algoritam
na Javu, opet sam dobijao neke bezvezne vrednosti. Stvarno ne znam u čemu je problem (i dalje)
jedino što mi pada na pamet je bit-order (Big ili Little Endian).
[ Jovan Marjanovic @ 19.05.2003. 18:33 ] @
Citat:
mucky:
svaka je velika 4 bajta (ili DWORD za C
programere).


Koliko me secanje sluzi, DWORD je majkrsoftova bljuvotina a ne ANSI C standardni tip promenljive. C programer bi to zvao int ...
Ispravite me ako gresim.
[ leka @ 19.05.2003. 19:07 ] @

Ofkors mister Marjanovic :)

S tim da je valjda to ostalo iz dana kad je sve to funkalo na 16bit-nim masinama gde int nije 4 bajta :)

Meni je bas slatka ona notacija tipa u_int32_t ...
[ mucky @ 19.05.2003. 20:15 ] @
Citat:
Jovan Marjanovic:
Citat:
mucky:
svaka je velika 4 bajta (ili DWORD za C
programere).

Koliko me secanje sluzi, DWORD je majkrsoftova bljuvotina a ne ANSI C standardni tip promenljive. C programer bi to zvao int ...


Ja zaista nisam C programer :)
Programiram u Javi, i uopšte mi nije jasno zašto bi neko ovu temu prebacio u forum za C.
[ Jovan Marjanovic @ 19.05.2003. 20:19 ] @
U tom slucaju ti je oprosteno, a temu prebacujem na JAVA forum.
[ jc denton @ 19.05.2003. 21:28 ] @
Ne znam da li moze da pomogne, ali ovo je gotovo resenje koje ja koristim u VB-u, verujem da nije tesko da se prepravi za java-u posto je Win32 API u pitanju.

deklaracije :

Public Declare Function AVIFileOpen Lib "avifil32.dll" (ByRef ppfile As Long, ByVal szFile As String, ByVal uMode As Long, ByVal pclsidHandler As Long) As Long 'HRESULT

Public Declare Function AVIFileGetStream Lib "avifil32.dll" (ByVal pfile As Long, ByRef ppaviStream As Long, ByVal fccType As Long, ByVal lParam As Long) As Long

Public Declare Function AVIStreamLength Lib "avifil32.dll" (ByVal pavi As Long) As Long

Public Declare Function AVIStreamRelease Lib "avifil32.dll" (ByVal pavi As Long) As Long 'ULONG

Public Declare Function AVIFileRelease Lib "avifil32.dll" (ByVal pfile As Long) As Long

Public Const streamtypeVIDEO As Long = 1935960438 'equivalent to: mmioStringToFOURCC("vids", 0&)
Public Const OF_SHARE_DENY_WRITE As Long = &H20


procedura:

Dim res As Long 'result code
Dim szFile As String 'filename
Dim pAVIFile As Long 'pointer to AVI file interface (PAVIFILE handle)
Dim pAVIStream As Long 'pointer to AVI stream interface (PAVISTREAM handle)
Dim numFrames As Long 'number of frames in video stream

szFile = ime_AVI_fajla

'Open the AVI File and get a file interface pointer (PAVIFILE)
res = AVIFileOpen(pAVIFile, szFile, OF_SHARE_DENY_WRITE, 0&)

'Get the first available video stream (PAVISTREAM)
res = AVIFileGetStream(pAVIFile, pAVIStream, streamtypeVIDEO, 0)

'get the length of video stream in frames
numFrames = AVIStreamLength(pAVIStream)

Call AVIStreamRelease(pAVIStream) '//closes video stream

Call AVIFileRelease(pAVIFile) '// closes the file
[ jc denton @ 19.05.2003. 21:56 ] @
Ups ;) hehehe, zezucnuh se malkice u poJenti. Dakle, mali dodaci u deklaracijama :

Public Type AVI_FILE_INFO '108 bytes?
dwMaxBytesPerSecond As Long
dwFlags As Long
dwCaps As Long
dwStreams As Long
dwSuggestedBufferSize As Long
dwWidth As Long
dwHeight As Long
dwScale As Long
dwRate As Long
dwLength As Long
dwEditCount As Long
szFileType As String * 64
End Type

Public Declare Function AVIFileInfo Lib "avifil32.dll" (ByVal pfile As Long, pfi As AVI_FILE_INFO, ByVal lSize As Long) As Long 'HRESULT


U proceduri nedostaje :

Dim fileInfo As AVI_FILE_INFO 'file info struct

res = AVIFileInfo(pAVIFile, fileInfo, Len(fileInfo))

' ovo je fps
fps = fileInfo.dwRate / fileInfo.dwScale


Kod mene sljaka :)
[ mucky @ 21.05.2003. 20:23 ] @
Hvala ti jc dentone što si se pomučio da mi postuješ taj kod, ali koliko vidim to je jako slično
onom u delphiju što sam našao na netu, i koji ne radi kad prevedem na Javu. Sada nemam
vremena da se igram sa time jer štrebam i radim neki drugi program, ali sve više i više sumnjam
na bit-order! Evo ti delić onog progračića u Delphiju samo da vidiš da je prilično sličan!

Code:

  Seek(AviFile,4);
  BlockRead(AviFile,TempSize,4);

  Seek(AviFile,28);
  BlockRead(AviFile,AviHeaderSize,4);

  AviHeaderStart := 32;

(****************************************)
  Seek(AviFile,AviHeaderStart);
  BlockRead(AviFile,TempMicrosec,4);
(****************************************)
(* Ova 4-ka na kraju procedure BlockRead znaci da se cita 4 bajta, sto je 32 bita tj. obican int u javi *)

  Seek(AviFile,AviHeaderStart + 16);
  BlockRead(AviFile,TempLengthInFrames,4);

  Seek(AviFile,AviHeaderStart + 32);
  BlockRead(AviFile,TempVWidth,4);

  Seek(AviFile,AviHeaderStart + 36);
  BlockRead(AviFile,TempVHeight,4);

  Seek(AviFile,AviHeaderStart + AviHeaderSize + 4);
  BlockRead(AviFile,VHeaderSize,4);

  VHeaderStart := AviHeaderStart + AviHeaderSize + 20;


A posle ide:

Code:

FPS := 1000000 / TempMicrosec;
[ jc denton @ 22.05.2003. 01:50 ] @
Ja bre ne vidim da ima slicnosti. U svakom sl., nadam se da ces nekako da resis taj problem.
[ leka @ 28.05.2003. 13:15 ] @
Ljudi koje se malo bave tim stvarima (a ja jedino kada koristim AVI je kad gledam filmove ;) znaju dobro da je AVI zapravo RIFF. RIFF je Microsoft "izmisljotina" (zapravo kao i (skoro)sve drugo nisu izmislili vec su samo "doradili" nesto postojece po svom ukusu), zapravo izmenjeni AIFF format.
O RIFF formatu postoji besplatna dokumentacija na Microsoft sajtu i tamo postoji i objasnjenje AVI podformata, sve skupa sa strukturama (u C-u) koje objasnjavaju strukturu pojedinih "chunk"-ova (RIFF format se zapravo sastoji od chunk-ova (delova) razlicitih formata).

Predlazem da nadjes taj dokument i procitas ga nekoliko puta.
[ leka @ 12.06.2003. 11:25 ] @
Kog su formata te vrednosti i kog tipa saznaje se iz glavnog RIFF chunk-a koji se cini mi se zove "fmt" :)