[Mplayer-felhasznalok] RAW RGB AVI lejatszas. (harmadik fordulo)

Toth Csaba tocsa at inf.bme.hu
Wed May 29 21:17:23 CEST 2002


Hi!

> > > > Lehet, hogy a problema a kovetkezo:
> > > > A kep 174x174-es, viszont nem 522x174-es matrixban van tarolva, hanem 
> > > > 524-es sorokat hasznal (pad to 4-byte boundary).
> > > mi ez a pad-to-4 ? sos ehallottam ilyenrol avi-nal
> > Ez a BMP vagy DIB (Device Independent Bitmap)-nal van elasva. Ugye a RAW 
> > AVI az DIB-ek sorozata.
> Az latod lehet. Meg kene neznem DIB/BMP doxokat...

http://www.wotsit.org-on van jó.

> > > a kerdes inkabb az, hogy hol van ez az avi-ban tarolva???
> > Implicit van tarolva. Az AVI tartalmazza a kepkocka meretet.
> > Ezutan raengeded a CODEC-et ;) amely DIB-kent ertelmezi es jol kiszamolja 
> > a sorhosszat.

A kép dimenzió nem csak a kodek magánügye (ezt nem neked mondom Árpi). Az
mplayer a tömörített frame-et kiveszi az adat chunkból, odaadja a
kodeknek. Ezután viszont fogadnia kell a kodektól az adatot, és ekkor
szüksége van a dimenzió és align információkra. Nameg persze
megjelenítésnél is.

> tehat igen, a biCompression az 0, tehat uncompressed.
> nemtom az a cvid mit keres ott, de az ugyse szamit.

A cvid jó azon a helyen. Az AVI file-ban sok stream helyezkedhet el, a
streamek különféle kodekekkel lehetnek tömörítve. A Main AVI headerben
(LIST 'hdrl' (avih)) található, hogy hány stream van a fileban. Utána
következik minden streamhez egy header (LIST 'strl' (strh, strf)). Az strh
AVIStreamHeader típusú header:

typedef struct {
    FOURCC  fccType;
    FOURCC  fccHandler;
...
};

Az fccType a stream típusa ('vids' kép streamnél, 'auds' hang streamnél).
Az fccHandler: "The fccHandler field contains a four-character code
describing the installable compressor or decompressor used with the data."
Ez tehát egy FOURCC, ami alapján a rendszer megállapítja, hogy pontosan
melyik kodekkel kell kitömörítenie az adott streamet. Az mplayer is ez
alapján dönt (gondolom, vagy inkább biztos vagyok benne, de nem méztem meg
a kódot), hogy milyen dekódert használjon a streamhez. Ez nem lehet 0
értékű, ezért 'cvid'.

A "tömörítetlenségre" utaló 0, az már nem FOURCC. Minden Stream headernek
chunknak (LIST 'strl') a második része az 'strf' már a stream típustól és
a kodektől függő információ. Videó streameknél ez egy BITMAPINFO
struktúra. Ennek az első fele a BITMAPINFOHEADER struktúra:

typedef struct tagBITMAPINFOHEADER{ // bmih 
    DWORD  biSize; 
    LONG   biWidth; 
    LONG   biHeight; 
    WORD   biPlanes; 
    WORD   biBitCount 
    DWORD  biCompression; 
    DWORD  biSizeImage; 
    LONG   biXPelsPerMeter; 
    LONG   biYPelsPerMeter; 
    DWORD  biClrUsed; 
    DWORD  biClrImportant; 
} BITMAPINFOHEADER; 

Ebben az esetben a biCompression mező értéke BI_RGB, amit a WINGDI.H file
definiál:

/* constants for the biCompression field */
#define BI_RGB        0L
#define BI_RLE8       1L
#define BI_RLE4       2L
#define BI_BITFIELDS  3L

Tehát ezért 0. "Normális" tömörített videófájlok esetén itt ugyanaz áll,
mint a FOURCC helyén (pl.: DIV3). Hogy ne legyen feneketlen az amit
beszélek (bár Árpi te tutire érted) az alábbit a riffwalk nevű Win3.1-es
programmal készítettem (ez az akkori Video for Windows SDK része volt, ma
már nincs ilyen, pedig elég hasznos) egy DivX 3.11-es aviról:

00000000    RIFF (147D4E44) 'AVI '
0000000C        LIST (0000227E) 'hdrl'
00000018            avih (00000038)
                        TotalFrames  : 52881
                        Streams      : 2
                        InitialFrames: 0
                        MaxBytes     : 0
                        BufferSize   : 0
                        uSecPerFrame : 40000
                        Rate         : 25.000 fps
                        Size         : (352, 288)
                        Flags        : 0x00000110
                            AVIF_HASINDEX
                            AVIF_ISINTERLEAVED
00000058            LIST (00001094) 'strl'
00000064                strh (00000038)
                            Stream Type   : vids
                            Stream Handler: DIV3
                            Samp/Sec      : 25.000
                            Priority      : 0
                            Language      : unspecified
                            InitialFrames : 0
                            Start         : 0
                            Length        : 52881
                            Length (sec)  : 2115.2
                            Flags         : 0x00000000
                            BufferSize    : 30594
                            Quality       : 10000
                            SampleSize    : 0
                            Frame Rect    : [0 0 352 288]
000000A4                strf (00000028)
                            Size        : (352, 288)
                            Bit Depth   : 24
                            Colors used : 0
                            Compression : DIV3
                            Image Size  : 304128
000000D4                JUNK (00001018)
000010F4            LIST (0000108A) 'strl'
00001100                strh (00000038)
                            Stream Type   : auds
                            Stream Handler: <default>
                            Samp/Sec      : 7963.000
                            Priority      : 0
                            Language      : unspecified
                            InitialFrames : 1
                            Start         : 0
                            Length        : 16843656
                            Length (sec)  : 2115.2
                            Flags         : 0x00000000
                            BufferSize    : 3981
                            Quality       : -1
                            SampleSize    : 1
                            Frame Rect    : [0 0 0 0]
00001140                strf (0000001E)
                            wFormatTag      : 85
                            nChannels       : 1
                            nSamplesPerSec  : 44100
                            nAvgBytesPerSec : 7963
                            nBlockAlign     : 1
                            nBitsPerSample  : 0
                            Extra Bytes     : 12
00001166                JUNK (00001018)
00002186            LIST (00000104) 'odml'
00002192                dmlh (000000F8)
00002292        JUNK (00000566)
00002800        LIST (146354CC) 'movi'
14637CD4        idx1 (0019D170)
147D4E4C
147D5000


Csak a teljesség kedvéért írom le, bocs Árpi, hogy csépelem a szót. A
'movi' LIST-ben van a lényeg, ott van a "film", ezek audió és videó data
chunkok meghatározott sorrendben (sorrendet jól el is lehet bénázni, ha
nem jól osztják el), az audió és videó frame-eket tárolják. Az idx1 a film
végén található összefoglalás arról, hogy a 'movi' részben milyen data
chunkok vannak, ezek milyen típusúak, és pontosan hol vannak.

megj.: az AVI formátumban egyébként érdekes, hogy a fő header-be minden
előzetes bevezetés nélkül már ott van a képdimenzió. Mi történik, ha több
video stream is van a fájlban, és nem ugyanolyan méretűek (bár ez elég
elborult dolog lenne)?

Az egész rizsának a konklúziója az, hogy akkor valamilyen módon a
codecs.conf-ba bele kéne a cvid-et vezetni, hogy az annak megfelelő
kodeknek, és azt a kodeket tartalmazó dll-nek adódjon át.

Persze érdekes kérdés a tömörítetlen DIB esete. Itt legfeljebb egy olyan
wrapper kodek szükséges, ami az mplayer által várt, szintén tömörítetlen
formátumra konvertálja a framet. Gondolok itt a color space típusra (YUV,
RGB, BGR, ...), vagy hogy a BMP az down-up és nem up-down, stb..

> 174*3=522
> igen, es valoban, 524*174 adja ki a 91176-ot :(
> 
> ez viszont azt jelenti, hogy sokmindent kell fixalnom.
> lehet, hogy ez megold majd mas bugokat is, ahol win32 codecek
> hulye kepmeretnel bugzottak/crasheltek...
> 
> amugy a vd_raw.c vegen kene ezt:
>         mpi->stride[0]=mpi->width*(mpi->bpp/8);
> atirni ilyesmire:
>         mpi->stride[0]=(mpi->width*(mpi->bpp/8)+3)&(~3);
> 
> igy felkerekiti jol.

A ((width*bitdepth/8)+3)&~3 képlet először gyanúsnak tűnt, de tényleg jó.
Talán még annyit, hogy a 8-al való osztás egy 3-as lefele shiftelésnek
felel meg. Bár valószínű, hogy ezt a compiler észreveszi, ha -Ox-el fordul
a kód.

Amire még vigyázni kellene, az az align. Mégpedig ha már fölkészülünk
tömörítetlen lejátszásra, akkor lehet, hogy kéne fogadni az RLE tömörített
DIB streamet is. Az viszont nem DWORD, hanem WORD boundary-re alignolt (?
ha jól olvastam a doksikat, de nem biztos). Nem tömörített esetben
egyébként a monkróm és a 16 színű bmp-knél/DIB-eknél is DWORD alignolás
van. Most próbáltam ki.

Üdv!

ui: ha kell a riffwalk, akkor oda tudom adni. Jól használható esetleg
userek által uploadolt hibás avi-k első megnézésére: hogy a file
struktúrával minden rendben van-e:

RIFFWALK.EXE
 Usage: %s [-d<x>] [-f<x> [-jx] <RIFF file>
 -d   : Maximum depth to descend to
 -f<x>: Expand specific chunks (verbosity level)
 -j   : Don't skip JUNK chunks
 -x   : Hex dump chunks that are otherwise not expanded
 -m   : Expand AVI 'movi' list
 
  This program will walk the structure of RIFF files.
  It knows something about the structure of .WAV and
  .AVI files, and can be useful in verifying them.
 
 Hint: -f2 will dump and verify the indexes of AVI files.

--

tocsa

 -----------------------------------------------
| email:     tocsa at inf.bme.hu                   |
| homepage:  http://www.iit.bme.hu/~tocsa       |
 -----------------------------------------------




More information about the MPlayer-felhasznalok mailing list