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