📄 mmoutput.c
字号:
/* -*- tab-width: 8; c-basic-offset: 4 -*- *//* * Digital video MCI Wine Driver * * Copyright 1999, 2000 Eric POUECH * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "private_mciavi.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(mciavi);static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList){ MMCKINFO mmckInfo; mmckInfo.ckid = ckidSTREAMHEADER; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'strh' chunk\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)&wma->ash_audio, sizeof(wma->ash_audio)); TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)), HIBYTE(LOWORD(wma->ash_audio.fccType)), LOBYTE(HIWORD(wma->ash_audio.fccType)), HIBYTE(HIWORD(wma->ash_audio.fccType))); TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccHandler)), HIBYTE(LOWORD(wma->ash_audio.fccHandler)), LOBYTE(HIWORD(wma->ash_audio.fccHandler)), HIBYTE(HIWORD(wma->ash_audio.fccHandler))); TRACE("ash.dwFlags=%ld\n", wma->ash_audio.dwFlags); TRACE("ash.wPriority=%d\n", wma->ash_audio.wPriority); TRACE("ash.wLanguage=%d\n", wma->ash_audio.wLanguage); TRACE("ash.dwInitialFrames=%ld\n", wma->ash_audio.dwInitialFrames); TRACE("ash.dwScale=%ld\n", wma->ash_audio.dwScale); TRACE("ash.dwRate=%ld\n", wma->ash_audio.dwRate); TRACE("ash.dwStart=%ld\n", wma->ash_audio.dwStart); TRACE("ash.dwLength=%ld\n", wma->ash_audio.dwLength); TRACE("ash.dwSuggestedBufferSize=%ld\n", wma->ash_audio.dwSuggestedBufferSize); TRACE("ash.dwQuality=%ld\n", wma->ash_audio.dwQuality); TRACE("ash.dwSampleSize=%ld\n", wma->ash_audio.dwSampleSize); TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left, wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right); mmioAscend(wma->hFile, &mmckInfo, 0); mmckInfo.ckid = ckidSTREAMFORMAT; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'strh' chunk\n"); return FALSE; } if (mmckInfo.cksize < sizeof(WAVEFORMAT)) { WARN("Size of strf chunk (%ld) < audio format struct\n", mmckInfo.cksize); return FALSE; } wma->lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); if (!wma->lpWaveFormat) { WARN("Can't alloc WaveFormat\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)wma->lpWaveFormat, mmckInfo.cksize); TRACE("waveFormat.wFormatTag=%d\n", wma->lpWaveFormat->wFormatTag); TRACE("waveFormat.nChannels=%d\n", wma->lpWaveFormat->nChannels); TRACE("waveFormat.nSamplesPerSec=%ld\n", wma->lpWaveFormat->nSamplesPerSec); TRACE("waveFormat.nAvgBytesPerSec=%ld\n", wma->lpWaveFormat->nAvgBytesPerSec); TRACE("waveFormat.nBlockAlign=%d\n", wma->lpWaveFormat->nBlockAlign); TRACE("waveFormat.wBitsPerSample=%d\n", wma->lpWaveFormat->wBitsPerSample); if (mmckInfo.cksize >= sizeof(WAVEFORMATEX)) TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize); mmioAscend(wma->hFile, &mmckInfo, 0); return TRUE;}static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList){ MMCKINFO mmckInfo; mmckInfo.ckid = ckidSTREAMHEADER; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'strh' chunk\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)&wma->ash_video, sizeof(wma->ash_video)); TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccType)), HIBYTE(LOWORD(wma->ash_video.fccType)), LOBYTE(HIWORD(wma->ash_video.fccType)), HIBYTE(HIWORD(wma->ash_video.fccType))); TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccHandler)), HIBYTE(LOWORD(wma->ash_video.fccHandler)), LOBYTE(HIWORD(wma->ash_video.fccHandler)), HIBYTE(HIWORD(wma->ash_video.fccHandler))); TRACE("ash.dwFlags=%ld\n", wma->ash_video.dwFlags); TRACE("ash.wPriority=%d\n", wma->ash_video.wPriority); TRACE("ash.wLanguage=%d\n", wma->ash_video.wLanguage); TRACE("ash.dwInitialFrames=%ld\n", wma->ash_video.dwInitialFrames); TRACE("ash.dwScale=%ld\n", wma->ash_video.dwScale); TRACE("ash.dwRate=%ld\n", wma->ash_video.dwRate); TRACE("ash.dwStart=%ld\n", wma->ash_video.dwStart); TRACE("ash.dwLength=%ld\n", wma->ash_video.dwLength); TRACE("ash.dwSuggestedBufferSize=%ld\n", wma->ash_video.dwSuggestedBufferSize); TRACE("ash.dwQuality=%ld\n", wma->ash_video.dwQuality); TRACE("ash.dwSampleSize=%ld\n", wma->ash_video.dwSampleSize); TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left, wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right); mmioAscend(wma->hFile, &mmckInfo, 0); mmckInfo.ckid = ckidSTREAMFORMAT; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'strh' chunk\n"); return FALSE; } wma->inbih = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); if (!wma->inbih) { WARN("Can't alloc input BIH\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)wma->inbih, mmckInfo.cksize); TRACE("bih.biSize=%ld\n", wma->inbih->biSize); TRACE("bih.biWidth=%ld\n", wma->inbih->biWidth); TRACE("bih.biHeight=%ld\n", wma->inbih->biHeight); TRACE("bih.biPlanes=%d\n", wma->inbih->biPlanes); TRACE("bih.biBitCount=%d\n", wma->inbih->biBitCount); TRACE("bih.biCompression=%lx\n", wma->inbih->biCompression); TRACE("bih.biSizeImage=%ld\n", wma->inbih->biSizeImage); TRACE("bih.biXPelsPerMeter=%ld\n", wma->inbih->biXPelsPerMeter); TRACE("bih.biYPelsPerMeter=%ld\n", wma->inbih->biYPelsPerMeter); TRACE("bih.biClrUsed=%ld\n", wma->inbih->biClrUsed); TRACE("bih.biClrImportant=%ld\n", wma->inbih->biClrImportant); mmioAscend(wma->hFile, &mmckInfo, 0); return TRUE;}struct AviListBuild { DWORD numVideoFrames; DWORD numAudioAllocated; DWORD numAudioBlocks; DWORD inVideoSize; DWORD inAudioSize;};static BOOL MCIAVI_AddFrame(WINE_MCIAVI* wma, LPMMCKINFO mmck, struct AviListBuild* alb){ if (mmck->ckid == ckidAVIPADDING) return TRUE; switch (TWOCCFromFOURCC(mmck->ckid)) { case cktypeDIBbits: case cktypeDIBcompressed: case cktypePALchange: TRACE("Adding video frame[%ld]: %ld bytes\n", alb->numVideoFrames, mmck->cksize); if (alb->numVideoFrames < wma->dwPlayableVideoFrames) { wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset; wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize; if (alb->inVideoSize < mmck->cksize) alb->inVideoSize = mmck->cksize; alb->numVideoFrames++; } else { WARN("Too many video frames\n"); } break; case cktypeWAVEbytes: TRACE("Adding audio frame[%ld]: %ld bytes\n", alb->numAudioBlocks, mmck->cksize); if (wma->lpWaveFormat) { if (alb->numAudioBlocks >= alb->numAudioAllocated) { alb->numAudioAllocated += 32; wma->lpAudioIndex = HeapReAlloc(GetProcessHeap(), 0, wma->lpAudioIndex, alb->numAudioAllocated * sizeof(struct MMIOPos)); if (!wma->lpAudioIndex) return FALSE; } wma->lpAudioIndex[alb->numAudioBlocks].dwOffset = mmck->dwDataOffset; wma->lpAudioIndex[alb->numAudioBlocks].dwSize = mmck->cksize; if (alb->inAudioSize < mmck->cksize) alb->inAudioSize = mmck->cksize; alb->numAudioBlocks++; } else { WARN("Wave chunk without wave format... discarding\n"); } break; default: WARN("Unknown frame type %04x\n", TWOCCFromFOURCC(mmck->ckid)); break; } return TRUE;}BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma){ MMCKINFO ckMainRIFF; MMCKINFO mmckHead; MMCKINFO mmckList; MMCKINFO mmckInfo; struct AviListBuild alb; if (mmioDescend(wma->hFile, &ckMainRIFF, NULL, 0) != 0) { WARN("Can't find 'RIFF' chunk\n"); return FALSE; } if ((ckMainRIFF.ckid != FOURCC_RIFF) || (ckMainRIFF.fccType != formtypeAVI)) { WARN("Can't find 'AVI ' chunk\n"); return FALSE; } mmckHead.fccType = listtypeAVIHEADER; if (mmioDescend(wma->hFile, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) { WARN("Can't find 'hdrl' list\n"); return FALSE; } mmckInfo.ckid = ckidAVIMAINHDR; if (mmioDescend(wma->hFile, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'avih' chunk\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)&wma->mah, sizeof(wma->mah)); TRACE("mah.dwMicroSecPerFrame=%ld\n", wma->mah.dwMicroSecPerFrame); TRACE("mah.dwMaxBytesPerSec=%ld\n", wma->mah.dwMaxBytesPerSec); TRACE("mah.dwPaddingGranularity=%ld\n", wma->mah.dwPaddingGranularity); TRACE("mah.dwFlags=%ld\n", wma->mah.dwFlags); TRACE("mah.dwTotalFrames=%ld\n", wma->mah.dwTotalFrames); TRACE("mah.dwInitialFrames=%ld\n", wma->mah.dwInitialFrames); TRACE("mah.dwStreams=%ld\n", wma->mah.dwStreams); TRACE("mah.dwSuggestedBufferSize=%ld\n", wma->mah.dwSuggestedBufferSize); TRACE("mah.dwWidth=%ld\n", wma->mah.dwWidth); TRACE("mah.dwHeight=%ld\n", wma->mah.dwHeight); mmioAscend(wma->hFile, &mmckInfo, 0); mmckList.fccType = listtypeSTREAMHEADER; if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) { WARN("Can't find 'strl' list\n"); return FALSE; } if (!MCIAVI_GetInfoVideo(wma, &mmckList)) { return FALSE; } mmioAscend(wma->hFile, &mmckList, 0); mmckList.fccType = listtypeSTREAMHEADER; if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) { if (!MCIAVI_GetInfoAudio(wma, &mmckList)) { return FALSE; } mmioAscend(wma->hFile, &mmckList, 0); } mmioAscend(wma->hFile, &mmckHead, 0); /* no need to read optional JUNK chunk */ mmckList.fccType = listtypeAVIMOVIE; if (mmioDescend(wma->hFile, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) { WARN("Can't find 'movi' list\n"); return FALSE; } wma->dwPlayableVideoFrames = wma->mah.dwTotalFrames; wma->lpVideoIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -