📄 main.cpp
字号:
} if (fout) { fwrite (pBuffer, 1, length, fout); return 0; } BufferPool *BP; BP = &BPmp4; int idx = ((int)pBuffer - (int)BP->start_address) / BP->buffers_size; ASSERT (idx >= 0); RMuint32 buflen; while (length) { addref_buffer (&(BP->B[idx])); buflen = MY_MIN (0xffff, length); if (flags & CHUNK_FLAGS_TIME_VALID) { DEBUGMSG (0, ("video cts = %d\n", (RMint32)time)); mpegerr = pMpegDecoder->WriteMpegVideo (pBuffer, buflen, &(BP->B[idx]), CTS_AVAILABLE_FLAG, mp4_scr0, mp4_scr0 + mp4_scrDelay + time); } else mpegerr = pMpegDecoder->WriteMpegVideo (pBuffer, buflen, &(BP->B[idx]), 0, 0, 0); ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR); if (mpegerr != MPEG_DECODER_ERROR_NO_ERROR) { ASSERT (0); release_buffer (&(BP->B[idx])); return 0; } flags = 0; pBuffer += buflen; length -= buflen; ASSERT ((RMint32)length >= 0); } } else if (trackid == 1) { if (flags & CHUNK_FLAGS_TIME_VALID) { time = time * vopTimeIncrRes / audioTimeScale; aacframe_valid = 0; } if (resync_aacstream) { if ((flags & CHUNK_FLAGS_TIME_VALID) == 0) return 0; resync_aacstream = 0; }#ifdef KERNEL_MODULE_SUPPORTS_AAC#ifdef REFORMAT_AAC_TO_ADTS // reformat then send to decoder (hardware decoding) RMuint8 *adts; aaclen = (RMint32)length; ASSERT (aaclen < sizeof (databuffer)); while (aaclen > 0) { ASSERT (aaclen > 0); MPEG_DECODER_ERROR status; BufferPool *BP; BP = &BPadts; int idx; do { idx = find_free_buffer (BP, 0); if ((idx < 0) && PreBuffering) { pMpegDecoder->Play (); PreBuffering = 0; DEBUGMSG (1, ("play due to adts buffer full\n")); } } while (idx < 0); adts = (RMuint8 *)get_buffer_address (&BPadts, idx); RMuint32 hdrlength; hdrlength = 0; if (flags & CHUNK_FLAGS_SAMPLE_START) { memcpy (adts, aacframe, adtshdrlength); hdrlength = adtshdrlength; } n = MP4_MIN (aaclen, (ADTSBUFFERSIZE - hdrlength)); memcpy (adts + hdrlength, pBuffer, n); addref_buffer (&(BP->B[idx])); if (flags & CHUNK_FLAGS_TIME_VALID) { DEBUGMSG (0, ("[frame] WriteAAC (%08lx, %d, %d)\n", (RMuint32)adts, (int)(n + hdrlength), (int)((mp4_scr0 + mp4_scrDelay + time) * 1000 / vopTimeIncrRes))); status = pMpegDecoder->WriteAAC (adts, n + hdrlength, &(BP->B[idx]), CTS_AVAILABLE_FLAG, mp4_scr0, mp4_scr0 + mp4_scrDelay + time); } else { DEBUGMSG (0, ("[frame] WriteAAC (%08lx, %d)\n", (RMuint32)adts, (int)(n + hdrlength))); status = pMpegDecoder->WriteAAC (adts, n + hdrlength, &(BP->B[idx]), 0, 0, 0); } ASSERT (status == MPEG_DECODER_ERROR_NO_ERROR); if (status != MPEG_DECODER_ERROR_NO_ERROR) { release_buffer (&(BP->B[idx])); } pBuffer += n; aaclen -= n; flags = 0; ASSERT (aaclen >= 0); } return 0;#else // send directly to kernel module (hardware decoding) MPEG_DECODER_ERROR status; BufferPool *BP; BP = &BPmp4; int idx = ((int)pBuffer - (int)BP->start_address) / BP->buffers_size; ASSERT (idx >= 0); RMuint32 len; while (length) { len = MP4_MIN (length, 0x2000); addref_buffer (&(BP->B[idx])); if (flags & CHUNK_FLAGS_TIME_VALID) { // send an audio cts once every 30 times (~1 every second) if ((cts_counter++ % 30) == 0) { DEBUGMSG (0, ("[frame] WriteAAC (%08lx, %d, %d)\n", (RMuint32)pBuffer, (int)len, (int)((mp4_scr0 + mp4_scrDelay + time) * 1000 / vopTimeIncrRes))); status = pMpegDecoder->WriteAAC (pBuffer, len, &(BP->B[idx]), CTS_AVAILABLE_FLAG, mp4_scr0, mp4_scr0 + mp4_scrDelay + time); } else { DEBUGMSG (0, ("[frame] WriteAAC (%08lx, %d)\n", (RMuint32)pBuffer, (int)len)); status = pMpegDecoder->WriteAAC (pBuffer, len, &(BP->B[idx]), 0, 0, 0); } } else { DEBUGMSG (0, ("[frame] WriteAAC (%08lx, %d)\n", (RMuint32)pBuffer, (int)len)); status = pMpegDecoder->WriteAAC (pBuffer, len, &(BP->B[idx]), 0, 0, 0); } ASSERT (status == MPEG_DECODER_ERROR_NO_ERROR); if (status != MPEG_DECODER_ERROR_NO_ERROR) { release_buffer (&(BP->B[idx])); } flags = 0; length -= len; pBuffer += len; }#endif return 0;#endif // decode then send as PCM data RMint32 t0, t1, acount; RMint16 *pcm; aaclen = (RMint32)length; ASSERT (aaclen < sizeof (databuffer)); acount = 0; t0 = gettime_ms (); while (aaclen > 0) { if (aacframe_valid) { ASSERT (aaclen <= sizeof (aacframe)); RMint32 templen = MP4_MIN (aaclen, sizeof (aacframe) - aacframe_valid); memcpy (aacframe+aacframe_valid, pBuffer, templen); int idx; do { idx = find_free_buffer (&BPpcm, 0); if ((idx < 0) && PreBuffering) { pMpegDecoder->Play (); PreBuffering = 0; DEBUGMSG (1, ("play due to pcm buffer full\n")); } } while (idx < 0); pcm = (RMint16 *)get_buffer_address (&BPpcm, idx); DEBUGMSG (0, ("(0) aacdecode: %08lx, %d\n", (RMuint32)aacframe, (int)aacframe_valid+templen)); n = pAACDecoder->DecodeFrame (aacframe, aacframe_valid+aaclen, pcm, 4096); if (n > 0) { if (fpcm) fwrite (pcm, 1, 2048*2, fpcm); MPEG_DECODER_ERROR err; addref_buffer (&(BPpcm.B[idx])); err = pMpegDecoder->WritePCM ((RMuint8 *)pcm, 4096, &(BPpcm.B[idx]), 0, 0, 0); ASSERT (err == MPEG_DECODER_ERROR_NO_ERROR); } else { // error: dump buffer //ASSERT (0); resync_aacstream = 1; aacframe_valid = 0; return 0; } ASSERT (n > 0); ASSERT (n/8 <= (RMint32)(aacframe_valid+aaclen)); ASSERT ((n/8 - aacframe_valid) >= 0); pBuffer += (n/8 - aacframe_valid); aaclen -= (n/8 - aacframe_valid); aacframe_valid = 0; ASSERT (aaclen < sizeof (databuffer)); } ASSERT (aaclen < sizeof (databuffer)); if (aaclen) { ASSERT (aaclen > 0); int idx; do { idx = find_free_buffer (&BPpcm, 0); if ((idx < 0) && PreBuffering) { pMpegDecoder->Play (); PreBuffering = 0; DEBUGMSG (1, ("play due to pcm buffer full\n")); } } while (idx < 0); pcm = (RMint16 *)get_buffer_address (&BPpcm, idx); DEBUGMSG (0, ("(1) aacdecode: %08lx, %d\n", (RMuint32)pBuffer, (int)aaclen)); n = pAACDecoder->DecodeFrame (pBuffer, aaclen, pcm, 4096); if (n > 0) { if (fpcm) fwrite (pcm, 1, 2048*2, fpcm); MPEG_DECODER_ERROR err; addref_buffer (&(BPpcm.B[idx])); if (flags & CHUNK_FLAGS_TIME_VALID) { DEBUGMSG (0, ("audio cts = %d\n", (RMint32)time)); err = pMpegDecoder->WritePCM ((RMuint8 *)pcm, 4096, &(BPpcm.B[idx]), CTS_AVAILABLE_FLAG, mp4_scr0, mp4_scr0 + mp4_scrDelay + time); } else err = pMpegDecoder->WritePCM ((RMuint8 *)pcm, 4096, &(BPpcm.B[idx]), 0, 0, 0); flags = 0; ASSERT (err == MPEG_DECODER_ERROR_NO_ERROR); } if (n < 0) { DEBUGMSG (0, ("aacdec save %d bytes\n", (int)aaclen)); memcpy (aacframe, pBuffer, aaclen); aacframe_valid = aaclen; break; } pBuffer += (n/8); aaclen -= (n/8); ASSERT (aaclen >= 0); ASSERT (aaclen < sizeof (databuffer)); } acount++; } t1 = gettime_ms (); DEBUGMSG (0, ("%d frames, %d ms\n", acount, t1-t0)); aacframe_count += acount; aacdecode_time += (t1-t0); } return 0;}int main (int argc, char *argv[]){ if (argc < 2) { printf ("usage: mp4play <filename>\n"); return 0; }#ifdef USE_FATFS fs_fat_mount ();#endif dac_init (); init_buffer_pool (&BPmp4, (long unsigned int *)databuffer, BUFFERSIZE, NBUFFERS); init_buffer_pool (&BPpcm, (long unsigned int *)pcmbuffer, PCMBUFFERSIZE, PCMNBUFFERS); init_buffer_pool (&BPadts, (long unsigned int *)adtsbuffer, ADTSBUFFERSIZE, ADTSNBUFFERS); pMpegDecoder = (MpegDecoder *) new MpegDecoder; ASSERT (pMpegDecoder); pMpegDecoder->Init (); pMpegDecoder->SetupDisplay (1); // ntsc MP4Demux *pMP4Demux = (MP4Demux *)new MP4Demux; pAACDecoder = (AACDecoder *)new AACDecoder; ASSERT (pAACDecoder); pAACDecoder->Init (); MP4_CALLBACK_TABLE CallbackTable; CallbackTable.addref = my_addref; CallbackTable.context = 0; CallbackTable.fclose = my_fclose; CallbackTable.fopen = my_fopen; CallbackTable.fread = my_fread; CallbackTable.fseek = my_fseek; CallbackTable.ftell = my_ftell; CallbackTable.info = mp4_info; CallbackTable.getData = mp4_getData; CallbackTable.putDSI = mp4_putDSI; CallbackTable.putChunk = mp4_putChunk; CallbackTable.release = my_release; pMP4Demux->Init (); pMP4Demux->InitCallbackTable (&CallbackTable);// if (argc > 3)// fout = fopen (argv[2], "wb");// fpcm = fopen ("/hd/mp4.pcm", "wb"); RMuint32 t0, t1; adtshdrlength = 0; resync_aacstream = 1; if (pMP4Demux->Demux (argv[1]) == MP4_ERROR_NO_ERROR) { t0 = 0; while (pMP4Demux->Schedule () != MP4_ERROR_END_OF_FILE) { t1 = gettime_ms (); if ((t1 - t0) > 1000) { RMint64 stc; pMpegDecoder->GetSTC (&stc, 1000); DEBUGMSG (1, ("stc = %d ms\n", (RMint32)stc)); t0 = gettime_ms (); } } int i; for (i=0; i<10; i++) { RMint64 stc; pMpegDecoder->GetSTC (&stc, 1000); DEBUGMSG (1, ("stc = %d ms\n", (RMint32)stc)); sleep (1); } } else { DEBUGMSG (1, ("not a valid .mp4 file\n")); } delete pMP4Demux; pMpegDecoder->Stop (); pMpegDecoder->Exit (); delete pMpegDecoder; delete pAACDecoder; deinit_buffer_pool (&BPmp4); deinit_buffer_pool (&BPpcm); deinit_buffer_pool (&BPadts); if (fout) fclose (fout); if (fpcm) fclose (fpcm); DEBUGMSG (1, ("%d frames decoded in %d ms\n", aacframe_count, aacdecode_time)); DEBUGMSG (1, ("%d ms/frame\n", aacdecode_time/aacframe_count));#ifdef USE_FATFS fs_fat_unmount ();#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -