Add signal handler for viddec3test and videnc2test
[glsdk/omapdrmtest.git] / videnc2test.c
1 /*
2  * Copyright (c) 2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <unistd.h>
36 #include <stdint.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <time.h>
43 #include <sys/mman.h>
44 #include <signal.h>
47 #include <omap_drm.h>
48 #include <omap_drmif.h>
49 #include "libdce.h"
51 #include <ti/sdo/ce/Engine.h>
52 #include <ti/sdo/ce/video2/videnc2.h>
53 #include <ti/sdo/codecs/h264enc/ih264enc.h>
54 #include <ti/sdo/codecs/mpeg4enc/impeg4enc.h>
58 //#define PRINT_DEBUG
60 #define ERROR(FMT, ...)  printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
61 // enable below to print debug information
62 #ifdef PRINT_DEBUG
63 #define MSG(FMT, ...)  printf("%s:%d:\t%s\tdebug: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
64 #else
65 #define MSG(FMT, ...)
66 #endif
67 #define INFO(FMT, ...)  printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
68 #define MIN(a, b)        (((a) < (b)) ? (a) : (b))
70 /* align x to next highest multiple of 2^n */
71 #define ALIGN2(x, n)   (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
73 // Profile the init and encode calls
74 //#define PROFILE_TIME
76 // Getting codec version through XDM_GETVERSION
77 #define GETVERSION
79 enum {
80     IVAHD_H264_ENCODE,
81     IVAHD_MPEG4_ENCODE,
82     IVAHD_H263_ENCODE
83 };
85 enum {
86         DCE_ENC_TEST_H264  = 1,
87         DCE_ENC_TEST_MPEG4 = 2,
88         DCE_ENC_TEST_H263 = 3
89 };
91 enum {
92         MEMTYPE_INVALID = -1,
93         MEMTYPE_OMAPDRM = 0,
94 };
96 typedef struct _bufferDesc{
97         void *y_bo; //buffer object for y pointer
98         void *uv_bo; //buffer object for uv pointer
99         int fdy; // y dma buf
100         int fduv; // uv dma buf
101         int sizey; // size of y
102         int sizeuv; // size of uv
103         void *ybuff; // Virtual addresses of y
104         void *uvbuff; // virtual address of uv
105 }bufferdesc;
107 typedef struct encoderObj{
108         int drmfd; //DRM device fd
109         void *dev; // Device handle
110         char *in_pattern; //Input filename with full path
111         char *out_pattern; //Output filename with full path
112         FILE *fin; // Input stream
113         FILE *fout; // output stream
114         int width; //Frame width
115         int height; // Frame height
116         int codectype; // H264 or MPEG4 or H263
117         int profile;
118         int level;
119         int nframes; // Number of frames to write
120         int memtype; // Memory allocation scheme (OMAPDRM)
121         int fps; //Frame rate
122         int bps; //bitrate
123         bufferdesc buf; // Holds input buffer address
124         struct omap_bo *output_bo;
125         unsigned char *cdata;
126         struct omap_bo *mv_bo;
128         int padded_width;
129         int padded_height;
130         int num_buffers;
131         Engine_Handle            engine;
132         VIDENC2_Handle           codec;
133         VIDENC2_Params          *params;
134         VIDENC2_DynamicParams   *dynParams;
135         VIDENC2_Status          *status;
136         VIDENC2_DynamicParams   *dynParams1;
137         VIDENC2_Status          *status1;
138         IVIDEO2_BufDesc         *inBufs;
139         XDM2_BufDesc            *outBufs;
140         VIDENC2_InArgs          *inArgs;
141         VIDENC2_OutArgs         *outArgs;
143         // H.264 specific
144         IH264ENC_InArgs          *h264enc_inArgs;
145         IH264ENC_OutArgs         *h264enc_outArgs;
146         IH264ENC_Params          *h264enc_params;
147         IH264ENC_DynamicParams   *h264enc_dynParams;
148         IH264ENC_Status          *h264enc_status;
150         // MPEG4/H.263 specific
151         IMPEG4ENC_InArgs          *mpeg4enc_inArgs;
152         IMPEG4ENC_OutArgs         *mpeg4enc_outArgs;
153         IMPEG4ENC_Params          *mpeg4enc_params;
154         IMPEG4ENC_DynamicParams   *mpeg4enc_dynParams;
155         IMPEG4ENC_Status          *mpeg4enc_status;
157 }encoder;
158 /*
159  * A very simple VIDENC2 client which will encode raw (unstrided) NV12 YUV frames
160  * and write out to either h264, MPEG4, or H.263 format.
161  */
163 static int encoder_init(encoder *enc);
164 static int encoder_deinit(encoder *enc);
165 static void usage(char **argv);
168 static int read_NV12frame(encoder *enc)
170         int numbytes =  0;
171         if(!enc->fin){
172                 enc->fin = fopen(enc->in_pattern, "r+");
173                 if(!enc->fin){
174                         ERROR("Could not open input file %s\n", enc->in_pattern);
175                         goto bail;
176                 }
177         }
178         numbytes = fread(enc->buf.ybuff, 1, enc->width * enc->height, enc->fin);
179         numbytes += fread(enc->buf.uvbuff, 1, (enc->width * enc->height) / 2, enc->fin);
181         return numbytes;
182 bail:
183         return -1;
187 /* helper to write one frame of output */
188 int write_output(encoder *enc, int bytesToWrite)
190         int nbytes = -1;
191         if(!enc->fout){
192                 enc->fout = fopen(enc->out_pattern, "wb+");
193                 if(!enc->fout){
194                         ERROR("Could not open file for output %s", enc->out_pattern);
195                         goto fail;
196                 }
197         }
198         nbytes = fwrite(enc->cdata, 1, bytesToWrite, enc->fout);
199     return nbytes;
200 fail:
201         return -1;
205 static int parse_codecinfo(char *argv[], encoder *enc)
207 /*
208  * Configuration based on the input parameters
209  */
210         const char *argcodec    = argv[8];
211         const char *profile             = argv[9];
212         const char *level               = argv[10];
214         enc->level = atoi(level);
215     if( (!(strcmp(argcodec, "h264"))) ) {
216         enc->codectype = DCE_ENC_TEST_H264;
217         if( (!(strcmp(profile, "baseline"))) ) {
218             enc->profile = IH264_BASELINE_PROFILE;
219         } else if( (!(strcmp(profile, "high"))) ) {
220             enc->profile = IH264_HIGH_PROFILE;
221         } else {
222             ERROR("Wrong profile value. Please use: baseline or high.\n");
223                         usage(argv);
224             return -1;
225         }
227         switch(enc->level) {
228             case IH264_LEVEL_10 :
229             case IH264_LEVEL_1b :
230             case IH264_LEVEL_11 :
231             case IH264_LEVEL_12 :
232             case IH264_LEVEL_13 :
233             case IH264_LEVEL_20 :
234             case IH264_LEVEL_21 :
235             case IH264_LEVEL_22 :
236             case IH264_LEVEL_30 :
237             case IH264_LEVEL_31 :
238             case IH264_LEVEL_32 :
239             case IH264_LEVEL_40 :
240             case IH264_LEVEL_41 :
241             case IH264_LEVEL_42 :
242             case IH264_LEVEL_50 :
243             case IH264_LEVEL_51 :
244                 MSG("Acceptable H.264 level value = %d\n", enc->level);
245                 break;
246             default :
247                 ERROR("Wrong level value. Please use the correct level value for H.264\n");
248                                 usage(argv);
249                 return -1;
250         }
251     } else if( !(strcmp(argcodec, "mpeg4"))) {
253         enc->codectype = DCE_ENC_TEST_MPEG4;
255         if( (!(strcmp(profile, "simple"))) ) {
256             enc->profile = 3;
257         } else {
258             ERROR("Wrong profile value. Please use: simple\n");
259                         usage(argv);
260             return -1;
261         }
263         switch(enc->level) {
264             case IMPEG4ENC_SP_LEVEL_0 :
265             case IMPEG4ENC_SP_LEVEL_0B :
266             case IMPEG4ENC_SP_LEVEL_1 :
267             case IMPEG4ENC_SP_LEVEL_2 :
268             case IMPEG4ENC_SP_LEVEL_3 :
269             case IMPEG4ENC_SP_LEVEL_4A :
270             case IMPEG4ENC_SP_LEVEL_5 :
271             case IMPEG4ENC_SP_LEVEL_6 :
272                 MSG("Acceptable MPEG4 level value = %d\n", enc->level);
273                 break;
274             default :
275                 ERROR("Wrong level value. Please use the correct level value for MPEG4\n");
276                                 usage(argv);
277                 return -1;
278         }
279     } else if( !(strcmp(argcodec, "h263"))) {
281         enc->codectype = DCE_ENC_TEST_H263;
283         if( (!(strcmp(profile, "simple"))) ) {
284             enc->profile = 3;
285         } else {
286             ERROR("Wrong profile value. Please use: simple\n");
287                         usage(argv);
288             return -1;
289         }
291         switch(enc->level) {
292             case IMPEG4ENC_H263_LEVEL_10 :
293             case IMPEG4ENC_H263_LEVEL_20 :
294             case IMPEG4ENC_H263_LEVEL_30 :
295             case IMPEG4ENC_H263_LEVEL_40 :
296             case IMPEG4ENC_H263_LEVEL_45 :
297             case IMPEG4ENC_H263_LEVEL_50 :
298             case IMPEG4ENC_H263_LEVEL_60 :
299             case IMPEG4ENC_H263_LEVEL_70 :
300                 MSG("Acceptable H263 level value = %d\n", enc->level);
301                 break;
302             default :
303                 ERROR("Wrong level value. Please use the correct level value for H263\n");
304                                 usage(argv);
305                 return -1;
306         }
307     } else {
308         ERROR("No valid codec entry. Please use: h264 or mpeg4 or h263\n");
309                 usage(argv);
310         return -1;
311     }
312     MSG("Selected codec: %d\n", enc->codectype);
313         return 0;
317 static void usage(char **argv)
319         printf("usage: %s width height frames_to_write inpattern outpattern fps bitrate(kbps) codec baseline/high level buffertype\n", argv[0]);
320         printf("example: %s 1920 1088 300 in.yuv out.h264 15 128 h264 baseline 10 OMAPDRM\n", argv[0]);
321         printf("example: %s 176 144 300 in.yuv out.m4v 30 64 mpeg4 simple/baseline 0 OMAPDRM\n", argv[0]);
322         printf("example: %s 176 144 300 in.yuv out.m4v 15 150 h263 simple/baseline 0 OMAPDRM\n", argv[0]);
323         printf("Currently supported codecs: h264 or mpeg4 or h263\n");
324         printf("Currently supported Buffertypes: OMAPDRM\n");
325         printf("Run this command for help on the use case:%s\n", argv[0]);
326         return;
328 static int parse_command(int argc, char *argv[], encoder *enc)
331     if( argc != 12 ) {
332                 usage(argv);
333         return -1;
334     }
335     enc->width  = atoi(argv[1]);
336     enc->height = atoi(argv[2]);
337     enc->nframes = atoi(argv[3]);
338     enc->in_pattern  = argv[4];
339     enc->out_pattern = argv[5];
340         enc->fps = atoi(argv[6]);
341         enc->bps = atoi(argv[7]) * 1000;
342         if(parse_codecinfo(argv, enc))
343                 return -1;
345         if(!strcmp(argv[11], "OMAPDRM")){
346                 MSG("Only DRM buffer type supported.. Rolling back to OMAPDRM\n");
347         }
349         enc->memtype =  MEMTYPE_OMAPDRM;
350     MSG("Selected buffer: %d\n", enc->memtype);
352         return 0;
356 static void init_common_static_params(encoder *enc)
358         VIDENC2_Params *params = enc->params;
359     params->encodingPreset = XDM_USER_DEFINED; //XDM_USER_DEFINED; //XDM_EncodingPreset
360     params->rateControlPreset = IVIDEO_USER_DEFINED;
361     params->maxHeight = enc->height;
362     params->maxWidth = enc->width;
363     params->dataEndianness = XDM_BYTE; //XDM_DataFormat
364     params->maxBitRate = -1; //IGNORED
365     params->minBitRate = 0;
366     params->inputChromaFormat = XDM_YUV_420SP; //XDM_ChromaFormat
367     params->inputContentType = IVIDEO_PROGRESSIVE; //IVIDEO_ContentType
368     params->operatingMode = IVIDEO_ENCODE_ONLY; //IVIDEO_OperatingMode
369     params->profile = enc->profile;
370     params->level = enc->level;
371     params->inputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
372     params->outputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
373     params->numInputDataUnits = 1;
374     params->numOutputDataUnits = 1;
375     params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
376     params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
377     params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
378         return;
381 static int init_h264_static_params(encoder *enc)
383         IH264ENC_Params          *h264enc_params    = NULL;
384         enc->inArgs = dce_alloc(sizeof(IH264ENC_InArgs));
385         if(!enc->inArgs) goto bail;
386         enc->inArgs->size = sizeof(IH264ENC_InArgs);
387         enc->outArgs = dce_alloc(sizeof(IH264ENC_OutArgs));
388         if(!enc->outArgs) goto bail;
389         enc->outArgs->size = sizeof(IH264ENC_OutArgs);
390         enc->h264enc_outArgs = (IH264ENC_OutArgs *) enc->outArgs;
391         enc->params = dce_alloc(sizeof(IH264ENC_Params));
392         if(!enc->params) goto bail;
393         enc->params->size = sizeof(IH264ENC_Params);
395         init_common_static_params(enc);
396         MSG("H.264 Encoding with profile_value %d level %d", enc->profile, enc->level);
397         enc->params->maxInterFrameInterval = 1; //1,31 if IVIDEO_ContentType is IVIDEO_PROGRESSIVE
398     //Miscellaneous
399         h264enc_params    =  enc->h264enc_params = (IH264ENC_Params *) enc->params;
400         h264enc_params->interlaceCodingType = IH264_INTERLACE_DEFAULT;
401         h264enc_params->bottomFieldIntra = 0;
402         h264enc_params->gopStructure = IH264ENC_GOPSTRUCTURE_DEFAULT; // IH264ENC_GOPSTRUCTURE_NONUNIFORM
403         h264enc_params->entropyCodingMode = IH264_ENTROPYCODING_DEFAULT; // IH264_ENTROPYCODING_CAVLC - BASE PROFILE
404         h264enc_params->transformBlockSize = IH264_TRANSFORM_4x4; // BASE PROFILE
405         h264enc_params->log2MaxFNumMinus4 = 10;
406         h264enc_params->picOrderCountType = IH264_POC_TYPE_DEFAULT; // IH264_POC_TYPE_0
407         h264enc_params->enableWatermark = 0;
408         h264enc_params->IDRFrameInterval = 1;
409         h264enc_params->pConstantMemory = NULL;
410         h264enc_params->maxIntraFrameInterval = 0x7FFFFFFF;
411     h264enc_params->debugTraceLevel = 0;
412     h264enc_params->lastNFramesToLog = 0;
413     h264enc_params->enableAnalyticinfo = 0;
414     h264enc_params->enableGMVSei = 0;
415     h264enc_params->constraintSetFlags = 20;
416     h264enc_params->enableRCDO = 0;
417     h264enc_params->enableLongTermRefFrame = IH264ENC_LTRP_NONE;
418     h264enc_params->LTRPPeriod = 0;
420     //H-P Coding Control Params
421     h264enc_params->numTemporalLayer = IH264_TEMPORAL_LAYERS_1;
422     h264enc_params->referencePicMarking = IH264_LONG_TERM_PICTURE;
423     h264enc_params->reservedParams[0] = 0;
424     h264enc_params->reservedParams[1] = 0;
425     h264enc_params->reservedParams[2] = 0;
427     //rate control params
428     h264enc_params->rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
429     h264enc_params->rateControlParams.scalingMatrixPreset = IH264_SCALINGMATRIX_NONE;
430     h264enc_params->rateControlParams.rcAlgo = IH264_RATECONTROL_DEFAULT; // 0
431     h264enc_params->rateControlParams.qpI = 28;
432     h264enc_params->rateControlParams.qpMaxI = 36;
433     h264enc_params->rateControlParams.qpMinI = 10;
434     h264enc_params->rateControlParams.qpP = 28;
435     h264enc_params->rateControlParams.qpMaxP = 40;
436     h264enc_params->rateControlParams.qpMinP = 10;
437     h264enc_params->rateControlParams.qpOffsetB = 4;
438     h264enc_params->rateControlParams.qpMaxB = 44;
439     h264enc_params->rateControlParams.qpMinB = 10;
440     h264enc_params->rateControlParams.allowFrameSkip = 0;
441     h264enc_params->rateControlParams.removeExpensiveCoeff = 0;
442     h264enc_params->rateControlParams.chromaQPIndexOffset = 0;
443     h264enc_params->rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT; // 0
444     h264enc_params->rateControlParams.initialBufferLevel = 64000;
445     h264enc_params->rateControlParams.HRDBufferSize = 64000;
446     h264enc_params->rateControlParams.minPicSizeRatioI = 0;
447     h264enc_params->rateControlParams.maxPicSizeRatioI = 20;
448     h264enc_params->rateControlParams.minPicSizeRatioP = 0;
449     h264enc_params->rateControlParams.maxPicSizeRatioP = 0;
450     h264enc_params->rateControlParams.minPicSizeRatioB = 0;
451     h264enc_params->rateControlParams.maxPicSizeRatioB = 0;
452     h264enc_params->rateControlParams.enablePRC = 1;
453     h264enc_params->rateControlParams.enablePartialFrameSkip = 0;
454     h264enc_params->rateControlParams.discardSavedBits = 0;
455     h264enc_params->rateControlParams.reserved = 0;
456     h264enc_params->rateControlParams.VBRDuration = 8;
457     h264enc_params->rateControlParams.VBRsensitivity = 0;
458     h264enc_params->rateControlParams.skipDistributionWindowLength = 5;
459     h264enc_params->rateControlParams.numSkipInDistributionWindow =1;
460     h264enc_params->rateControlParams.enableHRDComplianceMode = 1;
461     h264enc_params->rateControlParams.frameSkipThMulQ5 = 0;
462     h264enc_params->rateControlParams.vbvUseLevelThQ5 = 0;
463     h264enc_params->rateControlParams.reservedRC[0] = 0;
464     h264enc_params->rateControlParams.reservedRC[1] = 0;
465     h264enc_params->rateControlParams.reservedRC[2] = 0;
467     //intercoding coding params
468     h264enc_params->interCodingParams.interCodingPreset = IH264_INTERCODING_USERDEFINED;
469     h264enc_params->interCodingParams.searchRangeHorP = 144;
470     h264enc_params->interCodingParams.searchRangeVerP = 32;
471     h264enc_params->interCodingParams.searchRangeHorB = 144;
472     h264enc_params->interCodingParams.searchRangeVerB = 16;
473     h264enc_params->interCodingParams.interCodingBias = IH264_BIASFACTOR_DEFAULT;
474     h264enc_params->interCodingParams.skipMVCodingBias = IH264_BIASFACTOR_MILD;
475     h264enc_params->interCodingParams.minBlockSizeP = IH264_BLOCKSIZE_8x8;
476     h264enc_params->interCodingParams.minBlockSizeB = IH264_BLOCKSIZE_8x8;
477     h264enc_params->interCodingParams.meAlgoMode = IH264ENC_MOTIONESTMODE_DEFAULT;
479     //intra coding params.
480     h264enc_params->intraCodingParams.intraCodingPreset = IH264_INTRACODING_DEFAULT;
481     h264enc_params->intraCodingParams.lumaIntra4x4Enable = 0;
482     h264enc_params->intraCodingParams.lumaIntra8x8Enable = 0x0FF;
483     h264enc_params->intraCodingParams.lumaIntra16x16Enable = 0;  // BASE PROFILE
484     h264enc_params->intraCodingParams.chromaIntra8x8Enable = 0;  // BASE PROFILE
485     h264enc_params->intraCodingParams.chromaComponentEnable = IH264_CHROMA_COMPONENT_CB_CR_BOTH;  // BASE PROFILE
486     h264enc_params->intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_DEFAULT;
487     h264enc_params->intraCodingParams.intraRefreshRate = 0;
488     h264enc_params->intraCodingParams.gdrOverlapRowsBtwFrames = 0;
489     h264enc_params->intraCodingParams.constrainedIntraPredEnable = 0;
490     h264enc_params->intraCodingParams.intraCodingBias = IH264ENC_INTRACODINGBIAS_DEFAULT;
492     //NALU Control Params.
493     h264enc_params->nalUnitControlParams.naluControlPreset = IH264_NALU_CONTROL_USERDEFINED;
494     h264enc_params->nalUnitControlParams.naluPresentMaskStartOfSequence = 0x01A0; // 416
495     h264enc_params->nalUnitControlParams.naluPresentMaskIDRPicture = 0x0020; //32
496     h264enc_params->nalUnitControlParams.naluPresentMaskIntraPicture = 2;
497     h264enc_params->nalUnitControlParams.naluPresentMaskNonIntraPicture = 2;
498     h264enc_params->nalUnitControlParams.naluPresentMaskEndOfSequence = 0x0C00; // 3072
500     //Slice coding params
501     h264enc_params->sliceCodingParams.sliceCodingPreset = IH264_SLICECODING_DEFAULT;
502     h264enc_params->sliceCodingParams.sliceMode = IH264_SLICEMODE_DEFAULT;
503     h264enc_params->sliceCodingParams.sliceUnitSize = 0;
504     h264enc_params->sliceCodingParams.sliceStartOffset[0] = 0;
505     h264enc_params->sliceCodingParams.sliceStartOffset[1] = 0;
506     h264enc_params->sliceCodingParams.sliceStartOffset[2] = 0;
507     h264enc_params->sliceCodingParams.streamFormat = IH264_STREAM_FORMAT_DEFAULT;
509     //Loop Filter Params
510     h264enc_params->loopFilterParams.loopfilterPreset = IH264_LOOPFILTER_DEFAULT;
511     h264enc_params->loopFilterParams.loopfilterDisableIDC = IH264_DISABLE_FILTER_DEFAULT;
512     h264enc_params->loopFilterParams.filterOffsetA = 0;
513     h264enc_params->loopFilterParams.filterOffsetB = 0;
515     //fmo coding params
516     h264enc_params->fmoCodingParams.fmoCodingPreset = IH264_FMOCODING_DEFAULT;
517     h264enc_params->fmoCodingParams.numSliceGroups = 1;
518     h264enc_params->fmoCodingParams.sliceGroupMapType = IH264_SLICE_GRP_MAP_DEFAULT; // 4
519     h264enc_params->fmoCodingParams.sliceGroupChangeDirectionFlag = IH264ENC_SLICEGROUP_CHANGE_DIRECTION_DEFAULT;
520     h264enc_params->fmoCodingParams.sliceGroupChangeRate = 0;
521     h264enc_params->fmoCodingParams.sliceGroupChangeCycle = 0;
522     h264enc_params->fmoCodingParams.sliceGroupParams[0] = 0;
523     h264enc_params->fmoCodingParams.sliceGroupParams[1] = 0;
525     //VUI Control Params
526     h264enc_params->vuiCodingParams.vuiCodingPreset = IH264_VUICODING_DEFAULT;
527     h264enc_params->vuiCodingParams.aspectRatioInfoPresentFlag = 0;
528     h264enc_params->vuiCodingParams.aspectRatioIdc = 0;
529     h264enc_params->vuiCodingParams.videoSignalTypePresentFlag = 0;
530     h264enc_params->vuiCodingParams.videoFormat = IH264ENC_VIDEOFORMAT_NTSC;
531     h264enc_params->vuiCodingParams.videoFullRangeFlag = 0;
532     h264enc_params->vuiCodingParams.timingInfoPresentFlag = 0;
533     h264enc_params->vuiCodingParams.hrdParamsPresentFlag = 0;
534     h264enc_params->vuiCodingParams.numUnitsInTicks= 1000;
536     //Stereo Info Control Params
537     h264enc_params->stereoInfoParams.stereoInfoPreset = IH264_STEREOINFO_DISABLE;
538     h264enc_params->stereoInfoParams.topFieldIsLeftViewFlag = 1;
539     h264enc_params->stereoInfoParams.viewSelfContainedFlag = 0;
541     //Frame Packing SEI Params
542     h264enc_params->framePackingSEIParams.framePackingPreset = IH264_FRAMEPACK_SEI_DISABLE;
543     h264enc_params->framePackingSEIParams.framePackingType = IH264_FRAMEPACK_TYPE_DEFAULT;
544     h264enc_params->framePackingSEIParams.frame0PositionX = 0;
545     h264enc_params->framePackingSEIParams.frame0PositionY = 0;
546     h264enc_params->framePackingSEIParams.frame1PositionX = 0;
547     h264enc_params->framePackingSEIParams.frame1PositionY = 0;
548     h264enc_params->framePackingSEIParams.reservedByte = 0;
550     //SVC coding params
551     h264enc_params->svcCodingParams.svcExtensionFlag = IH264_SVC_EXTENSION_FLAG_DISABLE;
552     h264enc_params->svcCodingParams.dependencyID = 0;
553     h264enc_params->svcCodingParams.qualityID = 0;
554     h264enc_params->svcCodingParams.enhancementProfileID = 0;
555     h264enc_params->svcCodingParams.layerIndex = 0;
556     h264enc_params->svcCodingParams.refLayerDQId = 0;
558     MSG("dce_alloc VIDENC2_Params successful h264enc_params=%p", h264enc_params);
559     enc->codec = VIDENC2_create(enc->engine, (char*) "ivahd_h264enc", (VIDENC2_Params *)h264enc_params);
560         if(!enc->codec){
561                 ERROR("Codec could not be created %p\n", enc->codec);
562                 goto bail;
563         }
564         return 0;
565 bail:
566         encoder_deinit(enc);
567         return -1;
570 static int init_mpeg4_static_params(encoder *enc)
572         IMPEG4ENC_Params          *mpeg4enc_params    = NULL;
573     enc->inArgs = dce_alloc(sizeof(IMPEG4ENC_InArgs));
574         if(!enc->inArgs) goto bail;
575     enc->inArgs->size = sizeof(IMPEG4ENC_InArgs);
577     enc->outArgs = dce_alloc(sizeof(IMPEG4ENC_OutArgs));
578         if(!enc->outArgs) goto bail;
579     enc->outArgs->size = sizeof (IMPEG4ENC_OutArgs);
580     enc->mpeg4enc_outArgs = (IMPEG4ENC_OutArgs *) enc->outArgs;
582     enc->params = dce_alloc(sizeof(IMPEG4ENC_Params));
583         if(!enc->params) goto bail;
584     enc->params->size = sizeof(IMPEG4ENC_Params);
586         init_common_static_params(enc);
588         enc->params->maxInterFrameInterval = 0;
589     mpeg4enc_params = enc->mpeg4enc_params = (IMPEG4ENC_Params *) enc->params;
591     mpeg4enc_params->useDataPartitioning = 0;
592     mpeg4enc_params->useRvlc = 0;
593     if( enc->codectype == DCE_ENC_TEST_H263 ) {
594         mpeg4enc_params->useShortVideoHeader = 1;
595     } else {
596         mpeg4enc_params->useShortVideoHeader = 0;
597     }
598     mpeg4enc_params->vopTimeIncrementResolution = 30;
599     mpeg4enc_params->nonMultiple16RefPadMethod = IMPEG4_PAD_METHOD_MPEG4;
600     mpeg4enc_params->pixelRange = IMPEG4ENC_PR_0_255;
601     mpeg4enc_params->enableSceneChangeAlgo = IMPEG4ENC_SCDA_DISABLE;
602     mpeg4enc_params->useVOS = 0;
603     mpeg4enc_params->enableMONA = 0;
604     mpeg4enc_params->enableAnalyticinfo = -1;
605     mpeg4enc_params->debugTraceLevel = 0;
606     mpeg4enc_params->lastNFramesToLog = 0;
608     // IMPEG4ENC_RateControlParams
609     mpeg4enc_params->rateControlParams.rateControlParamsPreset = IMPEG4_RATECONTROLPARAMS_DEFAULT;
610     mpeg4enc_params->rateControlParams.rcAlgo = IMPEG4_RATECONTROLALGO_VBR;
611     mpeg4enc_params->rateControlParams.qpI = 5;
612     mpeg4enc_params->rateControlParams.qpP = 5;
613     mpeg4enc_params->rateControlParams.seIntialQP = 5;
614     mpeg4enc_params->rateControlParams.qpMax = 31;
615     mpeg4enc_params->rateControlParams.qpMin = 1;
616     mpeg4enc_params->rateControlParams.enablePerceptualQuantMode = 0;
617     mpeg4enc_params->rateControlParams.allowFrameSkip = 0;
618     mpeg4enc_params->rateControlParams.initialBufferLevel = 0;
619     mpeg4enc_params->rateControlParams.vbvBufferSize = 0;
620     mpeg4enc_params->rateControlParams.qpMinIntra = 0;
622     // IMPEG4ENC_InterCodingParams
623     mpeg4enc_params->interCodingParams.interCodingPreset = IMPEG4_INTERCODING_DEFAULT;
624     mpeg4enc_params->interCodingParams.searchRangeHorP = 144;
625     mpeg4enc_params->interCodingParams.searchRangeVerP = 32;
626     mpeg4enc_params->interCodingParams.globalOffsetME = 1;
627     mpeg4enc_params->interCodingParams.earlySkipThreshold = 200;
628     mpeg4enc_params->interCodingParams.enableThresholdingMethod = 1;
629     mpeg4enc_params->interCodingParams.minBlockSizeP = IMPEG4_BLOCKSIZE_8x8;
630     mpeg4enc_params->interCodingParams.enableRoundingControl = 1;
632     // IMPEG4ENC_IntraCodingParams
633     mpeg4enc_params->intraCodingParams.intraCodingPreset = IMPEG4_INTRACODING_DEFAULT;
634     mpeg4enc_params->intraCodingParams.intraRefreshMethod = 0;
635     mpeg4enc_params->intraCodingParams.intraRefreshRate = 0;
636     mpeg4enc_params->intraCodingParams.acpredEnable = 1;
637     mpeg4enc_params->intraCodingParams.insertGOVHdrBeforeIframe = 0;
638     mpeg4enc_params->intraCodingParams.enableDriftControl = 1;
640     // IMPEG4ENC_sliceCodingParams
641     mpeg4enc_params->sliceCodingParams.sliceCodingPreset = IMPEG4_SLICECODING_DEFAULT;
642     mpeg4enc_params->sliceCodingParams.sliceMode = IMPEG4_SLICEMODE_NONE;
643     mpeg4enc_params->sliceCodingParams.sliceUnitSize = 0;
644     mpeg4enc_params->sliceCodingParams.gobInterval = 0;
645     mpeg4enc_params->sliceCodingParams.useHec = 0;
647     MSG("dce_alloc VIDENC2_Params successful mpeg4enc_params=%p", mpeg4enc_params);
648         enc->codec = VIDENC2_create(enc->engine, (String)"ivahd_mpeg4enc", (VIDENC2_Params *)mpeg4enc_params);
649         if(!enc->codec){
650                 ERROR("Codec could not be created %p\n", enc->codec);
651                 goto bail;
652         }
653         return 0;
654 bail:
655         encoder_deinit(enc);
656         return -1;
660 static void set_common_dyn_params(encoder *enc)
662         VIDENC2_DynamicParams   *dynParams = enc->dynParams;
663     dynParams->inputHeight  = enc->height;
664     dynParams->inputWidth  = enc->width;
665     dynParams->refFrameRate = enc->fps * 1000; // refFrameRate in fps * 1000
666     dynParams->targetFrameRate= enc->fps * 1000; // Target frame rate in fps * 1000
667     dynParams->targetBitRate = enc->bps;
668         MSG("targetFramerate = %d, targetbitrate = %d\n", dynParams->targetFrameRate, dynParams->targetBitRate);
669     dynParams->intraFrameInterval = 30; //Only 1st frame to be intra frame (I-frame)
670     dynParams->generateHeader = XDM_ENCODE_AU;
671     dynParams->captureWidth = enc->width;
672     dynParams->forceFrame = IVIDEO_NA_FRAME;
673     dynParams->sampleAspectRatioHeight = 1;
674     dynParams->sampleAspectRatioWidth = 1;
675     dynParams->ignoreOutbufSizeFlag = XDAS_FALSE;  // If this is XDAS_TRUE then getBufferFxn and getBufferHandle needs to be set.
676     dynParams->putDataFxn = NULL;
677     dynParams->putDataHandle = NULL;
678     dynParams->getDataFxn = NULL;
679     dynParams->getDataHandle = NULL;
680     dynParams->getBufferFxn = NULL;
681     dynParams->getBufferHandle = NULL;
682     dynParams->lateAcquireArg = -1;
683         return;
686 static inline int init_mpeg4_dyn_params(encoder *enc)
688         VIDENC2_DynamicParams   *dynParams = NULL;
689     XDAS_Int32      err;
690         IMPEG4ENC_DynamicParams   *mpeg4enc_dynParams;
692         dynParams = enc->dynParams = dce_alloc(sizeof(IMPEG4ENC_DynamicParams));
693         if(!enc->dynParams) goto bail;
694         enc->dynParams->size = sizeof(IMPEG4ENC_DynamicParams);
695         MSG("dce_alloc dynParams successful dynParams=%p size=%d", enc->dynParams, enc->dynParams->size);
696         set_common_dyn_params(enc);
697     dynParams->interFrameInterval = 0;
698     dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_HALFPEL; //IVIDENC2_MotionVectorAccuracy
700     MSG("dce_alloc IMPEG4ENC_DynamicParams successful size %d dynParams=%p", dynParams->size, dynParams);
701     mpeg4enc_dynParams = (IMPEG4ENC_DynamicParams *) dynParams;
703     mpeg4enc_dynParams->aspectRatioIdc = IMPEG4ENC_ASPECTRATIO_SQUARE;
705     // IMPEG4ENC_RateControlParams
706     memcpy(&mpeg4enc_dynParams->rateControlParams, &(enc->mpeg4enc_params->rateControlParams), sizeof(IMPEG4ENC_RateControlParams));
707     // IMPEG4ENC_InterCodingParams
708     memcpy(&mpeg4enc_dynParams->interCodingParams, &(enc->mpeg4enc_params->interCodingParams), sizeof(IMPEG4ENC_InterCodingParams));
709     // IMPEG4ENC_sliceCodingParams
710     memcpy(&mpeg4enc_dynParams->sliceCodingParams, &(enc->mpeg4enc_params->sliceCodingParams), sizeof(IMPEG4ENC_sliceCodingParams));
712     enc->mpeg4enc_status = dce_alloc(sizeof(IMPEG4ENC_Status));
713         if(!enc->mpeg4enc_status) goto bail;
714     ((VIDENC2_Status *)(enc->mpeg4enc_status))->size = sizeof(IMPEG4ENC_Status);
715     MSG("dce_alloc IMPEG4ENC_Status successful status=%p", enc->mpeg4enc_status);
717     err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) (enc->mpeg4enc_status));
718         if(err){
719                 ERROR("Codec_control returned err=%d, extendedError=%08x", err, enc->mpeg4enc_status->videnc2Status.extendedError);
720                 goto bail;
721         }
722         return 0;
723 bail:
724         encoder_deinit(enc);
725         return -1;
728 static inline int init_h264_dyn_params(encoder *enc)
730         VIDENC2_DynamicParams   *dynParams = NULL;
731         IH264ENC_DynamicParams   *h264enc_dynParams;
732     XDAS_Int32      err;
734         dynParams = enc->dynParams = dce_alloc(sizeof(IH264ENC_DynamicParams));
735         if(!enc->dynParams) goto bail;
736         enc->dynParams->size = sizeof(IH264ENC_DynamicParams);
737         MSG("dce_alloc dynParams successful dynParams=%p size=%d", enc->dynParams, enc->dynParams->size);
738         set_common_dyn_params(enc);
739     dynParams->interFrameInterval = 1; // 2 B frames
740     dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; //IVIDENC2_MotionVectorAccuracy
742     MSG("dce_alloc IH264ENC_DynamicParams successful size %d dynParams=%p", dynParams->size, dynParams);
743     h264enc_dynParams = (IH264ENC_DynamicParams *) dynParams;
745     h264enc_dynParams->sliceGroupChangeCycle = 0;
746     h264enc_dynParams->searchCenter.x = 0x7FFF; // or 32767
747     h264enc_dynParams->searchCenter.y = 0x7FFF; // or 32767
748     h264enc_dynParams->enableStaticMBCount = 0;
749     h264enc_dynParams->enableROI = 0;
750     h264enc_dynParams->reservedDynParams[0] = 0;
751     h264enc_dynParams->reservedDynParams[1] = 0;
752     h264enc_dynParams->reservedDynParams[2] = 0;
754     //Rate Control Params
755     h264enc_dynParams->rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_EXISTING;
756     h264enc_dynParams->rateControlParams.scalingMatrixPreset = IH264_SCALINGMATRIX_NONE;
757     h264enc_dynParams->rateControlParams.rcAlgo = IH264_RATECONTROL_DEFAULT;
758     h264enc_dynParams->rateControlParams.qpI = 28;
759     h264enc_dynParams->rateControlParams.qpMaxI = 36;
760     h264enc_dynParams->rateControlParams.qpMinI = 10;
761     h264enc_dynParams->rateControlParams.qpP = 28;
762     h264enc_dynParams->rateControlParams.qpMaxP = 40;
763     h264enc_dynParams->rateControlParams.qpMinP = 10;
764     h264enc_dynParams->rateControlParams.qpOffsetB = 4;
765     h264enc_dynParams->rateControlParams.qpMaxB = 44;
766     h264enc_dynParams->rateControlParams.qpMinB = 10;
767     h264enc_dynParams->rateControlParams.allowFrameSkip = 0;
768     h264enc_dynParams->rateControlParams.removeExpensiveCoeff = 0;
769     h264enc_dynParams->rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT;
770     h264enc_dynParams->rateControlParams.chromaQPIndexOffset = 0;
771     h264enc_dynParams->rateControlParams.initialBufferLevel = 64000;
772     h264enc_dynParams->rateControlParams.HRDBufferSize = 64000;
773     h264enc_dynParams->rateControlParams.enablePartialFrameSkip = 0;
774     h264enc_dynParams->rateControlParams.minPicSizeRatioI = 0;
775     h264enc_dynParams->rateControlParams.maxPicSizeRatioI = 20;
776     h264enc_dynParams->rateControlParams.minPicSizeRatioP = 0;
777     h264enc_dynParams->rateControlParams.maxPicSizeRatioP = 0;
778     h264enc_dynParams->rateControlParams.minPicSizeRatioB = 0;
779     h264enc_dynParams->rateControlParams.maxPicSizeRatioB = 0;
780     h264enc_dynParams->rateControlParams.enablePRC = 1;
781     h264enc_dynParams->rateControlParams.enableHRDComplianceMode = 0;
782     h264enc_dynParams->rateControlParams.reserved = 0;
783     h264enc_dynParams->rateControlParams.VBRDuration = 8;
784     h264enc_dynParams->rateControlParams.VBRsensitivity = 0;
785     h264enc_dynParams->rateControlParams.skipDistributionWindowLength = 5;
786     h264enc_dynParams->rateControlParams.numSkipInDistributionWindow = 1;
787     h264enc_dynParams->rateControlParams.enableHRDComplianceMode = 1;
788     h264enc_dynParams->rateControlParams.frameSkipThMulQ5 = 0;
789     h264enc_dynParams->rateControlParams.vbvUseLevelThQ5 = 0;
790     h264enc_dynParams->rateControlParams.reservedRC[0] = 0;
791     h264enc_dynParams->rateControlParams.reservedRC[1] = 0;
792     h264enc_dynParams->rateControlParams.reservedRC[2] = 0;
794     //Inter Coding Params
795     h264enc_dynParams->interCodingParams.interCodingPreset = IH264_INTERCODING_EXISTING;
796     h264enc_dynParams->interCodingParams.searchRangeHorP = 144;
797     h264enc_dynParams->interCodingParams.searchRangeVerP = 32;
798     h264enc_dynParams->interCodingParams.searchRangeHorB = 144;
799     h264enc_dynParams->interCodingParams.searchRangeVerB = 16;
800     h264enc_dynParams->interCodingParams.interCodingBias= IH264_BIASFACTOR_DEFAULT;
801     h264enc_dynParams->interCodingParams.skipMVCodingBias = IH264_BIASFACTOR_MILD;
802     h264enc_dynParams->interCodingParams.minBlockSizeP = IH264_BLOCKSIZE_8x8;
803     h264enc_dynParams->interCodingParams.minBlockSizeB = IH264_BLOCKSIZE_8x8;
804     h264enc_dynParams->interCodingParams.meAlgoMode = IH264ENC_MOTIONESTMODE_DEFAULT;
806     //Intra Coding Params
807     h264enc_dynParams->intraCodingParams.intraCodingPreset = IH264_INTRACODING_EXISTING;
808     h264enc_dynParams->intraCodingParams.lumaIntra4x4Enable = 0xFF; // or 255 BASE PROFILE
809     h264enc_dynParams->intraCodingParams.lumaIntra8x8Enable = 0; // BASE PROFILE
810     h264enc_dynParams->intraCodingParams.lumaIntra16x16Enable = 0;
811     h264enc_dynParams->intraCodingParams.chromaIntra8x8Enable = 0;
812     h264enc_dynParams->intraCodingParams.chromaComponentEnable = IH264_CHROMA_COMPONENT_CB_CR_BOTH;
813     h264enc_dynParams->intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_DEFAULT;
814     h264enc_dynParams->intraCodingParams.intraRefreshRate = 0;
815     h264enc_dynParams->intraCodingParams.gdrOverlapRowsBtwFrames = 0;
816     h264enc_dynParams->intraCodingParams.constrainedIntraPredEnable = 0;
817     h264enc_dynParams->intraCodingParams.intraCodingBias = IH264ENC_INTRACODINGBIAS_DEFAULT;
819     //Slice Coding Params
820     h264enc_dynParams->sliceCodingParams.sliceCodingPreset = IH264_SLICECODING_EXISTING;
821     h264enc_dynParams->sliceCodingParams.sliceMode = IH264_SLICEMODE_DEFAULT;
822     h264enc_dynParams->sliceCodingParams.sliceUnitSize = 0;
823     h264enc_dynParams->sliceCodingParams.sliceStartOffset[0] = 0;
824     h264enc_dynParams->sliceCodingParams.sliceStartOffset[1] = 0;
825     h264enc_dynParams->sliceCodingParams.sliceStartOffset[2] = 0;
826     h264enc_dynParams->sliceCodingParams.streamFormat = IH264_STREAM_FORMAT_DEFAULT;
828     enc->h264enc_status = dce_alloc(sizeof(IH264ENC_Status));
829         if(!enc->h264enc_status) goto bail;
830     ((VIDENC2_Status*)(enc->h264enc_status))->size = sizeof(IH264ENC_Status);
831     MSG("dce_alloc IH264ENC_Status successful status=%p", enc->h264enc_status);
833     err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) (enc->h264enc_status));
834     if( err ) {
835                 ERROR("Codec_control returned err=%d, extendedError=%08x", err, enc->h264enc_status->videnc2Status.extendedError);
836         goto bail;
837     }
838     MSG("dce_alloc IH264ENC_Status successful h264enc_status=%p", enc->h264enc_status);
841         return 0;
842 bail:
843         encoder_deinit(enc);
844         return -1;
847 static int encoder_init(encoder *enc)
849     Engine_Error    ec;
850     XDAS_Int32      err;
851     int  output_size = 0;
852     int  mvbufinfo_size = 0;
855         /*Initialze and Open DRM device*/
856         enc->drmfd = drmOpen("omapdrm", "platform:omapdrm:00");
857         if(!enc->drmfd)
858         {
859                 ERROR("Unable to open drm device");
860                 return -1;
861         }
862         dce_set_fd(enc->drmfd);
863         enc->dev = dce_init();
865         enc->engine = Engine_open((String)"ivahd_vidsvr", NULL, &ec);
866     if( !enc->engine ) {
867         ERROR("Engine open failed");
868         goto bail;
869     }
870     MSG("Engine_open successful engine=%p", enc->engine);
871     /* input buffer parameters in terms of MBs, Needs alignment to multiple of 16 */
872     enc->width  = ALIGN2(enc->width, 4);         /* round up to MB */
873     enc->height = ALIGN2(enc->height, 1);        /* round up to MB */
875     switch( enc->codectype ) {
876         case DCE_ENC_TEST_H264 :
877         case DCE_ENC_TEST_MPEG4 :
878         case DCE_ENC_TEST_H263 :
879             enc->num_buffers = 1;
880             break;
881         default :
882             ERROR("Unrecognized codec to encode");
883     }
884         /*Allocate the input buffers */
885         enc->buf.y_bo = omap_bo_new(enc->dev, enc->width * enc->height, OMAP_BO_WC);
886         if(!enc->buf.y_bo) goto bail;
887         enc->buf.ybuff = omap_bo_map(enc->buf.y_bo);
888         enc->buf.fdy = omap_bo_dmabuf(enc->buf.y_bo);
889         dce_buf_lock(1, (size_t*) &enc->buf.fdy);
890         enc->buf.sizey = enc->width * enc->height;
891         enc->buf.uv_bo = omap_bo_new(enc->dev,
892                                                                 (enc->width * enc->height) / 2, OMAP_BO_WC);
893         if(!enc->buf.uv_bo) goto bail;
894         enc->buf.uvbuff = omap_bo_map(enc->buf.uv_bo);
895         enc->buf.fduv = omap_bo_dmabuf(enc->buf.uv_bo);
896         dce_buf_lock(1, (size_t*) &enc->buf.fduv);
897         enc->buf.sizeuv = (enc->width * enc->height) / 2;
899         /*Initialize the static ivariant input buffer parameters*/
900     MSG("input buffer configuration width %d height %d", enc->width, enc->height);
901     enc->inBufs = dce_alloc(sizeof(IVIDEO2_BufDesc));
902         if(!enc->inBufs) goto bail;
903     enc->inBufs->numPlanes = 2;
904     enc->inBufs->imageRegion.topLeft.x = 0;
905     enc->inBufs->imageRegion.topLeft.y = 0;
906     enc->inBufs->imageRegion.bottomRight.x = enc->width;
908     enc->inBufs->topFieldFirstFlag = 0; //Only valid for interlace content.
909     enc->inBufs->contentType = IVIDEO_PROGRESSIVE;
911     enc->inBufs->activeFrameRegion.topLeft.x = 0;
912     enc->inBufs->activeFrameRegion.topLeft.y = 0;
913     enc->inBufs->activeFrameRegion.bottomRight.x = enc->width;
914     enc->inBufs->activeFrameRegion.bottomRight.y = enc->height;
916     enc->inBufs->imageRegion.bottomRight.y = enc->height;
917     enc->inBufs->chromaFormat = XDM_YUV_420SP;
919     enc->inBufs->secondFieldOffsetWidth[0] = 0;
920     enc->inBufs->secondFieldOffsetHeight[0] = 0;
923     MSG("Allocating input buffers from omapdrm");
925     enc->inBufs->imagePitch[0] = enc->width;
926     enc->inBufs->planeDesc[0].memType = XDM_MEMTYPE_RAW;
927     enc->inBufs->planeDesc[0].bufSize.bytes = enc->width * enc->height;
928     enc->inBufs->secondFieldOffsetWidth[1] = 1;
929     enc->inBufs->secondFieldOffsetHeight[1] = 0;
931     enc->inBufs->imagePitch[1] = enc->width;
932     enc->inBufs->planeDesc[1].memType = XDM_MEMTYPE_RAW;
933     enc->inBufs->planeDesc[1].bufSize.bytes = enc->width * enc->height / 2;
937         /*Initiaze static parameters of the codec*/
938         switch(enc->codectype){
939         case DCE_ENC_TEST_H264:
940                 if(init_h264_static_params(enc)){
941                         ERROR("H264 encoder static parameter error");
942                         goto bail;
943                 }
945                 if(init_h264_dyn_params(enc)){
946                         ERROR("H264 encoder static parameter error");
947                         goto bail;
948                 }
949                 enc->status = (VIDENC2_Status*) (enc->h264enc_status);
950                 break;
951         case DCE_ENC_TEST_MPEG4:
952         case DCE_ENC_TEST_H263:
953                 if(init_mpeg4_static_params(enc)){
954                         ERROR("MPEG4 encoder static parameter error");
955                         goto bail;
956                 }
957                 if(init_mpeg4_dyn_params(enc)){
958                         ERROR("H264 encoder static parameter error");
959                         goto bail;
960                 }
961                 enc->status = (VIDENC2_Status*) (enc->mpeg4enc_status);
962                 break;
963         default:
964                 ERROR("Unknown codec type");
965                 goto bail;
966         }
967     // XDM_GETBUFINFO
968     // Send Control cmd XDM_GETBUFINFO to get min output and output size
969     err = VIDENC2_control(enc->codec, XDM_GETBUFINFO, enc->dynParams, (VIDENC2_Status*) enc->status);
970     MSG("VIDENC2_control - XDM_GETBUFINFO err %d status numOutBuf %d OutBufSize %d MVBufInfo %d",
971                         err, ((VIDENC2_Status *)(enc->status))->bufInfo.minNumOutBufs,
972                          ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[0].bytes, ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[1].bytes);
973 /*
974  * outBufs handling
975  */
976     enc->outBufs = dce_alloc(sizeof(XDM2_BufDesc));
977         if(!enc->outBufs) goto bail;
978     output_size = ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[0].bytes;
979     mvbufinfo_size = ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[1].bytes;
981         enc->outBufs->numBufs = (enc->codectype == DCE_ENC_TEST_H264) ? ((VIDENC2_Status *)(enc->h264enc_status))->bufInfo.minNumOutBufs : 1;
983         /*allocate the output buffer*/
984         enc->output_bo = omap_bo_new(enc->dev, output_size, OMAP_BO_WC);
985         enc->cdata = omap_bo_map(enc->output_bo);
986         enc->outBufs->descs[0].buf = (void *)omap_bo_dmabuf(enc->output_bo);
987         dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[0].buf));
988     enc->outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
989     enc->outBufs->descs[0].bufSize.bytes = output_size;
990     MSG("buf %p  fd %p ", enc->output_bo, enc->outBufs->descs[0].buf);
992     if( mvbufinfo_size > 0 ) {
993                 /*Allocate the output mv buffer*/
994                 enc->mv_bo = omap_bo_new(enc->dev, mvbufinfo_size, OMAP_BO_WC);
995                 enc->outBufs->descs[1].buf = (void *)omap_bo_dmabuf(enc->mv_bo);
996                 dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[1].buf));
997                 enc->outBufs->descs[1].memType = XDM_MEMTYPE_RAW;
998                 enc->outBufs->descs[1].bufSize.bytes = mvbufinfo_size;
999                 MSG("mv buf %p  fd %p ", enc->mv_bo, enc->outBufs->descs[1].buf);
1000         }
1002         return 0;
1003 bail:
1004         err = encoder_deinit(enc);
1005         return -1;
1008 static int encoder_deinit(encoder *enc)
1011         if(enc->buf.y_bo) {
1012                 dce_buf_unlock(1, (size_t*) &enc->buf.fdy);
1013                 close(enc->buf.fdy);
1014                 omap_bo_del(enc->buf.y_bo);
1015         }
1016         if(enc->buf.uv_bo) {
1017                 dce_buf_unlock(1, (size_t*) &enc->buf.fduv);
1018                 close(enc->buf.fduv);
1019                 omap_bo_del(enc->buf.uv_bo);
1020         }
1022         if(enc->codec) {
1023                 MSG("\nDeleting encoder codec...\n");
1024             VIDENC2_delete(enc->codec);
1025         }
1027     if( enc->output_bo ) {
1028         MSG("\nFreeing output %p \n", enc->output_bo);
1029                 dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[0].buf));
1030                 close((int)(enc->outBufs->descs[0].buf));
1031                 omap_bo_del(enc->output_bo);
1032     }
1033     if( enc->mv_bo ){
1034         MSG("\nFreeing output_mvbuf %p...\n", enc->mv_bo);
1035                 dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[1].buf));
1036                 close((int)(enc->outBufs->descs[1].buf));
1037                 omap_bo_del(enc->mv_bo);
1038     }
1040     if( enc->params ) {
1041         dce_free(enc->params);
1042     }
1043     if( enc->dynParams ) {
1044         dce_free(enc->dynParams);
1045     }
1046     if( enc->h264enc_status ) {
1047         dce_free(enc->h264enc_status);
1048     }
1049     if( enc->mpeg4enc_status ) {
1050         dce_free(enc->mpeg4enc_status);
1051     }
1052     if( enc->inBufs ) {
1053         dce_free(enc->inBufs);
1054     }
1055     if( enc->outBufs ) {
1056         dce_free(enc->outBufs);
1057     }
1058     if( enc->inArgs ) {
1059         dce_free(enc->inArgs);
1060     }
1061     if( enc->outArgs ) {
1062         dce_free(enc->outArgs);
1063     }
1064     if( enc->engine ) {
1065         Engine_close(enc->engine);
1066     }
1068         if(enc->fin) fclose(enc->fin);
1069         if(enc->fout) fclose(enc->fout);
1070         if(enc->dev) dce_deinit(enc->dev);
1071         if(enc->drmfd) drmClose(enc->drmfd);
1072         memset(enc, 0, sizeof(encoder));
1073         return 0;
1076 encoder encObj;
1078 static void sig_handler(int signo, siginfo_t *siginfo, void *context)
1079  {
1080    if (signo == SIGINT) {
1081        encoder_deinit(&encObj);
1082        sleep(1);
1083        exit(0);
1084    }
1085  }
1087 /* encoder body */
1088 int main(int argc, char * *argv)
1090         struct sigaction sa;
1091         sa.sa_handler = sig_handler;
1092         sigemptyset(&sa.sa_mask);
1093         sa.sa_flags = SA_SIGINFO;
1094         if (sigaction(SIGINT, &sa, NULL) == -1) {
1095             ERROR ("\nDid not catch  SIGINT\n");
1096         }
1098         XDAS_Int32      err;
1099         IH264ENC_InArgs *h264enc_inArgs;
1100         IMPEG4ENC_InArgs *mpeg4enc_inArgs;
1101         IH264ENC_OutArgs *h264enc_outArgs;
1102         IMPEG4ENC_OutArgs *mpeg4enc_outArgs;
1104     int             in_cnt = 0, out_cnt = 0, iters = 0;
1105     int             eof = 0;
1106     int             bytesGenerated = 0;
1109         memset(&encObj, 0, sizeof(encoder));
1111         if(parse_command(argc, argv, &encObj)){
1112                 goto shutdown;
1113         }
1116         if(encoder_init(&encObj))
1117         {
1118                 MSG("Error during encoder initialization");
1119                 goto shutdown;
1120         }
1122 /*
1123  * codec process
1124  */
1125     while( encObj.inBufs->numPlanes && encObj.outBufs->numBufs ) {
1126         int    n;
1127         MSG("Looping on reading input inBufs->numPlanes %d outBufs->numBufs %d",
1128                                          encObj.inBufs->numPlanes, encObj.outBufs->numBufs);
1130         //Read the NV12 frame to input buffer to be encoded.
1131         n = read_NV12frame(&encObj);
1133         if( n > 0) {
1134             eof = 0;
1135                         /*Pass the FDs for subplanes*/
1136             encObj.inBufs->planeDesc[0].buf = (XDAS_Int8 *)(encObj.buf.fdy);
1137             encObj.inBufs->planeDesc[1].buf = (XDAS_Int8 *)(encObj.buf.fduv);
1138             MSG("inBufs->planeDesc[0].buf %p inBufs->planeDesc[1].buf %p",
1139                                          encObj.inBufs->planeDesc[0].buf, encObj.inBufs->planeDesc[1].buf);
1140             MSG("push: %d (plane[0]= %d + plane[1]= %d = %d bytes) (%p)",
1141                                          in_cnt, encObj.inBufs->planeDesc[0].bufSize.bytes, encObj.inBufs->planeDesc[1].bufSize.bytes, n, &encObj.buf);
1142             in_cnt++;
1144             encObj.inArgs->inputID = in_cnt; // Send frame count as the input ID
1145             /*
1146              * Input buffer has data to be encoded.
1147              */
1148         } else if( n == -1 ) {
1150             // Set EOF as 1 to ensure flush completes
1151             eof = 1;
1152             in_cnt++;
1154             MSG("n == -1 - go to shutdown");
1155                         printf("Encoding completed successfully\n");
1157             goto shutdown;
1158         } else {
1159             /* end of input..  (n == 0) */
1160             encObj.inBufs->numPlanes = 0;
1161             eof = 1;
1162             MSG("n == 0 - go to shutdown");
1163                         printf("Encoding completed successfully\n");
1165             goto shutdown;
1167         }
1170         do {
1172             if( encObj.codectype == DCE_ENC_TEST_H264 ) {
1173                 h264enc_inArgs = (IH264ENC_InArgs *) encObj.inArgs;
1174                                 h264enc_outArgs = (IH264ENC_OutArgs *) encObj.outArgs;
1175                 MSG("TEST inArgs->inputID %d h264enc_inArgs->videnc2InArgs.inputID %d",
1176                                                  encObj.inArgs->inputID, h264enc_inArgs->videnc2InArgs.inputID);
1177                 err = VIDENC2_process(encObj.codec, encObj.inBufs, encObj.outBufs, (VIDENC2_InArgs *) h264enc_inArgs, (VIDENC2_OutArgs *) h264enc_outArgs);
1178                 MSG("[DCE_ENC_TEST] VIDENC2_process - err %d", err);
1180                 if( err < 0 ) {
1181                     int    i = 0;
1183                     for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) {
1184                         MSG("DETAIL EXTENDED ERROR h264enc_outArgs->extErrorCode[%d]=%08x", i, (uint)h264enc_outArgs->extErrorCode[i]);
1185                     }
1187                     err = VIDENC2_control(encObj.codec, XDM_GETSTATUS, (VIDENC2_DynamicParams *) encObj.dynParams, (VIDENC2_Status *) encObj.h264enc_status);
1188                     MSG("[DCE_ENC_TEST] VIDENC2_control - XDM_GETSTATUS err %d", err);
1190                     for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) {
1191                         MSG("DETAIL EXTENDED ERROR h264enc_status->extErrorCode[%d]=%08x", i, (uint)encObj.h264enc_status->extErrorCode[i]);
1192                     }
1194                     if( XDM_ISFATALERROR(h264enc_outArgs->videnc2OutArgs.extendedError) ) {
1195                         ERROR("process returned error: %d\n", err);
1196                         ERROR("extendedError: %08x", h264enc_outArgs->videnc2OutArgs.extendedError);
1197                                                 printf("Encoding Error\n");
1198                         goto shutdown;
1199                     } else if( eof ) {
1200                         ERROR("Codec_process returned err=%d, extendedError=%08x", err, h264enc_outArgs->videnc2OutArgs.extendedError);
1201                         err = XDM_EFAIL;
1203                         if( err == XDM_EFAIL ) {
1204                             MSG("-------------------- Flush completed------------------------");
1205                         }
1206                     } else {
1207                         ERROR("Non-fatal err=%d, h264enc_outArgs->videnc2OutArgs.extendedError=%08x ", err, h264enc_outArgs->videnc2OutArgs.extendedError);
1208                         err = XDM_EOK;
1209                     }
1210                 }
1212                 MSG("bytesGenerated %d", h264enc_outArgs->videnc2OutArgs.bytesGenerated);
1213                 bytesGenerated = h264enc_outArgs->videnc2OutArgs.bytesGenerated;
1214             } else if( encObj.codectype == DCE_ENC_TEST_MPEG4 || encObj.codectype == DCE_ENC_TEST_H263 ) {
1215                 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) encObj.inArgs;
1216                                 mpeg4enc_outArgs = (IMPEG4ENC_OutArgs *) encObj.outArgs;
1217                 MSG("TEST inArgs->inputID %d mpeg4enc_inArgs->videnc2InArgs.inputID %d", encObj.inArgs->inputID, mpeg4enc_inArgs->videnc2InArgs.inputID);
1218                 MSG("[DCE_ENC_TEST] codec %p inBufs %p outBufs %p mpeg4enc_inArgs %p mpeg4enc_outArgs %p", encObj.codec, encObj.inBufs, encObj.outBufs, mpeg4enc_inArgs, mpeg4enc_outArgs);
1219                 err = VIDENC2_process(encObj.codec, encObj.inBufs, encObj.outBufs, (VIDENC2_InArgs *) mpeg4enc_inArgs, (VIDENC2_OutArgs *) mpeg4enc_outArgs);
1220                 MSG("[DCE_ENC_TEST] VIDENC2_process - err %d", err);
1221                 if( err < 0 ) {
1222                     //TODO error handling on MPEG4/H.263
1223                     ERROR("Codec_process returned err=%d, extendedError=%08x", err, mpeg4enc_outArgs->videnc2OutArgs.extendedError);
1224                                         printf("Encoding Error\n");
1225                     goto shutdown;
1226                 }
1227                 MSG("\n bytesGenerated %d", mpeg4enc_outArgs->videnc2OutArgs.bytesGenerated);
1228                 bytesGenerated = mpeg4enc_outArgs->videnc2OutArgs.bytesGenerated;
1229             }
1232             /*
1233              * Handling of output data from codec
1234              */
1236             /* get the output buffer and write it to file */
1237             if( bytesGenerated ) {
1238                 // write the frames to output file based on the value of frames_to_write on how many frames to write.
1239                 if( out_cnt > encObj.nframes ){
1240                                         printf("Encoding completed successfully\n");
1241                                         goto shutdown;
1242                                 }
1243                 INFO("Dumping frame %d", out_cnt);
1244                                 write_output(&encObj, bytesGenerated);
1245             }
1246             out_cnt++;
1247             ++iters; // Guard for infinite VIDENC2_PROCESS loop when codec never return XDM_EFAIL
1248         } while( eof && (err != XDM_EFAIL) && (iters < 1000));  // Multiple VIDENC2_process when eof until err == XDM_EFAIL
1249     }
1250 shutdown:
1251         encoder_deinit(&encObj);
1252     return 0;