diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index b7a69208d5..0dfcf3914f 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -37,6 +37,15 @@ const int LOG_PENDING_MAX = 120 * 10000; const int LOG_LATENCY_DELAY_MS = 20; const int LOG_SHUTDOWN_DELAY_MS = 250; const int LOG_MAX_DISPLAY_LINES = 4000; + +int ConsoleListener::refCount = 0; +HANDLE ConsoleListener::hThread = NULL; +HANDLE ConsoleListener::hTriggerEvent = NULL; +CRITICAL_SECTION ConsoleListener::criticalSection; + +char *ConsoleListener::logPending = NULL; +volatile u32 ConsoleListener::logPendingReadPos = 0; +volatile u32 ConsoleListener::logPendingWritePos = 0; #endif ConsoleListener::ConsoleListener() @@ -45,12 +54,12 @@ ConsoleListener::ConsoleListener() hConsole = NULL; bUseColor = true; - hThread = NULL; - hTriggerEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - InitializeCriticalSection(&criticalSection); - logPending = NULL; - logPendingReadPos = 0; - logPendingWritePos = 0; + if (hTriggerEvent == NULL) + { + hTriggerEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + InitializeCriticalSection(&criticalSection); + } + ++refCount; #else bUseColor = isatty(fileno(stdout)); #endif @@ -59,13 +68,6 @@ ConsoleListener::ConsoleListener() ConsoleListener::~ConsoleListener() { Close(); - -#ifdef _WIN32 - DeleteCriticalSection(&criticalSection); - - if (logPending != NULL) - delete [] logPending; -#endif } // 100, 100, "Dolphin Log Console" @@ -96,7 +98,7 @@ void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title hConsole = GetStdHandle(STD_OUTPUT_HANDLE); } - if (hTriggerEvent != NULL) + if (hTriggerEvent != NULL && hThread == NULL) { logPending = new char[LOG_PENDING_MAX]; hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &ConsoleListener::RunThread, this, 0, NULL); @@ -135,17 +137,30 @@ void ConsoleListener::Close() if (hConsole == NULL) return; - if (hThread != NULL) + if (--refCount <= 0) { - Common::AtomicStoreRelease(logPendingWritePos, (u32) -1); + if (hThread != NULL) + { + Common::AtomicStoreRelease(logPendingWritePos, (u32) -1); - SetEvent(hTriggerEvent); - WaitForSingleObject(hThread, LOG_SHUTDOWN_DELAY_MS); - CloseHandle(hThread); - hThread = NULL; + SetEvent(hTriggerEvent); + WaitForSingleObject(hThread, LOG_SHUTDOWN_DELAY_MS); + CloseHandle(hThread); + hThread = NULL; + } + if (hTriggerEvent != NULL) + { + DeleteCriticalSection(&criticalSection); + CloseHandle(hTriggerEvent); + hTriggerEvent = NULL; + } + if (logPending != NULL) + { + delete [] logPending; + logPending = NULL; + } + refCount = 0; } - if (hTriggerEvent != NULL) - CloseHandle(hTriggerEvent); FreeConsole(); hConsole = NULL; diff --git a/Common/ConsoleListener.h b/Common/ConsoleListener.h index b98cf444cd..42547c0a00 100644 --- a/Common/ConsoleListener.h +++ b/Common/ConsoleListener.h @@ -55,13 +55,14 @@ private: void SendToThread(LogTypes::LOG_LEVELS Level, const char *Text); void WriteToConsole(LogTypes::LOG_LEVELS Level, const char *Text, size_t Len); - HANDLE hThread; - HANDLE hTriggerEvent; - CRITICAL_SECTION criticalSection; + static int refCount; + static HANDLE hThread; + static HANDLE hTriggerEvent; + static CRITICAL_SECTION criticalSection; - char *logPending; - volatile u32 logPendingReadPos; - volatile u32 logPendingWritePos; + static char *logPending; + static volatile u32 logPendingReadPos; + static volatile u32 logPendingWritePos; #endif bool bHidden; bool bUseColor; diff --git a/Common/FileSearch.cpp b/Common/FileSearch.cpp index aa836a166f..3d8e07d852 100644 --- a/Common/FileSearch.cpp +++ b/Common/FileSearch.cpp @@ -28,7 +28,6 @@ #ifdef __APPLE__ #include #endif -#include #include "FileSearch.h" diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 758b135fed..8297f71205 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -15,9 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include -#include - #include "input/input_state.h" #include "Core/Config.h" #include "KeyMap.h" diff --git a/Common/MemArena.cpp b/Common/MemArena.cpp index 3cd996fea0..b8191b0808 100644 --- a/Common/MemArena.cpp +++ b/Common/MemArena.cpp @@ -15,7 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "Common.h" #include "MemoryUtil.h" #include "MemArena.h" diff --git a/Core/CoreTiming.h b/Core/CoreTiming.h index d4bdd12aca..8d8281f6c8 100644 --- a/Core/CoreTiming.h +++ b/Core/CoreTiming.h @@ -33,8 +33,6 @@ #include "../Globals.h" -#include - class PointerWrap; //const int CPU_HZ = 222000000; diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index 5d08b3a521..711dbfaa44 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -22,14 +22,12 @@ #include #endif -#include #include #include "../../Globals.h" #include "../../Core/MemMap.h" #include "SymbolMap.h" -#include #include SymbolMap symbolMap; diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index d4ad023815..b25e4039e0 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -20,6 +20,9 @@ #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceRtc.h" #include "Core/System.h" +#undef st_ctime +#undef st_atime +#undef st_mtime enum SceUtilitySavedataType { diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp index cfbe1ecc21..7757f61b7e 100644 --- a/Core/ELF/ParamSFO.cpp +++ b/Core/ELF/ParamSFO.cpp @@ -17,7 +17,6 @@ #include #include -#include "../Globals.h" #include "ParamSFO.h" struct Header diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index 85686a256a..90d2a516e7 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -18,10 +18,10 @@ #pragma once -#include #include #include "Common/CommonTypes.h" +#include "../Globals.h" class ParamSFOData { diff --git a/Core/ELF/PrxDecrypter.cpp b/Core/ELF/PrxDecrypter.cpp index f9a643463b..7d7bf9ef4b 100644 --- a/Core/ELF/PrxDecrypter.cpp +++ b/Core/ELF/PrxDecrypter.cpp @@ -1,5 +1,3 @@ -#include - extern "C" { #include "ext/libkirk/kirk_engine.h" diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index e4cff8abac..baa34111d5 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -23,8 +23,6 @@ // The ISOFileSystemReader reads from a BlockDevice, so it automatically works // with CISO images. -#include - #include "../../Globals.h" #include "Core/ELF/PBPReader.h" diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index 1ee0ac474a..d7bd082535 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -20,7 +20,6 @@ // TODO: Remove the Windows-specific code, FILE is fine there too. #include -#include #include "../Core/FileSystems/FileSystem.h" diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 6f3c447acf..3fed1c855a 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -19,7 +19,6 @@ #include "../../Globals.h" #include "ChunkFile.h" -#include enum FileAccess { diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 66bfbd1693..7555e993ae 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -18,9 +18,7 @@ #pragma once #include -#include #include -#include #include "FileSystem.h" diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 3c1da12fb8..53dde68286 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -19,7 +19,6 @@ #include "../../Globals.h" #include "Common.h" -#include #include class PointerWrap; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index c542b4cbd8..1a1e394615 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -17,7 +17,6 @@ #include #include -#include #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 69d9239486..4fde020ddf 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -23,7 +23,8 @@ #include "sceKernelThread.h" #include "HLE.h" #include "../HW/MediaEngine.h" -#include "../../Core/Config.h" +#include "Core/Config.h" +#include "Core/Reporting.h" static bool useMediaEngine; @@ -193,7 +194,7 @@ MpegContext *getMpegCtx(u32 mpegAddr) { // TODO: Remove. if (mpegMap.find(mpeg) == mpegMap.end()) { - ERROR_LOG(HLE, "Bad mpeg handle %08x - using last one (%08x) instead", mpeg, lastMpegHandle); + ERROR_LOG_REPORT(HLE, "Bad mpeg handle %08x - using last one (%08x) instead", mpeg, lastMpegHandle); mpeg = lastMpegHandle; } @@ -630,10 +631,10 @@ u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr, u32 i u32 init = Memory::Read_U32(initAddr); DEBUG_LOG(HLE, "*buffer = %08x, *init = %08x", buffer, init); - if (ctx->mediaengine->stepVideo()) { + if (ctx->mediaengine->stepVideo(ctx->videoPixelMode)) { ctx->mediaengine->writeVideoImage(Memory::GetPointer(buffer), frameWidth, ctx->videoPixelMode); } - ringbuffer.packetsFree = std::min(16, ctx->mediaengine->getRemainSize() / 2048); + ringbuffer.packetsFree = std::max(0, ringbuffer.packets - ctx->mediaengine->getBufferedSize() / 2048); avcAu.pts = ctx->mediaengine->getVideoTimeStamp(); @@ -774,12 +775,12 @@ int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initAddr) u32 init = Memory::Read_U32(initAddr); DEBUG_LOG(HLE, "*buffer = %08x, *init = %08x", buffer, init); - if (ctx->mediaengine->stepVideo()) { + if (ctx->mediaengine->stepVideo(ctx->videoPixelMode)) { // do nothing ; } - ringbuffer.packetsFree = std::min(16, ctx->mediaengine->getRemainSize() / 2048); + ringbuffer.packetsFree = std::max(0, ringbuffer.packets - ctx->mediaengine->getBufferedSize() / 2048); avcAu.pts = ctx->mediaengine->getVideoTimeStamp(); ctx->avc.avcFrameStatus = 1; @@ -886,13 +887,15 @@ void PostPutAction::run(MipsCall &call) { WARN_LOG(HLE, "sceMpegRingbufferPut clamping packetsAdded old=%i new=%i", packetsAdded, ringbuffer.packetsFree); packetsAdded = ringbuffer.packetsFree; } - ctx->mediaengine->addStreamData(Memory::GetPointer(ringbuffer.data), packetsAdded * 2048); + int actuallyAdded = ctx->mediaengine->addStreamData(Memory::GetPointer(ringbuffer.data), packetsAdded * 2048) / 2048; + if (actuallyAdded != packetsAdded) { + WARN_LOG_REPORT(HLE, "sceMpegRingbufferPut(): unable to enqueue all added packets, going to overwrite some frames."); + } ringbuffer.packetsRead += packetsAdded; ringbuffer.packetsWritten += packetsAdded; - //ringbuffer.packetsFree = std::min(16, ctx->mediaengine->getRemainSize() / 2048); - ringbuffer.packetsFree = 0; + ringbuffer.packetsFree -= packetsAdded; } - DEBUG_LOG(HLE, "packetAdded: %i packetsRead: %i packetsTotol: %i", packetsAdded, ringbuffer.packetsRead, ringbuffer.packets); + DEBUG_LOG(HLE, "packetAdded: %i packetsRead: %i packetsTotal: %i", packetsAdded, ringbuffer.packetsRead, ringbuffer.packets); Memory::WriteStruct(ringAddr_, &ringbuffer); call.setReturnValue(packetsAdded); diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 18e8a8256f..f2c9b58a2f 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -673,22 +673,38 @@ int scePsmfPlayerBreak(u32 psmfPlayer) int scePsmfPlayerSetPsmf(u32 psmfPlayer, const char *filename) { ERROR_LOG(HLE, "UNIMPL scePsmfPlayerSetPsmf(%08x, %s)", psmfPlayer, filename); + PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) + { psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY; - psmfplayer->mediaengine->loadFile(filename); - psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); + psmfplayer->mediaengine->loadFile(filename); + psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); + } + else + { + ERROR_LOG(HLE, "psmfplayer null in scePsmfPlayerSetPsmf"); + } + return 0; } int scePsmfPlayerSetPsmfCB(u32 psmfPlayer, const char *filename) { ERROR_LOG(HLE, "UNIMPL scePsmfPlayerSetPsmfCB(%08x, %s)", psmfPlayer, filename); + PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer); if (psmfplayer) + { psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY; - psmfplayer->mediaengine->loadFile(filename); - psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); + psmfplayer->mediaengine->loadFile(filename); + psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp(); + } + else + { + ERROR_LOG(HLE, "psmfplayer null in scePsmfPlayerSetPsmfCB"); + } + return 0; } @@ -763,7 +779,7 @@ int scePsmfPlayerUpdate(u32 psmfPlayer) } } // TODO: Once we start increasing pts somewhere, and actually know the last timestamp, do this better. - psmfplayer->mediaengine->stepVideo(); + psmfplayer->mediaengine->stepVideo(videoPixelMode); psmfplayer->psmfPlayerAvcAu.pts = psmfplayer->mediaengine->getVideoTimeStamp(); // This seems to be crazy! return hleDelayResult(0, "psmfPlayer update", 30000); diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index ca18719b8a..56d15d7087 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -43,45 +43,45 @@ static const int TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551 = 0x01; static const int TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444 = 0x02; static const int TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888 = 0x03; -inline void YUV444toRGB888(u8 ypos, u8 upos, u8 vpos, u8 &r, u8 &g, u8 &b) +#ifdef USE_FFMPEG +static AVPixelFormat getSwsFormat(int pspFormat) { - u8 u = upos - 128; - u8 v = vpos -128; - int rdif = v + ((v * 103) >> 8); - int invgdif = ((u * 88) >> 8) + ((v * 183) >> 8); - int bdif = u + ((u * 198) >> 8); - - r = (u8)(ypos + rdif); - g = (u8)(ypos - invgdif); - b = (u8)(ypos + bdif); -} - -void getPixelColor(u8 r, u8 g, u8 b, u8 a, int pixelMode, u16* color) -{ - switch (pixelMode) + switch (pspFormat) { - case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: - { - *color = ((b >> 3) << 11) | ((g >> 2) << 5) | (r >> 3); - } - break; + case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: + return AV_PIX_FMT_BGR565LE; case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: - { - *color = ((a >> 7) << 15) | ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3); - } - break; + return AV_PIX_FMT_BGR555LE; case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: - { - *color = ((a >> 4) << 12) | ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); - } - break; + return AV_PIX_FMT_BGR444LE; + case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: + return AV_PIX_FMT_RGBA; + default: - // do nothing yet - break; + ERROR_LOG(ME, "Unknown pixel format"); + return (AVPixelFormat)0; + } +} +#endif + +static int getPixelFormatBytes(int pspFormat) +{ + switch (pspFormat) + { + case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: + return 2; + case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: + return 4; + + default: + ERROR_LOG(ME, "Unknown pixel format"); + return 4; } } -MediaEngine::MediaEngine(): m_pdata(0), m_streamSize(0), m_readSize(0){ +MediaEngine::MediaEngine(): m_streamSize(0), m_readSize(0), m_pdata(0) { m_pFormatCtx = 0; m_pCodecCtx = 0; m_pFrame = 0; @@ -174,11 +174,11 @@ bool MediaEngine::openContext() { if(avformat_find_stream_info(pFormatCtx, NULL) < 0) return false; - // Dump information about file onto standard error + // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, NULL, 0); // Find the first video stream - for(int i = 0; i < pFormatCtx->nb_streams; i++) { + for(int i = 0; i < (int)pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { m_videoStream = i; break; @@ -259,7 +259,7 @@ bool MediaEngine::loadFile(const char* filename) return true; } -void MediaEngine::addStreamData(u8* buffer, int addSize) { +int MediaEngine::addStreamData(u8* buffer, int addSize) { int size = std::min(addSize, m_streamSize - m_readSize); if (size > 0) { memcpy(m_pdata + m_readSize, buffer, size); @@ -271,6 +271,7 @@ void MediaEngine::addStreamData(u8* buffer, int addSize) { m_demux->demux(); } } + return size; } bool MediaEngine::setVideoDim(int width, int height) @@ -294,37 +295,55 @@ bool MediaEngine::setVideoDim(int width, int height) // Allocate video frame m_pFrame = avcodec_alloc_frame(); - m_sws_ctx = (void*) - sws_getContext - ( - pCodecCtx->width, - pCodecCtx->height, - pCodecCtx->pix_fmt, - m_desWidth, - m_desHeight, - PIX_FMT_RGB24, - SWS_BILINEAR, - NULL, - NULL, - NULL - ); + m_sws_ctx = NULL; + m_sws_fmt = -1; + updateSwsFormat(TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888); // Allocate video frame for RGB24 m_pFrameRGB = avcodec_alloc_frame(); - int numBytes = avpicture_get_size(PIX_FMT_RGB24, m_desWidth, m_desHeight); + int numBytes = avpicture_get_size((AVPixelFormat)m_sws_fmt, m_desWidth, m_desHeight); m_buffer = (u8*)av_malloc(numBytes * sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in pFrameRGB - avpicture_fill((AVPicture *)m_pFrameRGB, m_buffer, PIX_FMT_RGB24, m_desWidth, m_desHeight); + avpicture_fill((AVPicture *)m_pFrameRGB, m_buffer, (AVPixelFormat)m_sws_fmt, m_desWidth, m_desHeight); #endif // USE_FFMPEG return true; } -bool MediaEngine::stepVideo() { +void MediaEngine::updateSwsFormat(int videoPixelMode) { +#ifdef USE_FFMPEG + AVCodecContext *pCodecCtx = (AVCodecContext*)m_pCodecCtx; + AVPixelFormat swsDesired = getSwsFormat(videoPixelMode); + if (swsDesired != m_sws_fmt) { + m_sws_fmt = swsDesired; + m_sws_ctx = sws_getCachedContext + ( + m_sws_ctx, + pCodecCtx->width, + pCodecCtx->height, + pCodecCtx->pix_fmt, + m_desWidth, + m_desHeight, + (AVPixelFormat)m_sws_fmt, + SWS_BILINEAR, + NULL, + NULL, + NULL + ); + } +#endif +} + +bool MediaEngine::stepVideo(int videoPixelMode) { // if video engine is broken, force to add timestamp m_videopts += 3003; #ifdef USE_FFMPEG + updateSwsFormat(videoPixelMode); + // TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf. + // Update the linesize for the new format too. We started with the largest size, so it should fit. + m_pFrameRGB->linesize[0] = getPixelFormatBytes(videoPixelMode) * m_desWidth; + AVFormatContext *pFormatCtx = (AVFormatContext*)m_pFormatCtx; AVCodecContext *pCodecCtx = (AVCodecContext*)m_pCodecCtx; AVFrame *pFrame = (AVFrame*)m_pFrame; @@ -337,9 +356,9 @@ bool MediaEngine::stepVideo() { while(av_read_frame(pFormatCtx, &packet)>=0) { if(packet.stream_index == m_videoStream) { // Decode video frame - avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); - sws_scale((SwsContext*)m_sws_ctx, pFrame->data, pFrame->linesize, 0, - pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); + avcodec_decode_video2(pCodecCtx, m_pFrame, &frameFinished, &packet); + sws_scale(m_sws_ctx, m_pFrame->data, m_pFrame->linesize, 0, + pCodecCtx->height, m_pFrameRGB->data, m_pFrameRGB->linesize); if(frameFinished) { if (m_videopts == 3003) { @@ -354,7 +373,7 @@ bool MediaEngine::stepVideo() { } if (m_audiopts > 0) { if (m_audiopts - m_videopts > 5000) - return stepVideo(); + return stepVideo(videoPixelMode); } return bGetFrame; #else @@ -366,43 +385,53 @@ bool MediaEngine::writeVideoImage(u8* buffer, int frameWidth, int videoPixelMode if ((!m_pFrame)||(!m_pFrameRGB)) return false; #ifdef USE_FFMPEG - AVFrame *pFrameRGB = (AVFrame*)m_pFrameRGB; // lock the image size int height = m_desHeight; int width = m_desWidth; - u8* imgbuf = buffer; - u8* data = pFrameRGB->data[0]; - if (videoPixelMode == TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888) - { - // ABGR8888 + u8 *imgbuf = buffer; + u8 *data = m_pFrameRGB->data[0]; + u16 *imgbuf16 = (u16 *)buffer; + u16 *data16 = (u16 *)data; + + switch (videoPixelMode) { + case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) - { - u8 r = *(data++); - u8 g = *(data++); - u8 b = *(data++); - *(imgbuf++) = r; - *(imgbuf++) = g; - *(imgbuf++) = b; - *(imgbuf++) = 0xFF; - } - imgbuf += (frameWidth - width) * 4; + memcpy(imgbuf, data, width * sizeof(u32)); + data += width * sizeof(u32); + imgbuf += frameWidth * sizeof(u32); } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: + for (int y = 0; y < height; y++) { + memcpy(imgbuf, data, width * sizeof(u16)); + data += width * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); + } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + *imgbuf16++ = *data16++ | (1 << 15); + } + imgbuf16 += (frameWidth - width); + } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + *imgbuf16++ = *data16++ | (0xF << 12); + } + imgbuf16 += (frameWidth - width); + } + break; + + default: + ERROR_LOG(ME, "Unsupported video pixel format %d", videoPixelMode); + break; } - else - { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) - { - u8 r = *(data++); - u8 g = *(data++); - u8 b = *(data++); - getPixelColor(r, g, b, 0xFF, videoPixelMode, (u16*)imgbuf); - imgbuf += 2; - } - imgbuf += (frameWidth - width) * 2; - } - } #endif // USE_FFMPEG return true; } @@ -412,45 +441,57 @@ bool MediaEngine::writeVideoImageWithRange(u8* buffer, int frameWidth, int video if ((!m_pFrame)||(!m_pFrameRGB)) return false; #ifdef USE_FFMPEG - AVFrame *pFrameRGB = (AVFrame*)m_pFrameRGB; // lock the image size - u8* imgbuf = buffer; - u8* data = pFrameRGB->data[0]; - if (videoPixelMode == TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888) - { - // ABGR8888 - data += (ypos * m_desWidth + xpos) * 3; + u8 *imgbuf = buffer; + u8 *data = m_pFrameRGB->data[0]; + u16 *imgbuf16 = (u16 *)buffer; + u16 *data16 = (u16 *)data; + + switch (videoPixelMode) { + case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888: + data += (ypos * m_desWidth + xpos) * sizeof(u32); for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) - { - u8 r = *(data++); - u8 g = *(data++); - u8 b = *(data++); - *(imgbuf++) = r; - *(imgbuf++) = g; - *(imgbuf++) = b; - *(imgbuf++) = 0xFF; - } - imgbuf += (frameWidth - width) * 4; - data += (m_desWidth - width) * 3; + memcpy(imgbuf, data, width * sizeof(u32)); + data += m_desWidth * sizeof(u32); + imgbuf += frameWidth * sizeof(u32); } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650: + data += (ypos * m_desWidth + xpos) * sizeof(u16); + for (int y = 0; y < height; y++) { + memcpy(imgbuf, data, width * sizeof(u16)); + data += m_desWidth * sizeof(u16); + imgbuf += frameWidth * sizeof(u16); + } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR5551: + data += (ypos * m_desWidth + xpos) * sizeof(u16); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + *imgbuf16++ = *data16++ | (1 << 15); + } + imgbuf16 += (frameWidth - width); + data16 += (m_desWidth - width); + } + break; + + case TPSM_PIXEL_STORAGE_MODE_16BIT_ABGR4444: + data += (ypos * m_desWidth + xpos) * sizeof(u16); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + *imgbuf16++ = *data16++ | (0xF << 12); + } + imgbuf16 += (frameWidth - width); + data16 += (m_desWidth - width); + } + break; + + default: + ERROR_LOG(ME, "Unsupported video pixel format %d", videoPixelMode); + break; } - else - { - data += (ypos * m_desWidth + xpos) * 3; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) - { - u8 r = *(data++); - u8 g = *(data++); - u8 b = *(data++); - getPixelColor(r, g, b, 0xFF, videoPixelMode, (u16*)imgbuf); - imgbuf += 2; - } - imgbuf += (frameWidth - width) * 2; - data += (m_desWidth - width) * 3; - } - } #endif // USE_FFMPEG return true; } @@ -521,4 +562,5 @@ s64 MediaEngine::getLastTimeStamp() { return 0; int lastTimeStamp = bswap32(*(int*)(m_pdata + 92)); return lastTimeStamp; -} \ No newline at end of file +} + diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h index e10147748b..958518cba1 100644 --- a/Core/HW/MediaEngine.h +++ b/Core/HW/MediaEngine.h @@ -30,6 +30,9 @@ #include "ChunkFile.h" #include "Core/HW/MpegDemux.h" +struct SwsContext; +struct AVFrame; + class MediaEngine { public: @@ -39,10 +42,12 @@ public: void closeMedia(); bool loadStream(u8* buffer, int readSize, int StreamSize); bool loadFile(const char* filename); - void addStreamData(u8* buffer, int addSize); + // Returns number of packets actually added. + int addStreamData(u8* buffer, int addSize); int getRemainSize() { return m_streamSize - m_readSize;} + int getBufferedSize() { return m_readSize - m_decodePos; } - bool stepVideo(); + bool stepVideo(int videoPixelMode); bool writeVideoImage(u8* buffer, int frameWidth = 512, int videoPixelMode = 3); bool writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode, int xpos, int ypos, int width, int height); @@ -61,17 +66,19 @@ public: private: bool openContext(); + void updateSwsFormat(int videoPixelMode); public: void *m_pFormatCtx; void *m_pCodecCtx; - void *m_pFrame; - void *m_pFrameRGB; + AVFrame *m_pFrame; + AVFrame *m_pFrameRGB; void *m_pIOContext; int m_videoStream; - void *m_sws_ctx; - u8* m_buffer; + SwsContext *m_sws_ctx; + int m_sws_fmt; + u8 *m_buffer; int m_desWidth; int m_desHeight; diff --git a/Core/HW/OMAConvert.cpp b/Core/HW/OMAConvert.cpp index 7ace225257..71a1cd9bb4 100644 --- a/Core/HW/OMAConvert.cpp +++ b/Core/HW/OMAConvert.cpp @@ -1,5 +1,4 @@ #include "OMAConvert.h" -#include namespace OMAConvert { diff --git a/Core/Host.h b/Core/Host.h index 07611b22e7..626f35a08d 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -17,8 +17,6 @@ #pragma once -#include -#include #include "../Globals.h" struct InputState; diff --git a/Core/Util/BlockAllocator.h b/Core/Util/BlockAllocator.h index 4d7b7a1ee9..ec512e6c98 100644 --- a/Core/Util/BlockAllocator.h +++ b/Core/Util/BlockAllocator.h @@ -19,9 +19,7 @@ #include "../../Globals.h" -#include #include -#include class PointerWrap; diff --git a/GPU/GLES/TextureScaler.cpp b/GPU/GLES/TextureScaler.cpp index d8a6564432..6227564945 100644 --- a/GPU/GLES/TextureScaler.cpp +++ b/GPU/GLES/TextureScaler.cpp @@ -28,15 +28,6 @@ #include #include -#ifdef __SYMBIAN32__ -#define p -#elif defined(IOS) -#include -namespace p = std::tr1::placeholders; -#else -namespace p = std::placeholders; -#endif - #if _M_SSE >= 0x402 #include #endif @@ -604,22 +595,22 @@ void TextureScaler::Scale(u32* &data, GLenum &dstFmt, int &width, int &height, i void TextureScaler::ScaleXBRZ(int factor, u32* source, u32* dest, int width, int height) { xbrz::ScalerCfg cfg; - GlobalThreadPool::Loop(bind(&xbrz::scale, factor, source, dest, width, height, cfg, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&xbrz::scale, factor, source, dest, width, height, cfg, placeholder::_1, placeholder::_2), 0, height); } void TextureScaler::ScaleBilinear(int factor, u32* source, u32* dest, int width, int height) { bufTmp1.resize(width*height*factor); u32 *tmpBuf = bufTmp1.data(); - GlobalThreadPool::Loop(bind(&bilinearH, factor, source, tmpBuf, width, p::_1, p::_2), 0, height); - GlobalThreadPool::Loop(bind(&bilinearV, factor, tmpBuf, dest, width, 0, height, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&bilinearH, factor, source, tmpBuf, width, placeholder::_1, placeholder::_2), 0, height); + GlobalThreadPool::Loop(bind(&bilinearV, factor, tmpBuf, dest, width, 0, height, placeholder::_1, placeholder::_2), 0, height); } void TextureScaler::ScaleBicubicBSpline(int factor, u32* source, u32* dest, int width, int height) { - GlobalThreadPool::Loop(bind(&scaleBicubicBSpline, factor, source, dest, width, height, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&scaleBicubicBSpline, factor, source, dest, width, height, placeholder::_1, placeholder::_2), 0, height); } void TextureScaler::ScaleBicubicMitchell(int factor, u32* source, u32* dest, int width, int height) { - GlobalThreadPool::Loop(bind(&scaleBicubicMitchell, factor, source, dest, width, height, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&scaleBicubicMitchell, factor, source, dest, width, height, placeholder::_1, placeholder::_2), 0, height); } void TextureScaler::ScaleHybrid(int factor, u32* source, u32* dest, int width, int height, bool bicubic) { @@ -635,8 +626,8 @@ void TextureScaler::ScaleHybrid(int factor, u32* source, u32* dest, int width, i bufTmp1.resize(width*height); bufTmp2.resize(width*height*factor*factor); bufTmp3.resize(width*height*factor*factor); - GlobalThreadPool::Loop(bind(&generateDistanceMask, source, bufTmp1.data(), width, height, p::_1, p::_2), 0, height); - GlobalThreadPool::Loop(bind(&convolve3x3, bufTmp1.data(), bufTmp2.data(), KERNEL_SPLAT, width, height, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&generateDistanceMask, source, bufTmp1.data(), width, height, placeholder::_1, placeholder::_2), 0, height); + GlobalThreadPool::Loop(bind(&convolve3x3, bufTmp1.data(), bufTmp2.data(), KERNEL_SPLAT, width, height, placeholder::_1, placeholder::_2), 0, height); ScaleBilinear(factor, bufTmp2.data(), bufTmp3.data(), width, height); // mask C is now in bufTmp3 @@ -649,15 +640,15 @@ void TextureScaler::ScaleHybrid(int factor, u32* source, u32* dest, int width, i // Now we can mix it all together // The factor 8192 was found through practical testing on a variety of textures - GlobalThreadPool::Loop(bind(&mix, dest, bufTmp2.data(), bufTmp3.data(), 8192, width*factor, p::_1, p::_2), 0, height*factor); + GlobalThreadPool::Loop(bind(&mix, dest, bufTmp2.data(), bufTmp3.data(), 8192, width*factor, placeholder::_1, placeholder::_2), 0, height*factor); } void TextureScaler::DePosterize(u32* source, u32* dest, int width, int height) { bufTmp3.resize(width*height); - GlobalThreadPool::Loop(bind(&deposterizeH, source, bufTmp3.data(), width, p::_1, p::_2), 0, height); - GlobalThreadPool::Loop(bind(&deposterizeV, bufTmp3.data(), dest, width, height, p::_1, p::_2), 0, height); - GlobalThreadPool::Loop(bind(&deposterizeH, dest, bufTmp3.data(), width, p::_1, p::_2), 0, height); - GlobalThreadPool::Loop(bind(&deposterizeV, bufTmp3.data(), dest, width, height, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&deposterizeH, source, bufTmp3.data(), width, placeholder::_1, placeholder::_2), 0, height); + GlobalThreadPool::Loop(bind(&deposterizeV, bufTmp3.data(), dest, width, height, placeholder::_1, placeholder::_2), 0, height); + GlobalThreadPool::Loop(bind(&deposterizeH, dest, bufTmp3.data(), width, placeholder::_1, placeholder::_2), 0, height); + GlobalThreadPool::Loop(bind(&deposterizeV, bufTmp3.data(), dest, width, height, placeholder::_1, placeholder::_2), 0, height); } void TextureScaler::ConvertTo8888(GLenum format, u32* source, u32* &dest, int width, int height) { @@ -667,15 +658,15 @@ void TextureScaler::ConvertTo8888(GLenum format, u32* source, u32* &dest, int wi break; case GL_UNSIGNED_SHORT_4_4_4_4: - GlobalThreadPool::Loop(bind(&convert4444, (u16*)source, dest, width, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&convert4444, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height); break; case GL_UNSIGNED_SHORT_5_6_5: - GlobalThreadPool::Loop(bind(&convert565, (u16*)source, dest, width, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&convert565, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height); break; case GL_UNSIGNED_SHORT_5_5_5_1: - GlobalThreadPool::Loop(bind(&convert5551, (u16*)source, dest, width, p::_1, p::_2), 0, height); + GlobalThreadPool::Loop(bind(&convert5551, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height); break; default: diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 017cda1970..18a1afd16b 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -20,7 +20,6 @@ #include "../Globals.h" #include "../native/gfx/gl_common.h" #include "ge_constants.h" -#include struct GPUgstate { diff --git a/Globals.h b/Globals.h index c4d45fd73f..64e8c11c4b 100644 --- a/Globals.h +++ b/Globals.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include #include diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 5d197b16bb..1468ecf418 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -665,7 +665,7 @@ void AudioScreen::render() { int stride = 40; int columnw = 400; UICheckBox(GEN_ID, x, y += stride, a->T("Enable Sound"), ALIGN_TOPLEFT, &g_Config.bEnableSound); - if (Atrac3plus_Decoder::IsInstalled()) { + if (Atrac3plus_Decoder::IsInstalled() && g_Config.bEnableSound) { UICheckBox(GEN_ID, x, y += stride, a->T("Enable Atrac3+"), ALIGN_TOPLEFT, &g_Config.bEnableAtrac3plus); } diff --git a/ffmpeg b/ffmpeg index fe9c6b483d..75911d922f 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit fe9c6b483d42c2e481deea97fb6a382c050c10f2 +Subproject commit 75911d922f8324abd9b6209d76c6ff2b4114df06