From 1478885cd8c5ee460b834f12fe7447783f13fcb7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 28 Mar 2017 21:51:26 +0100 Subject: [PATCH] OMXImage: Rearchitect to use file buffer --- xbmc/TextureCacheJob.cpp | 38 ++++--- xbmc/cores/omxplayer/OMXImage.cpp | 165 +++++++++--------------------- xbmc/cores/omxplayer/OMXImage.h | 33 +----- xbmc/guilib/TexturePi.cpp | 21 ++-- 4 files changed, 89 insertions(+), 168 deletions(-) diff --git a/xbmc/TextureCacheJob.cpp b/xbmc/TextureCacheJob.cpp index 1b0818612b67d..eb997ce7e07d2 100644 --- a/xbmc/TextureCacheJob.cpp +++ b/xbmc/TextureCacheJob.cpp @@ -81,20 +81,6 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture) else if (m_details.hash == m_oldHash) return true; -#if defined(TARGET_RASPBERRY_PI) - if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool("videoplayer.acceleratedjpegs") && COMXImage::CreateThumb(image, width, height, additional_info, CTextureCache::GetCachedPath(m_cachePath + ".jpg"))) - { - m_details.width = width; - m_details.height = height; - m_details.file = m_cachePath + ".jpg"; - if (out_texture) - *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, "" /* already flipped */); - CLog::Log(LOGDEBUG, "Fast %s image '%s' to '%s': %p", - m_oldHash.empty() ? "Caching" : "Recaching", CURL::GetRedacted(image), - m_details.file, static_cast(out_texture)); - return true; - } -#endif CBaseTexture *texture = nullptr; if (additional_info == "music") { // special case for embedded music images @@ -110,6 +96,30 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture) if (!(!(file.IsPicture() && !(file.IsZIP() || file.IsRAR() || file.IsCBR() || file.IsCBZ() )) && !StringUtils::StartsWithNoCase(file.GetMimeType(), "image/") && !StringUtils::EqualsNoCase(file.GetMimeType(), "application/octet-stream"))) // ignore non-pictures { +#if defined(TARGET_RASPBERRY_PI) + if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool("videoplayer.acceleratedjpegs")) + { + // Read image into memory to use our vfs + XFILE::CFile xfile; + XFILE::auto_buffer buf; + + if (xfile.LoadFile(image, buf) > 0) + { + if (COMXImage::CreateThumb(image, buf, width, height, additional_info, CTextureCache::GetCachedPath(m_cachePath + ".jpg"))) + { + m_details.width = width; + m_details.height = height; + m_details.file = m_cachePath + ".jpg"; + if (out_texture) + *out_texture = LoadImage(CTextureCache::GetCachedPath(m_details.file), width, height, "" /* already flipped */); + CLog::Log(LOGDEBUG, "Fast %s image '%s' to '%s': %p", + m_oldHash.empty() ? "Caching" : "Recaching", CURL::GetRedacted(image), + m_details.file, static_cast(out_texture)); + return true; + } + } + } +#endif texture = new CTexture(); if (!(texture->LoadFromFileInternal(image, width, height, true, file.GetMimeType()))) { diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp index d2588213a320b..2a13e0fc9dcbc 100644 --- a/xbmc/cores/omxplayer/OMXImage.cpp +++ b/xbmc/cores/omxplayer/OMXImage.cpp @@ -113,27 +113,11 @@ bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int w return ret; } -COMXImageFile *COMXImage::LoadJpeg(const std::string& texturePath) -{ - COMXImageFile *file = new COMXImageFile(); - if (!file->ReadFile(texturePath)) - { - delete file; - file = NULL; - } - return file; -} - -void COMXImage::CloseJpeg(COMXImageFile *file) -{ - delete file; -} - -bool COMXImage::DecodeJpeg(COMXImageFile *file, unsigned int width, unsigned int height, unsigned int stride, void *pixels) +bool COMXImage::DecodeJpeg(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, unsigned int stride, void *pixels) { bool ret = false; COMXImageDec omx_image; - if (omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, stride, pixels)) + if (omx_image.Decode(reinterpret_cast(buf.get()), buf.size(), width, height, stride, pixels)) { assert(width == omx_image.GetDecodedWidth()); assert(height == omx_image.GetDecodedHeight()); @@ -141,7 +125,7 @@ bool COMXImage::DecodeJpeg(COMXImageFile *file, unsigned int width, unsigned int ret = true; } else - CLog::Log(LOGNOTICE, "%s: unable to decode %s %dx%d", __func__, file->GetFilename(), width, height); + CLog::Log(LOGNOTICE, "%s: unable to decode %s %dx%d", __func__, srcFile.c_str(), width, height); omx_image.Close(); return ret; } @@ -196,17 +180,20 @@ bool COMXImage::ClampLimits(unsigned int &width, unsigned int &height, unsigned return clamped; } -bool COMXImage::CreateThumb(const std::string& srcFile, unsigned int maxHeight, unsigned int maxWidth, std::string &additional_info, const std::string& destFile) +bool COMXImage::CreateThumb(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int maxHeight, unsigned int maxWidth, std::string &additional_info, const std::string& destFile) { bool okay = false; - COMXImageFile file; COMXImageReEnc reenc; if (!reenc.Gpu()) return false; void *pDestBuffer; unsigned int nDestSize; int orientation = additional_info == "flipped" ? 1:0; - if (URIUtils::HasExtension(srcFile, ".jpg|.tbn") && file.ReadFile(srcFile, orientation) && reenc.ReEncode(file, maxWidth, maxHeight, pDestBuffer, nDestSize)) + unsigned int width = 0, height = 0; + std::string error; + if (URIUtils::HasExtension(srcFile, ".jpg|.tbn") && + GetCodingType(buf, width, height, orientation, error) && + reenc.ReEncode(srcFile, buf, width, height, maxWidth, maxHeight, orientation, pDestBuffer, nDestSize)) { XFILE::CFile outfile; if (outfile.OpenForWrite(destFile, true)) @@ -303,7 +290,7 @@ bool COMXImage::DestroyTextureInternal(EGLDisplay egl_display, EGLContext egl_co return s; } -bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata) +bool COMXImage::DecodeJpegToTexture(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, void **userdata) { bool ret = false; COMXTexture omx_image; @@ -323,15 +310,15 @@ bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, uns SendMessage(AllocTextureCallback, tex); - if (tex->egl_image && tex->texture && omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, tex->egl_image)) + if (tex->egl_image && tex->texture && omx_image.Decode(reinterpret_cast(buf.get()), buf.size(), width, height, tex->egl_image)) { ret = true; *userdata = tex; - CLog::Log(LOGDEBUG, "%s: decoded %s %dx%d", __func__, file->GetFilename(), width, height); + CLog::Log(LOGDEBUG, "%s: decoded %s %dx%d", __func__, CURL::GetRedacted(srcFile).c_str(), width, height); } else { - CLog::Log(LOGNOTICE, "%s: unable to decode to texture %s %dx%d", __func__, file->GetFilename(), width, height); + CLog::Log(LOGNOTICE, "%s: unable to decode to texture %s %dx%d", __func__, CURL::GetRedacted(srcFile).c_str(), width, height); DestroyTexture(tex); } return ret; @@ -474,26 +461,6 @@ void COMXImage::OnExit() { } -#ifdef CLASSNAME -#undef CLASSNAME -#endif -#define CLASSNAME "COMXImageFile" - -COMXImageFile::COMXImageFile() -{ - m_image_size = 0; - m_image_buffer = NULL; - m_orientation = 0; - m_width = 0; - m_height = 0; -} - -COMXImageFile::~COMXImageFile() -{ - if(m_image_buffer) - free(m_image_buffer); -} - typedef enum { /* JPEG marker codes */ M_SOF0 = 0xc0, M_SOF1 = 0xc1, @@ -568,47 +535,47 @@ typedef enum { /* JPEG marker codes */ M_TEM = 0x01, } JPEG_MARKER; -static uint8_t inline READ8(uint8_t * &p) +static uint8_t inline READ8(const uint8_t * &p) { uint8_t r = p[0]; p += 1; return r; } -static uint16_t inline READ16(uint8_t * &p) +static uint16_t inline READ16(const uint8_t * &p) { uint16_t r = (p[0] << 8) | p[1]; p += 2; return r; } -static uint32_t inline READ32(uint8_t * &p) +static uint32_t inline READ32(const uint8_t * &p) { uint32_t r = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; p += 4; return r; } -static void inline SKIPN(uint8_t * &p, unsigned int n) +static void inline SKIPN(const uint8_t * &p, unsigned int n) { p += n; } -bool COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int orientation, std::string &error) +bool COMXImage::GetCodingType(const XFILE::auto_buffer &buf, unsigned int &width, unsigned int &height, int &orientation, std::string &error) { bool valid = false; bool progressive = false; int components = 0; - m_orientation = 0; + int m_orientation = 0; - if(!m_image_size) + if (buf.size() <= 0 || !buf.get()) { - error = "m_image_size unexpected"; + error = "buffer size unexpected"; return OMX_IMAGE_CodingMax; } - uint8_t *p = m_image_buffer; - uint8_t *q = m_image_buffer + m_image_size; + const uint8_t *p = reinterpret_cast(buf.get()); + const uint8_t *q = p + buf.size(); /* JPEG Header */ if(READ16(p) == 0xFFD8) @@ -855,9 +822,9 @@ bool COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int error = "unsupported image format"; // apply input orientation - m_orientation = m_orientation ^ orientation; - if(m_orientation < 0 || m_orientation >= 8) - m_orientation = 0; + orientation ^= m_orientation; + if(orientation < 0 || orientation >= 8) + orientation = 0; if(progressive) { @@ -871,7 +838,7 @@ bool COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int valid = false; } - if(m_width < 1 || m_height < 1) + if(width < 1 || height < 1) { error = "invalid dimensions"; valid = false; @@ -881,46 +848,6 @@ bool COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height, int } -bool COMXImageFile::ReadFile(const std::string& inputFile, int orientation) -{ - XFILE::CFile m_pFile; - m_filename = CURL::GetRedacted(inputFile); - if(!m_pFile.Open(inputFile, 0)) - { - CLog::Log(LOGERROR, "%s::%s %s not found\n", CLASSNAME, __func__, GetFilename()); - return false; - } - - if(m_image_buffer) - free(m_image_buffer); - m_image_buffer = NULL; - - m_image_size = m_pFile.GetLength(); - - if(!m_image_size) - { - CLog::Log(LOGERROR, "%s::%s %s m_image_size zero\n", CLASSNAME, __func__, GetFilename()); - return false; - } - m_image_buffer = (uint8_t *)malloc(m_image_size); - if(!m_image_buffer) - { - CLog::Log(LOGERROR, "%s::%s %s m_image_buffer null (%lu)\n", CLASSNAME, __func__, GetFilename(), m_image_size); - return false; - } - - m_pFile.Read(m_image_buffer, m_image_size); - m_pFile.Close(); - - std::string error; - if (!GetCodingType(m_width, m_height, orientation, error)) - { - CLog::Log(LOGNOTICE, "%s::%s %s %dx%d %s", CLASSNAME, __func__, GetFilename(), m_width, m_height, error.c_str()); - return false; - } - return true; -} - #ifdef CLASSNAME #undef CLASSNAME #endif @@ -1785,7 +1712,7 @@ bool COMXImageReEnc::HandlePortSettingChange(unsigned int resize_width, unsigned return true; } -bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, unsigned int maxHeight, void * &pDestBuffer, unsigned int &nDestSize) +bool COMXImageReEnc::ReEncode(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, unsigned int maxWidth, unsigned int maxHeight, int orientation, void * &pDestBuffer, unsigned int &nDestSize) { if (!m_gpu) return false; @@ -1793,21 +1720,21 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns CSingleLock lock(m_OMXSection); OMX_ERRORTYPE omx_err = OMX_ErrorNone; - COMXImage::ClampLimits(maxWidth, maxHeight, srcFile.GetWidth(), srcFile.GetHeight(), srcFile.GetOrientation() & 4); - unsigned int demuxer_bytes = srcFile.GetImageSize(); - unsigned char *demuxer_content = (unsigned char *)srcFile.GetImageBuffer(); + COMXImage::ClampLimits(maxWidth, maxHeight, width, height, orientation & 4); + unsigned int demuxer_bytes = buf.size(); + const uint8_t *demuxer_content = reinterpret_cast(buf.get()); // initial dest buffer size nDestSize = 0; if(!demuxer_content || !demuxer_bytes) { - CLog::Log(LOGERROR, "%s::%s %s no input buffer\n", CLASSNAME, __func__, srcFile.GetFilename()); + CLog::Log(LOGERROR, "%s::%s %s no input buffer\n", CLASSNAME, __func__, srcFile.c_str()); return false; } if(!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit)) { - CLog::Log(LOGERROR, "%s::%s %s error m_omx_decoder.Initialize\n", CLASSNAME, __func__, srcFile.GetFilename()); + CLog::Log(LOGERROR, "%s::%s %s error m_omx_decoder.Initialize\n", CLASSNAME, __func__, srcFile.c_str()); return false; } @@ -1819,7 +1746,7 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } @@ -1830,21 +1757,21 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } omx_err = m_omx_decoder.AllocInputBuffers(); if(omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.AllocInputBuffers result(0x%x)", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.AllocInputBuffers result(0x%x)", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting); if (omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.SetStateForComponent result(0x%x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s m_omx_decoder.SetStateForComponent result(0x%x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } @@ -1870,7 +1797,7 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer); return false; } @@ -1885,21 +1812,21 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, timeout); if(omx_err == OMX_ErrorNone) { - if (!HandlePortSettingChange(maxWidth, maxHeight, srcFile.GetOrientation(), port_settings_changed)) + if (!HandlePortSettingChange(maxWidth, maxHeight, orientation, port_settings_changed)) { - CLog::Log(LOGERROR, "%s::%s %s HandlePortSettingChange() failed\n", srcFile.GetFilename(), CLASSNAME, __func__); + CLog::Log(LOGERROR, "%s::%s %s HandlePortSettingChange() failed\n", srcFile.c_str(), CLASSNAME, __func__); return false; } port_settings_changed = true; } else if(omx_err == OMX_ErrorStreamCorrupt) { - CLog::Log(LOGERROR, "%s::%s %s - image not supported", CLASSNAME, __func__, srcFile.GetFilename()); + CLog::Log(LOGERROR, "%s::%s %s - image not supported", CLASSNAME, __func__, srcFile.c_str()); return false; } else if(timeout || omx_err != OMX_ErrorTimeout) { - CLog::Log(LOGERROR, "%s::%s %s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } @@ -1909,7 +1836,7 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_encoder.FillThisBuffer(m_encoded_buffer); if(omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s FillThisBuffer() failed (%x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s FillThisBuffer() failed (%x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); m_omx_encoder.DecoderFillBufferDone(m_omx_encoder.GetComponent(), m_encoded_buffer); return false; } @@ -1919,12 +1846,12 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns omx_err = m_omx_encoder.WaitForOutputDone(2000); if (omx_err != OMX_ErrorNone) { - CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone result(0x%x)\n", CLASSNAME, __func__, srcFile.GetFilename(), omx_err); + CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone result(0x%x)\n", CLASSNAME, __func__, srcFile.c_str(), omx_err); return false; } if (!m_encoded_buffer->nFilledLen) { - CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone no data\n", CLASSNAME, __func__, srcFile.GetFilename()); + CLog::Log(LOGERROR, "%s::%s %s m_omx_encoder.WaitForOutputDone no data\n", CLASSNAME, __func__, srcFile.c_str()); return false; } if (m_encoded_buffer->nFlags & OMX_BUFFERFLAG_EOS) @@ -1946,7 +1873,7 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns return false; pDestBuffer = m_pDestBuffer; - CLog::Log(LOGDEBUG, "%s::%s : %s %dx%d -> %dx%d\n", CLASSNAME, __func__, srcFile.GetFilename(), srcFile.GetWidth(), srcFile.GetHeight(), maxWidth, maxHeight); + CLog::Log(LOGDEBUG, "%s::%s : %s %dx%d -> %dx%d\n", CLASSNAME, __func__, srcFile.c_str(), maxWidth, maxHeight, maxWidth, maxHeight); m_success = true; Close(); diff --git a/xbmc/cores/omxplayer/OMXImage.h b/xbmc/cores/omxplayer/OMXImage.h index 987c4c7640a6d..10df0d21ac575 100644 --- a/xbmc/cores/omxplayer/OMXImage.h +++ b/xbmc/cores/omxplayer/OMXImage.h @@ -44,20 +44,19 @@ class COMXImage : public CThread virtual ~COMXImage(); void Initialize(); void Deinitialize(); - static COMXImageFile *LoadJpeg(const std::string& texturePath); - static void CloseJpeg(COMXImageFile *file); - static bool DecodeJpeg(COMXImageFile *file, unsigned int maxWidth, unsigned int maxHeight, unsigned int stride, void *pixels); + static bool DecodeJpeg(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int maxWidth, unsigned int maxHeight, unsigned int stride, void *pixels); static bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const std::string& destFile); static bool ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed = false); - static bool CreateThumb(const std::string& srcFile, unsigned int width, unsigned int height, std::string &additional_info, const std::string& destFile); + static bool CreateThumb(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, std::string &additional_info, const std::string& destFile); bool SendMessage(bool (*callback)(EGLDisplay egl_display, EGLContext egl_context, void *cookie), void *cookie); - bool DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata); + bool DecodeJpegToTexture(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, void **userdata); void DestroyTexture(void *userdata); void GetTexture(void *userdata, GLuint *texture); bool AllocTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex); bool DestroyTextureInternal(EGLDisplay egl_display, EGLContext egl_context, struct textureinfo *tex); + static bool GetCodingType(const XFILE::auto_buffer &buf, unsigned int &width, unsigned int &height, int &orientation, std::string &error); private: EGLContext m_egl_context; @@ -68,28 +67,6 @@ class COMXImage : public CThread std::queue m_texqueue; }; -class COMXImageFile -{ -public: - COMXImageFile(); - virtual ~COMXImageFile(); - bool ReadFile(const std::string& inputFile, int orientation = 0); - int GetOrientation() const { return m_orientation; }; - unsigned int GetWidth() const { return m_width; }; - unsigned int GetHeight() const { return m_height; }; - unsigned long GetImageSize() const { return m_image_size; }; - const uint8_t *GetImageBuffer() const { return (const uint8_t *)m_image_buffer; }; - const char *GetFilename() const { return m_filename.c_str(); }; -protected: - bool GetCodingType(unsigned int &width, unsigned int &height, int orientation, std::string &error); - uint8_t *m_image_buffer; - unsigned long m_image_size; - unsigned int m_width; - unsigned int m_height; - int m_orientation; - std::string m_filename; -}; - class COMXImageDec { public: @@ -144,7 +121,7 @@ class COMXImageReEnc // Required overrides void Close(); - bool ReEncode(COMXImageFile &srcFile, unsigned int width, unsigned int height, void * &pDestBuffer, unsigned int &nDestSize); + bool ReEncode(const std::string& srcFile, const XFILE::auto_buffer &buf, unsigned int width, unsigned int height, unsigned int maxWidth, unsigned int maxHeight, int orientation, void * &pDestBuffer, unsigned int &nDestSize); bool Gpu() { return m_gpu; } protected: bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, int orientation, bool port_settings_changed); diff --git a/xbmc/guilib/TexturePi.cpp b/xbmc/guilib/TexturePi.cpp index 1694f787055ea..8c49ba6f24e5d 100644 --- a/xbmc/guilib/TexturePi.cpp +++ b/xbmc/guilib/TexturePi.cpp @@ -106,29 +106,36 @@ bool CPiTexture::LoadFromFileInternal(const std::string& texturePath, unsigned i { if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool("videoplayer.acceleratedjpegs") && URIUtils::HasExtension(texturePath, ".jpg|.tbn")) { - COMXImageFile *file = g_OMXImage.LoadJpeg(texturePath); - if (file) + // Read image into memory to use our vfs + XFILE::CFile file; + XFILE::auto_buffer buf; + + if (file.LoadFile(texturePath, buf) <= 0) + return false; + + unsigned int width = 0, height = 0; + int orientation = 0; + std::string error; + if (g_OMXImage.GetCodingType(buf, width, height, orientation, error)) { bool okay = false; - int orientation = file->GetOrientation(); // limit the sizes of jpegs (even if we fail to decode) - g_OMXImage.ClampLimits(maxWidth, maxHeight, file->GetWidth(), file->GetHeight(), orientation & 4); + g_OMXImage.ClampLimits(maxWidth, maxHeight, width, height, orientation & 4); if (requirePixels) { Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8); - if (m_pixels && COMXImage::DecodeJpeg(file, maxWidth, GetRows(), GetPitch(), (void *)m_pixels)) + if (m_pixels && COMXImage::DecodeJpeg(texturePath, buf, maxWidth, GetRows(), GetPitch(), (void *)m_pixels)) okay = true; } else { - if (g_OMXImage.DecodeJpegToTexture(file, maxWidth, maxHeight, &m_egl_image) && m_egl_image) + if (g_OMXImage.DecodeJpegToTexture(texturePath, buf, maxWidth, maxHeight, &m_egl_image) && m_egl_image) { Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8); okay = true; } } - g_OMXImage.CloseJpeg(file); if (okay) { m_hasAlpha = false;