char* play() { Alert("vplay\n"); delay=1000000000/ot->dmx->fps; next=sceKernelGetSystemTimeWide(); for(u32 s=0; (s<ot->dmx->Vlen); s++) { if(ot->sys->pad&PSP_CTRL_CIRCLE)break; ot->me->nal.nal=ot->dmx->getVSample(s,&ot->me->nal.nalLen); ot->me->nal.mode=s?0:3; sceMpegGetAvcNalAu(Mpeg,&ot->me->nal,ot->me->mpegAu); if(sceMpegAvcDecode(Mpeg,ot->me->mpegAu,ot->lcd->size,0,&ot->me->pics)<0) { blitErr(); //("VdecErr"); continue; } sceMpegAvcDecodeDetail2(Mpeg,&ot->me->d);// ot->me->d = *Mpeg[414]<7?*Mpeg[424]+0x2C:*Mpeg[419]; SceMpegAvcMode mode= {-1,ot->lcd->type}; sceMpegAvcDecodeMode(&ot->me->mpeg,&mode); for(int i=0; i<ot->me->pics; i++) { Mp4AvcYuvStruct*yuv=ot->me->d->yuv+i; Mp4AvcCscStruct csc= {(ot->me->d->info->height+15)>>4,(ot->me->d->info->width+15)>>4,0,0,yuv->b0,yuv->b1,yuv->b2,yuv->b3,yuv->b4,yuv->b5,yuv->b6,yuv->b7}; sceMpegBaseCscAvc(swapBuffer(),0,ot->lcd->size, &csc); if(ot->gui)Draw(2);//draw some overlay stuff } } return NULL; } char* seek(int t,int o) { Alert("vseek\n"); return NULL; }
void testDecodeVideo() { checkpointNext("testDecodeVideo:"); const int PACKETS_PER_RUN = 24; const int MAX_FRAMES = 180; void *vbuffer = memalign(64, 512 * 272 * 4); void *abuffer; SceInt32 atracParamNotTestedYet = 1; SceInt32 avcParamNotSureYet = 6; // TODO: Possible a struct? Or wrong? SceInt32 decodeParamNotSureYet = 512; int j; for (j = 0; j < MAX_FRAMES; ++j) { checkpointNext("Next frame"); int freePackets = sceMpegRingbufferAvailableSize((SceMpegRingbuffer *) &g_ringbuffer); checkpoint(" sceMpegRingbufferAvailableSize: %d", freePackets); int result = sceMpegRingbufferPut((SceMpegRingbuffer *) &g_ringbuffer, PACKETS_PER_RUN, freePackets); checkpoint(" sceMpegRingbufferPut: %08x", result); freePackets = sceMpegRingbufferAvailableSize((SceMpegRingbuffer *) &g_ringbuffer); checkpoint(" sceMpegRingbufferAvailableSize: %d", freePackets); result = sceMpegGetAtracAu(&g_mpeg, g_atrac_stream, &g_atrac_au, &abuffer); checkpoint(" sceMpegGetAtracAu: %08x (at %08x from %08x)", result, abuffer, g_atracData); schedfAu(&g_atrac_au); result = sceMpegAtracDecode(&g_mpeg, &g_atrac_au, abuffer, atracParamNotTestedYet); checkpoint(" sceMpegAtracDecode: %08x", result); schedfAu(&g_atrac_au); result = sceMpegGetAvcAu(&g_mpeg, g_avc_stream, &g_avc_au, &avcParamNotSureYet); checkpoint(" sceMpegGetAvcAu: %08x (%08x)", result, avcParamNotSureYet); schedfAu(&g_avc_au); SceInt32 *decodeParamNotSureYetp = &decodeParamNotSureYet; result = sceMpegAvcDecode(&g_mpeg, &g_avc_au, 512, &vbuffer, (SceInt32 *) &decodeParamNotSureYetp); checkpoint(" sceMpegAvcDecode: %08x (%08x, %08x)", result, decodeParamNotSureYet, decodeParamNotSureYetp); schedfAu(&g_avc_au); checkpoint(" *** Frame: %d ***", j); } checkpoint(" sceMpegAvcDecodeFlush: %08x", sceMpegAvcDecodeFlush(&g_mpeg)); free(vbuffer); }
int LPP_Mp4Play(LPP_Mp4 *vd, unsigned int frame_count) { if(frame_count > vd->reader.file.number_of_video_frames) return -1; Mp4AvcDecoderStruct *avc = vd->avc; vd->nal.sps_buffer = avc->mpeg_sps_pps_buffer; vd->nal.sps_size = avc->mpeg_sps_size; vd->nal.pps_buffer = avc->mpeg_sps_pps_buffer+avc->mpeg_sps_size; vd->nal.pps_size = avc->mpeg_pps_size; vd->nal.nal_prefix_size = avc->mpeg_nal_prefix_size; if (mp4_read_get_video(&(vd->reader), frame_count, &(vd->v_packet))) { return (-1); } vd->nal.nal_buffer = vd->v_packet.video_buffer; vd->nal.nal_size = vd->v_packet.video_length; frame_count ? (vd->nal.mode=0) : (vd->nal.mode=3); sceMpegGetAvcNalAu(&avc->mpeg, &vd->nal, avc->mpeg_au); sceMpegAvcDecode(&avc->mpeg, avc->mpeg_au, 512, 0, &avc->mpeg_pic_num); sceMpegAvcDecodeDetail2(&avc->mpeg, &avc->mpeg_detail2); if (avc->mpeg_pic_num > 0) { int i; for(i = 0; i < avc->mpeg_pic_num; i++) { Mp4AvcCscStruct csc; csc.height = (avc->mpeg_detail2->info_buffer->height+15) >> 4; csc.width = (avc->mpeg_detail2->info_buffer->width+15) >> 4; csc.mode0 = 0; csc.mode1 = 0; csc.buffer0 = avc->mpeg_detail2->yuv_buffer->buffer0; csc.buffer1 = avc->mpeg_detail2->yuv_buffer->buffer1; csc.buffer2 = avc->mpeg_detail2->yuv_buffer->buffer2; csc.buffer3 = avc->mpeg_detail2->yuv_buffer->buffer3; csc.buffer4 = avc->mpeg_detail2->yuv_buffer->buffer4; csc.buffer5 = avc->mpeg_detail2->yuv_buffer->buffer5; csc.buffer6 = avc->mpeg_detail2->yuv_buffer->buffer6; csc.buffer7 = avc->mpeg_detail2->yuv_buffer->buffer7; if(!sceMpegBaseCscAvc(LPPG_GetFrameBuffer(),0,(avc->mpeg_mode == 4) ? 512 : 768, &csc)); } }
int T_Decoder(SceSize _args, void *_argp) { int retVal; int oldButtons = 0; SceCtrlData pad; #if DEBUG_TIMING int start, end; char s[200]; #endif int iInitAudio = 1; SceInt32 iVideoStatus = 0; int videoFrameCount = 0; int audioFrameCount = 0; SceInt32 unknown = 0; int iThreadsRunning = 0; SceInt32 m_iAudioCurrentTimeStamp = 0; SceInt32 m_iVideoCurrentTimeStamp = 0; SceInt32 m_iVideoLastTimeStamp = 0; DecoderThreadData* D = *((DecoderThreadData**)_argp); SceUInt32 m_iLastPacketsWritten = D->Reader->m_Ringbuffer->iUnk1; SceInt32 m_iLastPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer); D->Connector->initConnector(); for(;;) { sceKernelDelayThread(1); scePowerTick(0); sceCtrlReadBufferPositive(&pad, 1); int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons; if (buttonDown & PSP_CTRL_CIRCLE) { break; } if( iThreadsRunning == 0 && IsRingbufferFull(D->Reader) && D->Video->m_iNumBuffers == D->Video->m_iFullBuffers) { iThreadsRunning = 1; sceKernelSignalSema(D->Video->m_SemaphoreStart, 1); sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1); } if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) { break; } else if(D->Reader->m_Status == ReaderThreadData::READER_EOF) { retVal = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer); if(retVal == D->Reader->m_RingbufferPackets) break; } if(!IsRingbufferFull(D->Reader)) { sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0); if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) break; } if (DEBUG_USERDATA) { SceInt32 unknown2[2]; SceUInt32 i; unknown2[0] = 0x12345678; unknown2[1] = 0xABCDEF98; retVal = sceMpegGetUserdataAu(&D->m_Mpeg, D->m_MpegStreamUserdata, D->m_MpegAuUserdata, unknown2); u8 *esBuffer = (u8 *) D->m_MpegAuUserdata->iEsBuffer; SceUInt32 esSize = D->m_MpegAuUserdata->iAuSize; sprintf(s, "sceMpegGetUserdataAu result 0x%08X", retVal); debug(s); if (retVal == 0) { sprintf(s, "sceMpegGetUserdataAu unknown[0]=0x%08X, unknown[1]=0x%08X, esBuffer=0x%08X, esSize=0x%X", unknown2[0], unknown2[1], D->m_MpegAuUserdata->iEsBuffer, esSize); debug(s); debug(D->m_MpegAuUserdata); for (i = 0; i < esSize; i += 8) { sprintf(s, "0x%08X: %02X %02X %02X %02X %02X %02X %02X %02X", D->m_MpegAuUserdata->iEsBuffer + i, esBuffer[i], esBuffer[i+1], esBuffer[i+2], esBuffer[i+3], esBuffer[i+4], esBuffer[i+5], esBuffer[i+6], esBuffer[i+7]); debug(s); } } } if(D->Audio->m_iFullBuffers < D->Audio->m_iNumBuffers) { #if DEBUG_TIMING start = sceKernelGetSystemTimeLow(); #endif retVal = sceMpegGetAtracAu(&D->m_Mpeg, D->m_MpegStreamAtrac, D->m_MpegAuAtrac, &unknown); #if DEBUG_TIMING end = sceKernelGetSystemTimeLow(); sprintf(s, "Duration sceMpegGetAtracAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAtrac->iPts, m_iAudioCurrentTimeStamp + D->m_iAudioFrameDuration, D->m_MpegAuAtrac->iDts); debug(s); debug(D->m_MpegAuAtrac); debug(D->Reader->m_Ringbuffer); #endif if(retVal != 0) { if(!IsRingbufferFull(D->Reader)) { sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0); if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) break; } } else { if(m_iAudioCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration) break; #if DEBUG_TIMING start = sceKernelGetSystemTimeLow(); #endif retVal = sceMpegAtracDecode(&D->m_Mpeg, D->m_MpegAuAtrac, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], iInitAudio); #if DEBUG_TIMING end = sceKernelGetSystemTimeLow(); sprintf(s, "Duration sceMpegAtracDecode %d, return %X", end - start, retVal); debug(s); debug(D->Reader->m_Ringbuffer); #endif if(retVal != 0) { sprintf(D->m_LastError, "sceMpegAtracDecode() failed: 0x%08X", retVal); break; } if(D->m_MpegAuAtrac->iPts == 0xFFFFFFFF) m_iAudioCurrentTimeStamp += D->m_iAudioFrameDuration; else m_iAudioCurrentTimeStamp = D->m_MpegAuAtrac->iPts; if(m_iAudioCurrentTimeStamp <= 0x15F90 /* video start ts */ - D->m_iAudioFrameDuration) iInitAudio = 1; D->Audio->m_iBufferTimeStamp[D->Audio->m_iDecodeBuffer] = m_iAudioCurrentTimeStamp; if(iInitAudio == 0) { D->Connector->sendAudioFrame(audioFrameCount, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], D->m_MpegAtracOutSize, m_iAudioCurrentTimeStamp); audioFrameCount++; sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0); D->Audio->m_iFullBuffers++; sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1); D->Audio->m_iDecodeBuffer = (D->Audio->m_iDecodeBuffer + 1) % D->Audio->m_iNumBuffers; } iInitAudio = 0; } } if(!IsRingbufferFull(D->Reader)) { sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0); if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) break; } if(D->Video->m_iFullBuffers < D->Video->m_iNumBuffers) { #if DEBUG_TIMING start = sceKernelGetSystemTimeLow(); #endif retVal = sceMpegGetAvcAu(&D->m_Mpeg, D->m_MpegStreamAVC, D->m_MpegAuAVC, &unknown); #if DEBUG_TIMING end = sceKernelGetSystemTimeLow(); sprintf(s, "Duration sceMpegGetAvcAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAVC->iPts, m_iVideoCurrentTimeStamp + 3004, D->m_MpegAuAVC->iDts); debug(s); debug(D->m_MpegAuAVC); debug(D->Reader->m_Ringbuffer); #endif if((SceUInt32)retVal == 0x80618001) { if(!IsRingbufferFull(D->Reader)) { sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0); if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) break; } } else if(retVal != 0) { sprintf(D->m_LastError, "sceMpegGetAvcAu() failed: 0x%08X", retVal); break; } else { if(m_iVideoCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration) break; #if DEBUG_TIMING start = sceKernelGetSystemTimeLow(); #endif retVal = sceMpegAvcDecode(&D->m_Mpeg, D->m_MpegAuAVC, BUFFER_WIDTH, &D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], &iVideoStatus); #if DEBUG_TIMING end = sceKernelGetSystemTimeLow(); sprintf(s, "Duration sceMpegAvcDecode %d, return %X", end - start, retVal); debug(s); debug(D->Reader->m_Ringbuffer); #endif if(retVal != 0) { sprintf(D->m_LastError, "sceMpegAvcDecode() failed: 0x%08X", retVal); break; } if(D->m_MpegAuAVC->iPts == 0xFFFFFFFF) m_iVideoCurrentTimeStamp += 0x0BBC; else m_iVideoCurrentTimeStamp = D->m_MpegAuAVC->iPts; if(iVideoStatus == 1) { SceUInt32 m_iPacketsWritten = D->Reader->m_Ringbuffer->iUnk1; SceInt32 m_iPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer); SceInt32 m_iDeltaPacketsWritten = m_iPacketsWritten - m_iLastPacketsWritten; if (m_iDeltaPacketsWritten < 0) { m_iDeltaPacketsWritten += D->Reader->m_Ringbuffer->iPackets; } SceInt32 m_iDeltaPacketsAvailable = m_iPacketsAvailable - m_iLastPacketsAvailable; SceInt32 m_iConsumedPackets = m_iDeltaPacketsAvailable + m_iDeltaPacketsWritten; m_iLastPacketsWritten = m_iPacketsWritten; m_iLastPacketsAvailable = m_iPacketsAvailable; D->Connector->sendVideoFrame(videoFrameCount, D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], m_iVideoCurrentTimeStamp, D->Reader, m_iConsumedPackets); videoFrameCount++; D->Video->m_iBufferTimeStamp[D->Video->m_iPlayBuffer] = m_iVideoLastTimeStamp; sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0); D->Video->m_iFullBuffers++; sceKernelSignalSema(D->Video->m_SemaphoreLock, 1); } m_iVideoLastTimeStamp = m_iVideoCurrentTimeStamp; } } if(!IsRingbufferFull(D->Reader)) { sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0); if(D->Reader->m_Status == ReaderThreadData::READER_ABORT) break; } } D->Connector->exitConnector(); sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1); sceKernelSignalSema(D->Video->m_SemaphoreStart, 1); D->Reader->m_Status = ReaderThreadData::READER_ABORT; D->Audio->m_iAbort = 1; while(D->Video->m_iFullBuffers > 0) { sceKernelWaitSema(D->Video->m_SemaphoreWait, 1, 0); sceKernelSignalSema(D->Video->m_SemaphoreLock, 1); } sceMpegAvcDecodeStop(&D->m_Mpeg, BUFFER_WIDTH, D->Video->m_pVideoBuffer, &iVideoStatus); if(iVideoStatus > 0) { sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0); D->Video->m_iFullBuffers++; sceKernelSignalSema(D->Video->m_SemaphoreLock, 1); } D->Video->m_iAbort = 1; sceMpegFlushAllStream(&D->m_Mpeg); sceKernelExitThread(0); return 0; }