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