int load_wav ( FIL *fp, /* Pointer to the open file object to play */ const char *title, /* Title (file name, etc...) */ void *work, /* Pointer to working buffer (must be-4 byte aligned) */ UINT sz_work /* Size of working buffer (must be power of 2) */ ) { UINT md, wi, br, tc, t, btr; DWORD sz, ssz, offw, szwav, wsmp, fsmp, eof; WAVFIFO fcb; BYTE k, *buff = work; char *p, nam[NBSIZE], art[NBSIZE]; //xprintf(PSTR("%s\n"), title); /* Put title */ /* Is it a WAV file? */ if (f_read(fp, buff, 12, &br) || br != 12) return -1; if (LD_DWORD(&buff[0]) != FCC('R','I','F','F')) return -1; if (LD_DWORD(&buff[8]) != FCC('W','A','V','E')) return -1; eof = LD_DWORD(&buff[4]) + 8; /* Analyze the RIFF-WAVE header and get properties */ nam[0] = art[0] = 0; md = fsmp = wsmp = offw = szwav = 0; while (f_tell(fp) < eof) { if (f_read(fp, buff, 8, &br) || br != 8) return -1; sz = (LD_DWORD(&buff[4]) + 1) & ~1; switch (LD_DWORD(&buff[0])) { case FCC('f','m','t',' ') : if (sz > 1000 || sz < 16 || f_read(fp, buff, sz, &br) || sz != br) return -1; if (LD_WORD(&buff[0]) != 0x1) return -1; /* Check if LPCM */ if (LD_WORD(&buff[2]) == 2) { /* Channels (1 or 2) */ md = 1; wsmp = 2; } else { md = 0; wsmp = 1; } if (LD_WORD(&buff[14]) == 16) { /* Resolution (8 or 16) */ md |= 2; wsmp *= 2; } fsmp = LD_DWORD(&buff[4]); /* Sampling rate */ break; case FCC('f','a','c','t') : f_lseek(fp, f_tell(fp) + sz); break; case FCC('d','a','t','a') : offw = f_tell(fp); /* Wave data start offset */ szwav = sz; /* Wave data length [byte] */ f_lseek(fp, f_tell(fp) + sz); break; case FCC('L','I','S','T'): sz += f_tell(fp); if (f_read(fp, buff, 4, &br) || br != 4) return -1; if (LD_DWORD(buff) == FCC('I','N','F','O')) { /* LIST/INFO chunk */ while (f_tell(fp) < sz) { if (f_read(fp, buff, 8, &br) || br != 8) return -1; ssz = (LD_DWORD(&buff[4]) + 1) & ~1; p = 0; switch (LD_DWORD(buff)) { case FCC('I','N','A','M'): /* INAM sub-chunk */ p = nam; break; case FCC('I','A','R','T'): /* IART sub-cnunk */ p = art; break; } if (p && ssz <= NBSIZE) { if (f_read(fp, p, ssz, &br) || br != ssz) return -1; } else { if (f_lseek(fp, f_tell(fp) + ssz)) return -1; } } } else { if (f_lseek(fp, sz)) return -1; /* Skip unknown sub-chunk type */ } break; default : /* Unknown chunk */ return -1; } } if (!szwav || !fsmp) return -1; /* Check if valid WAV file */ if (f_lseek(fp, offw)) return -1; /* Seek to top of wav data */ tc = (UINT)(szwav / fsmp / wsmp); /* Length (sec) */ //xprintf(PSTR("IART=%s\nINAM=%s\n"), art, nam); //xprintf(PSTR("Sample=%u.%ukHz/%ubit/%S\nLength=%u:%02u\n"), (UINT)(fsmp / 1000), (UINT)(fsmp / 100) % 10, (md & 2) ? 16 : 8, (md & 1) ? PSTR("st") : PSTR("mo"), tc / 60, tc % 60); /* Initialize stream parameters and start sound streming */ fcb.mode = md; fcb.buff = buff; fcb.sz_buff = sz_work; if (!sound_start(&fcb, fsmp)) return -1; k = 0; wi = 0; while (szwav || fcb.ct >= 4) { if (szwav && fcb.ct <= sz_work / 2) { /* Refill FIFO when it gets half empty */ btr = (szwav >= sz_work / 2) ? sz_work / 2 : szwav; f_read(fp, &buff[wi], btr, &br); if (br != btr) break; szwav -= br; wi = (wi + br) & (sz_work - 1); cli(); fcb.ct += br; sei(); } //if (uart_test()) { /* Exit if a command arrived */ // k = uart_getc(); // break; //} if (btn_check_press() == BTN2) { sound_stop(); break; } t = (f_tell(fp) - offw - fcb.ct) / fsmp / wsmp; /* Refresh time display every 1 sec */ if (t != tc) { tc = t; //xprintf(PSTR("\rTime=%u:%02u"), tc / 60, tc % 60); } } sound_stop(); /* Stop sound output */ //xputc('\n'); return k; /* Terminated due to -1:error, 0:eot, >0:key code */ }
void CWAVFile::SetProperties(IBaseFilter* pBF) { if (m_info.GetCount() > 0) { if (CComQIPtr<IDSMPropertyBag> pPB = pBF) { POSITION pos = m_info.GetStartPosition(); while (pos) { DWORD fcc; CStringA value; m_info.GetNextAssoc(pos, fcc, value); switch (fcc) { case FCC('INAM'): pPB->SetProperty(L"TITL", CStringW(value)); break; case FCC('IART'): pPB->SetProperty(L"AUTH", CStringW(value)); break; case FCC('ICOP'): pPB->SetProperty(L"CPYR", CStringW(value)); break; case FCC('ISBJ'): pPB->SetProperty(L"DESC", CStringW(value)); break; } } } } }
HRESULT CWAVFile::ReadRIFFINFO(const __int64 info_pos, const int info_size) { m_info.RemoveAll(); DWORD id = 0; m_pFile->Seek(info_pos); if (info_size < 4 || m_pFile->ByteRead((BYTE*)&id, 4) != S_OK || id != FCC('INFO')) { return E_FAIL; } __int64 end = info_pos + info_size; chunk_t Chunk; while (m_pFile->GetPos() + 8 < end && m_pFile->ByteRead(Chunk.data, sizeof(Chunk)) == S_OK && m_pFile->GetPos() + Chunk.size <= end) { __int64 pos = m_pFile->GetPos(); if (Chunk.size > 0 && (Chunk.id == FCC('INAM') || Chunk.id == FCC('IART') || Chunk.id == FCC('ICOP') || Chunk.id == FCC('ISBJ'))) { CStringA value; if (S_OK != m_pFile->ByteRead((BYTE*)value.GetBufferSetLength(Chunk.size), Chunk.size)) { return S_FALSE; } m_info[Chunk.id] = value; } m_pFile->Seek(pos + Chunk.size); } return S_OK; }
virtual void OnGotActualChunkHeaderSize( const ChunkHeader& ch, uint64_t actualSize ) { bool needToFixSize = ch.fcc == FCC('AVI ') || ch.fcc == FCC('AVIX') || ch.fcc == FCC('movi'); if ( !needToFixSize ) return; //std::trace << FCCtoString( ch.fcc ) << " -- " << actualSize << " @" << ch.startPos+4 << std::endl; ChunkHeader fixedCh = ch; fixedCh.size = (uint32_t) actualSize; if ( ch.fcc == FCC('AVI ') ) _Info._AVIchs.push_back( fixedCh ); if ( ch.fcc == FCC('AVIX') ) _Info._AVIchs.push_back( fixedCh ); if ( ch.fcc == FCC('movi') ) _Info._MOVIchs.push_back( fixedCh ); }
int avi_get_data_id (AviFormat format, int stream) { char fcc[5]; if (avi_get_format_type (format) == FCC("vids")) sprintf (fcc,"%2.2ddc",stream); else if (avi_get_format_type (format) == FCC("auds")) sprintf (fcc,"%2.2ddc",stream); else return 0; return FCC(fcc); }
int avi_get_format_fcc(AviFormat format) { switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: case AVI_FORMAT_AVI_RGB: return FCC("DIB "); case AVI_FORMAT_MJPEG: return FCC("MJPG"); default: return 0; } }
static DWORD load_header (void) /* 0:Invalid format, 1:I/O error, >1:Number of samples */ { DWORD sz; if (pf_read(Buff1, 12, &rb)) return 1; /* Load file header (12 bytes) */ if (rb != 12 || LD_DWORD(Buff1+8) != FCC('W','A','V','E')) return 0; for (;;) { pf_read(Buff1, 8, &rb); /* Get Chunk ID and size */ if (rb != 8) return 0; sz = LD_DWORD(&Buff1[4]); /* Chunk size */ switch (LD_DWORD(&Buff1[0])) { /* FCC */ case FCC('f','m','t',' ') : /* 'fmt ' chunk */ if (sz > 100 || sz < 16) return 0; /* Check chunk size */ pf_read(Buff1, sz, &rb); /* Get content */ if (rb != sz) return 0; if (Buff1[0] != 1) return 0; /* Check coding type (1) */ if (Buff1[2] != 1 && Buff1[2] != 2) /* Check channels (1/2) */ return 0; if (Buff1[14] != 8 && Buff1[14] != 16) /* Check resolution (8/16) */ return 0; OCR0A = (BYTE)(F_CPU/8/LD_WORD(&Buff1[4]))-1; /* Sampling freq */ break; case FCC('d','a','t','a') : /* 'data' chunk (start to play) */ return sz; case FCC('L','I','S','T') : /* 'LIST' chunk (skip) */ case FCC('f','a','c','t') : /* 'fact' chunk (skip) */ pf_lseek(Fs.fptr + sz); break; default : /* Unknown chunk (error) */ return 0; } } return 0; }
HRESULT CWavDestFilter::StopStreaming() { IStream* pStream; if (m_pOutput->IsConnected() == FALSE) { return E_FAIL; } IPin* pDwnstrmInputPin = m_pOutput->GetConnected(); if (!pDwnstrmInputPin) { return E_FAIL; } HRESULT hr = ((IMemInputPin*) pDwnstrmInputPin)->QueryInterface(IID_IStream, (void**)&pStream); if (SUCCEEDED(hr)) { BYTE* pb = (BYTE*)_alloca(m_cbHeader); RIFFLIST* pRiffWave = (RIFFLIST*)pb; RIFFCHUNK* pRiffFmt = (RIFFCHUNK*)(pRiffWave + 1); RIFFCHUNK* pRiffData = (RIFFCHUNK*)(((BYTE*)(pRiffFmt + 1)) + m_pInput->CurrentMediaType().FormatLength()); pRiffData->fcc = FCC('data'); pRiffData->cb = m_cbWavData; pRiffFmt->fcc = FCC('fmt '); pRiffFmt->cb = m_pInput->CurrentMediaType().FormatLength(); CopyMemory(pRiffFmt + 1, m_pInput->CurrentMediaType().Format(), pRiffFmt->cb); pRiffWave->fcc = FCC('RIFF'); pRiffWave->cb = m_cbWavData + m_cbHeader - sizeof(RIFFCHUNK); pRiffWave->fccListType = FCC('WAVE'); LARGE_INTEGER li; ZeroMemory(&li, sizeof(li)); hr = pStream->Seek(li, STREAM_SEEK_SET, 0); if (SUCCEEDED(hr)) { hr = pStream->Write(pb, m_cbHeader, 0); } pStream->Release(); } return hr; }
// Save recorded speech to file int SaveRecordtoFile(const char* fileName, WAVEFORMATEX* wf, HWAVEIN* hWaveIn, WAVEHDR* waveHeader, MMTIME* mmTime) { int res; DWORD NumToWrite=0; DWORD dwNumber = 0; waveHeader->dwBytesRecorded = mmTime->u.cb; HANDLE FileHandle = CreateFile( CString(fileName), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); dwNumber = FCC("RIFF"); WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); dwNumber = waveHeader->dwBytesRecorded + 18 + 20; WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); dwNumber = FCC("WAVE"); WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); dwNumber = FCC("fmt "); WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); dwNumber = 18L; WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); WriteFile(FileHandle, wf, sizeof(WAVEFORMATEX), &NumToWrite, NULL); dwNumber = FCC("data"); WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); dwNumber = waveHeader->dwBytesRecorded; WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL); WriteFile(FileHandle, waveHeader->lpData, waveHeader->dwBytesRecorded, &NumToWrite, NULL); SetEndOfFile( FileHandle ); CloseHandle( FileHandle ); FileHandle = INVALID_HANDLE_VALUE; _debug_print("SaveRecordtoFile SUCCEED!",1); return 0; }
int avi_get_format_type(AviFormat format) { switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: case AVI_FORMAT_AVI_RGB: case AVI_FORMAT_MJPEG: return FCC("vids"); default: return 0; } }
static HRESULT ensure_driver(AVICompressor *This) { if(This->hic) return S_OK; This->hic = ICOpen(FCC('v','i','d','c'), This->fcc_handler, ICMODE_COMPRESS); if(!This->hic) { FIXME("ICOpen failed\n"); return E_FAIL; } return S_OK; }
int avi_get_format_compression (AviFormat format) { switch (format) { case AVI_FORMAT_RGB24: case AVI_FORMAT_RGB32: case AVI_FORMAT_AVI_RGB: return 0; break; case AVI_FORMAT_MJPEG: return FCC("MJPG"); break; default: return 0; break; } }
static DWORD load_header (void) /* 0:Invalid format, 1:I/O error, >=1024:Number of samples */ { DWORD sz, f; BYTE b, al = 0; if (pf_read(Buff, 12, &rb)) return 1; /* Load file header (12 bytes) */ if (rb != 12 || LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 0; for (;;) { wdt_reset(); pf_read(Buff, 8, &rb); /* Get Chunk ID and size */ if (rb != 8) return 0; sz = LD_DWORD(&Buff[4]); /* Chunk size */ switch (LD_DWORD(&Buff[0])) { /* Switch by chunk ID */ case FCC('f','m','t',' ') : /* 'fmt ' chunk */ if (sz & 1) sz++; /* Align chunk size */ if (sz > 100 || sz < 16) return 0; /* Check chunk size */ pf_read(Buff, sz, &rb); /* Get content */ if (rb != sz) return 0; if (Buff[0] != 1) return 0; /* Check coding type (LPCM) */ b = Buff[2]; if (b != 1 && b != 2) return 0; /* Check channels (1/2) */ GPIOR0 = al = b; /* Save channel flag */ b = Buff[14]; if (b != 8 && b != 16) return 0; /* Check resolution (8/16 bit) */ GPIOR0 |= b; /* Save resolution flag */ if (b & 16) al <<= 1; f = LD_DWORD(&Buff[4]); /* Check sampling freqency (8k-48k) */ if (f < 8000 || f > 48000) return 4; OCR0A = (BYTE)(F_CPU / 8 / f) - 1; /* Set sampling interval */ break; case FCC('d','a','t','a') : /* 'data' chunk */ if (!al) return 0; /* Check if format is valid */ if (sz < 1024 || (sz & (al - 1))) return 0; /* Check size */ if (Fs.fptr & (al - 1)) return 0; /* Check word alignment */ return sz; /* Start to play */ case FCC('D','I','S','P') : /* 'DISP' chunk */ case FCC('L','I','S','T') : /* 'LIST' chunk */ case FCC('f','a','c','t') : /* 'fact' chunk */ if (sz & 1) sz++; /* Align chunk size */ pf_lseek(Fs.fptr + sz); /* Skip this chunk */ break; default : /* Unknown chunk */ return 0; } } return 0; }
// the captureAVI 'AVI ' and 'movi' chunk sizes are incorrect (well, only the last ones) virtual bool IsInsideChunk( const ChunkHeader& ch ) { bool inAVIChunk = ch.fcc == FCC('AVI ') || ch.fcc == FCC('AVIX'); bool inMOVIChunk = ch.fcc == FCC('movi'); if ( !inAVIChunk && !inMOVIChunk ) return ParserBase::IsInsideChunk( ch ); uint64_t alignBits = _Stream->Pos()&1; // chunks start on 2-byte boundaries if ( _Stream->Pos()+alignBits+4 >= _Stream->Size() ) return false; // EOF _Stream->SetPos( _Stream->Pos() + alignBits ); FOURCC nextFCC = _Stream->Read<FOURCC>(); _Stream->SetPos( _Stream->Pos() - 4 - alignBits ); if ( inAVIChunk ) return nextFCC != FCC('RIFF'); // only a 'RIFF' or EOF ends an AVI chunk if ( inMOVIChunk ) return nextFCC != FCC('idx1') /*&& nextFCC != FCC('JUNK')*/ && !ChunkHeader::IsList( nextFCC ); assert( false ); return false; }
static DWORD loadheader (FIL* fp) /* 0:Invalid format, 1:I/O error, >=1024:Number of samples */ { DWORD sz, f; BYTE b; UINT rb; if (f_read(fp, buffer, 12, &rb) != FR_OK) return 1; /* Load file header (12 bytes) */ if (rb != 12 || LD_DWORD(buffer+8) != FCC('W','A','V','E')) return 0; for (;;) { f_read(fp, buffer, 8, &rb); /* Get Chunk ID and size */ if (rb != 8) return 0; sz = LD_DWORD(&buffer[4]); /* Chunk size */ switch (LD_DWORD(&buffer[0])) { /* Switch by chunk ID */ case FCC('f','m','t',' ') : /* 'fmt ' chunk */ if (sz & 1) sz++; /* Align chunk size */ if (sz > 100 || sz < 16) return 0; /* Check chunk size */ f_read(fp, buffer, sz, &rb); /* Get content */ if (rb != sz) return 0; if (buffer[0] != 1) return 0; /* Check coding type (LPCM) */ b = buffer[2]; if (b != 1) return 0; /* Mono Only */ b = buffer[14]; if (b != 8) return 0; /* resolution 8bit only */ f = LD_DWORD(&buffer[4]); /* Check sampling freqency (8k-48k) */ if (f != 8000) return 4; /* 8kHz only */ break; case FCC('d','a','t','a') : /* 'data' chunk */ if (sz < 1024) return 0; /* Check size */ return sz; /* Start to play */ case FCC('D','I','S','P') : /* 'DISP' chunk */ case FCC('L','I','S','T') : /* 'LIST' chunk */ case FCC('f','a','c','t') : /* 'fact' chunk */ if (sz & 1) sz++; /* Align chunk size */ f_lseek(fp, fp->fptr + sz); /* Skip this chunk */ break; default : /* Unknown chunk */ return 0; } } return 0; }
void CStreamVideoSource::OnNewFrame(DWORD dwFourCC, unsigned char *pBuf, unsigned int uiLen, void *pUserData) { // See if it's a video stream if( (FCC('xxdc') & 0xFFFF0000) == (dwFourCC & 0xFFFF0000)) { // Lock the buffer EnterCriticalSection(&m_csBufLock); // This is quite slow, but our AVI parser is quite basic. Functions down the line need aligned memory // so we copy it across here... memcpy( m_pAlignedImg, pBuf, uiLen ); m_bGotVideoFrame = TRUE; SetEvent( m_hEvent ); LeaveCriticalSection(&m_csBufLock); } }
static void register_vfw_codecs(void) { WCHAR avico_clsid_str[CHARS_IN_GUID]; HKEY basekey, key; ICINFO icinfo; DWORD i, res; static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; static const WCHAR FccHandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; StringFromGUID2(&CLSID_AVICo, avico_clsid_str, sizeof(avico_clsid_str)/sizeof(WCHAR)); basekey = open_special_category_key(&CLSID_VideoCompressorCategory, TRUE); if(!basekey) { ERR("Could not create key\n"); return; } for(i=0; ICInfo(FCC('v','i','d','c'), i, &icinfo); i++) { WCHAR fcc_str[5] = {LOBYTE(LOWORD(icinfo.fccHandler)), HIBYTE(LOWORD(icinfo.fccHandler)), LOBYTE(HIWORD(icinfo.fccHandler)), HIBYTE(HIWORD(icinfo.fccHandler))}; res = RegCreateKeyW(basekey, fcc_str, &key); if(res != ERROR_SUCCESS) continue; RegSetValueExW(key, CLSIDW, 0, REG_SZ, (const BYTE*)avico_clsid_str, sizeof(avico_clsid_str)); RegSetValueExW(key, FccHandlerW, 0, REG_SZ, (const BYTE*)fcc_str, sizeof(fcc_str)); RegSetValueExW(key, FriendlyNameW, 0, REG_SZ, (const BYTE*)icinfo.szName, (strlenW(icinfo.szName)+1)*sizeof(WCHAR)); /* FIXME: Set ClassManagerFlags and FilterData values */ RegCloseKey(key); } RegCloseKey(basekey); }
static HRESULT WINAPI AVICompressorPropertyBag_Load(IPersistPropertyBag *iface, IPropertyBag *pPropBag, IErrorLog *pErrorLog) { AVICompressor *This = impl_from_IPersistPropertyBag(iface); BSTR str; VARIANT v; HRESULT hres; static const WCHAR fcc_handlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; TRACE("(%p)->(%p %p)\n", This, pPropBag, pErrorLog); V_VT(&v) = VT_EMPTY; hres = IPropertyBag_Read(pPropBag, fcc_handlerW, &v, NULL); if(FAILED(hres)) { WARN("Could not read FccHandler: %08x\n", hres); return hres; } if(V_VT(&v) != VT_BSTR) { FIXME("Got vt %d\n", V_VT(&v)); VariantClear(&v); return E_FAIL; } str = V_BSTR(&v); TRACE("FccHandler = %s\n", debugstr_w(str)); if(SysStringLen(str) != 4) { FIXME("Invalid FccHandler len\n"); SysFreeString(str); return E_FAIL; } This->fcc_handler = FCC(str[0], str[1], str[2], str[3]); SysFreeString(str); return S_OK; }
/***************************************************************************** * OpenAudio: *****************************************************************************/ static int OpenAudio( decoder_t *p_dec ) { decoder_sys_t *p_sys; int i_error; char fcc[4]; unsigned long WantedBufferSize; unsigned long InputBufferSize = 0; unsigned long OutputBufferSize = 0; /* get lock, avoid segfault */ vlc_mutex_lock( &qt_mutex ); p_sys = calloc( 1, sizeof( decoder_sys_t ) ); p_dec->p_sys = p_sys; p_dec->pf_decode_audio = DecodeAudio; if( p_dec->fmt_in.i_original_fourcc ) memcpy( fcc, &p_dec->fmt_in.i_original_fourcc, 4 ); else memcpy( fcc, &p_dec->fmt_in.i_codec, 4 ); #ifdef __APPLE__ EnterMovies(); #endif if( QTAudioInit( p_dec ) ) { msg_Err( p_dec, "cannot initialize QT"); goto exit_error; } #ifndef __APPLE__ if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) ) { msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error ); goto exit_error; } #endif /* input format settings */ p_sys->InputFormatInfo.flags = 0; p_sys->InputFormatInfo.sampleCount = 0; p_sys->InputFormatInfo.buffer = NULL; p_sys->InputFormatInfo.reserved = 0; p_sys->InputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels; p_sys->InputFormatInfo.sampleSize = p_dec->fmt_in.audio.i_bitspersample; p_sys->InputFormatInfo.sampleRate = p_dec->fmt_in.audio.i_rate; p_sys->InputFormatInfo.format = FCC( fcc[0], fcc[1], fcc[2], fcc[3] ); /* output format settings */ p_sys->OutputFormatInfo.flags = 0; p_sys->OutputFormatInfo.sampleCount = 0; p_sys->OutputFormatInfo.buffer = NULL; p_sys->OutputFormatInfo.reserved = 0; p_sys->OutputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels; p_sys->OutputFormatInfo.sampleSize = 16; p_sys->OutputFormatInfo.sampleRate = p_dec->fmt_in.audio.i_rate; p_sys->OutputFormatInfo.format = FCC( 'N', 'O', 'N', 'E' ); i_error = p_sys->SoundConverterOpen( &p_sys->InputFormatInfo, &p_sys->OutputFormatInfo, &p_sys->myConverter ); if( i_error ) { msg_Err( p_dec, "error on SoundConverterOpen = %d", i_error ); goto exit_error; } #if 0 /* tell the sound converter we accept VBR formats */ i_error = SoundConverterSetInfo( p_dec->myConverter, siClientAcceptsVBR, (void *)true ); #endif if( p_dec->fmt_in.i_extra > 36 + 8 ) { i_error = p_sys->SoundConverterSetInfo( p_sys->myConverter, FCC( 'w', 'a', 'v', 'e' ), ((uint8_t*)p_dec->fmt_in.p_extra) + 36 + 8 ); msg_Dbg( p_dec, "error on SoundConverterSetInfo = %d", i_error ); } WantedBufferSize = p_sys->OutputFormatInfo.numChannels * p_sys->OutputFormatInfo.sampleRate * 2; p_sys->FramesToGet = 0; i_error = p_sys->SoundConverterGetBufferSizes( p_sys->myConverter, WantedBufferSize, &p_sys->FramesToGet, &InputBufferSize, &OutputBufferSize ); msg_Dbg( p_dec, "WantedBufferSize=%li InputBufferSize=%li " "OutputBufferSize=%li FramesToGet=%li", WantedBufferSize, InputBufferSize, OutputBufferSize, p_sys->FramesToGet ); p_sys->InFrameSize = (InputBufferSize + p_sys->FramesToGet - 1 ) / p_sys->FramesToGet; p_sys->OutFrameSize = OutputBufferSize / p_sys->FramesToGet; msg_Dbg( p_dec, "frame size %d -> %d", p_sys->InFrameSize, p_sys->OutFrameSize ); if( (i_error = p_sys->SoundConverterBeginConversion(p_sys->myConverter)) ) { msg_Err( p_dec, "error on SoundConverterBeginConversion = %d", i_error ); goto exit_error; } es_format_Init( &p_dec->fmt_out, AUDIO_ES, VLC_CODEC_S16N ); p_dec->fmt_out.audio.i_rate = p_sys->OutputFormatInfo.sampleRate; p_dec->fmt_out.audio.i_channels = p_sys->OutputFormatInfo.numChannels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_maps[p_sys->OutputFormatInfo.numChannels]; date_Init( &p_sys->date, p_dec->fmt_out.audio.i_rate, 1 ); p_sys->i_buffer = 0; p_sys->i_buffer_size = 100*1000; p_sys->p_buffer = malloc( p_sys->i_buffer_size ); if( !p_sys->p_buffer ) goto exit_error; p_sys->i_out = 0; p_sys->i_out_frames = 0; vlc_mutex_unlock( &qt_mutex ); return VLC_SUCCESS; exit_error: #ifdef LOADER Restore_LDT_Keeper( p_sys->ldt_fs ); #endif vlc_mutex_unlock( &qt_mutex ); free( p_sys ); return VLC_EGENERIC; }
int load_wav ( FIL *fp, /* Pointer to the open file object to play */ const char *title, /* Title (file name, etc...) */ void *work, /* Pointer to working buffer (must be-4 byte aligned) */ uint32_t sz_work /* Size of working buffer (must be power of 2) */ ) { UINT md, wi, br, tc, t, btr; DWORD sz, ssz, offw, szwav, wsmp, fsmp, eof; WAVFIFO fcb; BYTE k, *buff = work; char *p, nam[NBSIZE], art[NBSIZE]; xprintf("**** RIFF-WAVE Player ****\nFile=%s\n", title); /* Put title */ /* Is this a WAV file? */ if (f_read(fp, buff, 12, &br) || br != 12) return -1; if (LD_DWORD(&buff[0]) != FCC('R','I','F','F')) return -1; if (LD_DWORD(&buff[8]) != FCC('W','A','V','E')) return -1; eof = LD_DWORD(&buff[4]) + 8; /* Analyze the RIFF-WAVE header and get properties */ nam[0] = art[0] = 0; md = fsmp = wsmp = offw = szwav = 0; while (f_tell(fp) < eof) { if (f_read(fp, buff, 8, &br) || br != 8) return -1; sz = (LD_DWORD(&buff[4]) + 1) & ~1; switch (LD_DWORD(&buff[0])) { case FCC('f','m','t',' ') : /* fmt chunk */ if (sz > 1000 || sz < 16 || f_read(fp, buff, sz, &br) || sz != br) return -1; if (LD_WORD(&buff[0]) != 0x1) return -1; /* Check if LPCM or not */ if (LD_WORD(&buff[2]) == 2) { /* Check channels (1 or 2) */ md = 1; wsmp = 2; } else { md = 0; wsmp = 1; } if (LD_WORD(&buff[14]) == 16) { /* Resolution (8 or 16) */ md |= 2; wsmp *= 2; } fsmp = LD_DWORD(&buff[4]); /* Sampling rate */ break; case FCC('f','a','c','t') : /* fact chunk */ f_lseek(fp, f_tell(fp) + sz); break; case FCC('d','a','t','a') : /* data chunk */ offw = f_tell(fp); /* Wave data start offset */ szwav = sz; /* Size of wave data [byte] */ f_lseek(fp, f_tell(fp) + sz); break; case FCC('L','I','S','T'): /* LIST chunk */ sz += f_tell(fp); if (f_read(fp, buff, 4, &br) || br != 4) return -1; if (LD_DWORD(buff) == FCC('I','N','F','O')) { /* LIST/INFO sub-chunk */ while (f_tell(fp) < sz) { if (f_read(fp, buff, 8, &br) || br != 8) return -1; ssz = (LD_DWORD(&buff[4]) + 1) & ~1; p = 0; switch (LD_DWORD(buff)) { case FCC('I','N','A','M'): /* INAM (name) field */ p = nam; break; case FCC('I','A','R','T'): /* IART (artist) field */ p = art; break; } if (p && ssz <= NBSIZE) { if (f_read(fp, p, ssz, &br) || br != ssz) return -1; } else { if (f_lseek(fp, f_tell(fp) + ssz)) return -1; } } } else { if (f_lseek(fp, sz)) return -1; /* Skip unknown sub-chunk */ } break; default : /* Unknown chunk */ return -1; } } if (!szwav || !fsmp) return -1; /* Check if valid WAV file */ if (f_lseek(fp, offw)) return -1; /* Seek to top of wav data */ tc = szwav / fsmp / wsmp; /* Length (sec) */ xprintf("IART=%s\nINAM=%s\n", art, nam); xprintf("Sample=%u.%ukHz/%ubit/%s\nLength=%u:%02u\n", fsmp / 1000, (fsmp / 100) % 10, (md & 2) ? 16 : 8, (md & 1) ? "Stereo" : "Mono", tc / 60, tc % 60); /* Initialize sound FIFO and start sound streming */ fcb.mode = md; /* Sampling: b0=mono(0)/stereo(1), b1=8bit(0)/16bit(1) */ fcb.buff = buff; /* Pointer to streaming buffer */ fcb.sz_buff = sz_work; /* Size of streaming buffer */ if (!sound_start(&fcb, fsmp)) return -1; /* Start sound streaming */ k = 0; wi = 0; while (szwav || fcb.ct >= 4) { /* Sount streaming loop */ if (szwav && fcb.ct <= sz_work / 2) { /* Refill FIFO when it gets half empty */ btr = (szwav >= sz_work / 2) ? sz_work / 2 : szwav; f_read(fp, &buff[wi], btr, &br); if (br != btr) break; /* Exit if illigal file termination or FS error */ szwav -= br; wi = (wi + br) & (sz_work - 1); IEN(CMT3, CMI3) = 0; /* Disable CMT3 compare match irq */ fcb.ct += br; IEN(CMT3, CMI3) = 1; /* Enable CMT3 compare match irq */ } if (scif_test()) { /* Exit if a user command arrived */ k = scif_getc(); break; } t = (f_tell(fp) - offw - fcb.ct) / fsmp / wsmp; /* Refresh time display every 1 sec */ if (t != tc) { tc = t; xprintf("\rTime=%u:%02u", tc / 60, tc % 60); } } sound_stop(); /* Stop sound streaming */ xputc('\n'); return k; /* Terminated due to -1:error, 0:eot, >0:key code */ }
// // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // ////////////////////////////////////////////////////////////////////////// #include "WavSource.h" #include "RiffParser.h" // FOURCCs that we need const FOURCC ckid_WAVE_FILE = FCC('WAVE'); // RIFF type for .wav files const FOURCC ckid_WAVE_FMT = FCC('fmt '); // WAVEFORMATEX chunk const FOURCC ckid_WAVE_DATA = FCC('data'); // Audio data chunk CRiffChunk::CRiffChunk() { this->fcc = 0; this->cb = 0; } CRiffChunk::CRiffChunk(const RIFFCHUNK& c) { this->fcc = c.fcc; this->cb = c.cb; }
CString CBaseSplitterOutputPin::GetMediaTypeDesc(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter) { if (mts.IsEmpty()) { return pName; } CLSID clSID; HRESULT hr = pFilter->GetClassID(&clSID); if ((clSID == __uuidof(CMpegSourceFilter)) || (clSID == __uuidof(CMpegSplitterFilter))) { return pName; } CAtlList<CString> Infos; const CMediaType* pmt = &mts[0]; if (pmt->majortype == MEDIATYPE_Video) { const VIDEOINFOHEADER *pVideoInfo = NULL; const VIDEOINFOHEADER2 *pVideoInfo2 = NULL; BOOL bAdd = FALSE; if (pmt->formattype == FORMAT_VideoInfo) { pVideoInfo = GetFormatHelper(pVideoInfo, pmt); } else if (pmt->formattype == FORMAT_MPEGVideo) { Infos.AddTail(L"MPEG"); const MPEG1VIDEOINFO *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo = &pInfo->hdr; bAdd = TRUE; } else if (pmt->formattype == FORMAT_MPEG2_VIDEO) { const MPEG2VIDEOINFO *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo2 = &pInfo->hdr; bool bIsAVC = false; bool bIsMPEG2 = false; if (pInfo->hdr.bmiHeader.biCompression == FCC('AVC1') || pInfo->hdr.bmiHeader.biCompression == FCC('H264')) { bIsAVC = true; Infos.AddTail(L"AVC (H.264)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == FCC('AMVC')) { bIsAVC = true; Infos.AddTail(L"MVC (Full)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == FCC('EMVC')) { bIsAVC = true; Infos.AddTail(L"MVC (Subset)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == 0) { Infos.AddTail(L"MPEG2"); bIsMPEG2 = true; bAdd = TRUE; } if (bIsMPEG2) { Infos.AddTail(MPEG2_Profile[pInfo->dwProfile]); } else if (pInfo->dwProfile) { if (bIsAVC) { switch (pInfo->dwProfile) { case 44: Infos.AddTail(L"CAVLC Profile"); break; case 66: Infos.AddTail(L"Baseline Profile"); break; case 77: Infos.AddTail(L"Main Profile"); break; case 88: Infos.AddTail(L"Extended Profile"); break; case 100: Infos.AddTail(L"High Profile"); break; case 110: Infos.AddTail(L"High 10 Profile"); break; case 118: Infos.AddTail(L"Multiview High Profile"); break; case 122: Infos.AddTail(L"High 4:2:2 Profile"); break; case 244: Infos.AddTail(L"High 4:4:4 Profile"); break; case 128: Infos.AddTail(L"Stereo High Profile"); break; default: Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile)); break; } } else { Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile)); } } if (bIsMPEG2) { Infos.AddTail(MPEG2_Level[pInfo->dwLevel]); } else if (pInfo->dwLevel) { if (bIsAVC) { Infos.AddTail(FormatString(L"Level %1.1f", double(pInfo->dwLevel)/10.0)); } else { Infos.AddTail(FormatString(L"Level %d", pInfo->dwLevel)); } } } else if (pmt->formattype == FORMAT_VIDEOINFO2) { const VIDEOINFOHEADER2 *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo2 = pInfo; } if (!bAdd) { BITMAPINFOHEADER bih; bool fBIH = ExtractBIH(pmt, &bih); if (fBIH) { CString codecName = CMediaTypeEx::GetVideoCodecName(pmt->subtype, bih.biCompression); if (codecName.GetLength() > 0) { Infos.AddTail(codecName); } } } if (pVideoInfo2) { if (pVideoInfo2->bmiHeader.biWidth && pVideoInfo2->bmiHeader.biHeight) { Infos.AddTail(FormatString(L"%dx%d", pVideoInfo2->bmiHeader.biWidth, pVideoInfo2->bmiHeader.biHeight)); } if (pVideoInfo2->AvgTimePerFrame) { Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo2->AvgTimePerFrame))); } if (pVideoInfo2->dwBitRate) { Infos.AddTail(FormatBitrate(pVideoInfo2->dwBitRate)); } } else if (pVideoInfo) { if (pVideoInfo->bmiHeader.biWidth && pVideoInfo->bmiHeader.biHeight) { Infos.AddTail(FormatString(L"%dx%d", pVideoInfo->bmiHeader.biWidth, pVideoInfo->bmiHeader.biHeight)); } if (pVideoInfo->AvgTimePerFrame) { Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo->AvgTimePerFrame))); } if (pVideoInfo->dwBitRate) { Infos.AddTail(FormatBitrate(pVideoInfo->dwBitRate)); } } } else if (pmt->majortype == MEDIATYPE_Audio) { if (pmt->formattype == FORMAT_WaveFormatEx) { const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, pmt); if (pmt->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO) { Infos.AddTail(L"DVD LPCM"); } else if (pmt->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO) { const WAVEFORMATEX_HDMV_LPCM *pInfoHDMV = GetFormatHelper(pInfoHDMV, pmt); UNREFERENCED_PARAMETER(pInfoHDMV); Infos.AddTail(L"HDMV LPCM"); } if (pmt->subtype == MEDIASUBTYPE_DOLBY_DDPLUS) { Infos.AddTail(L"Dolby Digital Plus"); } else { switch (pInfo->wFormatTag) { case WAVE_FORMAT_MPEG: { const MPEG1WAVEFORMAT* pInfoMPEG1 = GetFormatHelper(pInfoMPEG1, pmt); int layer = GetHighestBitSet32(pInfoMPEG1->fwHeadLayer) + 1; Infos.AddTail(FormatString(L"MPEG1 - Layer %d", layer)); } break; default: { CString codecName = CMediaTypeEx::GetAudioCodecName(pmt->subtype, pInfo->wFormatTag); if (codecName.GetLength() > 0) { Infos.AddTail(codecName); } } break; } } if (pInfo->nSamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec)/1000.0)); } if (pInfo->nChannels) { Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels)); } if (pInfo->wBitsPerSample) { Infos.AddTail(FormatString(L"%d bit", pInfo->wBitsPerSample)); } if (pInfo->nAvgBytesPerSec) { Infos.AddTail(FormatBitrate(pInfo->nAvgBytesPerSec * 8)); } } else if (pmt->formattype == FORMAT_VorbisFormat) { const VORBISFORMAT *pInfo = GetFormatHelper(pInfo, pmt); Infos.AddTail(CMediaTypeEx::GetAudioCodecName(pmt->subtype, 0)); if (pInfo->nSamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec)/1000.0)); } if (pInfo->nChannels) { Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels)); } if (pInfo->nAvgBitsPerSec) { Infos.AddTail(FormatString(L"%d bit", pInfo->nAvgBitsPerSec)); } if (pInfo->nAvgBitsPerSec) { Infos.AddTail(FormatBitrate(pInfo->nAvgBitsPerSec * 8)); } } else if (pmt->formattype == FORMAT_VorbisFormat2) { const VORBISFORMAT2 *pInfo = GetFormatHelper(pInfo, pmt); Infos.AddTail(CMediaTypeEx::GetAudioCodecName(pmt->subtype, 0)); if (pInfo->SamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->SamplesPerSec)/1000.0)); } if (pInfo->Channels) { Infos.AddTail(FormatString(L"%d chn", pInfo->Channels)); } } } if (!Infos.IsEmpty()) { CString Ret = pName; Ret += " ("; bool bFirst = true; for (POSITION pos = Infos.GetHeadPosition(); pos; Infos.GetNext(pos)) { const CString& String = Infos.GetAt(pos); if (bFirst) { Ret += String; } else { Ret += L", " + String; } bFirst = false; } Ret += ')'; return Ret; } return pName; }
const TCHAR* VideoSubtypeName(GUID& guid) { if (guid == MEDIASUBTYPE_RGB565) { return TEXT("RGB565"); } else if (guid == MEDIASUBTYPE_RGB555) { return TEXT("RGB555"); } else if (guid == MEDIASUBTYPE_RGB24) { return TEXT("RGB24"); } else if (guid == MEDIASUBTYPE_RGB32) { return TEXT("RGB32"); } else if ((guid == MEDIASUBTYPE_YVU9) || (guid == MEDIASUBTYPE_Y411)) { return TEXT("YVU9"); } else if (guid == MEDIASUBTYPE_YUY2) { return TEXT("YUY2"); } else if (guid == MEDIASUBTYPE_UYVY) { return TEXT("UYVY"); } else if (guid == MEDIASUBTYPE_Y211) { return TEXT("Y211"); } else if (guid == MEDIASUBTYPE_IYUV) { return TEXT("IYUV"); } else if (guid == MEDIASUBTYPE_dvsd) { return TEXT("DV(SD)"); } // what is MEDIASUBTYPE_dvc ? else { // Some YUV types don't get a proper GUID. if (GuidIsFcc(guid, FCC('I420'))) { return TEXT("I420"); } if (GuidIsFcc(guid, FCC('YV12'))) { return TEXT("YV12"); } } return TEXT("????"); }
HRESULT CWAVFile::Open(CBaseSplitterFile* pFile) { m_pFile = pFile; m_startpos = 0; m_pFile->Seek(0); BYTE data[12]; if (m_pFile->ByteRead(data, sizeof(data)) != S_OK || *(DWORD*)(data+0) != FCC('RIFF') || *(DWORD*)(data+4) < (4 + 8 + sizeof(PCMWAVEFORMAT) + 8) // 'WAVE' + ('fmt ' + fmt.size) + sizeof(PCMWAVEFORMAT) + (data + data.size) || *(DWORD*)(data+8) != FCC('WAVE')) { return E_FAIL; } __int64 end = min((__int64)*(DWORD*)(data + 4) + 8, m_pFile->GetLength()); chunk_t Chunk; while (m_pFile->ByteRead(Chunk.data, sizeof(Chunk)) == S_OK && m_pFile->GetPos() < end) { __int64 pos = m_pFile->GetPos(); TRACE(L"CWAVFile::Open() : found '%c%c%c%c' chunk.\n", TCHAR((Chunk.id>>0)&0xff), TCHAR((Chunk.id>>8)&0xff), TCHAR((Chunk.id>>16)&0xff), TCHAR((Chunk.id>>24)&0xff)); switch (Chunk.id) { case FCC('fmt '): if (m_fmtdata || Chunk.size < sizeof(PCMWAVEFORMAT) || Chunk.size > 65536) { TRACE(L"CWAVFile::Open() : bad format\n"); return E_FAIL; } m_fmtsize = max(Chunk.size, sizeof(WAVEFORMATEX)); // PCMWAVEFORMAT to WAVEFORMATEX m_fmtdata = DNew BYTE[m_fmtsize]; memset(m_fmtdata, 0, m_fmtsize); if (m_pFile->ByteRead(m_fmtdata, Chunk.size) != S_OK) { TRACE(L"CWAVFile::Open() : format can not be read.\n"); return E_FAIL; } break; case FCC('data'): if (m_endpos) { TRACE(L"CWAVFile::Open() : bad format\n"); return E_FAIL; } m_startpos = pos; m_length = min(Chunk.size, m_pFile->GetLength() - m_startpos); break; case FCC('LIST'): ReadRIFFINFO(pos, Chunk.size); break; case FCC('wavl'): // not supported case FCC('slnt'): // not supported TRACE(L"CWAVFile::Open() : WAVE file is not supported!\n"); return E_FAIL; default: for (int i = 0; i < sizeof(Chunk.id); i++) { BYTE ch = Chunk.data[i]; if (ch != 0x20 && (ch < '0' || ch > '9') && (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { TRACE(L"CWAVFile::Open() : broken file!\n"); return E_FAIL; } } // Known chunks: // 'fact' // 'JUNK' // 'PAD ' // 'cue ' // 'plst' // 'list' (contains 'labl', 'note' and 'ltxt' subchunks) // 'PEAK' // 'smpl' // 'inst' // 'bext' // 'minf' // 'elm1' break; } m_pFile->Seek(pos + Chunk.size); } if (!m_startpos || !ProcessWAVEFORMATEX()) { return E_FAIL; } m_length -= m_length % m_nBlockAlign; m_endpos = m_startpos + m_length; m_rtduration = 10000000i64 * m_length / m_nAvgBytesPerSec; CheckDTSAC3CD(); return S_OK; }
int UtVideoFormatToVCMFormat(DWORD *biCompression, WORD *biBitCount, utvf_t utvf) { switch (utvf) { case UTVF_NFCC_BGR_BU: *biCompression = BI_RGB; *biBitCount = 24; return 0; case UTVF_NFCC_BGRX_BU: *biCompression = BI_RGB; *biBitCount = 32; return 0; case UTVF_NFCC_BGRA_BU: *biCompression = BI_RGB; *biBitCount = 32; return 0; } if (!is_fourcc(utvf)) return -1; switch (utvf) { case UTVF_ULRA: *biBitCount = 32; break; case UTVF_ULRG: case UTVF_ULY2: case UTVF_ULY0: case UTVF_ULH2: case UTVF_ULH0: *biBitCount = 24; break; case UTVF_UQRA: *biBitCount = 40; break; case UTVF_UQRG: case UTVF_UQY2: *biBitCount = 30; break; case UTVF_YUY2: case UTVF_YUYV: case UTVF_YUNV: case UTVF_yuvs: case UTVF_UYVY: case UTVF_UYNV: case UTVF_2vuy: case UTVF_HDYC: *biBitCount = 16; break; case UTVF_YV12: *biBitCount = 12; break; case UTVF_v210: *biBitCount = 20; break; case UTVF_b64a: *biBitCount = 64; break; case UTVF_b48r: *biBitCount = 48; break; default: return -1; } *biCompression = FCC(utvf); return 0; }
virtual void OnGotChunk( const ChunkHeader& ch ) { FCCParser fcc( ch.fcc ); // per file if ( fcc == FCC('dmlh') ) _Info._DMLHch = ch; if ( fcc == FCC('hdrl') ) _Info._HDRLch = ch; if ( fcc == FCC('avih') ) _Info._AVIHch = ch; if ( fcc == FCC('idx1') ) _Info._IDX1ch = ch; // per stream if ( fcc == FCC('strl') ) { int idx = (int)_Info._StreamInfos.size(); _Info._StreamInfos.push_back( AVIStreamInfo( idx ) ); } if ( fcc == FCC('strh') ) { _Info._StreamInfos.back().streamInfo.header = _Stream->Read<MediaStreamHeader>(); _Info._StreamInfos.back().STRHch = ch; } if ( fcc == FCC('indx') ) _Info._StreamInfos.back().streamInfo.indxChunk = ch; if ( fcc == FCC('strf') && _Info._StreamInfos.back().streamInfo.IsVideo() ) _Info._StreamInfos.back().streamInfo.video = _Stream->Read<BITMAPINFOHEADER>(); if ( fcc == FCC('strf') && _Info._StreamInfos.back().streamInfo.IsAudio() ) _Info._StreamInfos.back().streamInfo.audio = WaveFormatEx::FromStream( *_Stream ); // standard index (type 2) if ( fcc == FCC('ix##') ) _Info._StreamInfos[fcc.StreamIndex()].indexes.push_back( Index( ch ) ); // index entry if ( fcc == FCC('##db') ) _Info._StreamInfos[fcc.StreamIndex()].indexes.back().AddEntry( ch, true /*keyframe*/ ); if ( fcc == FCC('##dc') ) _Info._StreamInfos[fcc.StreamIndex()].indexes.back().AddEntry( ch, false/*delta frame*/ ); if ( fcc == FCC('##wb') ) _Info._StreamInfos[fcc.StreamIndex()].indexes.back().AddEntry( ch, true /*keyframe*/ ); }
BOOST_DATA_TEST_CASE(vcm_encdec, make_data_from_tuple_container(vecEncDecClips), src, dst, fmt, config, tolerance) { VideoClip srcClip(src); VideoClip dstClip(dst); DWORD fccCodec = FCC(fmt); BOOST_REQUIRE(srcClip.GetWidth() == dstClip.GetWidth()); BOOST_REQUIRE(srcClip.GetHeight() == dstClip.GetHeight()); DWORD fccSrc = srcClip.GetFourCC(); DWORD fccDst = dstClip.GetFourCC(); unsigned int nWidth = srcClip.GetWidth(); unsigned int nHeight = srcClip.GetHeight(); size_t cbSrcData; size_t cbDstData; size_t cbCompressedData; HIC hicEncode, hicDecode; LRESULT lr; union { BITMAPINFOHEADER bihCompressed; char bihCompressedBuf[128]; }; BITMAPINFOHEADER bihSrc; BITMAPINFOHEADER bihDst; hicEncode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_COMPRESS); BOOST_REQUIRE(hicEncode != NULL); ICCloser iccloserEnc(hicEncode); lr = ICSetState(hicEncode, &config.front(), config.size()); BOOST_REQUIRE(lr == config.size()); hicDecode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_DECOMPRESS); BOOST_REQUIRE(hicDecode != NULL); ICCloser iccloserDec(hicDecode); memset(&bihSrc, 0, sizeof(BITMAPINFOHEADER)); bihSrc.biSize = sizeof(BITMAPINFOHEADER); bihSrc.biWidth = nWidth; bihSrc.biHeight = nHeight; bihSrc.biPlanes = 1; bihSrc.biBitCount = FCC2BitCount(fccSrc); bihSrc.biCompression = FCC2Compression(fccSrc); bihSrc.biSizeImage = 10000000; memset(&bihDst, 0, sizeof(BITMAPINFOHEADER)); bihDst.biSize = sizeof(BITMAPINFOHEADER); bihDst.biWidth = nWidth; bihDst.biHeight = nHeight; bihDst.biPlanes = 1; bihDst.biBitCount = FCC2BitCount(fccDst); bihDst.biCompression = FCC2Compression(fccDst); bihDst.biSizeImage = 10000000; lr = ICCompressGetFormat(hicEncode, &bihSrc, &bihCompressed); BOOST_REQUIRE_EQUAL(lr, ICERR_OK); cbCompressedData = ICCompressGetSize(hicEncode, &bihSrc, &bihCompressed); lr = ICCompressBegin(hicEncode, &bihSrc, &bihCompressed); BOOST_REQUIRE_EQUAL(lr, ICERR_OK); lr = ICDecompressBegin(hicDecode, &bihCompressed, &bihDst); BOOST_REQUIRE_EQUAL(lr, ICERR_OK); void *pSrcData; void *pDstData; void *pEncoderOut = malloc(cbCompressedData); void *pDecoderOut = NULL; int retSrc, retDst; LONG lFrameNum = 0; while ((retSrc = srcClip.GetNextFrame(&pSrcData, &cbSrcData, NULL)) == 0 && (retDst = dstClip.GetNextFrame(&pDstData, &cbDstData, NULL) == 0)) { DWORD dwFlags = 0; lr = ICCompress(hicEncode, 0, &bihCompressed, pEncoderOut, &bihSrc, pSrcData, NULL, &dwFlags, lFrameNum++, 0, 0, &bihSrc, NULL); BOOST_REQUIRE(lr == ICERR_OK); if (pDecoderOut == NULL) pDecoderOut = malloc(cbDstData); lr = ICDecompress(hicDecode, (dwFlags & AVIIF_KEYFRAME) ? 0 : ICDECOMPRESS_NOTKEYFRAME, &bihCompressed, pEncoderOut, &bihDst, pDecoderOut); BOOST_REQUIRE(lr == ICERR_OK); BOOST_CHECK(bihDst.biSizeImage == cbDstData); BOOST_CHECK(CompareFrame(pDstData, pDecoderOut, nWidth, cbDstData, fccDst, tolerance) == 0); } BOOST_CHECK(retSrc != 0 && retDst != 0); if (pDecoderOut != NULL) free(pDecoderOut); free(pEncoderOut); lr = ICDecompressEnd(hicDecode); BOOST_CHECK(lr == ICERR_OK); lr = ICCompressEnd(hicEncode); BOOST_CHECK(lr == ICERR_OK); }
AviError AVI_set_compress_option(AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data) { int i; int useconds; (void)stream; /* unused */ if (movie->header->TotalFrames != 0) /* Can't change params after we have already started writing frames */ return AVI_ERROR_OPTION; switch (option_type) { case AVI_OPTION_TYPE_MAIN: switch (option) { case AVI_OPTION_WIDTH: movie->header->Width = *((int *) opt_data); movie->header->SuggestedBufferSize = movie->header->Width * movie->header->Height * 3; for (i = 0; i < movie->header->Streams; i++) { if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) { ((AviBitmapInfoHeader *) movie->streams[i].sf)->Width = *((int *) opt_data); movie->streams[i].sh.SuggestedBufferSize = movie->header->SuggestedBufferSize; movie->streams[i].sh.right = *((int *) opt_data); ((AviBitmapInfoHeader *) movie->streams[i].sf)->SizeImage = movie->header->SuggestedBufferSize; fseek(movie->fp, movie->offset_table[1 + i * 2 + 1], SEEK_SET); awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); } } break; case AVI_OPTION_HEIGHT: movie->header->Height = *((int *) opt_data); movie->header->SuggestedBufferSize = movie->header->Width * movie->header->Height * 3; for (i = 0; i < movie->header->Streams; i++) { if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) { ((AviBitmapInfoHeader *) movie->streams[i].sf)->Height = *((int *) opt_data); movie->streams[i].sh.SuggestedBufferSize = movie->header->SuggestedBufferSize; movie->streams[i].sh.bottom = *((int *) opt_data); ((AviBitmapInfoHeader *) movie->streams[i].sf)->SizeImage = movie->header->SuggestedBufferSize; fseek(movie->fp, movie->offset_table[1 + i * 2 + 1], SEEK_SET); awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); } } break; case AVI_OPTION_QUALITY: for (i = 0; i < movie->header->Streams; i++) { if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) { movie->streams[i].sh.Quality = (*((int *) opt_data)) * 100; fseek(movie->fp, movie->offset_table[1 + i * 2 + 1], SEEK_SET); awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); } } break; case AVI_OPTION_FRAMERATE: useconds = (int)(1000000 / (*((double *) opt_data))); if (useconds) movie->header->MicroSecPerFrame = useconds; for (i = 0; i < movie->header->Streams; i++) { if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) { movie->streams[i].sh.Scale = movie->header->MicroSecPerFrame; fseek(movie->fp, movie->offset_table[1 + i * 2 + 1], SEEK_SET); awrite(movie, movie->streams[i].sf, 1, movie->streams[i].sf_size, movie->fp, AVI_BITMAPH); } } break; } fseek(movie->fp, movie->offset_table[0], SEEK_SET); awrite(movie, movie->header, 1, sizeof(AviMainHeader), movie->fp, AVI_MAINH); break; case AVI_OPTION_TYPE_STRH: break; case AVI_OPTION_TYPE_STRF: break; default: return AVI_ERROR_OPTION; break; } return AVI_ERROR_NONE; }
/***************************************************************************** * OpenVideo: *****************************************************************************/ static int OpenVideo( decoder_t *p_dec ) { #ifndef WIN32 decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; long i_result; ComponentDescription desc; Component prev; ComponentResult cres; ImageSubCodecDecompressCapabilities icap; /* for ImageCodecInitialize() */ CodecInfo cinfo; /* for ImageCodecGetCodecInfo() */ ImageDescription *id; char fcc[4]; int i_vide = p_dec->fmt_in.i_extra; uint8_t *p_vide = p_dec->fmt_in.p_extra; p_dec->p_sys = p_sys; p_dec->pf_decode_video = DecodeVideo; p_sys->i_late = 0; if( i_vide <= 0 ) { msg_Err( p_dec, "missing extra info" ); free( p_sys ); return VLC_EGENERIC; } if( p_dec->fmt_in.i_original_fourcc ) memcpy( fcc, &p_dec->fmt_in.i_original_fourcc, 4 ); else memcpy( fcc, &p_dec->fmt_in.i_codec, 4 ); msg_Dbg( p_dec, "quicktime_video %4.4s %dx%d", fcc, p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height ); /* get lock, avoid segfault */ vlc_mutex_lock( &qt_mutex ); #ifdef __APPLE__ EnterMovies(); #endif if( QTVideoInit( p_dec ) ) { msg_Err( p_dec, "cannot initialize QT"); goto exit_error; } #ifndef __APPLE__ if( ( i_result = p_sys->InitializeQTML( 6 + 16 ) ) ) { msg_Dbg( p_dec, "error on InitializeQTML = %d", (int)i_result ); goto exit_error; } #endif /* init ComponentDescription */ memset( &desc, 0, sizeof( ComponentDescription ) ); desc.componentType = FCC( 'i', 'm', 'd', 'c' ); desc.componentSubType = FCC( fcc[0], fcc[1], fcc[2], fcc[3] ); desc.componentManufacturer = 0; desc.componentFlags = 0; desc.componentFlagsMask = 0; if( !( prev = p_sys->FindNextComponent( NULL, &desc ) ) ) { msg_Err( p_dec, "cannot find requested component" ); goto exit_error; } msg_Dbg( p_dec, "component id=0x%p", prev ); p_sys->ci = p_sys->OpenComponent( prev ); msg_Dbg( p_dec, "component instance p=0x%p", p_sys->ci ); memset( &icap, 0, sizeof( ImageSubCodecDecompressCapabilities ) ); cres = p_sys->ImageCodecInitialize( p_sys->ci, &icap ); msg_Dbg( p_dec, "ImageCodecInitialize->0x%X size=%d (%d)", (int)cres, (int)icap.recordSize, (int)icap.decompressRecordSize); memset( &cinfo, 0, sizeof( CodecInfo ) ); cres = p_sys->ImageCodecGetCodecInfo( p_sys->ci, &cinfo ); msg_Dbg( p_dec, "Flags: compr: 0x%x decomp: 0x%x format: 0x%x", (unsigned int)cinfo.compressFlags, (unsigned int)cinfo.decompressFlags, (unsigned int)cinfo.formatFlags ); msg_Dbg( p_dec, "quicktime_video: Codec name: %.*s", ((unsigned char*)&cinfo.typeName)[0], ((unsigned char*)&cinfo.typeName)+1 ); /* make a yuy2 gworld */ p_sys->OutBufferRect.top = 0; p_sys->OutBufferRect.left = 0; p_sys->OutBufferRect.right = p_dec->fmt_in.video.i_width; p_sys->OutBufferRect.bottom = p_dec->fmt_in.video.i_height; /* codec data FIXME use codec not SVQ3 */ msg_Dbg( p_dec, "vide = %d", i_vide ); id = malloc( sizeof( ImageDescription ) + ( i_vide - 70 ) ); if( !id ) goto exit_error; id->idSize = sizeof( ImageDescription ) + ( i_vide - 70 ); id->cType = FCC( fcc[0], fcc[1], fcc[2], fcc[3] ); id->version = GetWBE ( p_vide + 0 ); id->revisionLevel = GetWBE ( p_vide + 2 ); id->vendor = GetDWBE( p_vide + 4 ); id->temporalQuality = GetDWBE( p_vide + 8 ); id->spatialQuality = GetDWBE( p_vide + 12 ); id->width = GetWBE ( p_vide + 16 ); id->height = GetWBE ( p_vide + 18 ); id->hRes = GetDWBE( p_vide + 20 ); id->vRes = GetDWBE( p_vide + 24 ); id->dataSize = GetDWBE( p_vide + 28 ); id->frameCount = GetWBE ( p_vide + 32 ); memcpy( &id->name, p_vide + 34, 32 ); id->depth = GetWBE ( p_vide + 66 ); id->clutID = GetWBE ( p_vide + 68 ); if( i_vide > 70 ) { memcpy( ((char*)&id->clutID) + 2, p_vide + 70, i_vide - 70 ); } msg_Dbg( p_dec, "idSize=%d ver=%d rev=%d vendor=%d tempQ=%d " "spaQ=%d w=%d h=%d dpi=%d%d dataSize=%d depth=%d frameCount=%d clutID=%d", (int)id->idSize, id->version, id->revisionLevel, (int)id->vendor, (int)id->temporalQuality, (int)id->spatialQuality, (int)id->width, (int)id->height, (int)id->hRes, (int)id->vRes, (int)id->dataSize, id->depth, id->frameCount, id->clutID ); p_sys->framedescHandle = (ImageDescriptionHandle) NewHandleClear( id->idSize ); memcpy( *p_sys->framedescHandle, id, id->idSize ); if( p_dec->fmt_in.video.i_width != 0 && p_dec->fmt_in.video.i_height != 0) p_sys->plane = malloc( p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 3 ); if( !p_sys->plane ) goto exit_error; i_result = p_sys->QTNewGWorldFromPtr( &p_sys->OutBufferGWorld, /*pixel format of new GWorld==YUY2 */ kYUVSPixelFormat, /* we should benchmark if yvu9 is * faster for svq3, too */ &p_sys->OutBufferRect, 0, 0, 0, p_sys->plane, p_dec->fmt_in.video.i_width * 2 ); msg_Dbg( p_dec, "NewGWorldFromPtr returned:%ld", 65536 - ( i_result&0xffff ) ); memset( &p_sys->decpar, 0, sizeof( CodecDecompressParams ) ); p_sys->decpar.imageDescription = p_sys->framedescHandle; p_sys->decpar.startLine = 0; p_sys->decpar.stopLine = ( **p_sys->framedescHandle ).height; p_sys->decpar.frameNumber = 1; p_sys->decpar.matrixFlags = 0; p_sys->decpar.matrixType = 0; p_sys->decpar.matrix = 0; p_sys->decpar.capabilities = &p_sys->codeccap; p_sys->decpar.accuracy = codecNormalQuality; p_sys->decpar.srcRect = p_sys->OutBufferRect; p_sys->decpar.transferMode = srcCopy; p_sys->decpar.dstPixMap = **p_sys->GetGWorldPixMap( p_sys->OutBufferGWorld );/*destPixmap; */ cres = p_sys->ImageCodecPreDecompress( p_sys->ci, &p_sys->decpar ); msg_Dbg( p_dec, "quicktime_video: ImageCodecPreDecompress cres=0x%X", (int)cres ); es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_CODEC_YUYV); p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width; p_dec->fmt_out.video.i_height= p_dec->fmt_in.video.i_height; p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_in.video.i_width / p_dec->fmt_in.video.i_height; vlc_mutex_unlock( &qt_mutex ); return VLC_SUCCESS; exit_error: #ifdef LOADER Restore_LDT_Keeper( p_sys->ldt_fs ); #endif vlc_mutex_unlock( &qt_mutex ); #else VLC_UNUSED( p_dec ); #endif /* !WIN32 */ return VLC_EGENERIC; }
// Assign a DirectShow YUV sample to a YUV_frame extern HRESULT YUV_frame_from_DirectShow(const CMediaType* pMT, BYTE* buff, YUV_frame* pFrame) { BITMAPINFOHEADER* pBmi; pBmi = GetBMI(pMT); if (pBmi == NULL) return E_UNEXPECTED; // set line stride if ((pBmi->biBitCount != 0) && ((pBmi->biBitCount & 7) == 0)) // For 'normal' formats, biWidth is in pixels. // Expand to bytes and round up to a multiple of 4. pFrame->Y.lineStride = ((pBmi->biWidth * (pBmi->biBitCount / 8)) + 3) & ~3; else // Otherwise, biWidth is in bytes. pFrame->Y.lineStride = pBmi->biWidth; // set pixel stride switch (pBmi->biCompression) { case FCC('YV12'): case FCC('IF09'): case FCC('YVU9'): case FCC('IYUV'): // planar formats pFrame->Y.pixelStride = 1; break; case FCC('UYVY'): case FCC('YUY2'): case FCC('YVYU'): case FCC('HDYC'): // multiplexed formats pFrame->Y.pixelStride = 2; break; default: return E_UNEXPECTED; } // set dimensions RECT* rcTarget = GetTargetRect(pMT); // If rcTarget is empty, use the whole image. if (IsRectEmpty(rcTarget)) { pFrame->Y.w = pBmi->biWidth; pFrame->Y.h = abs(pBmi->biHeight); } else // rcTarget is NOT empty. Use a sub-rectangle in the image. { pFrame->Y.w = rcTarget->right - rcTarget->left; pFrame->Y.h = rcTarget->bottom - rcTarget->top; buff += (rcTarget->top * pFrame->Y.lineStride) + (rcTarget->left * pFrame->Y.pixelStride); } // set subsampling pFrame->U = pFrame->Y; switch (pBmi->biCompression) { case FCC('UYVY'): case FCC('YUY2'): case FCC('YVYU'): case FCC('HDYC'): // horizontal 2:1 pFrame->U.w = pFrame->Y.w / 2; pFrame->U.pixelStride = pFrame->Y.pixelStride * 2; break; case FCC('YV12'): case FCC('IYUV'): // horizontal 2:1, vertical 2:1 pFrame->U.w = pFrame->Y.w / 2; pFrame->U.h = pFrame->Y.h / 2; pFrame->U.lineStride = pFrame->Y.lineStride / 2; break; case FCC('IF09'): case FCC('YVU9'): // horizontal 4:1, vertical 4:1 pFrame->U.w = pFrame->Y.w / 4; pFrame->U.h = pFrame->Y.h / 4; pFrame->U.lineStride = pFrame->Y.lineStride / 4; break; default: return E_UNEXPECTED; } pFrame->V = pFrame->U; // set buffer pointers switch (pBmi->biCompression) { case FCC('UYVY'): case FCC('HDYC'): pFrame->Y.buff = buff + 1; pFrame->U.buff = buff; pFrame->V.buff = buff + 2; break; case FCC('YUY2'): pFrame->Y.buff = buff; pFrame->U.buff = buff + 1; pFrame->V.buff = buff + 3; break; case FCC('YVYU'): pFrame->Y.buff = buff; pFrame->U.buff = buff + 3; pFrame->V.buff = buff + 1; break; case FCC('IYUV'): case FCC('IF09'): case FCC('YVU9'): pFrame->Y.buff = buff; pFrame->U.buff = pFrame->Y.buff + (pFrame->Y.lineStride * pFrame->Y.h); pFrame->V.buff = pFrame->U.buff + (pFrame->U.lineStride * pFrame->U.h); break; case FCC('YV12'): pFrame->Y.buff = buff; pFrame->V.buff = pFrame->Y.buff + (pFrame->Y.lineStride * pFrame->Y.h); pFrame->U.buff = pFrame->V.buff + (pFrame->V.lineStride * pFrame->V.h); break; default: return E_UNEXPECTED; } return S_OK; }