📄 main.cpp
字号:
*plength = (RMuint32)BPpcm.buffers_size; *pBuffer = (RMuint8 *)get_buffer_address (&BPpcm, idx); return 0;}static RMuint32 avi_loading (RMuint32 percent, void *context){ RMint8 text[64]; sprintf (text, "LOADING ... %d%% ", percent); pMpegDecoder->RenderText (text, 0xffff00, 32, 100, 320-32, 240-100); return 0;}static RMuint32 avi_gettime (void *context){ return gettime_ms ();}static RMuint32 avi_info (RMint32 msg, void *info, void *context){ AVI_MAIN_HEADER *pAVIHdr; AVI_STREAM_HEADER *pStreamHdr; AVI_BITMAPINFO *pBitmapInfo; AVI_WAVEFORMATEX *pWaveFormatEx; RMint32 w, h, n, d; switch (msg) { // this tells the application avi header information case AVI_DEMUX_MSG_AVIHDR: pAVIHdr = (AVI_MAIN_HEADER *)info; DEBUGMSG (1, ("AVI_MAIN_HEADER:\n")); DEBUGMSG (1, (" MicroSecPerFrame = %lu\n", pAVIHdr->MicroSecPerFrame)); DEBUGMSG (1, (" MaxBytesPerSec = %lu\n", pAVIHdr->MaxBytesPerSec)); DEBUGMSG (1, (" Flags = %lu\n", pAVIHdr->Flags)); DEBUGMSG (1, (" TotalFrames = %lu\n", pAVIHdr->TotalFrames)); DEBUGMSG (1, (" InitialFrames = %lu\n", pAVIHdr->InitialFrames)); DEBUGMSG (1, (" Streams = %lu\n", pAVIHdr->Streams)); DEBUGMSG (1, (" SuggestedBufferSize = %lu\n", pAVIHdr->SuggestedBufferSize)); DEBUGMSG (1, (" Width = %lu\n", pAVIHdr->Width)); DEBUGMSG (1, (" Height = %lu\n", pAVIHdr->Height)); DEBUGMSG (1, (" Scale = %lu\n", pAVIHdr->Scale)); DEBUGMSG (1, (" Rate = %lu\n", pAVIHdr->Rate)); DEBUGMSG (1, (" Start = %lu\n", pAVIHdr->Start)); DEBUGMSG (1, (" Length = %lu\n", pAVIHdr->Length)); break; // this tells the application stream information case AVI_DEMUX_MSG_STREAMHDR: pStreamHdr = (AVI_STREAM_HEADER *)info; if (pStreamHdr->fccType == AVI_FOURCC ('v','i','d','s')) { DEBUGMSG (1, ("AVI_STREAM_HEADER (video %d):\n", video_stream_count)); // take only the first video stream if (video_stream_count == 0) { ASSERT (pMpegDecoder); if (pStreamHdr->Scale < 1000) { DEBUGMSG (1, ("pStreamHdr->Scale < 1000: adjusting scale/rate\n")); DEBUGMSG (1, ("Scale: %d, Rate: %d\n", pStreamHdr->Scale, pStreamHdr->Rate)); RMuint32 scale = 1000 / pStreamHdr->Scale; pStreamHdr->Scale = pStreamHdr->Scale * scale; pStreamHdr->Rate = pStreamHdr->Rate * scale; DEBUGMSG (1, ("ADJUSTED: Scale: %d, Rate: %d\n", pStreamHdr->Scale, pStreamHdr->Rate)); } if (pStreamHdr->Rate > 64000) { DEBUGMSG (1, ("pStreamHdr->Scale > 64000: adjusting scale/rate\n")); DEBUGMSG (1, ("Scale: %d, Rate: %d\n", AVI_PACKED_STRUCTURE_ACCESS (*pStreamHdr, Scale), AVI_PACKED_STRUCTURE_ACCESS (*pStreamHdr, Rate))); pStreamHdr->Rate = (RMuint32) (((RMuint64)pStreamHdr->Rate) * (RMuint64)1000 / (RMuint64)pStreamHdr->Scale); pStreamHdr->Scale = 1000; DEBUGMSG (1, ("ADJUSTED: Scale: %d, Rate: %d\n", pStreamHdr->Scale, pStreamHdr->Rate)); } // we assume if the avi file says 23.975 or 23.976 frames/second, // then the _real_ value is 24000/1001 if ((pStreamHdr->Scale == 1000) && (pStreamHdr->Rate == 23975)) { DEBUGMSG (1, ("optimizing rate of 23975\n")); pStreamHdr->Rate = 24000; pStreamHdr->Scale = 1001; } else if ((pStreamHdr->Scale == 1000) && (pStreamHdr->Rate == 23976)) { DEBUGMSG (1, ("optimizing rate of 23976\n")); pStreamHdr->Rate = 24000; pStreamHdr->Scale = 1001; } // try to intelligently fix some bad avi headers // normally the frame rate should be 29.97 (30000/1001) else if ((pStreamHdr->Scale == 1000) && ((pStreamHdr->Rate >= 29970) && (pStreamHdr->Rate <= 30007)) && (pStreamHdr->Rate != 30000)) { DEBUGMSG (1, ("assuming 29.97 (%d,%d)\n", pStreamHdr->Scale, pStreamHdr->Rate)); pStreamHdr->Rate = 30000; pStreamHdr->Scale = 1001; } DEBUGMSG (1, ("Rate = %d\n", pStreamHdr->Rate)); DEBUGMSG (1, ("Scale = %d\n", pStreamHdr->Scale)); aviTimeScale = pStreamHdr->Rate; aviTicksPerFrame = pStreamHdr->Scale; aviTime0 = 1; aviStartupDelay = AVI_DELAY_MS * aviTimeScale / 1000; DEBUGMSG (1, ("aviStartupDelay = %d\n", aviStartupDelay)); audioTime = aviStartupDelay; videoTime = aviStartupDelay; aviFrameCounter = 0; currentRate = pStreamHdr->Rate; currentScale = pStreamHdr->Scale; } video_stream_count++; } else if (pStreamHdr->fccType == AVI_FOURCC ('a','u','d','s')) { DEBUGMSG (1, ("AVI_STREAM_HEADER (audio %d):\n", audio_stream_count)); audio_stream_count++; } else { DEBUGMSG (1, ("AVI_STREAM_HEADER:\n")); } avi_stream_count++; DEBUGMSG (1, (" fccType = %c%c%c%c\n", (RMint8)(pStreamHdr->fccType >> 0), (RMint8)(pStreamHdr->fccType >> 8), (RMint8)(pStreamHdr->fccType >> 16), (RMint8)(pStreamHdr->fccType >> 24))); DEBUGMSG (0, (" fccHandler = %c%c%c%c\n", (RMint8)(pStreamHdr->fccHandler >> 0), (RMint8)(pStreamHdr->fccHandler >> 8), (RMint8)(pStreamHdr->fccHandler >> 16), (RMint8)(pStreamHdr->fccHandler >> 24))); DEBUGMSG (1, (" Flags = %lu\n", pStreamHdr->Flags)); DEBUGMSG (1, (" InitialFrames = %lu\n", pStreamHdr->InitialFrames)); DEBUGMSG (1, (" Scale = %lu\n", pStreamHdr->Scale)); DEBUGMSG (1, (" Rate = %lu\n", pStreamHdr->Rate)); DEBUGMSG (1, (" Start = %lu\n", pStreamHdr->Start)); DEBUGMSG (1, (" Length = %lu\n", pStreamHdr->Length)); DEBUGMSG (1, (" SuggestedBufferSize = %lu\n", pStreamHdr->SuggestedBufferSize)); DEBUGMSG (1, (" Quality = %lu\n", pStreamHdr->Quality)); DEBUGMSG (1, (" SampleSize = %lu\n", pStreamHdr->SampleSize)); break; // this tells the application video information case AVI_DEMUX_MSG_BITMAPINFO: pBitmapInfo = (AVI_BITMAPINFO *)info; pMpegDecoder->GetScreenDimensions (&w, &h, &n, &d); DEBUGMSG (1, ("screen dimensions: %d x %d, %d:%d\n", w, h, n, d)); if (video_stream_count == 1) { ASSERT (pMpegDecoder); RMint32 x, y; if ((pBitmapInfo->Compression == div3_FOURCC) || (pBitmapInfo->Compression == DIV3_FOURCC) || (pBitmapInfo->Compression == mp43_FOURCC) || (pBitmapInfo->Compression == MP43_FOURCC)) { RMint8 text[64]; sprintf (text, "WARNING:"); pMpegDecoder->RenderText (text, 0xffff00, 32, 40, 320-32, 240-40); sprintf (text, "This file is in MS-MPEG4 format."); pMpegDecoder->RenderText (text, 0xffff00, 32, 70, 320-32, 240-70); sprintf (text, "To improve the rendering of this"); pMpegDecoder->RenderText (text, 0xffff00, 32, 100, 320-32, 240-100); sprintf (text, "file, it should be transcoded first."); pMpegDecoder->RenderText (text, 0xffff00, 32, 130, 320-32, 240-130); sleep (2); pMpegDecoder->RenderText (0, 0, 0, 0, 320, 240); } if ((pBitmapInfo->Width*1000*d/(w*n)) > pBitmapInfo->Height*1000/h) { ASSERT (d); ASSERT (pBitmapInfo->Width); y = (pBitmapInfo->Height * w / pBitmapInfo->Width) * n / d; ASSERT (y <= h); x = (h - y) / 2; ASSERT (x >= 0); ASSERT (w > 0); ASSERT (y > 0); DEBUGMSG (!(x >= 0) || !(w > 0) || !(y > 0) || (1), ("(a) x = %d, y = %d, w = %d, h = %d\n", x, y, w, h)); pMpegDecoder->SetVideoDestination (0, x, w, y); } else { ASSERT (d); ASSERT (pBitmapInfo->Height); y = (pBitmapInfo->Width * h / pBitmapInfo->Height) * d / n; ASSERT (y <= w); x = (w - y) / 2; ASSERT (x >= 0); DEBUGMSG (!(x >= 0) || !(y > 0) || !(h > 0) || (1), ("(b) x = %d, y = %d, w = %d, h = %d\n", x, y, w, h)); ASSERT (y > 0); ASSERT (h > 0); pMpegDecoder->SetVideoDestination (x, 0, y, h); } } DEBUGMSG (1, ("AVI_BITMAPINFO:\n")); DEBUGMSG (1, (" Size = %lu\n", pBitmapInfo->Size)); DEBUGMSG (1, (" Width = %lu\n", pBitmapInfo->Width)); DEBUGMSG (1, (" Height = %lu\n", pBitmapInfo->Height)); DEBUGMSG (1, (" Planes = %lu\n", pBitmapInfo->Planes)); DEBUGMSG (1, (" BitCount = %lu\n", pBitmapInfo->BitCount)); DEBUGMSG (1, (" Compression = %c%c%c%c\n", (RMint8)(pBitmapInfo->Compression >> 0), (RMint8)(pBitmapInfo->Compression >> 8), (RMint8)(pBitmapInfo->Compression >> 16), (RMint8)(pBitmapInfo->Compression >> 24))); DEBUGMSG (1, (" SizeImage = %lu\n", pBitmapInfo->SizeImage)); DEBUGMSG (1, (" XPelsPerMeter = %lu\n", pBitmapInfo->XPelsPerMeter)); DEBUGMSG (1, (" YPelsPerMeter = %lu\n", pBitmapInfo->YPelsPerMeter)); DEBUGMSG (1, (" ClrUsed = %lu\n", pBitmapInfo->ClrUsed)); DEBUGMSG (1, (" ClrImportant = %lu\n", pBitmapInfo->ClrImportant)); currentFOURCC = pBitmapInfo->Compression; currentWidth = pBitmapInfo->Width; currentHeight = pBitmapInfo->Height; // set the decoding standard MPEGVIDEO_PARAMETERS videoparams; if ((currentFOURCC == div3_FOURCC) || (currentFOURCC == DIV3_FOURCC) || (currentFOURCC == mp43_FOURCC) || (currentFOURCC == MP43_FOURCC)) { DEBUGMSG (1, ("MS-MPEG4v3 format\n")); videoparams.isMPEG4 = 2; } else { DEBUGMSG (1, ("ISO-MPEG4 format\n")); videoparams.isMPEG4 = 1; } videoparams.vopTimeIncrRes = currentRate; videoparams.videoTimeScale = currentRate; videoparams.audioTimeScale = currentRate; videoparams.fixedVOPRate = 1; videoparams.vopTimeIncr = currentScale; pMpegDecoder->SetMpegVideoParameters (&videoparams); break; // this tells the application audio information case AVI_DEMUX_MSG_WAVEFORMATEX: pWaveFormatEx = (AVI_WAVEFORMATEX *)info; // select the first mp3 audio track if ((pWaveFormatEx->wFormatTag == 0x55) && (selected_audio_stream[0] == 0xff) && (selected_audio_stream[1] == 0xff)) { // mp3 ASSERT (avi_stream_count > 0); sprintf (selected_audio_stream, "%02d", avi_stream_count - 1); ASSERT (pMP3BufferDecoder == 0); pMP3BufferDecoder = (MP3Decoder *) new MP3Decoder; ASSERT (pMP3BufferDecoder); selected_audio_stream_format = 0x55; MP3_CALLBACK_TABLE callback_table; callback_table.context = 0; // saved context information for application callback_table.fopen = 0; // fopen for file decoding callback_table.fread = 0; // fread for file decoding callback_table.fclose = 0; // fclose for file decoding callback_table.addref = my_addref; // addref a buffer callback_table.release = my_release; // release a buffer callback_table.info = 0; // inform app of some mp3 info callback_table.putPCM = mp3wma_putPCM; // output PCM bytes callback_table.getPCM = mp3wma_getPCM; // get a buffer for PCM data callback_table.getMP3 = 0; // get a buffer for reading MP3 data init_buffer_pool (&BPpcm, pcm_buffer, PCM_BUFFERSIZE, PCM_NBUFFERS); ASSERT (pMP3BufferDecoder); pMP3BufferDecoder->Init (); ASSERT (pMP3BufferDecoder); pMP3BufferDecoder->InitCallbackTable (&callback_table); pMP3BufferDecoder->DecodeBufferStart (); PCM_PARAMETERS pcmparams; pcmparams.NumberOfBitsPerSample = 16; pcmparams.NumberOfChannels = pWaveFormatEx->nChannels; pcmparams.SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; pMpegDecoder->SetPCMParameters (&pcmparams); NumberOfBitsPerSample = pcmparams.NumberOfBitsPerSample; NumberOfChannels = pcmparams.NumberOfChannels; SamplesPerSecond = pcmparams.SamplesPerSecond; BytesPerSecond = (NumberOfBitsPerSample / 8) * NumberOfChannels * SamplesPerSecond; CompressedBytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; tbytes = 0; } else if ((pWaveFormatEx->wFormatTag == 0x2000) && (selected_audio_stream[0] == 0xff) && (selected_audio_stream[1] == 0xff)) { // ac3 ASSERT (avi_stream_count > 0); sprintf (selected_audio_stream, "%02d", avi_stream_count - 1); selected_audio_stream_format = 0x2000; AC3_PARAMETERS ac3params; ac3params.rawOutput = 0; // decode ac3 ac3params.SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; NumberOfBitsPerSample = 16; SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; BytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; CompressedBytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; ASSERT (pMpegDecoder); pMpegDecoder->SetAC3Parameters (&ac3params); tbytes = 0; ac3FrameSize = 0; } else if ((pWaveFormatEx->wFormatTag == 0x1) && (pWaveFormatEx->wBitsPerSample == 16) && (selected_audio_stream[0] == 0xff) && (selected_audio_stream[1] == 0xff)) { // 16 bit pcm ASSERT (avi_stream_count > 0); sprintf (selected_audio_stream, "%02d", avi_stream_count - 1); selected_audio_stream_format = 0x1; PCM_PARAMETERS pcmparams; pcmparams.NumberOfBitsPerSample = 16; pcmparams.NumberOfChannels = pWaveFormatEx->nChannels; pcmparams.SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; pMpegDecoder->SetPCMParameters (&pcmparams); NumberOfBitsPerSample = pcmparams.NumberOfBitsPerSample; NumberOfChannels = pcmparams.NumberOfChannels; SamplesPerSecond = pcmparams.SamplesPerSecond; BytesPerSecond = (NumberOfBitsPerSample / 8) * NumberOfChannels * SamplesPerSecond; CompressedBytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; tbytes = 0; } else if ((pWaveFormatEx->wFormatTag == 0x2001) && (selected_audio_stream[0] == 0xff) && (selected_audio_stream[1] == 0xff)) { // dts ASSERT (avi_stream_count > 0); sprintf (selected_audio_stream, "%02d", avi_stream_count - 1); selected_audio_stream_format = 0x2001; DTS_PARAMETERS dtsparams; dtsparams.rawOutput = 1; // pass though only dtsparams.SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; NumberOfBitsPerSample = 16; SamplesPerSecond = pWaveFormatEx->nSamplesPerSec; BytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; CompressedBytesPerSecond = pWaveFormatEx->nAvgBytesPerSec; ASSERT (pMpegDecoder); pMpegDecoder->SetDTSParameters (&dtsparams); tbytes = 0; dtsFrameSize = 0; } DEBUGMSG (1, ("AVI_WAVEFORMATEX:\n")); DEBUGMSG (1, (" wFormatTag = %lu\n", pWaveFormatEx->wFormatTag)); DEBUGMSG (1, (" nChannels = %lu\n", pWaveFormatEx->nChannels)); DEBUGMSG (1, (" nSamplesPerSec = %lu\n", pWaveFormatEx->nSamplesPerSec)); DEBUGMSG (1, (" nAvgBytesPerSec = %lu\n", pWaveFormatEx->nAvgBytesPerSec)); DEBUGMSG (1, (" nBlockAlign = %lu\n", pWaveFormatEx->nBlockAlign)); DEBUGMSG (1, (" wBitsPerSample = %lu\n", pWaveFormatEx->wBitsPerSample)); DEBUGMSG (1, ("GLOBAL SETTINGS:\n")); DEBUGMSG (1, (" NumberOfBitsPerSample = %lu\n", NumberOfBitsPerSample)); DEBUGMSG (1, (" NumberOfChannels = %lu\n", NumberOfChannels)); DEBUGMSG (1, (" SamplesPerSecond = %lu\n", SamplesPerSecond)); DEBUGMSG (1, (" BytesPerSecond = %lu\n", BytesPerSecond)); DEBUGMSG (1, (" CompressedBytesPerSecond = %lu\n", CompressedBytesPerSecond)); break; // this tells the app what the current frame position is // when the demux is in KeyFrameOnly mode case AVI_DEMUX_KEYFRAME_POSITION: KeyFramesPosition = (RMuint32)info; DEBUGMSG (1, ("KEY FRAME %lu\n", KeyFramesPosition)); break; default: ASSERT (0); break; } return 0;}static RMuint32 avi_getAVI (RMuint8 **pBuffer, RMuint32 *plength, void *context){ DEBUGMSG (0, ("avi_getAVI\n")); saved_input = getinput (); if (saved_input) return 1; int idx = find_free_buffer (&BPavi, 0); if (idx < 0) { return 1; } *plength = (RMuint32)BPavi.buffers_size; *pBuffer = (RMuint8 *)get_buffer_address (&BPavi, idx); return 0;}static RMuint32 avi_putChunk (RMuint8 *chunkid, RMuint8 *buffer, RMuint32 buflen, RMuint32 flags, void *context){ MPEG_DECODER_ERROR mpegerr; DEBUGMSG (0, ("avi_putChunk (%c%c%c%c, 0x%08lx, %lu, 0x%08lx)\n", chunkid[0], chunkid[1], chunkid[2], chunkid[3], buffer, buflen, flags)); if ((buffer == 0) || (buflen == 0)) { if ((chunkid[2] == 'd') && ((chunkid[3] == 'c') || (chunkid[3] == 'b'))) { if (flags & AVI_FLAG_CHUNK_START) { aviFrameCounter++; DEBUGMSG (0, ("(1) aviFrameCounter: %lu\n", aviFrameCounter)); } } return 0; } if ((chunkid[2] == 'd') && ((chunkid[3] == 'c') || (chunkid[3] == 'b'))) { // video chunk if (msmpeg4v3) { #if 1 // filter ms-mpeg4v3 data // required for _some_ ms-mpeg4v3 streams because of encoding errors // and the decoder can not recover from these errors RMint32 f_todo; RMuint32 mp43flag = 0; if (flags & AVI_FLAG_CHUNK_START) mp43flag |= FLAG_BEGIN_CHUNK; if (flags & AVI_FLAG_CHUNK_END) mp43flag |= FLAG_END_CHUNK; f_todo = MP43_filter_processing (&MP43Scanner, mp43flag, buffer, buflen); if (f_todo == FILTER_DUMP) { DEBUGMSG (1, ("FILTER_DUMP (%d)\n", (RMint32)aviFrameCounter)); if (flags & AVI_FLAG_CHUNK_START) aviFrameCounter++; return 0; } if (f_todo == FILTER_PEND) { DEBUGMSG (0, ("FILTER_PEND (%d)\n", (RMint32)aviFrameCounter)); mp43scan_status += buflen; return 0; } ASSERT (f_todo == FILTER_SEND); if (mp43scan_status) { mp43scan_status += buflen; DEBUGMSG (0, ("** FILTER_SEND (%d, %d)\n", (RMint32)aviFrameCounter, (RMint32)mp43scan_status)); ASSERT (mp43scan_status < 128*1024); if (mp43scan_status < 128*1024) { // send picture header videoTime = aviStartupDelay + ((RMint64)aviFrameCounter * (RMint64)aviTicksPerFrame); DEBUGMSG (0, ("WriteMpegVideo (time = %d)\n", (RMint32)videoTime)); mpegerr = pMpegDecoder->WriteMpegVideo (pic_startcode, 4, 0, CTS_AVAILABLE_FLAG, aviTime0, videoTime); ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR); // send picture data RMint32 idx; do { idx = find_free_buffer (&BPscan, 0); } while (idx < 0); RMuint32 buflen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -