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