]> git.vomp.tv Git - vompclient.git/blob - imageomx.cc
OSDOpenVG: Render on demand: Fix backing out of a view render race
[vompclient.git] / imageomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009,2014 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <bcm_host.h>
21 #include "videoomx.h"
22 #include "log.h"
23 #include "vdr.h"
24 #include "woptionpane.h"
25 #include "util.h"
26 #include "osdopenvg.h"
27
28 #include "imageomx.h"
29
30 ImageOMX::ImageOMX(OsdVector::PictureReader * treader):OsdVector::PictureDecoder(treader)
31 {
32   initted = 0;
33
34   omx_running=false;
35   pictInfValid=false;
36   omx_imag_decode/*dec*/=NULL;
37   omx_egl_render/*dec*/=NULL;
38
39   buf_head_egl=NULL;
40   curformat = Unsupported;
41
42   strcpy(L_VPE_OMX_IMAGE_DECODER, VPE_OMX_IMAGE_DECODER);
43   strcpy(L_VPE_OMX_EGL_REND, VPE_OMX_EGL_REND);
44 }
45
46 ImageOMX::~ImageOMX()
47 {
48
49 }
50
51 void ImageOMX::init()
52 {
53  // AllocateCodecsOMX();
54 }
55
56 void ImageOMX::shutdown()
57 {
58         Log::getInstance()->log("ImageOMX", Log::DEBUG, "shutdown");
59         //DeAllocateCodecsOMX();
60 }
61
62
63
64
65
66 OMX_ERRORTYPE ImageOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/,OMX_IN OMX_PTR /*appdata*/,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
67
68         //Log::getInstance()->log("Image", Log::NOTICE, "EmptyBufferDone");
69         ImageOMX* image = static_cast<ImageOMX*>(buffer->pAppPrivate);
70         image->ReturnEmptyOMXBuffer(buffer);
71         return OMX_ErrorNone;
72
73 }
74
75 void ImageOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
76         input_bufs_omx_mutex.lock();
77         /*if (buffer->pBuffer) {
78                 free(buffer->pBuffer);
79                 buffer->pBuffer = NULL;
80         }*/
81         buffer->nAllocLen= 0;
82         //Log::getInstance()->log("Image", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
83         input_bufs_omx_free.push_back(buffer);
84         //Log::getInstance()->log("Image", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
85         input_bufs_omx_mutex.unlock();
86         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
87
88         video->signalOmx();
89 }
90
91 OMX_ERRORTYPE ImageOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
92          Log::getInstance()->log("ImageOmx", Log::NOTICE, "FillBufferDone");
93          ImageOMX* image = static_cast<ImageOMX*>(buffer->pAppPrivate);
94          image->ReturnFillOMXBuffer(buffer);
95         return OMX_ErrorNone;
96 }
97
98 void ImageOMX::ReturnFillOMXBuffer(OMX_BUFFERHEADERTYPE* /*buffer*/)
99  {
100          //input_bufs_omx_mutex.lock();
101          omx_egl_filled = true;
102         //output_bufs_omx_full.push_back(buffer);
103         //input_bufs_omx_mutex.unlock();
104     VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
105          video->signalOmx();
106  }
107
108
109 /*
110
111 int ImageOMX::play() {
112         if (!initted)
113                 return 0;
114         lastAType=MPTYPE_MPEG_Image;
115         Log::getInstance()->log("Image", Log::DEBUG, "enter play");
116
117         ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
118
119         if (!AllocateCodecsOMX()) {
120                 return 0;
121         }
122         return 1;
123 }*/
124
125
126
127
128
129 int ImageOMX::AllocateCodecsOMX(unsigned char * buffer, unsigned int length)
130 {
131         OMX_ERRORTYPE error;
132         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
133
134         //Log::getInstance()->log("Image", Log::NOTICE, "Allocate Codecs OMX");
135         //Clock, move later to Image
136         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
137
138         OMX_PORT_PARAM_TYPE p_param;
139         memset(&p_param,0,sizeof(p_param));
140         p_param.nSize=sizeof(p_param);
141         p_param.nVersion.nVersion=OMX_VERSION;
142
143
144         video->LockClock();
145
146
147         error = OMX_GetHandle(&omx_imag_decode, L_VPE_OMX_IMAGE_DECODER, NULL, &callbacks);
148         if (error != OMX_ErrorNone) {
149                 Log::getInstance()->log("Image", Log::DEBUG,
150                                 "Init OMX Image decoder failed %x", error);
151                 video->UnlockClock();
152                 return 0;
153         }
154
155
156
157         error = OMX_GetParameter(omx_imag_decode, OMX_IndexParamImageInit, &p_param);
158         if (error != OMX_ErrorNone) {
159                 Log::getInstance()->log("Image", Log::DEBUG,
160                                 "Init OMX Image rend OMX_GetParameter failed %x", error);
161                 video->UnlockClock();
162                 return 0;
163         }
164         omx_image_input_port = p_param.nStartPortNumber;
165         omx_image_output_port = p_param.nStartPortNumber+1;
166
167
168
169
170         OMX_IMAGE_PARAM_PORTFORMATTYPE ft_type;
171         memset(&ft_type,0,sizeof(ft_type));
172         ft_type.nSize=sizeof(ft_type);
173         ft_type.nVersion.nVersion=OMX_VERSION;
174
175         ft_type.nPortIndex=omx_image_input_port;
176
177         switch (curformat)
178         {
179         case Jpeg: ft_type.eCompressionFormat=OMX_IMAGE_CodingJPEG;
180         break;
181         case PNG: ft_type.eCompressionFormat=OMX_IMAGE_CodingPNG;
182         break;
183
184         case Unsupported:
185           ;
186         }
187
188
189         error=OMX_SetParameter(omx_imag_decode,OMX_IndexParamImagePortFormat,&ft_type);
190         if (error!=OMX_ErrorNone){
191                 Log::getInstance()->log("Image", Log::DEBUG, "Init OMX_IndexParamVImagePortFormat failed %x", error);
192                 video->UnlockClock();
193                 return 0;
194         }
195
196         if (!video->DisablePort(omx_imag_decode,omx_image_input_port) || !video->DisablePort(omx_imag_decode,omx_image_output_port)) {
197                 Log::getInstance()->log("Image", Log::DEBUG, "Disable Ports OMX Image decoder failed");
198                 video->UnlockClock();
199                 return 0;
200         }
201
202
203         if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
204                 Log::getInstance()->log("Image", Log::DEBUG, "image decode idle ChangeComponentState");
205                 video->UnlockClock();
206                 return 0;
207         }
208
209
210
211         if (!PrepareInputBufsOMX(true, buffer, length)) {
212                 video->UnlockClock();
213                 Log::getInstance()->log("Image", Log::DEBUG, "prepare input bufs failed");
214                 return 0;
215         }
216
217
218
219
220
221
222
223         if (!video->ChangeComponentState(omx_imag_decode,OMX_StateExecuting)) {
224                 Log::getInstance()->log("Image", Log::DEBUG, "omx_image_decode ChangeComponentState Execute");
225                 video->UnlockClock();
226                 return 0;
227         }
228
229
230
231
232         if (!video->EnablePort(omx_imag_decode,omx_image_input_port,false)
233                                         ) {
234                 Log::getInstance()->log("Image", Log::DEBUG, "Enable Ports OMXdecoder inputfailed");
235                 video->UnlockClock();
236                 return 0;
237         }
238
239
240
241
242         video->UnlockClock();
243         omx_running=true;
244
245
246
247         //Log::getInstance()->log("Image", Log::NOTICE, "Allocate Codecs OMX finished");
248
249         return 1;
250 }
251
252
253
254
255
256
257 unsigned char* ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
258 {
259         if (pictInfValid) return buffer; // does support only one image at a Time;
260 //      Log::getInstance()->log("Image", Log::DEBUG,
261 //                                      "decodePicture 1");
262         EGLPictureCreator * pictcreat =dynamic_cast<EGLPictureCreator*>(Osd::getInstance());
263         curformat=Unsupported;
264         if (buffer[0]== 0xff && buffer[1] ==0xd8) curformat=Jpeg;
265         if (buffer[0]== 0x89 && buffer[1] ==0x50 && buffer[2] ==0x4e) curformat=PNG;
266
267         if (curformat == Unsupported)   return buffer; // Jpeg magic numbers
268 //      Log::getInstance()->log("Image", Log::DEBUG,
269 //                                              "decodePicture 2");
270         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
271
272
273         if (!pictcreat) return NULL;
274         int oldcancelstate;
275         int oldcanceltype;
276         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
277         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
278
279         if (!AllocateCodecsOMX(buffer,length)) {
280                 DeAllocateCodecsOMX();
281                 pthread_setcancelstate(oldcancelstate, NULL);
282                 pthread_setcanceltype(oldcanceltype, NULL);
283                 return NULL;
284         }
285         bool ret=intDecodePicture(index, buffer, length, pictcreat, video);
286         DeAllocateCodecsOMX();
287         pthread_setcancelstate(oldcancelstate, NULL);
288         pthread_setcanceltype(oldcanceltype, NULL);
289         if (ret && freemem) free(buffer);
290
291         if (ret) return NULL;
292         else return buffer;
293 }
294
295
296 bool ImageOMX::intDecodePicture(LoadIndex index, unsigned char* /* buffer */, unsigned int length, EGLPictureCreator* pictcreat, VideoOMX *video)
297 {
298         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
299
300         // Use Buffer
301         OMX_BUFFERHEADERTYPE * bufhead;
302
303         input_bufs_omx_mutex.lock();
304         int count =0;
305         while (input_bufs_omx_free.size()==0) {
306                 input_bufs_omx_mutex.unlock();
307                 //Log::getInstance()->log("Image", Log::DEBUG, "DMP mark 6");
308                 //Log::getInstance()->log("Image", Log::DEBUG, "Deliver MediaPacket no free sample");
309                 //return 0; // we do not have a free media sample
310
311                 count++;
312                 if (count>100) return false;
313                 MILLISLEEP(10);
314
315                 input_bufs_omx_mutex.lock();
316
317         }
318         bufhead=input_bufs_omx_free.front();
319         bufhead->nFilledLen=length;
320         //bufhead->nAllocLen= length;
321         bufhead->nOffset=0;
322         bufhead->nTimeStamp=VideoOMX::intToOMXTicks(0);
323         //bufhead->pBuffer=buffer;
324         bufhead->pAppPrivate=this;
325         input_bufs_omx_free.pop_front();
326         input_bufs_omx_mutex.unlock();
327
328
329         bufhead->nFilledLen=length;//bufhead->nAllocLen;
330         bufhead->nFlags=OMX_BUFFERFLAG_EOS;
331         video->ProtOMXEmptyThisBuffer(omx_imag_decode, bufhead);
332
333
334
335         video->LockClock();
336 //      Log::getInstance()->log("Image", Log::DEBUG,
337 //                      "decodePicture 3");
338
339         video->WaitForEvent(omx_imag_decode,OMX_EventPortSettingsChanged);
340
341         OMX_ERRORTYPE error;
342
343         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
344         memset(&port_def_type,0,sizeof(port_def_type));
345         port_def_type.nSize=sizeof(port_def_type);
346         port_def_type.nVersion.nVersion=OMX_VERSION;
347         port_def_type.nPortIndex=omx_image_output_port;
348 //      Log::getInstance()->log("Image", Log::DEBUG,
349 //                      "decodePicture 3a");
350
351         error=OMX_GetParameter(omx_imag_decode,OMX_IndexParamPortDefinition, &port_def_type);
352         if (error != OMX_ErrorNone) {
353                 Log::getInstance()->log("Image", Log::DEBUG,
354                                 "OMX_IndexParamPortDefinition fix failed %x", error);
355                 video->UnlockClock();
356                 return false;
357         }
358 //      Log::getInstance()->log("Image", Log::DEBUG,
359 //                      "decodePicture 4");
360
361
362
363
364
365
366
367
368 /*
369         video->DisablePort(omx_imag_decode,omx_image_output_port,false);
370         Log::getInstance()->log("Image", Log::DEBUG,
371                         "decodePicture 5");
372
373         if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortDisable,omx_image_output_port)) {
374                 video->UnlockClock();
375                 Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end iop");
376                 return false;
377         }*/
378
379         switch (curformat)
380         {
381         case Jpeg:
382                 port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
383                 port_def_type.format.image.nSliceHeight = 16;
384                 port_def_type.format.image.nStride = 0;
385                 break;
386         case PNG:
387                 //port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
388                 //port_def_type.format.image.nSliceHeight = 32;
389                 //port_def_type.format.image.nStride = 0;
390                 port_def_type.format.image.nFrameHeight+=-(port_def_type.format.image.nFrameHeight%32); // The OpenMax png part is broken for the last slice
391                 // so we cut the broken part, not nice but works
392                 break;
393
394         case Unsupported:
395                 ;
396         }
397
398
399
400
401
402         error = OMX_SetParameter(omx_imag_decode, OMX_IndexParamPortDefinition,
403                         &port_def_type);
404         if (error != OMX_ErrorNone) {
405                 Log::getInstance()->log("Image", Log::DEBUG,
406                                 "Set OMX_IndexParamPortDefinition1 failed %x", error);
407                 video->UnlockClock();
408                 return false;
409         }
410
411
412 //      Log::getInstance()->log("Image", Log::DEBUG,
413 //                      "decodePicture 5 6");
414         error=OMX_GetHandle(&omx_egl_render,L_VPE_OMX_EGL_REND,NULL,&callbacks);
415
416         if (error!=OMX_ErrorNone){
417                 Log::getInstance()->log("Image", Log::DEBUG, "Init OMX EGL renderer failed %x", error);
418                 video->UnlockClock();
419                 return false;
420         }
421
422         OMX_PORT_PARAM_TYPE p_param;
423         memset(&p_param,0,sizeof(p_param));
424         p_param.nSize=sizeof(p_param);
425         p_param.nVersion.nVersion=OMX_VERSION;
426
427         error=OMX_GetParameter(omx_egl_render,OMX_IndexParamVideoInit,&p_param);
428         if (error!=OMX_ErrorNone){
429                 Log::getInstance()->log("Image", Log::DEBUG, "Init OMX EGL renderer OMX_GetParameter failed %x", error);
430                 video->UnlockClock();
431                 return false;
432         }
433         omx_egl_input_port=p_param.nStartPortNumber;
434         omx_egl_output_port=p_param.nStartPortNumber+1;
435
436
437
438
439         if (!video->DisablePort(omx_egl_render,omx_egl_input_port) || !video->DisablePort(omx_egl_render,omx_egl_output_port)) {
440                 Log::getInstance()->log("Image", Log::DEBUG, "Disable Ports OMX Image decoder failed");
441                 video->UnlockClock();
442                 return false;
443         }
444
445
446         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
447                 Log::getInstance()->log("Image", Log::DEBUG, "egl render idle ChangeComponentState");
448                 video->UnlockClock();
449                 return false;
450         }
451
452
453
454         //Setuo chain
455
456 /*      if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortDisable,omx_egl_input_port)) {
457                 video->UnlockClock();
458                 Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end eip");
459                 return false;
460         }*/
461
462
463
464
465         /*      port_def_type.nPortIndex=omx_egl_input_port;
466         error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
467                                 &port_def_type);
468         if (error != OMX_ErrorNone) {
469                 Log::getInstance()->log("Image", Log::DEBUG,
470                                 "Set OMX_IndexParamPortDefinition3 failed %x", error);
471                 video->UnlockClock();
472                 pthread_setcancelstate(oldcancelstate, NULL);
473                 pthread_setcanceltype(oldcanceltype, NULL);
474                 return false;
475         }*/
476
477         pictInf.width = port_def_type.format.image.nFrameWidth;
478         pictInf.height = port_def_type.format.image.nFrameHeight;
479         pictInf.decoder = this;
480         pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
481         pictInf.lindex = index;
482
483
484         port_def_type.nPortIndex=omx_egl_output_port;
485
486         error=OMX_GetParameter(omx_egl_render,OMX_IndexParamPortDefinition, &port_def_type);
487         if (error != OMX_ErrorNone) {
488                 Log::getInstance()->log("Image", Log::DEBUG,
489                                 "OMX_IndexParamPortDefinition fix failed %x", error);
490                 video->UnlockClock();
491                 return false;
492         }
493
494
495
496         port_def_type.nBufferCountActual = 1;
497         EGLDisplay egl_display;
498         if (!pictcreat->getEGLPicture(pictInf, &egl_display)) {
499                 Log::getInstance()->log("Image", Log::DEBUG,
500                                 "getEGLPict failed");
501                 video->UnlockClock();
502                 return false;
503         }
504         Log::getInstance()->log("Image", Log::DEBUG,
505                         "getEGLPict %x",pictInf.reference);
506
507         port_def_type.format.video.pNativeWindow = egl_display;
508         error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
509                         &port_def_type);
510         if (error != OMX_ErrorNone) {
511                 Log::getInstance()->log("Image", Log::DEBUG,
512                                 "Set OMX_IndexParamPortDefinition3 failed %x", error);
513                 video->UnlockClock();
514                 return false;
515         }
516
517
518
519
520
521
522
523
524
525
526         error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,omx_egl_render,omx_egl_input_port);
527         if (error!=OMX_ErrorNone){
528                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel decode to egl rend failed %x ");
529                 video->UnlockClock();
530                 return 0;
531         }
532
533         if (!video->EnablePort(omx_imag_decode,omx_image_output_port,false) || !video->EnablePort(omx_egl_render,omx_egl_input_port,false)
534         ) {
535                 Log::getInstance()->log("Image", Log::DEBUG, "Enable Ports OMXdecoder rend failed");
536                 video->UnlockClock();
537                 return 0;
538         }
539
540         if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortEnable,omx_image_output_port)) {
541                 video->UnlockClock();
542                 Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end iop");
543                 return 0;
544         }
545
546         if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortEnable,omx_egl_input_port)) {
547                 video->UnlockClock();
548                 Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end eip");
549                 return 0;
550         }
551
552 //      Log::getInstance()->log("Image", Log::DEBUG,
553 //                      "decodePicture 7");
554         video->WaitForEvent(omx_egl_render,OMX_EventPortSettingsChanged);
555
556         Log::getInstance()->log("Image", Log::DEBUG,
557                         "decodePicture 8");
558
559
560
561
562
563
564
565         error=OMX_SendCommand(omx_egl_render/*dec*/,OMX_CommandPortEnable,omx_egl_output_port/*codec*/,0);
566         if (error!=OMX_ErrorNone){
567                 Log::getInstance()->log("Image", Log::DEBUG, "Prepare omx_egl_output_port Send Command to enable port %x", error);
568                 return 0;
569         }
570
571
572         error=OMX_UseEGLImage(omx_egl_render/*dec*/,&buf_head_egl,omx_egl_output_port/*codec*/, this, pictInf.reference);
573         if (error!=OMX_ErrorNone){
574                 Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_UseEGLImage failed %x", error);
575                 video->UnlockClock();
576                 return false;
577         }
578         buf_head_egl->pAppPrivate=this;
579
580 //      Log::getInstance()->log("Image", Log::DEBUG,
581 //                      "decodePicture 8 a");
582
583         video->EnablePort(omx_imag_decode,omx_image_output_port,false);
584
585         if (!video->CommandFinished(omx_egl_render/*dec*/,OMX_CommandPortEnable, omx_egl_output_port /*codec*/)) {
586                 video->UnlockClock();
587                 return false;
588         }
589
590
591
592
593         Log::getInstance()->log("Image", Log::DEBUG,
594                         "decodePicture 8 end");
595
596         if (!video->ChangeComponentState(omx_egl_render,OMX_StateExecuting)) {
597                 Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_rendd ChangeComponentState Execute");
598                 video->UnlockClock();
599                 return false;
600         }
601
602
603 //      Log::getInstance()->log("Image", Log::DEBUG,
604 //                      "decodePicture 9");
605         //video->EnablePort(omx_egl_render,omx_egl_output_port,false);
606
607 //      Log::getInstance()->log("Image", Log::DEBUG,
608 //                      "decodePicture 10");
609
610         omx_egl_filled = false;
611         error = OMX_FillThisBuffer(omx_egl_render, buf_head_egl);
612
613         if (error!=OMX_ErrorNone){
614                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_FillThisBuffer failed %x", error);
615                 video->UnlockClock();
616                 return false;
617         }
618         count =1;
619         video->UnlockClock();
620         while (!omx_egl_filled) {
621
622                 count++;
623                 if (count>500) {
624                         Log::getInstance()->log("Image", Log::DEBUG, "No one filled my buffer");
625                         return false;
626                 }
627                 MILLISLEEP(1);
628
629
630         }
631         omx_egl_filled = false;
632
633 //      Log::getInstance()->log("Image", Log::DEBUG,
634 //                      "decodePicture left");
635
636
637
638         pictInfValid=true;
639         return true;
640
641 }
642
643 bool ImageOMX::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
644 {
645         if (!pictInfValid) return false;
646         pict_inf=pictInf;
647         pictInfValid = false;
648         return true;
649 }
650
651 void ImageOMX::freeReference(void* /* ref */)
652 {
653 }
654
655 int ImageOMX::PrepareInputBufsOMX(bool setportdef, unsigned char * buffer, unsigned int length) //needs to be called with locvke omx clock mutex
656 {
657         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
658         OMX_ERRORTYPE error;
659         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
660         memset(&port_def_type,0,sizeof(port_def_type));
661         port_def_type.nSize=sizeof(port_def_type);
662         port_def_type.nVersion.nVersion=OMX_VERSION;
663         port_def_type.nPortIndex=omx_image_input_port;//omx_codec_input_port;
664
665         error=OMX_GetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
666
667         if (error!=OMX_ErrorNone){
668                         Log::getInstance()->log("Image", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
669         }
670
671
672         if (setportdef) {
673                 port_def_type.nBufferCountActual=port_def_type.nBufferCountMin;
674                 port_def_type.nBufferSize=max(port_def_type.nBufferSize,length); // for transcoder important
675
676                 error=OMX_SetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
677
678                 if (error!=OMX_ErrorNone){
679                         Log::getInstance()->log("Image", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
680                 }
681         }
682
683
684         error=OMX_SendCommand(omx_imag_decode/*dec*/,OMX_CommandPortEnable,omx_image_input_port/*codec*/,0);
685         if (error!=OMX_ErrorNone){
686                 Log::getInstance()->log("Image", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
687                 return 0;
688         }
689
690         input_bufs_omx_mutex.lock();
691         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
692                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
693                 error=OMX_UseBuffer(omx_imag_decode/*dec*/,&buf_head,omx_image_input_port/*codec*/,this,port_def_type.nBufferSize, buffer);
694                 if (error!=OMX_ErrorNone){
695                         Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_UseBuffer failed %x", error);
696                         input_bufs_omx_mutex.unlock();
697                         return 0;
698                 }
699                 input_bufs_omx_all.push_back(buf_head);
700                 input_bufs_omx_free.push_back(buf_head);
701         }
702         omx_first_frame=true;
703
704
705         input_bufs_omx_mutex.unlock();
706
707         if (!video->CommandFinished(omx_imag_decode/*dec*/,OMX_CommandPortEnable, omx_image_input_port /*codec*/)) {
708                 return 0;
709         }
710
711         return 1;
712 }
713
714 int ImageOMX::DestroyInputBufsOMX() //call with clock mutex locked
715 {
716         OMX_ERRORTYPE error;
717
718         input_bufs_omx_mutex.lock();
719         for (UINT i=0; i< input_bufs_omx_all.size();i++) {
720                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_FreeBuffer mark");
721                 //if (input_bufs_omx_all[i]->pBuffer) free(input_bufs_omx_all[i]->pBuffer);
722                 input_bufs_omx_all[i]->pBuffer=NULL;
723                 error=OMX_FreeBuffer(omx_imag_decode/*dec*/,omx_image_input_port/*codec*/,input_bufs_omx_all[i]);
724                 if (error!=OMX_ErrorNone){
725                         Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
726                         input_bufs_omx_mutex.unlock();
727                         return 0;
728                 }
729
730         }
731         input_bufs_omx_all.clear();
732         input_bufs_omx_free.clear();
733         input_bufs_omx_mutex.unlock();
734
735         return 1;
736 }
737
738 int ImageOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
739 {
740         //OMX_ERRORTYPE error;
741
742         input_bufs_omx_mutex.lock();
743         while (input_bufs_omx_all.size()>0) {
744                 if (input_bufs_omx_free.size()>0) {
745                         // Destroy one buffer
746                         std::vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
747                         OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
748                         for (; itty!= input_bufs_omx_all.end();itty++) {
749                                 if ((*itty)==cur_buf) {
750                                         input_bufs_omx_all.erase(itty);
751                                         input_bufs_omx_free.pop_front();
752                                         break;
753                                 }
754                         }
755                 } else {
756                         input_bufs_omx_mutex.unlock();
757                         MILLISLEEP(5);
758                         input_bufs_omx_mutex.lock();
759                 }
760         }
761
762         Log::getInstance()->log("Image", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
763         input_bufs_omx_mutex.unlock();
764         return 1;
765 }
766
767
768 int ImageOMX::DeAllocateCodecsOMX()
769 {
770         OMX_ERRORTYPE error;
771         omx_running=false;
772         VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
773 //       Log::getInstance()->log("Image", Log::DEBUG, "enter deallocatecodecsomx");
774
775
776
777 //   Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 1");
778
779 //   Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 2");
780
781    video->LockClock();
782         if (omx_imag_decode/*dec*/) {
783
784
785                 if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
786                         Log::getInstance()->log("Image", Log::DEBUG, "omx_imag_decode ChangeComponentState");
787                 }
788
789                 if (omx_egl_render) {
790
791                         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
792                                 Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_render ChangeComponentState");
793                         }
794                         /*if (!video->ChangeComponentState(omx_egl_render,OMX_StateLoaded,false)) {
795                                 Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_render ChangeComponentState");
796                         }*/
797                 }
798
799         /*      if (!video->ChangeComponentState(omx_imag_decode,OMX_StateLoaded,false)) {
800                         Log::getInstance()->log("Image", Log::DEBUG, "omx_imag_decode ChangeComponentState");
801                 }*/
802
803
804
805         // TODO proper deinit sequence
806                 // first flush all buffers
807
808
809
810 //              Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 3");
811
812                 error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_output_port, NULL);
813                 if (error!=OMX_ErrorNone) {
814                         Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
815
816                 }
817
818                 if (omx_egl_render) {
819
820                         if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
821                                 Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_render ChangeComponentState");
822                         }
823
824 //                      Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 4");
825
826                         error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_input_port, NULL);
827                         if (error!=OMX_ErrorNone) {
828                                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
829
830                         }
831
832 //                      Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 5");
833
834                         error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_output_port, NULL);
835                         if (error!=OMX_ErrorNone) {
836                                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
837
838                         }
839
840 //                      Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6");
841
842                         if (!video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_input_port) ||
843                                         !video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_output_port)) {
844                                 Log::getInstance()->log("Image", Log::DEBUG, "flush cmd clock shed failed");
845                         }
846 //                      Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6 a");
847                 }
848                 error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_input_port, NULL);
849                 if (error!=OMX_ErrorNone) {
850                         Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
851
852                 }
853
854                 if (buf_head_egl) {
855                         error=OMX_FreeBuffer(omx_egl_render/*dec*/, omx_egl_output_port/*codec*/,buf_head_egl);
856                         if (error!=OMX_ErrorNone){
857                                 Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_FreeBuffer 2 failed %x", error);
858                         }
859                 }
860
861                 buf_head_egl=NULL;
862
863
864 //              Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6 b");
865
866                 if (!video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_input_port) ||
867                                 !video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_output_port) ) {
868                         Log::getInstance()->log("Image", Log::DEBUG, "flush cmd clock shed failed");
869                 }
870
871 //              Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6 c");
872
873
874                 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
875
876 //              Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 7");
877
878                 //todo flushing
879                 if (!video->DisablePort(omx_imag_decode,omx_image_output_port,true)) {
880                         Log::getInstance()->log("Image", Log::DEBUG, "Disable Tunnel Port failed 1");
881                 }
882
883                 if (omx_egl_render) {
884
885                         if (!video->DisablePort(omx_egl_render,omx_egl_input_port,true)) {
886                                 Log::getInstance()->log("Image", Log::DEBUG, "Disable Tunnel Port failed 4");
887                         }
888
889
890                         error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,NULL,0);
891                         if (error!=OMX_ErrorNone) {
892                                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
893
894                         }
895
896                         error=OMX_SetupTunnel(omx_egl_render,omx_egl_input_port,NULL,0);
897                         if (error!=OMX_ErrorNone) {
898                                 Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
899
900                         }
901                 }
902
903
904 //              Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 8");
905
906
907                 //error=OMX_FreeHandle(omx_aud_dec);
908                 error=OMX_FreeHandle(omx_imag_decode);
909                 if (error!=OMX_ErrorNone) {
910                         Log::getInstance()->log("Image", Log::DEBUG, "FreeHandle failed %d", error);
911                 }
912                 if (omx_egl_render) {
913                         error=OMX_FreeHandle(omx_egl_render);
914                         if (error!=OMX_ErrorNone) {
915                                 Log::getInstance()->log("Image", Log::DEBUG, "FreeHandle failed %d", error);
916                         }
917                 }
918                 video->UnlockClock();
919
920                 video->clearEventsForComponent(omx_imag_decode);
921                 video->clearEventsForComponent(omx_egl_render); // removes spurious error messages
922                 omx_imag_decode/*dec*/=NULL;
923                 omx_egl_render/*dec*/=NULL;
924
925         } else  {
926
927                 video->UnlockClock();
928         }
929 //        Log::getInstance()->log("Image", Log::DEBUG, "leave deallocate codecs OMX");
930
931         return 1;
932 }