1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of Code Aurora nor
12 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 #include "video_encoder_test.h"
29
30 #define DEBUG_PRINT printf
31 /************************************************************************/
32 /* #DEFINES */
33 /************************************************************************/
34
35 #define VOP_START_CODE 0x000001B6
36 #define SHORT_HEADER_START_CODE 0x00008000
37 #define H264_START_CODE 0x00000001
38
39 /************************************************************************/
40 /* STATIC VARIABLES */
41 /************************************************************************/
42
43 static int Code_type;
44 static int total_frames = 0;
45 static unsigned int header_code = 0;
46 static pthread_mutex_t read_lock;
47
48 static unsigned int read_frame ( unsigned char *dataptr,unsigned int length,
49 FILE * inputBufferFile
50 );
clp2(unsigned x)51 static unsigned clp2(unsigned x)
52 {
53 x = x - 1;
54 x = x | (x >> 1);
55 x = x | (x >> 2);
56 x = x | (x >> 4);
57 x = x | (x >> 8);
58 x = x | (x >>16);
59 return x + 1;
60 }
61
62
63 static void* video_thread (void *);
64 static void* async_thread (void *);
65
66
67
main(int argc,char ** argv)68 int main (int argc, char **argv)
69 {
70 struct video_encoder_context *encoder_context = NULL;
71 char *file_name = NULL;
72 FILE *file_ptr = NULL;
73 int temp1 =0,temp2 =0;
74 int error = 1;
75 unsigned int i = 0;
76
77 file_name = argv [1];
78 file_ptr = fopen (file_name,"rb");
79
80 if (file_ptr == NULL)
81 {
82 DEBUG_PRINT("\n File is not located ");
83 return -1;
84 }
85
86
87 encoder_context = (struct video_encoder_context *) \
88 calloc (sizeof (struct video_encoder_context),1);
89 if (encoder_context == NULL)
90 {
91 return -1;
92 }
93 encoder_context->outputBufferFile = NULL;
94 encoder_context->inputBufferFile = NULL;
95 encoder_context->video_driver_fd = -1;
96 encoder_context->inputBufferFile = file_ptr;
97 encoder_context->input_width = 176;
98 encoder_context->input_height = 144;
99 encoder_context->codectype = VEN_CODEC_MPEG4;
100 encoder_context->fps_num = 60;
101 encoder_context->fps_den = 2;
102 encoder_context->inputformat = VEN_INPUTFMT_NV12;
103 encoder_context->targetbitrate = 128000;
104
105 file_ptr = fopen ("/data/output.m4v","wb");
106 if (file_ptr == NULL)
107 {
108 DEBUG_PRINT("\n File can't be created");
109 free (encoder_context);
110 return -1;
111 }
112 encoder_context->outputBufferFile = file_ptr;
113
114 switch (atoi(argv[2]))
115 {
116 case 0:
117 DEBUG_PRINT("\n MPEG4 codec selected");
118 encoder_context->codectype = VEN_CODEC_MPEG4;
119 Code_type = 0;
120 break;
121 case 1:
122 DEBUG_PRINT("\n H.263");
123 encoder_context->codectype = VEN_CODEC_H263;
124 Code_type = 0;
125 break;
126 case 2:
127 DEBUG_PRINT("\n H.264");
128 encoder_context->codectype = VEN_CODEC_H264;
129 Code_type = 1;
130 break;
131 default:
132 DEBUG_PRINT("\n Wrong codec type");
133 error = -1;
134 break;
135 }
136
137 if (error != -1)
138 {
139 temp1 = atoi(argv[3]);
140 temp2 = atoi(argv[4]);
141
142 if (((temp1%16) != 0) || ((temp2%16) != 0))
143 {
144 error = -1;
145 }
146 else
147 {
148 encoder_context->input_width = temp1;
149 encoder_context->input_height = temp2;
150 }
151 }
152
153 switch (atoi(argv[5]))
154 {
155 case 0:
156 DEBUG_PRINT("\n No Sink");
157 encoder_context->outputBufferFile = NULL;
158 break;
159 }
160
161 if (error != -1)
162 {
163 encoder_context->targetbitrate = atoi (argv[6]);
164 }
165
166 if ( error != -1 && (init_encoder (encoder_context) == -1 ))
167 {
168 DEBUG_PRINT("\n Init decoder fails ");
169 error = -1;
170 }
171 DEBUG_PRINT("\n Decoder open successfull");
172
173
174 /*Allocate input and output buffers*/
175 if (error != -1 && (allocate_buffer (0,encoder_context)== -1))
176 {
177 DEBUG_PRINT("\n Error in input Buffer allocation");
178 error = -1;
179 }
180
181 if (error != -1 && (allocate_buffer (1,encoder_context)== -1))
182 {
183 DEBUG_PRINT("\n Error in output Buffer allocation");
184 error = -1;
185 }
186
187
188 if (error != -1 && (start_encoding (encoder_context) == -1))
189 {
190 DEBUG_PRINT("\n Error in start decoding call");
191 error = -1;
192 }
193
194 if (error != -1 && (stop_encoding (encoder_context) == -1))
195 {
196 DEBUG_PRINT("\n Error in stop decoding call");
197 error = -1;
198 }
199
200 DEBUG_PRINT("\n De-init the decoder");
201 if ((deinit_encoder (encoder_context) == -1))
202 {
203 error = -1;
204 }
205
206
207 (void)free_buffer (INPUT_BUFFER,encoder_context);
208 (void)free_buffer (OUTPUT_BUFFER,encoder_context);
209
210 if (encoder_context->inputBufferFile != NULL)
211 {
212 fclose (encoder_context->inputBufferFile);
213 }
214 if (encoder_context->outputBufferFile != NULL)
215 {
216 fclose (encoder_context->outputBufferFile);
217 }
218 DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames);
219 DEBUG_PRINT("\n closing the driver");
220 free (encoder_context);
221
222 return error;
223 }
224
init_encoder(struct video_encoder_context * init_decode)225 int init_encoder ( struct video_encoder_context *init_decode )
226 {
227 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
228 struct venc_basecfg basecfg;
229 struct video_queue_context *queue_ptr = NULL;
230 struct venc_ratectrlcfg ratecrl;
231 pthread_mutexattr_t init_values;
232 struct venc_profile profile;
233 struct ven_profilelevel profilelevel;
234
235 DEBUG_PRINT("\n Before calling the open");
236
237 init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \
238 O_RDWR | O_NONBLOCK);
239
240
241
242 if (init_decode->video_driver_fd < 0)
243 {
244 DEBUG_PRINT("\n Open failed");
245 return -1;
246 }
247
248 basecfg.codectype = init_decode->codectype;
249 basecfg.dvs_height = 0;
250 basecfg.dvs_width = 0;
251 basecfg.fps_den = init_decode->fps_den;
252 basecfg.fps_num = init_decode->fps_num;
253 basecfg.input_height = init_decode->input_height;
254 basecfg.input_width = init_decode->input_width;
255 basecfg.inputformat = init_decode->inputformat;
256 basecfg.targetbitrate = init_decode->targetbitrate;
257
258 /*Initialize Decoder with codec type and resolution*/
259 ioctl_msg.in = &basecfg;
260 ioctl_msg.out = NULL;
261
262 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG,
263 (void*)&ioctl_msg) < 0)
264 {
265 DEBUG_PRINT("\n Set base config type failed");
266 return -1;
267 }
268
269 /*Initialize Decoder with codec type and resolution*/
270 DEBUG_PRINT ("\n Switch off rate control");
271 ioctl_msg.in = &ratecrl;
272 ioctl_msg.out = NULL;
273 ratecrl.rcmode = VEN_RC_OFF;
274 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,
275 (void*)&ioctl_msg) < 0)
276 {
277 DEBUG_PRINT("\n Set rate control failed");
278 return -1;
279 }
280
281 if (basecfg.codectype == VEN_CODEC_H264)
282 {
283 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
284 ioctl_msg.in = &profile;
285 ioctl_msg.out = NULL;
286 profile.profile = VEN_PROFILE_H264_BASELINE;
287 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
288 (void*)&ioctl_msg) < 0)
289 {
290 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
291 return -1;
292 }
293
294 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
295 ioctl_msg.in = &profilelevel;
296 ioctl_msg.out = NULL;
297 profilelevel.level = VEN_LEVEL_H264_1p1;
298 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
299 (void*)&ioctl_msg) < 0)
300 {
301 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
302 return -1;
303 }
304
305 if (basecfg.input_width > 720)
306 {
307 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
308 ioctl_msg.in = &profile;
309 ioctl_msg.out = NULL;
310 profile.profile = VEN_PROFILE_H264_HIGH;
311 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
312 (void*)&ioctl_msg) < 0)
313 {
314 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
315 return -1;
316 }
317
318 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
319 ioctl_msg.in = &profilelevel;
320 ioctl_msg.out = NULL;
321 profilelevel.level = VEN_LEVEL_H264_3p1;
322 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
323 (void*)&ioctl_msg) < 0)
324 {
325 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
326 return -1;
327 }
328 }
329 }
330
331 DEBUG_PRINT("\n Query Input bufffer requirements");
332 /*Get the Buffer requirements for input and output ports*/
333
334
335
336 ioctl_msg.in = NULL;
337 ioctl_msg.out = &init_decode->input_buffer;
338
339 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,
340 (void*)&ioctl_msg) < 0)
341 {
342 DEBUG_PRINT("\n Requesting for input buffer requirements failed");
343 return -1;
344 }
345
346 DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \
347 (int)init_decode->input_buffer.datasize,\
348 (int)init_decode->input_buffer.mincount,\
349 (int)init_decode->input_buffer.actualcount);
350
351
352 ioctl_msg.in = &init_decode->input_buffer;
353 ioctl_msg.out = NULL;
354 init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2;
355
356 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,
357 (void*)&ioctl_msg) < 0)
358 {
359 DEBUG_PRINT("\n Set Buffer Requirements Failed");
360 return -1;
361 }
362
363
364 DEBUG_PRINT("\n Query output bufffer requirements");
365 ioctl_msg.in = NULL;
366 ioctl_msg.out = &init_decode->output_buffer;
367
368 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,
369 (void*)&ioctl_msg) < 0)
370 {
371 DEBUG_PRINT("\n Requesting for output buffer requirements failed");
372 return -1;
373 }
374
375 DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \
376 (int)init_decode->output_buffer.datasize,\
377 (int)init_decode->output_buffer.mincount,\
378 (int)init_decode->output_buffer.actualcount);
379
380 /*Create Queue related data structures*/
381 queue_ptr = &init_decode->queue_context;
382 queue_ptr->commandq_size = 50;
383 queue_ptr->dataq_size = 50;
384
385 sem_init(&queue_ptr->sem_message,0, 0);
386 sem_init(&init_decode->sem_synchronize,0, 0);
387
388 pthread_mutexattr_init (&init_values);
389 pthread_mutex_init (&queue_ptr->mutex,&init_values);
390 pthread_mutex_init (&read_lock,&init_values);
391 DEBUG_PRINT("\n create Queues");
392 queue_ptr->ptr_cmdq = (struct video_msgq*) \
393 calloc (sizeof (struct video_msgq),
394 queue_ptr->commandq_size);
395 queue_ptr->ptr_dataq = (struct video_msgq*) \
396 calloc (sizeof (struct video_msgq),
397 queue_ptr->dataq_size
398 );
399
400 if ( queue_ptr->ptr_cmdq == NULL ||
401 queue_ptr->ptr_dataq == NULL
402 )
403 {
404 return -1;
405 }
406 DEBUG_PRINT("\n create Threads");
407 /*Create two threads*/
408 if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread,
409 init_decode) < 0) ||
410 (pthread_create (&init_decode->asyncthread_id,NULL,async_thread,
411 init_decode) < 0)
412 )
413 {
414 return -1;
415 }
416
417 return 1;
418 }
419
420
421
free_buffer(unsigned int buffer_dir,struct video_encoder_context * encoder_context)422 int free_buffer ( unsigned int buffer_dir,
423 struct video_encoder_context *encoder_context
424 )
425 {
426 unsigned int buffercount = 0,i=0;
427 struct venc_bufferpayload **ptemp = NULL;
428
429 if (encoder_context == NULL)
430 {
431 return -1;
432 }
433
434 if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer)
435 {
436 buffercount = encoder_context->input_buffer.actualcount;
437 ptemp = encoder_context->ptr_inputbuffer;
438
439 for (i=0;i<buffercount;i++)
440 {
441 if (ptemp [i])
442 {
443 if (ptemp [i]->fd != -1)
444 {
445 munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
446 ptemp [i]->pbuffer = NULL;
447 close (ptemp [i]->fd);
448 }
449 free (ptemp [i]);
450 ptemp [i] = NULL;
451 }
452 }
453 free (encoder_context->ptr_inputbuffer);
454 encoder_context->ptr_inputbuffer = NULL;
455 }
456 else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer )
457 {
458 buffercount = encoder_context->output_buffer.actualcount;
459 ptemp = encoder_context->ptr_outputbuffer;
460
461 if (ptemp)
462 {
463 for (i=0;i<buffercount;i++)
464 {
465 if (ptemp [i])
466 {
467 if (ptemp [i]->fd != -1)
468 {
469 munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
470 ptemp [i]->pbuffer = NULL;
471 close (ptemp [i]->fd);
472 }
473 free (ptemp [i]);
474 ptemp [i] = NULL;
475 }
476 }
477 free (ptemp);
478 encoder_context->ptr_outputbuffer = NULL;
479 }
480 }
481
482 return 1;
483 }
484
allocate_buffer(unsigned int buffer_dir,struct video_encoder_context * encoder_context)485 int allocate_buffer ( unsigned int buffer_dir,
486 struct video_encoder_context *encoder_context
487 )
488 {
489 struct venc_bufferpayload **ptemp = NULL;
490 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
491 unsigned int buffercount = 0,i=0,alignedsize=0;
492 unsigned int buffersize = 0;
493
494 if ( encoder_context == NULL)
495 {
496 DEBUG_PRINT ("\nallocate_buffer: context is NULL");
497 return -1;
498 }
499
500 if ( buffer_dir == INPUT_BUFFER )
501 {
502 /*Check if buffers are allocated*/
503 if (encoder_context->ptr_inputbuffer != NULL)
504 {
505 DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set");
506 return -1;
507 }
508
509 buffercount = encoder_context->input_buffer.actualcount;
510 alignedsize = encoder_context->input_buffer.alignment;
511 buffersize = encoder_context->input_buffer.datasize;
512 buffersize = (buffersize + alignedsize) & (~alignedsize);
513 }
514 else if (buffer_dir == OUTPUT_BUFFER)
515 {
516 /*Check if buffers are allocated*/
517 if (encoder_context->ptr_outputbuffer != NULL)
518 {
519 DEBUG_PRINT ("\nallocate_buffer: Double allcoate output");
520 return -1;
521 }
522
523 buffercount = encoder_context->output_buffer.actualcount;
524 alignedsize = encoder_context->output_buffer.alignment;
525 buffersize = encoder_context->output_buffer.datasize;
526 buffersize = (buffersize + alignedsize) & (~alignedsize);
527
528 }
529 else
530 {
531 DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions");
532 return -1;
533 }
534
535 ptemp = (struct venc_bufferpayload **)\
536 calloc (sizeof (struct venc_bufferpayload *),buffercount);
537
538 if (ptemp == NULL)
539 {
540 DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure");
541 return -1;
542 }
543
544
545 if (buffer_dir == OUTPUT_BUFFER)
546 {
547 DEBUG_PRINT ("\nallocate_buffer: OUT");
548 encoder_context->ptr_outputbuffer = ptemp;
549 }
550 else
551 {
552 DEBUG_PRINT ("\nallocate_buffer: IN");
553 encoder_context->ptr_inputbuffer = ptemp;
554 }
555
556 /*Allocate buffer headers*/
557 for (i=0; i< buffercount; i++)
558 {
559 ptemp [i] = (struct venc_bufferpayload*)\
560 calloc (sizeof (struct venc_bufferpayload),1);
561
562 if (ptemp [i] == NULL)
563 {
564 DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure");
565 return -1;
566 }
567 ptemp [i]->fd = -1;
568 }
569
570 for (i=0; i< buffercount; i++)
571 {
572 ptemp [i]->fd = open ("/dev/pmem_adsp",O_RDWR);
573
574 if (ptemp [i]->fd < 0)
575 {
576 DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed");
577 return -1;
578 }
579
580 ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE,
581 MAP_SHARED,ptemp [i]->fd,0);
582 DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\
583 ptemp [i]->pbuffer);
584 if (ptemp [i]->pbuffer == MAP_FAILED)
585 {
586 ptemp [i]->pbuffer = NULL;
587 DEBUG_PRINT ("\nallocate_buffer: MMAP failed");
588 return -1;
589 }
590 ptemp [i]->sz = buffersize;
591 ptemp [i]->maped_size = clp2 (buffersize);
592
593 ioctl_msg.in = ptemp [i];
594 ioctl_msg.out = NULL;
595
596 if (buffer_dir == OUTPUT_BUFFER)
597 {
598 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,
599 &ioctl_msg) < 0)
600 {
601 DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed");
602 return -1;
603 }
604 }
605 else
606 {
607 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER,
608 &ioctl_msg) < 0)
609 {
610 DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed");
611 return -1;
612 }
613 }
614
615 }
616 DEBUG_PRINT ("\nallocate_buffer: Success");
617 return 1;
618 }
619
620
621
start_encoding(struct video_encoder_context * encoder_context)622 int start_encoding (struct video_encoder_context *encoder_context)
623 {
624 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
625 struct venc_buffer enc_buffer;
626 unsigned int i = 0;
627 unsigned int data_len =0;
628
629
630 if (encoder_context == NULL)
631 {
632 return -1;
633 }
634
635 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START,
636 NULL) < 0)
637 {
638 DEBUG_PRINT("\n Start failed");
639 return -1;
640 }
641
642 DEBUG_PRINT("\n Start Issued successfully waiting for Start Done");
643 /*Wait for Start command response*/
644 sem_wait (&encoder_context->sem_synchronize);
645
646 /*Push output Buffers*/
647 i = 0;
648 while (i < encoder_context->output_buffer.actualcount)
649 {
650 enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i];
651 enc_buffer.flags = 0;
652 enc_buffer.sz = encoder_context->ptr_outputbuffer [i]->sz;
653 enc_buffer.len = 0;
654 enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer;
655 enc_buffer.offset = 0;
656 enc_buffer.timestamp = 0;
657
658 DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
659 ioctl_msg.in = &enc_buffer;
660 ioctl_msg.out = NULL;
661
662 if (ioctl (encoder_context->video_driver_fd,
663 VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
664 {
665 DEBUG_PRINT("\n fill output frame failed");
666 return -1;
667 }
668 i++;
669 }
670
671
672 /*push input buffers*/
673 i = 0;
674 while (i < encoder_context->input_buffer.actualcount)
675 {
676 DEBUG_PRINT("\n Read Frame from File");
677
678 enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i];
679 enc_buffer.flags = 0;
680 enc_buffer.sz = encoder_context->ptr_inputbuffer [i]->sz;
681 enc_buffer.len = 0;
682 enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer;
683 enc_buffer.offset = 0;
684 enc_buffer.timestamp = total_frames *
685 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
686 enc_buffer.len = (encoder_context->input_height *
687 encoder_context->input_width *3)/2;
688 data_len = read_frame ( enc_buffer.ptrbuffer,
689 enc_buffer.len,
690 encoder_context->inputBufferFile);
691 if (data_len == 0)
692 {
693 DEBUG_PRINT("\n Length is zero error");
694 return -1;
695 }
696 enc_buffer.len = data_len;
697 DEBUG_PRINT("\n Read Frame from File szie = %d",(int)data_len);
698
699 DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
700 ioctl_msg.in = &enc_buffer;
701 ioctl_msg.out = NULL;
702
703 if (ioctl (encoder_context->video_driver_fd,
704 VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
705 {
706 DEBUG_PRINT("\n Encode input frame failed");
707 return -1;
708 }
709 total_frames++;
710 i++;
711 }
712 DEBUG_PRINT ("\n Wait for EOS");
713 /*Wait for EOS or Error condition*/
714 sem_wait (&encoder_context->sem_synchronize);
715 DEBUG_PRINT ("\n Reached EOS");
716
717 return 1;
718 }
719
stop_encoding(struct video_encoder_context * encoder_context)720 int stop_encoding (struct video_encoder_context *encoder_context)
721 {
722 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
723 struct venc_bufferflush buffer_flush;
724
725 if (encoder_context == NULL)
726 {
727 return -1;
728 }
729 buffer_flush.flush_mode = VEN_FLUSH_INPUT;
730 ioctl_msg.in = &buffer_flush;
731 ioctl_msg.out = NULL;
732
733 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
734 &ioctl_msg) < 0)
735 {
736 DEBUG_PRINT("\n Flush input failed");
737 }
738 else
739 {
740 sem_wait (&encoder_context->sem_synchronize);
741 }
742
743 buffer_flush.flush_mode = VEN_FLUSH_OUTPUT;
744 ioctl_msg.in = &buffer_flush;
745 ioctl_msg.out = NULL;
746
747 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
748 &ioctl_msg) < 0)
749 {
750 DEBUG_PRINT("\n Flush output failed");
751 }
752 else
753 {
754 sem_wait (&encoder_context->sem_synchronize);
755 }
756
757 DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP");
758 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0)
759 {
760 DEBUG_PRINT("\n Stop failed");
761 }
762 else
763 {
764 sem_wait (&encoder_context->sem_synchronize);
765 }
766 return 1;
767 }
768
deinit_encoder(struct video_encoder_context * init_decode)769 int deinit_encoder (struct video_encoder_context *init_decode)
770 {
771 if (init_decode == NULL)
772 {
773 return -1;
774 }
775
776 /*Close the driver*/
777 if (init_decode->video_driver_fd != -1)
778 {
779 close (init_decode->video_driver_fd);
780 }
781
782 if (init_decode->queue_context.ptr_cmdq)
783 {
784 free (init_decode->queue_context.ptr_cmdq);
785 init_decode->queue_context.ptr_cmdq = NULL;
786 }
787
788 if (init_decode->queue_context.ptr_dataq)
789 {
790 free (init_decode->queue_context.ptr_dataq);
791 init_decode->queue_context.ptr_dataq = NULL;
792 }
793
794 sem_destroy (&init_decode->queue_context.sem_message);
795 sem_destroy (&init_decode->sem_synchronize);
796
797 pthread_mutex_destroy(&init_decode->queue_context.mutex);
798 pthread_mutex_destroy (&read_lock);
799
800 return 1;
801 }
802
video_thread(void * context)803 static void* video_thread (void *context)
804 {
805 struct video_encoder_context *encoder_context = NULL;
806 struct video_msgq *queueitem = NULL;
807 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
808 struct venc_bufferpayload *tempbuffer = NULL;
809 struct venc_buffer enc_buffer;
810 unsigned int data_len =0;
811
812
813 if (context == NULL)
814 {
815 DEBUG_PRINT("\n video thread recieved NULL context");
816 return NULL;
817 }
818 encoder_context = (struct video_encoder_context *) context;
819
820 /* Thread function which will accept commands from async thread
821 * or main thread
822 */
823 while (1)
824 {
825 queueitem = queue_get_cmd (&encoder_context ->queue_context);
826 if (queueitem != NULL)
827 {
828 switch (queueitem->cmd)
829 {
830 case VEN_MSG_START:
831 DEBUG_PRINT("\n recived start done command");
832 sem_post (&encoder_context->sem_synchronize);
833 break;
834
835 case VEN_MSG_STOP:
836 DEBUG_PRINT("\n recieved stop done");
837 sem_post (&encoder_context->sem_synchronize);
838 break;
839
840 case VEN_MSG_INPUT_BUFFER_DONE:
841
842 tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
843 if (tempbuffer == NULL)
844 {
845 DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
846 sem_post (&encoder_context->sem_synchronize);
847 break;
848 }
849 tempbuffer->filled_len = (encoder_context->input_height *
850 encoder_context->input_width *3)/2;
851
852 data_len = read_frame ( tempbuffer->pbuffer,
853 tempbuffer->filled_len,
854 encoder_context->inputBufferFile);
855
856 if (data_len == 0)
857 {
858 DEBUG_PRINT ("\n End of stream reached");
859 sem_post (&encoder_context->sem_synchronize);
860 break;
861 }
862 enc_buffer.clientdata = (void *)tempbuffer;
863 enc_buffer.flags = 0;
864 enc_buffer.ptrbuffer = tempbuffer->pbuffer;
865 enc_buffer.sz = tempbuffer->sz;
866 enc_buffer.len = tempbuffer->filled_len;
867 enc_buffer.offset = 0;
868 enc_buffer.timestamp = total_frames *
869 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
870
871 /*TODO: Time stamp needs to be updated*/
872 ioctl_msg.in = &enc_buffer;
873 ioctl_msg.out = NULL;
874 total_frames++;
875 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,
876 &ioctl_msg) < 0)
877 {
878 DEBUG_PRINT("\n Decoder frame failed");
879 sem_post (&encoder_context->sem_synchronize);
880 }
881 DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\
882 total_frames);
883 break;
884
885 case VEN_MSG_OUTPUT_BUFFER_DONE:
886
887 tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
888 if (tempbuffer == NULL)
889 {
890 DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
891 sem_post (&encoder_context->sem_synchronize);
892 break;
893 }
894
895 if (encoder_context->outputBufferFile != NULL)
896 {
897 fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len,
898 encoder_context->outputBufferFile);
899 }
900
901
902 DEBUG_PRINT("\n recieved output buffer consume outbuffer");
903 DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\
904 tempbuffer->pbuffer);
905 enc_buffer.clientdata = (void *)tempbuffer;
906 enc_buffer.flags = 0;
907 enc_buffer.sz = tempbuffer->sz;
908 enc_buffer.len = 0;
909 enc_buffer.ptrbuffer = tempbuffer->pbuffer;
910 enc_buffer.offset = 0;
911 enc_buffer.timestamp = 0;
912
913 ioctl_msg.in = &enc_buffer;
914 ioctl_msg.out = NULL;
915
916 if (ioctl (encoder_context->video_driver_fd,
917 VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
918 {
919 DEBUG_PRINT("\n Decoder frame failed");
920 return NULL;
921 }
922
923 break;
924
925 case VEN_MSG_FLUSH_INPUT_DONE:
926 DEBUG_PRINT("\n Flush input complete");
927 sem_post (&encoder_context->sem_synchronize);
928 break;
929
930 case VEN_MSG_FLUSH_OUPUT_DONE:
931 DEBUG_PRINT("\n Flush output complete");
932 sem_post (&encoder_context->sem_synchronize);
933 break;
934 }
935
936 if (queueitem->cmd == VEN_MSG_STOP)
937 {
938 DEBUG_PRINT("\n Playback has ended thread will exit");
939 return NULL;
940 }
941 }
942 else
943 {
944 DEBUG_PRINT("\n Error condition recieved NULL from Queue");
945 }
946
947 }
948 }
949
async_thread(void * context)950 static void* async_thread (void *context)
951 {
952 struct video_encoder_context *encoder_context = NULL;
953 struct video_msgq queueitem ;
954 struct venc_msg venc_msg;
955 struct venc_bufferpayload *tempbuffer = NULL;
956 struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
957 int result = -1;
958
959 if (context == NULL)
960 {
961 DEBUG_PRINT("\n aynsc thread recieved NULL context");
962 return NULL;
963 }
964 encoder_context = (struct video_encoder_context *) context;
965 DEBUG_PRINT("\n Entering the async thread");
966
967 while (1)
968 {
969 ioctl_msg.in = NULL;
970 ioctl_msg.out = (void*)&venc_msg;
971 DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg));
972 DEBUG_PRINT("\n Address of Venc msg in async thread %p",\
973 ioctl_msg.out);
974 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\
975 (void*)&ioctl_msg) < 0)
976 {
977 DEBUG_PRINT("\n Error in ioctl read next msg");
978 }
979 else
980 {
981 switch (venc_msg.msgcode)
982 {
983 case VEN_MSG_START:
984 case VEN_MSG_STOP:
985 case VEN_MSG_INDICATION:
986 DEBUG_PRINT("\nSTOP/START Indiacation");
987 queueitem.cmd = venc_msg.msgcode;
988 queueitem.status = venc_msg.statuscode;
989 queueitem.clientdata = NULL;
990 break;
991
992 case VEN_MSG_INPUT_BUFFER_DONE:
993 DEBUG_PRINT("\nINPUT buffer done Indiacation");
994 queueitem.cmd = venc_msg.msgcode;
995 queueitem.status = venc_msg.statuscode;
996 queueitem.clientdata = (void *)venc_msg.buf.clientdata;
997 DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata);
998 tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
999 DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer);
1000 tempbuffer->filled_len = venc_msg.buf.len;
1001 DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
1002 break;
1003 case VEN_MSG_OUTPUT_BUFFER_DONE:
1004 DEBUG_PRINT("\nOUPUT buffer done Indiacation");
1005 queueitem.cmd = venc_msg.msgcode;
1006 queueitem.status = venc_msg.statuscode;
1007 queueitem.clientdata = (void *)venc_msg.buf.clientdata;
1008 DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata);
1009 tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
1010 DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer);
1011 tempbuffer->filled_len = venc_msg.buf.len;
1012 DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
1013 break;
1014
1015 default:
1016 DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode);
1017 queueitem.cmd = venc_msg.msgcode;
1018 queueitem.status = venc_msg.statuscode;
1019 queueitem.clientdata = NULL;
1020 break;
1021 }
1022 result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
1023 while (result == 0)
1024 {
1025 result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
1026 }
1027
1028 if (result == -1)
1029 {
1030 DEBUG_PRINT("\n FATAL ERROR WITH Queue");
1031 }
1032 }
1033 if (venc_msg.msgcode == VEN_MSG_STOP)
1034 {
1035 /*Thread can exit at this point*/
1036 return NULL;
1037 }
1038 }
1039 }
1040
1041
read_frame(unsigned char * dataptr,unsigned int length,FILE * inputBufferFile)1042 static unsigned int read_frame (unsigned char *dataptr, unsigned int length,
1043 FILE * inputBufferFile)
1044 {
1045
1046 unsigned int readOffset = 0;
1047 int bytes_read = 0;
1048 unsigned int code = 0;
1049 int found = 0;
1050
1051 DEBUG_PRINT ("\n Inside the readframe");
1052
1053 if (dataptr == NULL && length == 0)
1054 {
1055 DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length);
1056 return 0;
1057 }
1058
1059 pthread_mutex_lock(&read_lock);
1060 bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile);
1061 pthread_mutex_unlock(&read_lock);
1062
1063 return bytes_read;
1064 }
1065