Skip to content
This repository
Browse code

[rbp/omxplayer] Restructure COMXImage

Tidy up of COMXImage. Separate into file reading, encode and decode classes with separate locks.
This allows some overlap of functionality which improves the speed.
  • Loading branch information...
commit ca509a110cccbeaad12b41068d8491f78886da0f 1 parent 5090ee1
popcornmix authored September 12, 2013
520  xbmc/cores/omxplayer/OMXImage.cpp
@@ -35,86 +35,130 @@
35 35
 #include "settings/AdvancedSettings.h"
36 36
 #include "settings/DisplaySettings.h"
37 37
 #include "settings/Settings.h"
  38
+#include "linux/RBP.h"
  39
+
  40
+#define EXIF_TAG_ORIENTATION    0x0112
  41
+
38 42
 
39 43
 #ifdef CLASSNAME
40 44
 #undef CLASSNAME
41 45
 #endif
42 46
 #define CLASSNAME "COMXImage"
43 47
 
44  
-#define CONTENTURI_MAXLEN 256
45  
-
46  
-#define EXIF_TAG_ORIENTATION    0x0112
47  
-
48  
-static CCriticalSection g_OMXSection;
49  
-
50  
-COMXImage::COMXImage()
  48
+bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
  49
+      unsigned int format, unsigned int pitch, const CStdString& destFile)
51 50
 {
52  
-  m_is_open       = false;
53  
-  m_image_size    = 0;
54  
-  m_image_buffer  = NULL;
55  
-  m_progressive   = false;
56  
-  m_alpha         = false;
57  
-  m_orientation   = 0;
58  
-  m_width         = 0;
59  
-  m_height        = 0;
60  
-
61  
-  m_decoded_buffer = NULL;
62  
-  m_encoded_buffer = NULL;
63  
-
64  
-  m_decoder_open  = false;
65  
-  m_encoder_open  = false;
66  
-
67  
-  OMX_INIT_STRUCTURE(m_decoded_format);
68  
-  OMX_INIT_STRUCTURE(m_encoded_format);
69  
-  memset(&m_omx_image, 0x0, sizeof(OMX_IMAGE_PORTDEFINITIONTYPE));
  51
+  COMXImageEnc omxImageEnc;
  52
+  bool ret = omxImageEnc.CreateThumbnailFromSurface(buffer, width, height, format, pitch, destFile);
  53
+  if (!ret)
  54
+    CLog::Log(LOGNOTICE, "%s: unable to create thumbnail %s %dx%d", __func__, destFile.c_str(), width, height);
  55
+  return ret;
70 56
 }
71 57
 
72  
-COMXImage::~COMXImage()
  58
+COMXImageFile *COMXImage::LoadJpeg(const CStdString& texturePath)
73 59
 {
74  
-  Close();
  60
+  COMXImageFile *file = new COMXImageFile();
  61
+  if (!file->ReadFile(texturePath))
  62
+  {
  63
+    CLog::Log(LOGNOTICE, "%s: unable to load %s", __func__, texturePath.c_str());
  64
+    delete file;
  65
+    file = NULL;
  66
+  }
  67
+  return file;
75 68
 }
76 69
 
77  
-void COMXImage::Close()
  70
+void COMXImage::CloseJpeg(COMXImageFile *file)
78 71
 {
79  
-  CSingleLock lock(g_OMXSection);
80  
-
81  
-  OMX_INIT_STRUCTURE(m_decoded_format);
82  
-  OMX_INIT_STRUCTURE(m_encoded_format);
83  
-  memset(&m_omx_image, 0x0, sizeof(OMX_IMAGE_PORTDEFINITIONTYPE));
  72
+  delete file;
  73
+}
84 74
 
85  
-  if(m_image_buffer)
86  
-    free(m_image_buffer);
  75
+bool COMXImage::DecodeJpeg(COMXImageFile *file, unsigned int width, unsigned int height, unsigned int stride, void *pixels)
  76
+{
  77
+  bool ret = false;
  78
+  COMXImageDec omx_image;
  79
+  if (omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, stride, pixels))
  80
+  {
  81
+    assert(width  == omx_image.GetDecodedWidth());
  82
+    assert(height == omx_image.GetDecodedHeight());
  83
+    assert(stride == omx_image.GetDecodedStride());
  84
+    ret = true;
  85
+  }
  86
+  else
  87
+    CLog::Log(LOGNOTICE, "%s: unable to decode %s %dx%d", __func__, file->GetFilename(), width, height);
  88
+  omx_image.Close();
  89
+  return ret;
  90
+}
87 91
 
88  
-  m_image_buffer  = NULL;
89  
-  m_image_size    = 0;
90  
-  m_width         = 0;
91  
-  m_height        = 0;
92  
-  m_is_open       = false;
93  
-  m_progressive   = false;
94  
-  m_orientation   = 0;
95  
-  m_decoded_buffer = NULL;
96  
-  m_encoded_buffer = NULL;
  92
+bool COMXImage::ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed)
  93
+{
  94
+  RESOLUTION_INFO& res_info = CDisplaySettings::Get().GetResolutionInfo(g_graphicsContext.GetVideoResolution());
  95
+  unsigned int max_width = width;
  96
+  unsigned int max_height = height;
  97
+  const unsigned int gui_width = transposed ? res_info.iHeight:res_info.iWidth;
  98
+  const unsigned int gui_height = transposed ? res_info.iWidth:res_info.iHeight;
  99
+  const float aspect = (float)m_width / m_height;
  100
+  bool clamped = false;
97 101
 
98  
-  if(m_decoder_open)
  102
+  if (max_width == 0 || max_height == 0)
99 103
   {
100  
-    m_omx_decoder.FlushInput();
101  
-    m_omx_decoder.FreeInputBuffers();
102  
-    m_omx_resize.FlushOutput();
103  
-    m_omx_resize.FreeOutputBuffers();
  104
+    max_height = g_advancedSettings.m_imageRes;
104 105
 
105  
-    m_omx_tunnel_decode.Deestablish();
106  
-    m_omx_decoder.Deinitialize();
107  
-    m_omx_resize.Deinitialize();
108  
-    m_decoder_open = false;
  106
+    if (g_advancedSettings.m_fanartRes > g_advancedSettings.m_imageRes)
  107
+    { // 16x9 images larger than the fanart res use that rather than the image res
  108
+      if (fabsf(aspect / (16.0f/9.0f) - 1.0f) <= 0.01f && m_height >= g_advancedSettings.m_fanartRes)
  109
+      {
  110
+        max_height = g_advancedSettings.m_fanartRes;
  111
+      }
  112
+    }
  113
+    max_width = max_height * 16/9;
109 114
   }
110 115
 
111  
-  if(m_encoder_open)
  116
+  if (gui_width)
  117
+    max_width = min(max_width, gui_width);
  118
+  if (gui_height)
  119
+    max_height = min(max_height, gui_height);
  120
+
  121
+  max_width  = min(max_width, 2048U);
  122
+  max_height = min(max_height, 2048U);
  123
+
  124
+  width = m_width;
  125
+  height = m_height;
  126
+  if (width > max_width || height > max_height)
112 127
   {
113  
-    m_omx_encoder.Deinitialize();
114  
-    m_encoder_open = false;
  128
+    if ((unsigned int)(max_width / aspect + 0.5f) > max_height)
  129
+      max_width = (unsigned int)(max_height * aspect + 0.5f);
  130
+    else
  131
+      max_height = (unsigned int)(max_width / aspect + 0.5f);
  132
+    width = max_width;
  133
+    height = max_height;
  134
+    clamped = true;
115 135
   }
  136
+  // Texture.cpp wants even width/height
  137
+  width  = (width  + 15) & ~15;
  138
+  height = (height + 15) & ~15;
116 139
 
117  
-  m_pFile.Close();
  140
+  return clamped;
  141
+}
  142
+
  143
+#ifdef CLASSNAME
  144
+#undef CLASSNAME
  145
+#endif
  146
+#define CLASSNAME "COMXImageFile"
  147
+
  148
+COMXImageFile::COMXImageFile()
  149
+{
  150
+  m_image_size    = 0;
  151
+  m_image_buffer  = NULL;
  152
+  m_orientation   = 0;
  153
+  m_width         = 0;
  154
+  m_height        = 0;
  155
+  m_filename      = "";
  156
+}
  157
+
  158
+COMXImageFile::~COMXImageFile()
  159
+{
  160
+  if(m_image_buffer)
  161
+    free(m_image_buffer);
118 162
 }
119 163
 
120 164
 typedef enum {      /* JPEG marker codes */
@@ -217,18 +261,13 @@ static void inline SKIPN(uint8_t * &p, unsigned int n)
217 261
   p += n;
218 262
 }
219 263
 
220  
-
221  
-OMX_IMAGE_CODINGTYPE COMXImage::GetCodingType()
  264
+OMX_IMAGE_CODINGTYPE COMXImageFile::GetCodingType(unsigned int &width, unsigned int &height)
222 265
 {
223  
-  memset(&m_omx_image, 0x0, sizeof(OMX_IMAGE_PORTDEFINITIONTYPE));
224  
-  m_width         = 0;
225  
-  m_height        = 0;
226  
-  m_progressive   = false;
  266
+  OMX_IMAGE_CODINGTYPE eCompressionFormat = OMX_IMAGE_CodingMax;
  267
+  bool progressive = false;
227 268
   int components = 0;
228 269
   m_orientation   = 0;
229 270
 
230  
-  m_omx_image.eCompressionFormat = OMX_IMAGE_CodingMax;
231  
-
232 271
   if(!m_image_size)
233 272
     return OMX_IMAGE_CodingMax;
234 273
 
@@ -238,7 +277,7 @@ OMX_IMAGE_CODINGTYPE COMXImage::GetCodingType()
238 277
   /* JPEG Header */
239 278
   if(READ16(p) == 0xFFD8)
240 279
   {
241  
-    m_omx_image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
  280
+    eCompressionFormat = OMX_IMAGE_CodingJPEG;
242 281
 
243 282
     READ8(p);
244 283
     unsigned char marker = READ8(p);
@@ -326,14 +365,14 @@ OMX_IMAGE_CODINGTYPE COMXImage::GetCodingType()
326 365
       {
327 366
         if(marker == M_SOF2 || marker == M_SOF6 || marker == M_SOF10 || marker == M_SOF14)
328 367
         {
329  
-          m_progressive = true;
  368
+          progressive = true;
330 369
         }
331 370
         int readBits = 2;
332 371
         SKIPN(p, 1);
333 372
         readBits ++;
334  
-        m_omx_image.nFrameHeight = READ16(p);
  373
+        height = READ16(p);
335 374
         readBits += 2;
336  
-        m_omx_image.nFrameWidth = READ16(p);
  375
+        width = READ16(p);
337 376
         readBits += 2;
338 377
         components = READ8(p);
339 378
         readBits += 1;
@@ -476,73 +515,36 @@ OMX_IMAGE_CODINGTYPE COMXImage::GetCodingType()
476 515
       marker = READ8(p);
477 516
 
478 517
     }
479  
-
480  
-    if(components > 3)
481  
-    {
482  
-      CLog::Log(LOGWARNING, "%s::%s Only YUV images are supported by decoder\n", CLASSNAME, __func__);
483  
-      m_omx_image.eCompressionFormat = OMX_IMAGE_CodingMax;
484  
-    }
485 518
   }
486 519
 
487 520
   if(m_orientation > 8)
488 521
     m_orientation = 0;
489 522
 
490  
-  m_width  = m_omx_image.nFrameWidth;
491  
-  m_height = m_omx_image.nFrameHeight;
492  
-
493  
-  return m_omx_image.eCompressionFormat;
494  
-}
495  
-
496  
-bool COMXImage::ClampLimits(unsigned int &width, unsigned int &height)
497  
-{
498  
-  RESOLUTION_INFO& res_info =  CDisplaySettings::Get().GetResolutionInfo(g_graphicsContext.GetVideoResolution());
499  
-  const bool transposed = m_orientation & 4;
500  
-  unsigned int max_width = width;
501  
-  unsigned int max_height = height;
502  
-  const unsigned int gui_width  = transposed ? res_info.iHeight:res_info.iWidth;
503  
-  const unsigned int gui_height = transposed ? res_info.iWidth:res_info.iHeight;
504  
-  const float aspect = (float)m_width / m_height;
505  
-
506  
-  if (max_width == 0 || max_height == 0)
  523
+  if(eCompressionFormat == OMX_IMAGE_CodingMax)
507 524
   {
508  
-    max_height = g_advancedSettings.m_imageRes;
509  
-
510  
-    if (g_advancedSettings.m_fanartRes > g_advancedSettings.m_imageRes)
511  
-    { // 16x9 images larger than the fanart res use that rather than the image res
512  
-      if (fabsf(aspect / (16.0f/9.0f) - 1.0f) <= 0.01f && m_height >= g_advancedSettings.m_fanartRes)
513  
-      {
514  
-        max_height = g_advancedSettings.m_fanartRes;
515  
-      }
516  
-    }
517  
-    max_width = max_height * 16/9;
  525
+    CLog::Log(LOGERROR, "%s::%s error unsupported image format\n", CLASSNAME, __func__);
518 526
   }
519 527
 
520  
-  if (gui_width)
521  
-    max_width = min(max_width, gui_width);
522  
-  if (gui_height)
523  
-    max_height = min(max_height, gui_height);
524  
-
525  
-  max_width  = min(max_width, 2048U);
526  
-  max_height = min(max_height, 2048U);
527  
-
  528
+  if(progressive)
  529
+  {
  530
+    CLog::Log(LOGWARNING, "%s::%s progressive images not supported by decoder\n", CLASSNAME, __func__);
  531
+    eCompressionFormat = OMX_IMAGE_CodingMax;
  532
+  }
528 533
 
529  
-  width = m_width;
530  
-  height = m_height;
531  
-  if (width > max_width || height > max_height)
  534
+  if(components > 3)
532 535
   {
533  
-    if ((unsigned int)(max_width / aspect + 0.5f) > max_height)
534  
-      max_width = (unsigned int)(max_height * aspect + 0.5f);
535  
-    else
536  
-      max_height = (unsigned int)(max_width / aspect + 0.5f);
537  
-    width = max_width;
538  
-    height = max_height;
539  
-    return true;
  536
+    CLog::Log(LOGWARNING, "%s::%s Only YUV images are supported by decoder\n", CLASSNAME, __func__);
  537
+    eCompressionFormat = OMX_IMAGE_CodingMax;
540 538
   }
541  
-  return false;
  539
+
  540
+  return eCompressionFormat;
542 541
 }
543 542
 
544  
-bool COMXImage::ReadFile(const CStdString& inputFile)
  543
+
  544
+bool COMXImageFile::ReadFile(const CStdString& inputFile)
545 545
 {
  546
+  XFILE::CFile      m_pFile;
  547
+  m_filename = inputFile.c_str();
546 548
   if(!m_pFile.Open(inputFile, 0))
547 549
   {
548 550
     CLog::Log(LOGERROR, "%s::%s %s not found\n", CLASSNAME, __func__, inputFile.c_str());
@@ -555,34 +557,79 @@ bool COMXImage::ReadFile(const CStdString& inputFile)
555 557
 
556 558
   m_image_size = m_pFile.GetLength();
557 559
 
558  
-  if(!m_image_size) {
  560
+  if(!m_image_size)
  561
+  {
559 562
     CLog::Log(LOGERROR, "%s::%s %s m_image_size zero\n", CLASSNAME, __func__, inputFile.c_str());
560 563
     return false;
561 564
   }
562 565
   m_image_buffer = (uint8_t *)malloc(m_image_size);
563  
-  if(!m_image_buffer) {
  566
+  if(!m_image_buffer)
  567
+  {
564 568
     CLog::Log(LOGERROR, "%s::%s %s m_image_buffer null (%lu)\n", CLASSNAME, __func__, inputFile.c_str(), m_image_size);
565 569
     return false;
566 570
   }
567 571
   
568 572
   m_pFile.Read(m_image_buffer, m_image_size);
  573
+  m_pFile.Close();
569 574
 
570  
-  if(GetCodingType() != OMX_IMAGE_CodingJPEG) {
571  
-    CLog::Log(LOGERROR, "%s::%s %s GetCodingType=0x%x\n", CLASSNAME, __func__, inputFile.c_str(), GetCodingType());
  575
+  OMX_IMAGE_CODINGTYPE eCompressionFormat = GetCodingType(m_width, m_height);
  576
+  if(eCompressionFormat != OMX_IMAGE_CodingJPEG)
  577
+  {
  578
+    CLog::Log(LOGERROR, "%s::%s %s GetCodingType=0x%x\n", CLASSNAME, __func__, inputFile.c_str(), eCompressionFormat);
572 579
     return false;
573 580
   }
574 581
 
575  
-  if(m_width < 1 || m_height < 1) {
  582
+  if(m_width < 1 || m_height < 1)
  583
+  {
576 584
     CLog::Log(LOGERROR, "%s::%s %s m_width=%d m_height=%d\n", CLASSNAME, __func__, inputFile.c_str(), m_width, m_height);
577 585
     return false;
578 586
   }
579 587
 
580  
-  m_is_open = true;
581  
-
582 588
   return true;
583 589
 }
584 590
 
585  
-bool COMXImage::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height)
  591
+#ifdef CLASSNAME
  592
+#undef CLASSNAME
  593
+#endif
  594
+#define CLASSNAME "COMXImageDec"
  595
+
  596
+COMXImageDec::COMXImageDec()
  597
+{
  598
+  m_decoded_buffer = NULL;
  599
+  OMX_INIT_STRUCTURE(m_decoded_format);
  600
+}
  601
+
  602
+COMXImageDec::~COMXImageDec()
  603
+{
  604
+  Close();
  605
+
  606
+  OMX_INIT_STRUCTURE(m_decoded_format);
  607
+  m_decoded_buffer = NULL;
  608
+}
  609
+
  610
+void COMXImageDec::Close()
  611
+{
  612
+  CSingleLock lock(m_OMXSection);
  613
+
  614
+  if(m_omx_decoder.IsInitialized())
  615
+  {
  616
+    m_omx_decoder.FlushInput();
  617
+    m_omx_decoder.FreeInputBuffers();
  618
+  }
  619
+  if(m_omx_resize.IsInitialized())
  620
+  {
  621
+    m_omx_resize.FlushOutput();
  622
+    m_omx_resize.FreeOutputBuffers();
  623
+  }
  624
+  if(m_omx_tunnel_decode.IsInitialized())
  625
+    m_omx_tunnel_decode.Deestablish();
  626
+  if(m_omx_decoder.IsInitialized())
  627
+    m_omx_decoder.Deinitialize(true);
  628
+  if(m_omx_resize.IsInitialized())
  629
+    m_omx_resize.Deinitialize(true);
  630
+}
  631
+
  632
+bool COMXImageDec::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height)
586 633
 {
587 634
   OMX_ERRORTYPE omx_err = OMX_ErrorNone;
588 635
   // on the first port settings changed event, we create the tunnel and alloc the buffer
@@ -593,6 +640,9 @@ bool COMXImage::HandlePortSettingChange(unsigned int resize_width, unsigned int
593 640
 
594 641
     port_def.nPortIndex = m_omx_decoder.GetOutputPort();
595 642
     m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
  643
+    port_def.format.image.nSliceHeight = 16;
  644
+    m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
  645
+
596 646
     port_def.nPortIndex = m_omx_resize.GetInputPort();
597 647
     m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
598 648
 
@@ -640,7 +690,7 @@ bool COMXImage::HandlePortSettingChange(unsigned int resize_width, unsigned int
640 690
     }
641 691
     assert(m_decoded_format.nBufferCountActual == 1);
642 692
 
643  
-    omx_err = m_omx_resize.AllocOutputBuffers();//false, true);
  693
+    omx_err = m_omx_resize.AllocOutputBuffers();
644 694
     if(omx_err != OMX_ErrorNone)
645 695
     {
646 696
       CLog::Log(LOGERROR, "%s::%s m_omx_resize.AllocOutputBuffers result(0x%x)\n", CLASSNAME, __func__, omx_err);
@@ -696,66 +746,50 @@ bool COMXImage::HandlePortSettingChange(unsigned int resize_width, unsigned int
696 746
   return true;
697 747
 }
698 748
 
699  
-bool COMXImage::Decode(unsigned width, unsigned height)
  749
+bool COMXImageDec::Decode(const uint8_t *demuxer_content, unsigned demuxer_bytes, unsigned width, unsigned height, unsigned stride, void *pixels)
700 750
 {
701  
-  CSingleLock lock(g_OMXSection);
702  
-  std::string componentName = "";
703  
-  unsigned int demuxer_bytes = 0;
704  
-  const uint8_t *demuxer_content = NULL;
  751
+  CSingleLock lock(m_OMXSection);
705 752
   OMX_ERRORTYPE omx_err = OMX_ErrorNone;
706 753
   OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
707 754
 
708  
-  if(!m_image_buffer)
  755
+  if(!demuxer_content || !demuxer_bytes)
709 756
   {
710 757
     CLog::Log(LOGERROR, "%s::%s no input buffer\n", CLASSNAME, __func__);
711 758
     return false;
712 759
   }
713 760
 
714  
-  if(GetCompressionFormat() == OMX_IMAGE_CodingMax)
715  
-  {
716  
-    CLog::Log(LOGERROR, "%s::%s error unsupported image format\n", CLASSNAME, __func__);
717  
-    return false;
718  
-  }
719  
-
720  
-  if(IsProgressive())
  761
+  if(!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit))
721 762
   {
722  
-    CLog::Log(LOGWARNING, "%s::%s progressive images not supported by decoder\n", CLASSNAME, __func__);
  763
+    CLog::Log(LOGERROR, "%s::%s error m_omx_decoder.Initialize\n", CLASSNAME, __func__);
723 764
     return false;
724 765
   }
725 766
 
726  
-  if(!m_is_open)
  767
+  if(!m_omx_resize.Initialize("OMX.broadcom.resize", OMX_IndexParamImageInit))
727 768
   {
728  
-    CLog::Log(LOGERROR, "%s::%s error not opened\n", CLASSNAME, __func__);
  769
+    CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize\n", CLASSNAME, __func__);
729 770
     return false;
730 771
   }
731 772
 
732  
-  componentName = "OMX.broadcom.image_decode";
733  
-  if(!m_omx_decoder.Initialize((const std::string)componentName, OMX_IndexParamImageInit))
734  
-  {
735  
-    CLog::Log(LOGERROR, "%s::%s error m_omx_decoder.Initialize\n", CLASSNAME, __func__);
736  
-    return false;
737  
-  }
  773
+  // set input format
  774
+  OMX_PARAM_PORTDEFINITIONTYPE portParam;
  775
+  OMX_INIT_STRUCTURE(portParam);
  776
+  portParam.nPortIndex = m_omx_decoder.GetInputPort();
738 777
 
739  
-  componentName = "OMX.broadcom.resize";
740  
-  if(!m_omx_resize.Initialize((const std::string)componentName, OMX_IndexParamImageInit))
  778
+  omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam);
  779
+  if(omx_err != OMX_ErrorNone)
741 780
   {
742  
-    CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize\n", CLASSNAME, __func__);
  781
+    CLog::Log(LOGERROR, "%s::%s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err);
743 782
     return false;
744 783
   }
745 784
 
746  
-  m_decoder_open = true;
747  
-  ClampLimits(width, height);
748  
-
749  
-  // set input format
750  
-  OMX_IMAGE_PARAM_PORTFORMATTYPE imagePortFormat;
751  
-  OMX_INIT_STRUCTURE(imagePortFormat);
752  
-  imagePortFormat.nPortIndex = m_omx_decoder.GetInputPort();
753  
-  imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG;
  785
+  portParam.nBufferCountActual = portParam.nBufferCountMin;
  786
+  portParam.nBufferSize = std::max(portParam.nBufferSize, ALIGN_UP(demuxer_bytes, portParam.nBufferAlignment));
  787
+  portParam.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
754 788
 
755  
-  omx_err = m_omx_decoder.SetParameter(OMX_IndexParamImagePortFormat, &imagePortFormat);
  789
+  omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam);
756 790
   if(omx_err != OMX_ErrorNone)
757 791
   {
758  
-    CLog::Log(LOGERROR, "%s::%s m_omx_decoder.SetParameter OMX_IndexParamImagePortFormat result(0x%x)\n", CLASSNAME, __func__, omx_err);
  792
+    CLog::Log(LOGERROR, "%s::%s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err);
759 793
     return false;
760 794
   }
761 795
 
@@ -773,11 +807,6 @@ bool COMXImage::Decode(unsigned width, unsigned height)
773 807
     return false;
774 808
   }
775 809
 
776  
-  demuxer_bytes   = GetImageSize();
777  
-  demuxer_content = GetImageBuffer();
778  
-  if(!demuxer_bytes || !demuxer_content)
779  
-    return false;
780  
-
781 810
   while(demuxer_bytes > 0 || !m_decoded_buffer)
782 811
   {
783 812
     long timeout = 0;
@@ -805,7 +834,7 @@ bool COMXImage::Decode(unsigned width, unsigned height)
805 834
          return false;
806 835
        }
807 836
     }
808  
-    else
  837
+    if (!demuxer_bytes)
809 838
     {
810 839
        // we've submitted all buffers so can wait now
811 840
        timeout = 1000;
@@ -819,35 +848,61 @@ bool COMXImage::Decode(unsigned width, unsigned height)
819 848
         return false;
820 849
       }
821 850
     }
822  
-    // we treat it as an error if a real timeout occurred
823  
-    else  if (timeout)
  851
+    else if(omx_err == OMX_ErrorStreamCorrupt)
824 852
     {
825  
-      CLog::Log(LOGERROR, "%s::%s HandlePortSettingChange() failed\n", CLASSNAME, __func__);
  853
+      CLog::Log(LOGERROR, "%s::%s - image not supported", CLASSNAME, __func__);
  854
+      return false;
  855
+    }
  856
+    else if(timeout || omx_err != OMX_ErrorTimeout)
  857
+    {
  858
+      CLog::Log(LOGERROR, "%s::%s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)\n", CLASSNAME, __func__, omx_err);
826 859
       return false;
827 860
     }
828 861
   }
829 862
 
830  
-  omx_err = m_omx_decoder.WaitForEvent(OMX_EventBufferFlag, 1000);
  863
+  omx_err = m_omx_resize.WaitForOutputDone(1000);
831 864
   if(omx_err != OMX_ErrorNone)
832 865
   {
833  
-    CLog::Log(LOGERROR, "%s::%s m_omx_decoder.WaitForEvent result(0x%x)\n", CLASSNAME, __func__, omx_err);
  866
+    CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForOutputDone result(0x%x)\n", CLASSNAME, __func__, omx_err);
834 867
     return false;
835 868
   }
836 869
 
837  
-  m_omx_tunnel_decode.Deestablish();
838  
-
839 870
   if(m_omx_decoder.BadState())
840 871
     return false;
841 872
 
  873
+  assert(m_decoded_buffer->nFilledLen <= stride * height);
  874
+  memcpy( (char*)pixels, m_decoded_buffer->pBuffer, m_decoded_buffer->nFilledLen);
  875
+
  876
+  Close();
842 877
   return true;
843 878
 }
844 879
 
  880
+#ifdef CLASSNAME
  881
+#undef CLASSNAME
  882
+#endif
  883
+#define CLASSNAME "COMXImageEnc"
  884
+
  885
+COMXImageEnc::COMXImageEnc()
  886
+{
  887
+  CSingleLock lock(m_OMXSection);
  888
+  OMX_INIT_STRUCTURE(m_encoded_format);
  889
+  m_encoded_buffer = NULL;
  890
+}
  891
+
  892
+COMXImageEnc::~COMXImageEnc()
  893
+{
  894
+  CSingleLock lock(m_OMXSection);
845 895
 
846  
-bool COMXImage::Encode(unsigned char *buffer, int size, unsigned width, unsigned height, unsigned int pitch)
  896
+  OMX_INIT_STRUCTURE(m_encoded_format);
  897
+  m_encoded_buffer = NULL;
  898
+  if(m_omx_encoder.IsInitialized())
  899
+    m_omx_encoder.Deinitialize(true);
  900
+}
  901
+
  902
+bool COMXImageEnc::Encode(unsigned char *buffer, int size, unsigned width, unsigned height, unsigned int pitch)
847 903
 {
848  
-  CSingleLock lock(g_OMXSection);
  904
+  CSingleLock lock(m_OMXSection);
849 905
 
850  
-  std::string componentName = "";
851 906
   unsigned int demuxer_bytes = 0;
852 907
   const uint8_t *demuxer_content = NULL;
853 908
   OMX_ERRORTYPE omx_err = OMX_ErrorNone;
@@ -863,15 +918,12 @@ bool COMXImage::Encode(unsigned char *buffer, int size, unsigned width, unsigned
863 918
     return false;
864 919
   }
865 920
 
866  
-  componentName = "OMX.broadcom.image_encode";
867  
-  if(!m_omx_encoder.Initialize((const std::string)componentName, OMX_IndexParamImageInit))
  921
+  if(!m_omx_encoder.Initialize("OMX.broadcom.image_encode", OMX_IndexParamImageInit))
868 922
   {
869 923
     CLog::Log(LOGERROR, "%s::%s error m_omx_encoder.Initialize\n", CLASSNAME, __func__);
870 924
     return false;
871 925
   }
872 926
 
873  
-  m_encoder_open = true;
874  
-
875 927
   OMX_PARAM_PORTDEFINITIONTYPE port_def;
876 928
   OMX_INIT_STRUCTURE(port_def);
877 929
   port_def.nPortIndex = m_omx_encoder.GetInputPort();
@@ -1001,10 +1053,10 @@ bool COMXImage::Encode(unsigned char *buffer, int size, unsigned width, unsigned
1001 1053
   if(omx_err != OMX_ErrorNone)
1002 1054
     return false;
1003 1055
 
1004  
-  omx_err = m_omx_encoder.WaitForEvent(OMX_EventBufferFlag, 1000);
  1056
+  omx_err = m_omx_encoder.WaitForOutputDone(1000);
1005 1057
   if(omx_err != OMX_ErrorNone)
1006 1058
   {
1007  
-    CLog::Log(LOGERROR, "%s::%s m_omx_encoder WaitForEvent result(0x%x)\n", CLASSNAME, __func__, omx_err);
  1059
+    CLog::Log(LOGERROR, "%s::%s m_omx_resize.WaitForOutputDone result(0x%x)\n", CLASSNAME, __func__, omx_err);
1008 1060
     return false;
1009 1061
   }
1010 1062
 
@@ -1022,97 +1074,17 @@ bool COMXImage::Encode(unsigned char *buffer, int size, unsigned width, unsigned
1022 1074
   return true;
1023 1075
 }
1024 1076
 
1025  
-unsigned char *COMXImage::GetDecodedData()
1026  
-{
1027  
-  if(!m_decoded_buffer)
1028  
-    return NULL;
1029  
-
1030  
-  return (unsigned char *)m_decoded_buffer->pBuffer;
1031  
-}
1032  
-
1033  
-unsigned int COMXImage::GetDecodedSize()
1034  
-{
1035  
-  if(!m_decoded_buffer)
1036  
-    return 0;
1037  
-  return (unsigned int)m_decoded_buffer->nFilledLen;
1038  
-}
1039  
-
1040  
-unsigned char *COMXImage::GetEncodedData()
1041  
-{
1042  
-  if(!m_encoded_buffer)
1043  
-    return NULL;
1044  
-
1045  
-  return (unsigned char *)m_encoded_buffer->pBuffer;
1046  
-}
1047  
-
1048  
-unsigned int COMXImage::GetEncodedSize()
1049  
-{
1050  
-  if(!m_encoded_buffer)
1051  
-    return 0;
1052  
-  return (unsigned int)m_encoded_buffer->nFilledLen;
1053  
-}
1054  
-
1055  
-bool COMXImage::SwapBlueRed(unsigned char *pixels, unsigned int height, unsigned int pitch, 
1056  
-  unsigned int elements, unsigned int offset)
1057  
-{
1058  
-  if (!pixels) return false;
1059  
-  unsigned char *dst = pixels;
1060  
-  for (unsigned int y = 0; y < height; y++)
1061  
-  {
1062  
-    dst = pixels + (y * pitch);
1063  
-    for (unsigned int x = 0; x < pitch; x+=elements)
1064  
-      std::swap(dst[x+offset], dst[x+2+offset]);
1065  
-  }
1066  
-  return true;
1067  
-}
1068  
-
1069  
-bool COMXImage::CreateThumbnail(const CStdString& sourceFile, const CStdString& destFile, 
1070  
-    int minx, int miny, bool rotateExif)
1071  
-{
1072  
-  if (!ReadFile(sourceFile))
1073  
-    return false;
1074  
-
1075  
-  return CreateThumbnailFromMemory(m_image_buffer, m_image_size, destFile, minx, miny);
1076  
-}
1077  
-
1078  
-bool COMXImage::CreateThumbnailFromMemory(unsigned char* buffer, unsigned int bufSize, const CStdString& destFile, 
1079  
-    unsigned int minx, unsigned int miny)
1080  
-{
1081  
-  if(!bufSize || !buffer)
1082  
-    return false;
1083  
-
1084  
-  if(!m_is_open)
1085  
-  {
1086  
-    m_image_size = bufSize;
1087  
-    m_image_buffer = (uint8_t *)malloc(m_image_size);
1088  
-    if(!m_image_buffer)
1089  
-      return false;
1090  
-
1091  
-    memcpy(m_image_buffer, buffer, m_image_size);
1092  
-
1093  
-    if(GetCodingType() != OMX_IMAGE_CodingJPEG) {
1094  
-      CLog::Log(LOGERROR, "%s::%s : %s GetCodingType()=0x%x\n", CLASSNAME, __func__, destFile.c_str(), GetCodingType());
1095  
-      return false;
1096  
-    }
1097  
-    m_is_open = true;
1098  
-  }
1099  
-
1100  
-  if(!Decode(minx, miny))
1101  
-    return false;
1102  
-
1103  
-  return CreateThumbnailFromSurface(GetDecodedData(), GetDecodedWidth(), GetDecodedHeight(), 
1104  
-    XB_FMT_A8R8G8B8, GetDecodedStride(), destFile);
1105  
-}
1106  
-
1107  
-bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, 
  1077
+bool COMXImageEnc::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
1108 1078
     unsigned int format, unsigned int pitch, const CStdString& destFile)
1109 1079
 {
1110  
-  if(format != XB_FMT_A8R8G8B8 || !buffer) {
  1080
+  if(format != XB_FMT_A8R8G8B8 || !buffer)
  1081
+  {
1111 1082
     CLog::Log(LOGDEBUG, "%s::%s : %s failed format=0x%x\n", CLASSNAME, __func__, destFile.c_str(), format);
1112 1083
     return false;
1113 1084
   }
1114 1085
 
1115  
-  if(!Encode(buffer, height * pitch, width, height, pitch)) {
  1086
+  if(!Encode(buffer, height * pitch, width, height, pitch))
  1087
+  {
1116 1088
     CLog::Log(LOGDEBUG, "%s::%s : %s encode failed\n", CLASSNAME, __func__, destFile.c_str());
1117 1089
     return false;
1118 1090
   }
@@ -1122,7 +1094,7 @@ bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int w
1122 1094
   {
1123 1095
     CLog::Log(LOGDEBUG, "%s::%s : %s width %d height %d\n", CLASSNAME, __func__, destFile.c_str(), width, height);
1124 1096
 
1125  
-    file.Write(GetEncodedData(), GetEncodedSize());
  1097
+    file.Write(m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen);
1126 1098
     file.Close();
1127 1099
     return true;
1128 1100
   }
95  xbmc/cores/omxplayer/OMXImage.h
@@ -37,72 +37,81 @@
37 37
 using namespace XFILE;
38 38
 using namespace std;
39 39
 
  40
+class COMXImageFile;
  41
+
40 42
 class COMXImage
41 43
 {
42 44
 public:
43  
-  COMXImage();
44  
-  virtual ~COMXImage();
  45
+  static COMXImageFile *LoadJpeg(const CStdString& texturePath);
  46
+  static void CloseJpeg(COMXImageFile *file);
45 47
 
46  
-  // Required overrides
47  
-  void Close(void);
48  
-  bool ClampLimits(unsigned int &width, unsigned int &height);
  48
+  static bool DecodeJpeg(COMXImageFile *file, unsigned int maxWidth, unsigned int maxHeight, unsigned int stride, void *pixels);
  49
+  static bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
  50
+      unsigned int format, unsigned int pitch, const CStdString& destFile);
  51
+  static bool ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed = false);
  52
+};
  53
+
  54
+class COMXImageFile
  55
+{
  56
+public:
  57
+  COMXImageFile();
  58
+  virtual ~COMXImageFile();
49 59
   bool ReadFile(const CStdString& inputFile);
50  
-  bool IsProgressive() { return m_progressive; };
51  
-  bool IsAlpha() { return m_alpha; };
52 60
   int  GetOrientation() { return m_orientation; };
53  
-  unsigned int GetOriginalWidth()  { return m_omx_image.nFrameWidth; };
54  
-  unsigned int GetOriginalHeight() { return m_omx_image.nFrameHeight; };
55 61
   unsigned int GetWidth()  { return m_width; };
56 62
   unsigned int GetHeight() { return m_height; };
57  
-  OMX_IMAGE_CODINGTYPE GetCodingType();
58  
-  const uint8_t *GetImageBuffer() { return (const uint8_t *)m_image_buffer; };
59 63
   unsigned long GetImageSize() { return m_image_size; };
60  
-  OMX_IMAGE_CODINGTYPE GetCompressionFormat() { return m_omx_image.eCompressionFormat; };
61  
-  bool Decode(unsigned int width, unsigned int height);
62  
-  bool Encode(unsigned char *buffer, int size, unsigned int width, unsigned int height, unsigned int pitch);
63  
-  unsigned int GetDecodedWidth() { return (unsigned int)m_decoded_format.format.image.nFrameWidth; };
64  
-  unsigned int GetDecodedHeight() { return (unsigned int)m_decoded_format.format.image.nFrameHeight; };
65  
-  unsigned int GetDecodedStride() { return (unsigned int)m_decoded_format.format.image.nStride; };
66  
-  unsigned char *GetDecodedData();
67  
-  unsigned int GetDecodedSize();
68  
-  unsigned int GetEncodedWidth() { return (unsigned int)m_encoded_format.format.image.nFrameWidth; };
69  
-  unsigned int GetEncodedHeight() { return (unsigned int)m_encoded_format.format.image.nFrameHeight; };
70  
-  unsigned int GetEncodedStride() { return (unsigned int)m_encoded_format.format.image.nStride; };
71  
-  unsigned char *GetEncodedData();
72  
-  unsigned int GetEncodedSize();
73  
-  bool SwapBlueRed(unsigned char *pixels, unsigned int height, unsigned int pitch, 
74  
-      unsigned int elements = 4, unsigned int offset=0);
75  
-  bool CreateThumbnail(const CStdString& sourceFile, const CStdString& destFile, 
76  
-      int minx, int miny, bool rotateExif);
77  
-  bool CreateThumbnailFromMemory(unsigned char* buffer, unsigned int bufSize, 
78  
-      const CStdString& destFile, unsigned int minx, unsigned int miny);
79  
-  bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, 
80  
-      unsigned int format, unsigned int pitch, const CStdString& destFile);
  64
+  const uint8_t *GetImageBuffer() { return (const uint8_t *)m_image_buffer; };
  65
+  const char *GetFilename() { return m_filename; };
81 66
 protected:
82  
-  bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height);
  67
+  OMX_IMAGE_CODINGTYPE GetCodingType(unsigned int &width, unsigned int &height);
83 68
   uint8_t           *m_image_buffer;
84  
-  bool              m_is_open;
85 69
   unsigned long     m_image_size;
86 70
   unsigned int      m_width;
87 71
   unsigned int      m_height;
88  
-  bool              m_progressive;
89  
-  bool              m_alpha;
90 72
   int               m_orientation;
91  
-  XFILE::CFile      m_pFile;
92  
-  OMX_IMAGE_PORTDEFINITIONTYPE  m_omx_image;
  73
+  const char *      m_filename;
  74
+};
93 75
 
  76
+class COMXImageDec
  77
+{
  78
+public:
  79
+  COMXImageDec();
  80
+  virtual ~COMXImageDec();
  81
+
  82
+  // Required overrides
  83
+  void Close();
  84
+  bool Decode(const uint8_t *data, unsigned size, unsigned int width, unsigned int height, unsigned stride, void *pixels);
  85
+  unsigned int GetDecodedWidth() { return (unsigned int)m_decoded_format.format.image.nFrameWidth; };
  86
+  unsigned int GetDecodedHeight() { return (unsigned int)m_decoded_format.format.image.nFrameHeight; };
  87
+  unsigned int GetDecodedStride() { return (unsigned int)m_decoded_format.format.image.nStride; };
  88
+protected:
  89
+  bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height);
94 90
   // Components
95 91
   COMXCoreComponent             m_omx_decoder;
96  
-  COMXCoreComponent             m_omx_encoder;
97 92
   COMXCoreComponent             m_omx_resize;
98 93
   COMXCoreTunel                 m_omx_tunnel_decode;
99 94
   OMX_BUFFERHEADERTYPE          *m_decoded_buffer;
100  
-  OMX_BUFFERHEADERTYPE          *m_encoded_buffer;
101 95
   OMX_PARAM_PORTDEFINITIONTYPE  m_decoded_format;
102  
-  OMX_PARAM_PORTDEFINITIONTYPE  m_encoded_format;
  96
+  CCriticalSection              m_OMXSection;
  97
+};
  98
+
  99
+class COMXImageEnc
  100
+{
  101
+public:
  102
+  COMXImageEnc();
  103
+  virtual ~COMXImageEnc();
103 104
 
104  
-  bool                          m_decoder_open;
105  
-  bool                          m_encoder_open;
  105
+  // Required overrides
  106
+  bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
  107
+      unsigned int format, unsigned int pitch, const CStdString& destFile);
  108
+protected:
  109
+  bool Encode(unsigned char *buffer, int size, unsigned int width, unsigned int height, unsigned int pitch);
  110
+  // Components
  111
+  COMXCoreComponent             m_omx_encoder;
  112
+  OMX_BUFFERHEADERTYPE          *m_encoded_buffer;
  113
+  OMX_PARAM_PORTDEFINITIONTYPE  m_encoded_format;
  114
+  CCriticalSection              m_OMXSection;
106 115
 };
107 116
 
108 117
 #endif
71  xbmc/guilib/Texture.cpp
@@ -223,66 +223,25 @@ bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned
223 223
   if (URIUtils::HasExtension(texturePath, ".jpg|.tbn")
224 224
       /*|| URIUtils::HasExtension(texturePath, ".png")*/)
225 225
   {
226  
-    COMXImage omx_image;
227  
-
228  
-    if(omx_image.ReadFile(texturePath))
  226
+    COMXImageFile *file = COMXImage::LoadJpeg(texturePath);
  227
+    if (file)
229 228
     {
230  
-      if(omx_image.Decode(maxWidth, maxHeight))
231  
-      {
232  
-        Allocate(omx_image.GetDecodedWidth(), omx_image.GetDecodedHeight(), XB_FMT_A8R8G8B8);
233  
-
234  
-        if(!m_pixels)
235  
-        {
236  
-          CLog::Log(LOGERROR, "Texture manager (OMX) out of memory");
237  
-          omx_image.Close();
238  
-          return false;
239  
-        }
240  
-
241  
-        m_originalWidth  = omx_image.GetOriginalWidth();
242  
-        m_originalHeight = omx_image.GetOriginalHeight();
243  
-
244  
-        m_hasAlpha = omx_image.IsAlpha();
245  
-
246  
-        if (autoRotate && omx_image.GetOrientation())
247  
-          m_orientation = omx_image.GetOrientation() - 1;
248  
-
249  
-        if(m_textureWidth != omx_image.GetDecodedWidth() || m_textureHeight != omx_image.GetDecodedHeight())
250  
-        {
251  
-          unsigned int imagePitch = GetPitch(m_imageWidth);
252  
-          unsigned int imageRows = GetRows(m_imageHeight);
253  
-          unsigned int texturePitch = GetPitch(m_textureWidth);
254  
-
255  
-          unsigned char *src = omx_image.GetDecodedData();
256  
-          unsigned char *dst = m_pixels;
257  
-          for (unsigned int y = 0; y < imageRows; y++)
258  
-          {
259  
-            memcpy(dst, src, imagePitch);
260  
-            src += imagePitch;
261  
-            dst += texturePitch;
262  
-          }
263  
-        }
264  
-        else
265  
-        {
266  
-          if(omx_image.GetDecodedData())
267  
-          {
268  
-            int size = ( ( GetPitch() * GetRows() ) > omx_image.GetDecodedSize() ) ?
269  
-                             omx_image.GetDecodedSize() : ( GetPitch() * GetRows() );
270  
-
271  
-            memcpy(m_pixels, (unsigned char *)omx_image.GetDecodedData(), size);
272  
-          }
273  
-        }
274  
-
275  
-        omx_image.Close();
276  
-
277  
-        return true;
278  
-      }
279  
-      else
  229
+      bool okay = false;
  230
+      int orientation = file->GetOrientation();
  231
+      // limit the sizes of jpegs (even if we fail to decode)
  232
+      COMXImage::ClampLimits(maxWidth, maxHeight, file->GetWidth(), file->GetHeight(), orientation & 4);
  233
+      Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8);
  234
+      if (m_pixels && COMXImage::DecodeJpeg(file, maxWidth, GetRows(), GetPitch(), (void *)m_pixels))
280 235
       {
281  
-        omx_image.Close();
  236
+        m_hasAlpha = false;
  237
+        if (autoRotate && orientation)
  238
+          m_orientation = orientation - 1;
  239
+        okay = true;
282 240
       }
  241
+      COMXImage::CloseJpeg(file);
  242
+      if (okay)
  243
+        return true;
283 244
     }
284  
-    // this limits the sizes of jpegs we failed to decode
285  
-    omx_image.ClampLimits(maxWidth, maxHeight);
286 245
   }
287 246
 #endif
288 247
   if (URIUtils::HasExtension(texturePath, ".dds"))
7  xbmc/pictures/Picture.cpp
@@ -45,13 +45,8 @@ bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width
45 45
   if (URIUtils::HasExtension(thumbFile, ".jpg"))
46 46
   {
47 47
 #if defined(HAS_OMXPLAYER)
48  
-    COMXImage *omxImage = new COMXImage();
49  
-    if (omxImage && omxImage->CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
50  
-    {
51  
-      delete omxImage;
  48
+    if (COMXImage::CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
52 49
       return true;
53  
-    }
54  
-    delete omxImage;
55 50
 #endif
56 51
   }
57 52
 

0 notes on commit ca509a1

Please sign in to comment.
Something went wrong with that request. Please try again.