void AnalyzeMpeg(u32 buffer_addr, MpegContext *ctx) { ctx->mpegStreamAddr = buffer_addr; ctx->mpegMagic = Memory::Read_U32(buffer_addr); ctx->mpegRawVersion = Memory::Read_U32(buffer_addr + PSMF_STREAM_VERSION_OFFSET); switch (ctx->mpegRawVersion) { case PSMF_VERSION_0012: ctx->mpegVersion = MPEG_VERSION_0012; break; case PSMF_VERSION_0013: ctx->mpegVersion = MPEG_VERSION_0013; break; case PSMF_VERSION_0014: ctx->mpegVersion = MPEG_VERSION_0014; break; case PSMF_VERSION_0015: ctx->mpegVersion = MPEG_VERSION_0015; break; default: ctx->mpegVersion = -1; break; } ctx->mpegOffset = bswap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_OFFSET_OFFSET)); ctx->mpegStreamSize = bswap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_SIZE_OFFSET)); ctx->mpegFirstTimestamp = getMpegTimeStamp(Memory::GetPointer(buffer_addr + PSMF_FIRST_TIMESTAMP_OFFSET)); ctx->mpegLastTimestamp = getMpegTimeStamp(Memory::GetPointer(buffer_addr + PSMF_LAST_TIMESTAMP_OFFSET)); ctx->mpegFirstDate = convertTimestampToDate(ctx->mpegFirstTimestamp); ctx->mpegLastDate = convertTimestampToDate(ctx->mpegLastTimestamp); ctx->avc.avcDetailFrameWidth = (Memory::Read_U8(buffer_addr + 142) * 0x10); ctx->avc.avcDetailFrameHeight = (Memory::Read_U8(buffer_addr + 143) * 0x10); ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS; ctx->avc.avcFrameStatus = 0; ctx->videoFrameCount = 0; ctx->audioFrameCount = 0; ctx->endOfAudioReached = false; ctx->endOfVideoReached = false; if (ctx->mpegMagic != PSMF_MAGIC || ctx->mpegVersion < 0 || (ctx->mpegOffset & 2047) != 0 || ctx->mpegOffset == 0) { // mpeg header is invalid! return; } if (ctx->mediaengine && (ctx->mpegStreamSize > 0) && !ctx->isAnalyzed) { // init mediaEngine ctx->mediaengine->loadStream(Memory::GetPointer(buffer_addr), ctx->mpegOffset, ctx->mpegOffset + ctx->mpegStreamSize); ctx->mediaengine->setVideoDim(); } // When used with scePsmf, some applications attempt to use sceMpegQueryStreamOffset // and sceMpegQueryStreamSize, which forces a packet overwrite in the Media Engine and in // the MPEG ringbuffer. // Mark the current MPEG as analyzed to filter this, and restore it at sceMpegFinish. ctx->isAnalyzed = true; INFO_LOG(ME, "Stream offset: %d, Stream size: 0x%X", ctx->mpegOffset, ctx->mpegStreamSize); INFO_LOG(ME, "First timestamp: %lld, Last timestamp: %lld", ctx->mpegFirstTimestamp, ctx->mpegLastTimestamp); }
void AnalyzeMpeg(u8 *buffer, MpegContext *ctx) { ctx->mpegMagic = *(u32_le*)buffer; ctx->mpegRawVersion = *(u32_le*)(buffer + PSMF_STREAM_VERSION_OFFSET); switch (ctx->mpegRawVersion) { case PSMF_VERSION_0012: ctx->mpegVersion = MPEG_VERSION_0012; break; case PSMF_VERSION_0013: ctx->mpegVersion = MPEG_VERSION_0013; break; case PSMF_VERSION_0014: ctx->mpegVersion = MPEG_VERSION_0014; break; case PSMF_VERSION_0015: ctx->mpegVersion = MPEG_VERSION_0015; break; default: ctx->mpegVersion = -1; break; } ctx->mpegOffset = bswap32(*(u32_le*)(buffer + PSMF_STREAM_OFFSET_OFFSET)); ctx->mpegStreamSize = bswap32(*(u32_le*)(buffer + PSMF_STREAM_SIZE_OFFSET)); ctx->mpegFirstTimestamp = getMpegTimeStamp(buffer + PSMF_FIRST_TIMESTAMP_OFFSET); ctx->mpegLastTimestamp = getMpegTimeStamp(buffer + PSMF_LAST_TIMESTAMP_OFFSET); ctx->mpegFirstDate = convertTimestampToDate(ctx->mpegFirstTimestamp); ctx->mpegLastDate = convertTimestampToDate(ctx->mpegLastTimestamp); ctx->avc.avcDetailFrameWidth = (*(u8*)(buffer + 142)) * 0x10; ctx->avc.avcDetailFrameHeight = (*(u8*)(buffer + 143)) * 0x10; ctx->avc.avcDecodeResult = 0; ctx->avc.avcFrameStatus = 0; ctx->videoFrameCount = 0; ctx->audioFrameCount = 0; ctx->endOfAudioReached = false; ctx->endOfVideoReached = false; if (ctx->mpegMagic != PSMF_MAGIC || ctx->mpegVersion < 0 || (ctx->mpegOffset & 2047) != 0 || ctx->mpegOffset == 0) { // mpeg header is invalid! return; } // When used with scePsmf, some applications attempt to use sceMpegQueryStreamOffset // and sceMpegQueryStreamSize, which forces a packet overwrite in the Media Engine and in // the MPEG ringbuffer. // Mark the current MPEG as analyzed to filter this, and restore it at sceMpegFinish. ctx->isAnalyzed = true; // copy header struct to mpeg header. memcpy(ctx->mpegheader, buffer, 2048); *(u32_le*)(ctx->mpegheader + PSMF_STREAM_OFFSET_OFFSET) = 0x80000; INFO_LOG(ME, "Stream offset: %d, Stream size: 0x%X", ctx->mpegOffset, ctx->mpegStreamSize); INFO_LOG(ME, "First timestamp: %lld, Last timestamp: %lld", ctx->mpegFirstTimestamp, ctx->mpegLastTimestamp); }
void AnalyzeMpeg(u32 buffer_addr, MpegContext *ctx) { ctx->mpegStreamAddr = buffer_addr; ctx->mpegMagic = Memory::Read_U32(buffer_addr); ctx->mpegRawVersion = Memory::Read_U32(buffer_addr + PSMF_STREAM_VERSION_OFFSET); switch (ctx->mpegRawVersion) { case PSMF_VERSION_0012: ctx->mpegVersion = MPEG_VERSION_0012; break; case PSMF_VERSION_0013: ctx->mpegVersion = MPEG_VERSION_0013; break; case PSMF_VERSION_0014: ctx->mpegVersion = MPEG_VERSION_0014; break; case PSMF_VERSION_0015: ctx->mpegVersion = MPEG_VERSION_0015; break; default: ctx->mpegVersion = -1; break; } ctx->mpegOffset = bswap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_OFFSET_OFFSET)); ctx->mpegStreamSize = bswap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_SIZE_OFFSET)); ctx->mpegFirstTimestamp = bswap32(Memory::Read_U32(buffer_addr + PSMF_FIRST_TIMESTAMP_OFFSET)); ctx->mpegLastTimestamp = bswap32(Memory::Read_U32(buffer_addr + PSMF_LAST_TIMESTAMP_OFFSET)); ctx->mpegFirstDate = convertTimestampToDate(ctx->mpegFirstTimestamp); ctx->mpegLastDate = convertTimestampToDate(ctx->mpegLastTimestamp); ctx->avc.avcDetailFrameWidth = (Memory::Read_U8(buffer_addr + 142) * 0x10); ctx->avc.avcDetailFrameHeight = (Memory::Read_U8(buffer_addr + 143) * 0x10); ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS; ctx->avc.avcFrameStatus = 0; //if (!isCurrentMpegAnalyzed) { //SceMpegRingBuffer ringbuffer; //InitRingbuffer(&ringbuffer, 0, 0, 0, 0, 0); // ???? //Memory::WriteStruct(ctx->mpegRingbufferAddr, &ringbuffer); //} ctx->videoFrameCount = 0; ctx->audioFrameCount = 0; ctx->endOfAudioReached = false; ctx->endOfVideoReached = false; if ((ctx->mpegStreamSize > 0) && !ctx->isAnalyzed) { ctx->mediaengine->setFakeMode(fakeMode); ctx->mediaengine->init(buffer_addr, ctx->mpegStreamSize, ctx->mpegOffset); ctx->mediaengine->setVideoDim(ctx->avc.avcDetailFrameWidth, ctx->avc.avcDetailFrameHeight); // mysterious? //meChannel = new PacketChannel(); //meChannel.write(buffer_addr, mpegOffset); } // When used with scePsmf, some applications attempt to use sceMpegQueryStreamOffset // and sceMpegQueryStreamSize, which forces a packet overwrite in the Media Engine and in // the MPEG ringbuffer. // Mark the current MPEG as analyzed to filter this, and restore it at sceMpegFinish. ctx->isAnalyzed = true; INFO_LOG(ME, "Stream offset: %d, Stream size: 0x%X", ctx->mpegOffset, ctx->mpegStreamSize); INFO_LOG(ME, "First timestamp: %d, Last timestamp: %d", ctx->mpegFirstTimestamp, ctx->mpegLastTimestamp); }