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