[VIDENC] Adding Video encoder
[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>
45 #include <omap_drm.h>
46 #include <omap_drmif.h>
47 #include "libdce.h"
49 #include <ti/sdo/ce/Engine.h>
50 #include <ti/sdo/ce/video2/videnc2.h>
51 #include <ti/sdo/codecs/h264enc/ih264enc.h>
52 #include <ti/sdo/codecs/mpeg4enc/impeg4enc.h>
56 //#define PRINT_DEBUG
58 #define ERROR(FMT, ...)  printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
59 // enable below to print debug information
60 #ifdef PRINT_DEBUG
61 #define MSG(FMT, ...)  printf("%s:%d:\t%s\tdebug: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
62 #else
63 #define MSG(FMT, ...)
64 #endif
65 #define INFO(FMT, ...)  printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
66 #define MIN(a, b)        (((a) < (b)) ? (a) : (b))
68 /* align x to next highest multiple of 2^n */
69 #define ALIGN2(x, n)   (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
71 // Profile the init and encode calls
72 //#define PROFILE_TIME
74 // Getting codec version through XDM_GETVERSION
75 #define GETVERSION
77 enum {
78     IVAHD_H264_ENCODE,
79     IVAHD_MPEG4_ENCODE,
80     IVAHD_H263_ENCODE
81 };
83 enum {
84         DCE_ENC_TEST_H264  = 1,
85         DCE_ENC_TEST_MPEG4 = 2,
86         DCE_ENC_TEST_H263 = 3
87 };
89 enum {
90         MEMTYPE_INVALID = -1,
91         MEMTYPE_OMAPDRM = 0,
92 };
94 typedef struct _bufferDesc{
95         void *y_bo; //buffer object for y pointer
96         void *uv_bo; //buffer object for uv pointer
97         int fdy; // y dma buf
98         int fduv; // uv dma buf
99         int sizey; // size of y
100         int sizeuv; // size of uv
101         void *ybuff; // Virtual addresses of y
102         void *uvbuff; // virtual address of uv
103 }bufferdesc;
105 typedef struct encoderObj{
106         int drmfd; //DRM device fd
107         void *dev; // Device handle
108         char *in_pattern; //Input filename with full path
109         char *out_pattern; //Output filename with full path
110         FILE *fin; // Input stream
111         FILE *fout; // output stream
112         int width; //Frame width
113         int height; // Frame height
114         int codectype; // H264 or MPEG4 or H263
115         int profile;
116         int level;
117         int nframes; // Number of frames to write
118         int memtype; // Memory allocation scheme (OMAPDRM)
119         int fps; //Frame rate
120         int bps; //bitrate
121         bufferdesc buf; // Holds input buffer address
122         struct omap_bo *output_bo;
123         unsigned char *cdata;
124         struct omap_bo *mv_bo;
126         int padded_width;
127         int padded_height;
128         int num_buffers;
129         Engine_Handle            engine;
130         VIDENC2_Handle           codec;
131         VIDENC2_Params          *params;
132         VIDENC2_DynamicParams   *dynParams;
133         VIDENC2_Status          *status;
134         VIDENC2_DynamicParams   *dynParams1;
135         VIDENC2_Status          *status1;
136         IVIDEO2_BufDesc         *inBufs;
137         XDM2_BufDesc            *outBufs;
138         VIDENC2_InArgs          *inArgs;
139         VIDENC2_OutArgs         *outArgs;
141         // H.264 specific
142         IH264ENC_InArgs          *h264enc_inArgs;
143         IH264ENC_OutArgs         *h264enc_outArgs;
144         IH264ENC_Params          *h264enc_params;
145         IH264ENC_DynamicParams   *h264enc_dynParams;
146         IH264ENC_Status          *h264enc_status;
148         // MPEG4/H.263 specific
149         IMPEG4ENC_InArgs          *mpeg4enc_inArgs;
150         IMPEG4ENC_OutArgs         *mpeg4enc_outArgs;
151         IMPEG4ENC_Params          *mpeg4enc_params;
152         IMPEG4ENC_DynamicParams   *mpeg4enc_dynParams;
153         IMPEG4ENC_Status          *mpeg4enc_status;
155 }encoder;
156 /*
157  * A very simple VIDENC2 client which will encode raw (unstrided) NV12 YUV frames
158  * and write out to either h264, MPEG4, or H.263 format.
159  */
161 static int encoder_init(encoder *enc);
162 static int encoder_deinit(encoder *enc);
163 static void usage(char **argv);
166 static int read_NV12frame(encoder *enc)
168         int numbytes =  0;
169         if(!enc->fin){
170                 enc->fin = fopen(enc->in_pattern, "r+");
171                 if(!enc->fin){
172                         ERROR("Could not open input file %s\n", enc->in_pattern);
173                         goto bail;
174                 }
175         }
176         numbytes = fread(enc->buf.ybuff, 1, enc->width * enc->height, enc->fin);
177         numbytes += fread(enc->buf.uvbuff, 1, (enc->width * enc->height) / 2, enc->fin);
179         return numbytes;
180 bail:
181         return -1;
185 /* helper to write one frame of output */
186 int write_output(encoder *enc, int bytesToWrite)
188         int nbytes = -1;
189         if(!enc->fout){
190                 enc->fout = fopen(enc->out_pattern, "wb+");
191                 if(!enc->fout){
192                         ERROR("Could not open file for output %s", enc->out_pattern);
193                         goto fail;
194                 }
195         }
196         nbytes = fwrite(enc->cdata, 1, bytesToWrite, enc->fout);
197     return nbytes;
198 fail:
199         return -1;
203 static int parse_codecinfo(char *argv[], encoder *enc)
205 /*
206  * Configuration based on the input parameters
207  */
208         const char *argcodec    = argv[8];
209         const char *profile             = argv[9];
210         const char *level               = argv[10];
212         enc->level = atoi(level);
213     if( (!(strcmp(argcodec, "h264"))) ) {
214         enc->codectype = DCE_ENC_TEST_H264;
215         if( (!(strcmp(profile, "baseline"))) ) {
216             enc->profile = IH264_BASELINE_PROFILE;
217         } else if( (!(strcmp(profile, "high"))) ) {
218             enc->profile = IH264_HIGH_PROFILE;
219         } else {
220             ERROR("Wrong profile value. Please use: baseline or high.\n");
221                         usage(argv);
222             return -1;
223         }
225         switch(enc->level) {
226             case IH264_LEVEL_10 :
227             case IH264_LEVEL_1b :
228             case IH264_LEVEL_11 :
229             case IH264_LEVEL_12 :
230             case IH264_LEVEL_13 :
231             case IH264_LEVEL_20 :
232             case IH264_LEVEL_21 :
233             case IH264_LEVEL_22 :
234             case IH264_LEVEL_30 :
235             case IH264_LEVEL_31 :
236             case IH264_LEVEL_32 :
237             case IH264_LEVEL_40 :
238             case IH264_LEVEL_41 :
239             case IH264_LEVEL_42 :
240             case IH264_LEVEL_50 :
241             case IH264_LEVEL_51 :
242                 MSG("Acceptable H.264 level value = %d\n", enc->level);
243                 break;
244             default :
245                 ERROR("Wrong level value. Please use the correct level value for H.264\n");
246                                 usage(argv);
247                 return -1;
248         }
249     } else if( !(strcmp(argcodec, "mpeg4"))) {
251         enc->codectype = DCE_ENC_TEST_MPEG4;
253         if( (!(strcmp(profile, "simple"))) ) {
254             enc->profile = 3;
255         } else {
256             ERROR("Wrong profile value. Please use: simple\n");
257                         usage(argv);
258             return -1;
259         }
261         switch(enc->level) {
262             case IMPEG4ENC_SP_LEVEL_0 :
263             case IMPEG4ENC_SP_LEVEL_0B :
264             case IMPEG4ENC_SP_LEVEL_1 :
265             case IMPEG4ENC_SP_LEVEL_2 :
266             case IMPEG4ENC_SP_LEVEL_3 :
267             case IMPEG4ENC_SP_LEVEL_4A :
268             case IMPEG4ENC_SP_LEVEL_5 :
269             case IMPEG4ENC_SP_LEVEL_6 :
270                 MSG("Acceptable MPEG4 level value = %d\n", enc->level);
271                 break;
272             default :
273                 ERROR("Wrong level value. Please use the correct level value for MPEG4\n");
274                                 usage(argv);
275                 return -1;
276         }
277     } else if( !(strcmp(argcodec, "h263"))) {
279         enc->codectype = DCE_ENC_TEST_H263;
281         if( (!(strcmp(profile, "simple"))) ) {
282             enc->profile = 3;
283         } else {
284             ERROR("Wrong profile value. Please use: simple\n");
285                         usage(argv);
286             return -1;
287         }
289         switch(enc->level) {
290             case IMPEG4ENC_H263_LEVEL_10 :
291             case IMPEG4ENC_H263_LEVEL_20 :
292             case IMPEG4ENC_H263_LEVEL_30 :
293             case IMPEG4ENC_H263_LEVEL_40 :
294             case IMPEG4ENC_H263_LEVEL_45 :
295             case IMPEG4ENC_H263_LEVEL_50 :
296             case IMPEG4ENC_H263_LEVEL_60 :
297             case IMPEG4ENC_H263_LEVEL_70 :
298                 MSG("Acceptable H263 level value = %d\n", enc->level);
299                 break;
300             default :
301                 ERROR("Wrong level value. Please use the correct level value for H263\n");
302                                 usage(argv);
303                 return -1;
304         }
305     } else {
306         ERROR("No valid codec entry. Please use: h264 or mpeg4 or h263\n");
307                 usage(argv);
308         return -1;
309     }
310     MSG("Selected codec: %d\n", enc->codectype);
311         return 0;
315 static void usage(char **argv)
317         printf("usage: %s width height frames_to_write inpattern outpattern fps bitrate(kbps) codec baseline/high level buffertype\n", argv[0]);
318         printf("example: %s 1920 1088 300 in.yuv out.h264 15 128 h264 baseline 10 OMAPDRM\n", argv[0]);
319         printf("example: %s 176 144 300 in.yuv out.m4v 30 64 mpeg4 simple/baseline 0 OMAPDRM\n", argv[0]);
320         printf("example: %s 176 144 300 in.yuv out.m4v 15 150 h263 simple/baseline 0 OMAPDRM\n", argv[0]);
321         printf("Currently supported codecs: h264 or mpeg4 or h263\n");
322         printf("Currently supported Buffertypes: OMAPDRM\n");
323         printf("Run this command for help on the use case:%s\n", argv[0]);
324         return;
326 static int parse_command(int argc, char *argv[], encoder *enc)
329     if( argc != 12 ) {
330                 usage(argv);
331         return -1;
332     }
333     enc->width  = atoi(argv[1]);
334     enc->height = atoi(argv[2]);
335     enc->nframes = atoi(argv[3]);
336     enc->in_pattern  = argv[4];
337     enc->out_pattern = argv[5];
338         enc->fps = atoi(argv[6]);
339         enc->bps = atoi(argv[7]) * 1000;
340         if(parse_codecinfo(argv, enc))
341                 return -1;
343         if(!strcmp(argv[11], "OMAPDRM")){
344                 MSG("Only DRM buffer type supported.. Rolling back to OMAPDRM\n");
345         }
347         enc->memtype =  MEMTYPE_OMAPDRM;
348     MSG("Selected buffer: %d\n", enc->memtype);
350         return 0;
354 static void init_common_static_params(encoder *enc)
356         VIDENC2_Params *params = enc->params;
357     params->encodingPreset = XDM_USER_DEFINED; //XDM_USER_DEFINED; //XDM_EncodingPreset
358     params->rateControlPreset = IVIDEO_USER_DEFINED;
359     params->maxHeight = enc->height;
360     params->maxWidth = enc->width;
361     params->dataEndianness = XDM_BYTE; //XDM_DataFormat
362     params->maxBitRate = -1; //IGNORED
363     params->minBitRate = 0;
364     params->inputChromaFormat = XDM_YUV_420SP; //XDM_ChromaFormat
365     params->inputContentType = IVIDEO_PROGRESSIVE; //IVIDEO_ContentType
366     params->operatingMode = IVIDEO_ENCODE_ONLY; //IVIDEO_OperatingMode
367     params->profile = enc->profile;
368     params->level = enc->level;
369     params->inputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
370     params->outputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
371     params->numInputDataUnits = 1;
372     params->numOutputDataUnits = 1;
373     params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
374     params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
375     params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
376         return;
379 static int init_h264_static_params(encoder *enc)
381         IH264ENC_Params          *h264enc_params    = NULL;
382         enc->inArgs = dce_alloc(sizeof(IH264ENC_InArgs));
383         if(!enc->inArgs) goto bail;
384         enc->inArgs->size = sizeof(IH264ENC_InArgs);
385         enc->outArgs = dce_alloc(sizeof(IH264ENC_OutArgs));
386         if(!enc->outArgs) goto bail;
387         enc->outArgs->size = sizeof(IH264ENC_OutArgs);
388         enc->h264enc_outArgs = (IH264ENC_OutArgs *) enc->outArgs;
389         enc->params = dce_alloc(sizeof(IH264ENC_Params));
390         if(!enc->params) goto bail;
391         enc->params->size = sizeof(IH264ENC_Params);
393         init_common_static_params(enc);
394         MSG("H.264 Encoding with profile_value %d level %d", enc->profile, enc->level);
395         enc->params->maxInterFrameInterval = 1; //1,31 if IVIDEO_ContentType is IVIDEO_PROGRESSIVE
396     //Miscellaneous
397         h264enc_params    =  enc->h264enc_params = (IH264ENC_Params *) enc->params;
398         h264enc_params->interlaceCodingType = IH264_INTERLACE_DEFAULT;
399         h264enc_params->bottomFieldIntra = 0;
400         h264enc_params->gopStructure = IH264ENC_GOPSTRUCTURE_DEFAULT; // IH264ENC_GOPSTRUCTURE_NONUNIFORM
401         h264enc_params->entropyCodingMode = IH264_ENTROPYCODING_DEFAULT; // IH264_ENTROPYCODING_CAVLC - BASE PROFILE
402         h264enc_params->transformBlockSize = IH264_TRANSFORM_4x4; // BASE PROFILE
403         h264enc_params->log2MaxFNumMinus4 = 10;
404         h264enc_params->picOrderCountType = IH264_POC_TYPE_DEFAULT; // IH264_POC_TYPE_0
405         h264enc_params->enableWatermark = 0;
406         h264enc_params->IDRFrameInterval = 1;
407         h264enc_params->pConstantMemory = NULL;
408         h264enc_params->maxIntraFrameInterval = 0x7FFFFFFF;
409     h264enc_params->debugTraceLevel = 0;
410     h264enc_params->lastNFramesToLog = 0;
411     h264enc_params->enableAnalyticinfo = 0;
412     h264enc_params->enableGMVSei = 0;
413     h264enc_params->constraintSetFlags = 20;
414     h264enc_params->enableRCDO = 0;
415     h264enc_params->enableLongTermRefFrame = IH264ENC_LTRP_NONE;
416     h264enc_params->LTRPPeriod = 0;
418     //H-P Coding Control Params
419     h264enc_params->numTemporalLayer = IH264_TEMPORAL_LAYERS_1;
420     h264enc_params->referencePicMarking = IH264_LONG_TERM_PICTURE;
421     h264enc_params->reservedParams[0] = 0;
422     h264enc_params->reservedParams[1] = 0;
423     h264enc_params->reservedParams[2] = 0;
425     //rate control params
426     h264enc_params->rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_USERDEFINED;
427     h264enc_params->rateControlParams.scalingMatrixPreset = IH264_SCALINGMATRIX_NONE;
428     h264enc_params->rateControlParams.rcAlgo = IH264_RATECONTROL_DEFAULT; // 0
429     h264enc_params->rateControlParams.qpI = 28;
430     h264enc_params->rateControlParams.qpMaxI = 36;
431     h264enc_params->rateControlParams.qpMinI = 10;
432     h264enc_params->rateControlParams.qpP = 28;
433     h264enc_params->rateControlParams.qpMaxP = 40;
434     h264enc_params->rateControlParams.qpMinP = 10;
435     h264enc_params->rateControlParams.qpOffsetB = 4;
436     h264enc_params->rateControlParams.qpMaxB = 44;
437     h264enc_params->rateControlParams.qpMinB = 10;
438     h264enc_params->rateControlParams.allowFrameSkip = 0;
439     h264enc_params->rateControlParams.removeExpensiveCoeff = 0;
440     h264enc_params->rateControlParams.chromaQPIndexOffset = 0;
441     h264enc_params->rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT; // 0
442     h264enc_params->rateControlParams.initialBufferLevel = 64000;
443     h264enc_params->rateControlParams.HRDBufferSize = 64000;
444     h264enc_params->rateControlParams.minPicSizeRatioI = 0;
445     h264enc_params->rateControlParams.maxPicSizeRatioI = 20;
446     h264enc_params->rateControlParams.minPicSizeRatioP = 0;
447     h264enc_params->rateControlParams.maxPicSizeRatioP = 0;
448     h264enc_params->rateControlParams.minPicSizeRatioB = 0;
449     h264enc_params->rateControlParams.maxPicSizeRatioB = 0;
450     h264enc_params->rateControlParams.enablePRC = 1;
451     h264enc_params->rateControlParams.enablePartialFrameSkip = 0;
452     h264enc_params->rateControlParams.discardSavedBits = 0;
453     h264enc_params->rateControlParams.reserved = 0;
454     h264enc_params->rateControlParams.VBRDuration = 8;
455     h264enc_params->rateControlParams.VBRsensitivity = 0;
456     h264enc_params->rateControlParams.skipDistributionWindowLength = 5;
457     h264enc_params->rateControlParams.numSkipInDistributionWindow =1;
458     h264enc_params->rateControlParams.enableHRDComplianceMode = 1;
459     h264enc_params->rateControlParams.frameSkipThMulQ5 = 0;
460     h264enc_params->rateControlParams.vbvUseLevelThQ5 = 0;
461     h264enc_params->rateControlParams.reservedRC[0] = 0;
462     h264enc_params->rateControlParams.reservedRC[1] = 0;
463     h264enc_params->rateControlParams.reservedRC[2] = 0;
465     //intercoding coding params
466     h264enc_params->interCodingParams.interCodingPreset = IH264_INTERCODING_USERDEFINED;
467     h264enc_params->interCodingParams.searchRangeHorP = 144;
468     h264enc_params->interCodingParams.searchRangeVerP = 32;
469     h264enc_params->interCodingParams.searchRangeHorB = 144;
470     h264enc_params->interCodingParams.searchRangeVerB = 16;
471     h264enc_params->interCodingParams.interCodingBias = IH264_BIASFACTOR_DEFAULT;
472     h264enc_params->interCodingParams.skipMVCodingBias = IH264_BIASFACTOR_MILD;
473     h264enc_params->interCodingParams.minBlockSizeP = IH264_BLOCKSIZE_8x8;
474     h264enc_params->interCodingParams.minBlockSizeB = IH264_BLOCKSIZE_8x8;
475     h264enc_params->interCodingParams.meAlgoMode = IH264ENC_MOTIONESTMODE_DEFAULT;
477     //intra coding params.
478     h264enc_params->intraCodingParams.intraCodingPreset = IH264_INTRACODING_DEFAULT;
479     h264enc_params->intraCodingParams.lumaIntra4x4Enable = 0;
480     h264enc_params->intraCodingParams.lumaIntra8x8Enable = 0x0FF;
481     h264enc_params->intraCodingParams.lumaIntra16x16Enable = 0;  // BASE PROFILE
482     h264enc_params->intraCodingParams.chromaIntra8x8Enable = 0;  // BASE PROFILE
483     h264enc_params->intraCodingParams.chromaComponentEnable = IH264_CHROMA_COMPONENT_CB_CR_BOTH;  // BASE PROFILE
484     h264enc_params->intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_DEFAULT;
485     h264enc_params->intraCodingParams.intraRefreshRate = 0;
486     h264enc_params->intraCodingParams.gdrOverlapRowsBtwFrames = 0;
487     h264enc_params->intraCodingParams.constrainedIntraPredEnable = 0;
488     h264enc_params->intraCodingParams.intraCodingBias = IH264ENC_INTRACODINGBIAS_DEFAULT;
490     //NALU Control Params.
491     h264enc_params->nalUnitControlParams.naluControlPreset = IH264_NALU_CONTROL_USERDEFINED;
492     h264enc_params->nalUnitControlParams.naluPresentMaskStartOfSequence = 0x01A0; // 416
493     h264enc_params->nalUnitControlParams.naluPresentMaskIDRPicture = 0x0020; //32
494     h264enc_params->nalUnitControlParams.naluPresentMaskIntraPicture = 2;
495     h264enc_params->nalUnitControlParams.naluPresentMaskNonIntraPicture = 2;
496     h264enc_params->nalUnitControlParams.naluPresentMaskEndOfSequence = 0x0C00; // 3072
498     //Slice coding params
499     h264enc_params->sliceCodingParams.sliceCodingPreset = IH264_SLICECODING_DEFAULT;
500     h264enc_params->sliceCodingParams.sliceMode = IH264_SLICEMODE_DEFAULT;
501     h264enc_params->sliceCodingParams.sliceUnitSize = 0;
502     h264enc_params->sliceCodingParams.sliceStartOffset[0] = 0;
503     h264enc_params->sliceCodingParams.sliceStartOffset[1] = 0;
504     h264enc_params->sliceCodingParams.sliceStartOffset[2] = 0;
505     h264enc_params->sliceCodingParams.streamFormat = IH264_STREAM_FORMAT_DEFAULT;
507     //Loop Filter Params
508     h264enc_params->loopFilterParams.loopfilterPreset = IH264_LOOPFILTER_DEFAULT;
509     h264enc_params->loopFilterParams.loopfilterDisableIDC = IH264_DISABLE_FILTER_DEFAULT;
510     h264enc_params->loopFilterParams.filterOffsetA = 0;
511     h264enc_params->loopFilterParams.filterOffsetB = 0;
513     //fmo coding params
514     h264enc_params->fmoCodingParams.fmoCodingPreset = IH264_FMOCODING_DEFAULT;
515     h264enc_params->fmoCodingParams.numSliceGroups = 1;
516     h264enc_params->fmoCodingParams.sliceGroupMapType = IH264_SLICE_GRP_MAP_DEFAULT; // 4
517     h264enc_params->fmoCodingParams.sliceGroupChangeDirectionFlag = IH264ENC_SLICEGROUP_CHANGE_DIRECTION_DEFAULT;
518     h264enc_params->fmoCodingParams.sliceGroupChangeRate = 0;
519     h264enc_params->fmoCodingParams.sliceGroupChangeCycle = 0;
520     h264enc_params->fmoCodingParams.sliceGroupParams[0] = 0;
521     h264enc_params->fmoCodingParams.sliceGroupParams[1] = 0;
523     //VUI Control Params
524     h264enc_params->vuiCodingParams.vuiCodingPreset = IH264_VUICODING_DEFAULT;
525     h264enc_params->vuiCodingParams.aspectRatioInfoPresentFlag = 0;
526     h264enc_params->vuiCodingParams.aspectRatioIdc = 0;
527     h264enc_params->vuiCodingParams.videoSignalTypePresentFlag = 0;
528     h264enc_params->vuiCodingParams.videoFormat = IH264ENC_VIDEOFORMAT_NTSC;
529     h264enc_params->vuiCodingParams.videoFullRangeFlag = 0;
530     h264enc_params->vuiCodingParams.timingInfoPresentFlag = 0;
531     h264enc_params->vuiCodingParams.hrdParamsPresentFlag = 0;
532     h264enc_params->vuiCodingParams.numUnitsInTicks= 1000;
534     //Stereo Info Control Params
535     h264enc_params->stereoInfoParams.stereoInfoPreset = IH264_STEREOINFO_DISABLE;
536     h264enc_params->stereoInfoParams.topFieldIsLeftViewFlag = 1;
537     h264enc_params->stereoInfoParams.viewSelfContainedFlag = 0;
539     //Frame Packing SEI Params
540     h264enc_params->framePackingSEIParams.framePackingPreset = IH264_FRAMEPACK_SEI_DISABLE;
541     h264enc_params->framePackingSEIParams.framePackingType = IH264_FRAMEPACK_TYPE_DEFAULT;
542     h264enc_params->framePackingSEIParams.frame0PositionX = 0;
543     h264enc_params->framePackingSEIParams.frame0PositionY = 0;
544     h264enc_params->framePackingSEIParams.frame1PositionX = 0;
545     h264enc_params->framePackingSEIParams.frame1PositionY = 0;
546     h264enc_params->framePackingSEIParams.reservedByte = 0;
548     //SVC coding params
549     h264enc_params->svcCodingParams.svcExtensionFlag = IH264_SVC_EXTENSION_FLAG_DISABLE;
550     h264enc_params->svcCodingParams.dependencyID = 0;
551     h264enc_params->svcCodingParams.qualityID = 0;
552     h264enc_params->svcCodingParams.enhancementProfileID = 0;
553     h264enc_params->svcCodingParams.layerIndex = 0;
554     h264enc_params->svcCodingParams.refLayerDQId = 0;
556     MSG("dce_alloc VIDENC2_Params successful h264enc_params=%p", h264enc_params);
557     enc->codec = VIDENC2_create(enc->engine, (char*) "ivahd_h264enc", (VIDENC2_Params *)h264enc_params);
558         if(!enc->codec){
559                 ERROR("Codec could not be created %p\n", enc->codec);
560                 goto bail;
561         }
562         return 0;
563 bail:
564         encoder_deinit(enc);
565         return -1;
568 static int init_mpeg4_static_params(encoder *enc)
570         IMPEG4ENC_Params          *mpeg4enc_params    = NULL;
571     enc->inArgs = dce_alloc(sizeof(IMPEG4ENC_InArgs));
572         if(!enc->inArgs) goto bail;
573     enc->inArgs->size = sizeof(IMPEG4ENC_InArgs);
575     enc->outArgs = dce_alloc(sizeof(IMPEG4ENC_OutArgs));
576         if(!enc->outArgs) goto bail;
577     enc->outArgs->size = sizeof (IMPEG4ENC_OutArgs);
578     enc->mpeg4enc_outArgs = (IMPEG4ENC_OutArgs *) enc->outArgs;
580     enc->params = dce_alloc(sizeof(IMPEG4ENC_Params));
581         if(!enc->params) goto bail;
582     enc->params->size = sizeof(IMPEG4ENC_Params);
584         init_common_static_params(enc);
586         enc->params->maxInterFrameInterval = 0;
587     mpeg4enc_params = enc->mpeg4enc_params = (IMPEG4ENC_Params *) enc->params;
589     mpeg4enc_params->useDataPartitioning = 0;
590     mpeg4enc_params->useRvlc = 0;
591     if( enc->codectype == DCE_ENC_TEST_H263 ) {
592         mpeg4enc_params->useShortVideoHeader = 1;
593     } else {
594         mpeg4enc_params->useShortVideoHeader = 0;
595     }
596     mpeg4enc_params->vopTimeIncrementResolution = 30;
597     mpeg4enc_params->nonMultiple16RefPadMethod = IMPEG4_PAD_METHOD_MPEG4;
598     mpeg4enc_params->pixelRange = IMPEG4ENC_PR_0_255;
599     mpeg4enc_params->enableSceneChangeAlgo = IMPEG4ENC_SCDA_DISABLE;
600     mpeg4enc_params->useVOS = 0;
601     mpeg4enc_params->enableMONA = 0;
602     mpeg4enc_params->enableAnalyticinfo = -1;
603     mpeg4enc_params->debugTraceLevel = 0;
604     mpeg4enc_params->lastNFramesToLog = 0;
606     // IMPEG4ENC_RateControlParams
607     mpeg4enc_params->rateControlParams.rateControlParamsPreset = IMPEG4_RATECONTROLPARAMS_DEFAULT;
608     mpeg4enc_params->rateControlParams.rcAlgo = IMPEG4_RATECONTROLALGO_VBR;
609     mpeg4enc_params->rateControlParams.qpI = 5;
610     mpeg4enc_params->rateControlParams.qpP = 5;
611     mpeg4enc_params->rateControlParams.seIntialQP = 5;
612     mpeg4enc_params->rateControlParams.qpMax = 31;
613     mpeg4enc_params->rateControlParams.qpMin = 1;
614     mpeg4enc_params->rateControlParams.enablePerceptualQuantMode = 0;
615     mpeg4enc_params->rateControlParams.allowFrameSkip = 0;
616     mpeg4enc_params->rateControlParams.initialBufferLevel = 0;
617     mpeg4enc_params->rateControlParams.vbvBufferSize = 0;
618     mpeg4enc_params->rateControlParams.qpMinIntra = 0;
620     // IMPEG4ENC_InterCodingParams
621     mpeg4enc_params->interCodingParams.interCodingPreset = IMPEG4_INTERCODING_DEFAULT;
622     mpeg4enc_params->interCodingParams.searchRangeHorP = 144;
623     mpeg4enc_params->interCodingParams.searchRangeVerP = 32;
624     mpeg4enc_params->interCodingParams.globalOffsetME = 1;
625     mpeg4enc_params->interCodingParams.earlySkipThreshold = 200;
626     mpeg4enc_params->interCodingParams.enableThresholdingMethod = 1;
627     mpeg4enc_params->interCodingParams.minBlockSizeP = IMPEG4_BLOCKSIZE_8x8;
628     mpeg4enc_params->interCodingParams.enableRoundingControl = 1;
630     // IMPEG4ENC_IntraCodingParams
631     mpeg4enc_params->intraCodingParams.intraCodingPreset = IMPEG4_INTRACODING_DEFAULT;
632     mpeg4enc_params->intraCodingParams.intraRefreshMethod = 0;
633     mpeg4enc_params->intraCodingParams.intraRefreshRate = 0;
634     mpeg4enc_params->intraCodingParams.acpredEnable = 1;
635     mpeg4enc_params->intraCodingParams.insertGOVHdrBeforeIframe = 0;
636     mpeg4enc_params->intraCodingParams.enableDriftControl = 1;
638     // IMPEG4ENC_sliceCodingParams
639     mpeg4enc_params->sliceCodingParams.sliceCodingPreset = IMPEG4_SLICECODING_DEFAULT;
640     mpeg4enc_params->sliceCodingParams.sliceMode = IMPEG4_SLICEMODE_NONE;
641     mpeg4enc_params->sliceCodingParams.sliceUnitSize = 0;
642     mpeg4enc_params->sliceCodingParams.gobInterval = 0;
643     mpeg4enc_params->sliceCodingParams.useHec = 0;
645     MSG("dce_alloc VIDENC2_Params successful mpeg4enc_params=%p", mpeg4enc_params);
646         enc->codec = VIDENC2_create(enc->engine, (String)"ivahd_mpeg4enc", (VIDENC2_Params *)mpeg4enc_params);
647         if(!enc->codec){
648                 ERROR("Codec could not be created %p\n", enc->codec);
649                 goto bail;
650         }
651         return 0;
652 bail:
653         encoder_deinit(enc);
654         return -1;
658 static void set_common_dyn_params(encoder *enc)
660         VIDENC2_DynamicParams   *dynParams = enc->dynParams;
661     dynParams->inputHeight  = enc->height;
662     dynParams->inputWidth  = enc->width;
663     dynParams->refFrameRate = enc->fps * 1000; // refFrameRate in fps * 1000
664     dynParams->targetFrameRate= enc->fps * 1000; // Target frame rate in fps * 1000
665     dynParams->targetBitRate = enc->bps;
666         MSG("targetFramerate = %d, targetbitrate = %d\n", dynParams->targetFrameRate, dynParams->targetBitRate);
667     dynParams->intraFrameInterval = 30; //Only 1st frame to be intra frame (I-frame)
668     dynParams->generateHeader = XDM_ENCODE_AU;
669     dynParams->captureWidth = enc->width;
670     dynParams->forceFrame = IVIDEO_NA_FRAME;
671     dynParams->sampleAspectRatioHeight = 1;
672     dynParams->sampleAspectRatioWidth = 1;
673     dynParams->ignoreOutbufSizeFlag = XDAS_FALSE;  // If this is XDAS_TRUE then getBufferFxn and getBufferHandle needs to be set.
674     dynParams->putDataFxn = NULL;
675     dynParams->putDataHandle = NULL;
676     dynParams->getDataFxn = NULL;
677     dynParams->getDataHandle = NULL;
678     dynParams->getBufferFxn = NULL;
679     dynParams->getBufferHandle = NULL;
680     dynParams->lateAcquireArg = -1;
681         return;
684 static inline int init_mpeg4_dyn_params(encoder *enc)
686         VIDENC2_DynamicParams   *dynParams = NULL;
687     XDAS_Int32      err;
688         IMPEG4ENC_DynamicParams   *mpeg4enc_dynParams;
690         dynParams = enc->dynParams = dce_alloc(sizeof(IMPEG4ENC_DynamicParams));
691         if(!enc->dynParams) goto bail;
692         enc->dynParams->size = sizeof(IMPEG4ENC_DynamicParams);
693         MSG("dce_alloc dynParams successful dynParams=%p size=%d", enc->dynParams, enc->dynParams->size);
694         set_common_dyn_params(enc);
695     dynParams->interFrameInterval = 0;
696     dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_HALFPEL; //IVIDENC2_MotionVectorAccuracy
698     MSG("dce_alloc IMPEG4ENC_DynamicParams successful size %d dynParams=%p", dynParams->size, dynParams);
699     mpeg4enc_dynParams = (IMPEG4ENC_DynamicParams *) dynParams;
701     mpeg4enc_dynParams->aspectRatioIdc = IMPEG4ENC_ASPECTRATIO_SQUARE;
703     // IMPEG4ENC_RateControlParams
704     memcpy(&mpeg4enc_dynParams->rateControlParams, &(enc->mpeg4enc_params->rateControlParams), sizeof(IMPEG4ENC_RateControlParams));
705     // IMPEG4ENC_InterCodingParams
706     memcpy(&mpeg4enc_dynParams->interCodingParams, &(enc->mpeg4enc_params->interCodingParams), sizeof(IMPEG4ENC_InterCodingParams));
707     // IMPEG4ENC_sliceCodingParams
708     memcpy(&mpeg4enc_dynParams->sliceCodingParams, &(enc->mpeg4enc_params->sliceCodingParams), sizeof(IMPEG4ENC_sliceCodingParams));
710     enc->mpeg4enc_status = dce_alloc(sizeof(IMPEG4ENC_Status));
711         if(!enc->mpeg4enc_status) goto bail;
712     ((VIDENC2_Status *)(enc->mpeg4enc_status))->size = sizeof(IMPEG4ENC_Status);
713     MSG("dce_alloc IMPEG4ENC_Status successful status=%p", enc->mpeg4enc_status);
715     err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) (enc->mpeg4enc_status));
716         if(err){
717                 ERROR("Codec_control returned err=%d, extendedError=%08x", err, enc->mpeg4enc_status->videnc2Status.extendedError);
718                 goto bail;
719         }
720         return 0;
721 bail:
722         encoder_deinit(enc);
723         return -1;
726 static inline int init_h264_dyn_params(encoder *enc)
728         VIDENC2_DynamicParams   *dynParams = NULL;
729         IH264ENC_DynamicParams   *h264enc_dynParams;
730     XDAS_Int32      err;
732         dynParams = enc->dynParams = dce_alloc(sizeof(IH264ENC_DynamicParams));
733         if(!enc->dynParams) goto bail;
734         enc->dynParams->size = sizeof(IH264ENC_DynamicParams);
735         MSG("dce_alloc dynParams successful dynParams=%p size=%d", enc->dynParams, enc->dynParams->size);
736         set_common_dyn_params(enc);
737     dynParams->interFrameInterval = 1; // 2 B frames
738     dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; //IVIDENC2_MotionVectorAccuracy
740     MSG("dce_alloc IH264ENC_DynamicParams successful size %d dynParams=%p", dynParams->size, dynParams);
741     h264enc_dynParams = (IH264ENC_DynamicParams *) dynParams;
743     h264enc_dynParams->sliceGroupChangeCycle = 0;
744     h264enc_dynParams->searchCenter.x = 0x7FFF; // or 32767
745     h264enc_dynParams->searchCenter.y = 0x7FFF; // or 32767
746     h264enc_dynParams->enableStaticMBCount = 0;
747     h264enc_dynParams->enableROI = 0;
748     h264enc_dynParams->reservedDynParams[0] = 0;
749     h264enc_dynParams->reservedDynParams[1] = 0;
750     h264enc_dynParams->reservedDynParams[2] = 0;
752     //Rate Control Params
753     h264enc_dynParams->rateControlParams.rateControlParamsPreset = IH264_RATECONTROLPARAMS_EXISTING;
754     h264enc_dynParams->rateControlParams.scalingMatrixPreset = IH264_SCALINGMATRIX_NONE;
755     h264enc_dynParams->rateControlParams.rcAlgo = IH264_RATECONTROL_DEFAULT;
756     h264enc_dynParams->rateControlParams.qpI = 28;
757     h264enc_dynParams->rateControlParams.qpMaxI = 36;
758     h264enc_dynParams->rateControlParams.qpMinI = 10;
759     h264enc_dynParams->rateControlParams.qpP = 28;
760     h264enc_dynParams->rateControlParams.qpMaxP = 40;
761     h264enc_dynParams->rateControlParams.qpMinP = 10;
762     h264enc_dynParams->rateControlParams.qpOffsetB = 4;
763     h264enc_dynParams->rateControlParams.qpMaxB = 44;
764     h264enc_dynParams->rateControlParams.qpMinB = 10;
765     h264enc_dynParams->rateControlParams.allowFrameSkip = 0;
766     h264enc_dynParams->rateControlParams.removeExpensiveCoeff = 0;
767     h264enc_dynParams->rateControlParams.IPQualityFactor = IH264_QUALITY_FACTOR_DEFAULT;
768     h264enc_dynParams->rateControlParams.chromaQPIndexOffset = 0;
769     h264enc_dynParams->rateControlParams.initialBufferLevel = 64000;
770     h264enc_dynParams->rateControlParams.HRDBufferSize = 64000;
771     h264enc_dynParams->rateControlParams.enablePartialFrameSkip = 0;
772     h264enc_dynParams->rateControlParams.minPicSizeRatioI = 0;
773     h264enc_dynParams->rateControlParams.maxPicSizeRatioI = 20;
774     h264enc_dynParams->rateControlParams.minPicSizeRatioP = 0;
775     h264enc_dynParams->rateControlParams.maxPicSizeRatioP = 0;
776     h264enc_dynParams->rateControlParams.minPicSizeRatioB = 0;
777     h264enc_dynParams->rateControlParams.maxPicSizeRatioB = 0;
778     h264enc_dynParams->rateControlParams.enablePRC = 1;
779     h264enc_dynParams->rateControlParams.enableHRDComplianceMode = 0;
780     h264enc_dynParams->rateControlParams.reserved = 0;
781     h264enc_dynParams->rateControlParams.VBRDuration = 8;
782     h264enc_dynParams->rateControlParams.VBRsensitivity = 0;
783     h264enc_dynParams->rateControlParams.skipDistributionWindowLength = 5;
784     h264enc_dynParams->rateControlParams.numSkipInDistributionWindow = 1;
785     h264enc_dynParams->rateControlParams.enableHRDComplianceMode = 1;
786     h264enc_dynParams->rateControlParams.frameSkipThMulQ5 = 0;
787     h264enc_dynParams->rateControlParams.vbvUseLevelThQ5 = 0;
788     h264enc_dynParams->rateControlParams.reservedRC[0] = 0;
789     h264enc_dynParams->rateControlParams.reservedRC[1] = 0;
790     h264enc_dynParams->rateControlParams.reservedRC[2] = 0;
792     //Inter Coding Params
793     h264enc_dynParams->interCodingParams.interCodingPreset = IH264_INTERCODING_EXISTING;
794     h264enc_dynParams->interCodingParams.searchRangeHorP = 144;
795     h264enc_dynParams->interCodingParams.searchRangeVerP = 32;
796     h264enc_dynParams->interCodingParams.searchRangeHorB = 144;
797     h264enc_dynParams->interCodingParams.searchRangeVerB = 16;
798     h264enc_dynParams->interCodingParams.interCodingBias= IH264_BIASFACTOR_DEFAULT;
799     h264enc_dynParams->interCodingParams.skipMVCodingBias = IH264_BIASFACTOR_MILD;
800     h264enc_dynParams->interCodingParams.minBlockSizeP = IH264_BLOCKSIZE_8x8;
801     h264enc_dynParams->interCodingParams.minBlockSizeB = IH264_BLOCKSIZE_8x8;
802     h264enc_dynParams->interCodingParams.meAlgoMode = IH264ENC_MOTIONESTMODE_DEFAULT;
804     //Intra Coding Params
805     h264enc_dynParams->intraCodingParams.intraCodingPreset = IH264_INTRACODING_EXISTING;
806     h264enc_dynParams->intraCodingParams.lumaIntra4x4Enable = 0xFF; // or 255 BASE PROFILE
807     h264enc_dynParams->intraCodingParams.lumaIntra8x8Enable = 0; // BASE PROFILE
808     h264enc_dynParams->intraCodingParams.lumaIntra16x16Enable = 0;
809     h264enc_dynParams->intraCodingParams.chromaIntra8x8Enable = 0;
810     h264enc_dynParams->intraCodingParams.chromaComponentEnable = IH264_CHROMA_COMPONENT_CB_CR_BOTH;
811     h264enc_dynParams->intraCodingParams.intraRefreshMethod = IH264_INTRAREFRESH_DEFAULT;
812     h264enc_dynParams->intraCodingParams.intraRefreshRate = 0;
813     h264enc_dynParams->intraCodingParams.gdrOverlapRowsBtwFrames = 0;
814     h264enc_dynParams->intraCodingParams.constrainedIntraPredEnable = 0;
815     h264enc_dynParams->intraCodingParams.intraCodingBias = IH264ENC_INTRACODINGBIAS_DEFAULT;
817     //Slice Coding Params
818     h264enc_dynParams->sliceCodingParams.sliceCodingPreset = IH264_SLICECODING_EXISTING;
819     h264enc_dynParams->sliceCodingParams.sliceMode = IH264_SLICEMODE_DEFAULT;
820     h264enc_dynParams->sliceCodingParams.sliceUnitSize = 0;
821     h264enc_dynParams->sliceCodingParams.sliceStartOffset[0] = 0;
822     h264enc_dynParams->sliceCodingParams.sliceStartOffset[1] = 0;
823     h264enc_dynParams->sliceCodingParams.sliceStartOffset[2] = 0;
824     h264enc_dynParams->sliceCodingParams.streamFormat = IH264_STREAM_FORMAT_DEFAULT;
826     enc->h264enc_status = dce_alloc(sizeof(IH264ENC_Status));
827         if(!enc->h264enc_status) goto bail;
828     ((VIDENC2_Status*)(enc->h264enc_status))->size = sizeof(IH264ENC_Status);
829     MSG("dce_alloc IH264ENC_Status successful status=%p", enc->h264enc_status);
831     err = VIDENC2_control(enc->codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) (enc->h264enc_status));
832     if( err ) {
833                 ERROR("Codec_control returned err=%d, extendedError=%08x", err, enc->h264enc_status->videnc2Status.extendedError);
834         goto bail;
835     }
836     MSG("dce_alloc IH264ENC_Status successful h264enc_status=%p", enc->h264enc_status);
839         return 0;
840 bail:
841         encoder_deinit(enc);
842         return -1;
845 static int encoder_init(encoder *enc)
847     Engine_Error    ec;
848     XDAS_Int32      err;
849     int  output_size = 0;
850     int  mvbufinfo_size = 0;
853         /*Initialze and Open DRM device*/
854         enc->drmfd = drmOpen("omapdrm", "platform:omapdrm:00");
855         if(!enc->drmfd)
856         {
857                 ERROR("Unable to open drm device");
858                 return -1;
859         }
860         dce_set_fd(enc->drmfd);
861         enc->dev = dce_init();
863         enc->engine = Engine_open((String)"ivahd_vidsvr", NULL, &ec);
864     if( !enc->engine ) {
865         ERROR("Engine open failed");
866         goto bail;
867     }
868     MSG("Engine_open successful engine=%p", enc->engine);
869     /* input buffer parameters in terms of MBs, Needs alignment to multiple of 16 */
870     enc->width  = ALIGN2(enc->width, 4);         /* round up to MB */
871     enc->height = ALIGN2(enc->height, 1);        /* round up to MB */
873     switch( enc->codectype ) {
874         case DCE_ENC_TEST_H264 :
875         case DCE_ENC_TEST_MPEG4 :
876         case DCE_ENC_TEST_H263 :
877             enc->num_buffers = 1;
878             break;
879         default :
880             ERROR("Unrecognized codec to encode");
881     }
882         /*Allocate the input buffers */
883         enc->buf.y_bo = omap_bo_new(enc->dev, enc->width * enc->height, OMAP_BO_WC);
884         if(!enc->buf.y_bo) goto bail;
885         enc->buf.ybuff = omap_bo_map(enc->buf.y_bo);
886         enc->buf.fdy = omap_bo_dmabuf(enc->buf.y_bo);
887         dce_buf_lock(1, (size_t*) &enc->buf.fdy);
888         enc->buf.sizey = enc->width * enc->height;
889         enc->buf.uv_bo = omap_bo_new(enc->dev,
890                                                                 (enc->width * enc->height) / 2, OMAP_BO_WC);
891         if(!enc->buf.uv_bo) goto bail;
892         enc->buf.uvbuff = omap_bo_map(enc->buf.uv_bo);
893         enc->buf.fduv = omap_bo_dmabuf(enc->buf.uv_bo);
894         dce_buf_lock(1, (size_t*) &enc->buf.fduv);
895         enc->buf.sizeuv = (enc->width * enc->height) / 2;
897         /*Initialize the static ivariant input buffer parameters*/
898     MSG("input buffer configuration width %d height %d", enc->width, enc->height);
899     enc->inBufs = dce_alloc(sizeof(IVIDEO2_BufDesc));
900         if(!enc->inBufs) goto bail;
901     enc->inBufs->numPlanes = 2;
902     enc->inBufs->imageRegion.topLeft.x = 0;
903     enc->inBufs->imageRegion.topLeft.y = 0;
904     enc->inBufs->imageRegion.bottomRight.x = enc->width;
906     enc->inBufs->topFieldFirstFlag = 0; //Only valid for interlace content.
907     enc->inBufs->contentType = IVIDEO_PROGRESSIVE;
909     enc->inBufs->activeFrameRegion.topLeft.x = 0;
910     enc->inBufs->activeFrameRegion.topLeft.y = 0;
911     enc->inBufs->activeFrameRegion.bottomRight.x = enc->width;
912     enc->inBufs->activeFrameRegion.bottomRight.y = enc->height;
914     enc->inBufs->imageRegion.bottomRight.y = enc->height;
915     enc->inBufs->chromaFormat = XDM_YUV_420SP;
917     enc->inBufs->secondFieldOffsetWidth[0] = 0;
918     enc->inBufs->secondFieldOffsetHeight[0] = 0;
921     MSG("Allocating input buffers from omapdrm");
923     enc->inBufs->imagePitch[0] = enc->width;
924     enc->inBufs->planeDesc[0].memType = XDM_MEMTYPE_RAW;
925     enc->inBufs->planeDesc[0].bufSize.bytes = enc->width * enc->height;
926     enc->inBufs->secondFieldOffsetWidth[1] = 1;
927     enc->inBufs->secondFieldOffsetHeight[1] = 0;
929     enc->inBufs->imagePitch[1] = enc->width;
930     enc->inBufs->planeDesc[1].memType = XDM_MEMTYPE_RAW;
931     enc->inBufs->planeDesc[1].bufSize.bytes = enc->width * enc->height / 2;
935         /*Initiaze static parameters of the codec*/
936         switch(enc->codectype){
937         case DCE_ENC_TEST_H264:
938                 if(init_h264_static_params(enc)){
939                         ERROR("H264 encoder static parameter error");
940                         goto bail;
941                 }
943                 if(init_h264_dyn_params(enc)){
944                         ERROR("H264 encoder static parameter error");
945                         goto bail;
946                 }
947                 enc->status = (VIDENC2_Status*) (enc->h264enc_status);
948                 break;
949         case DCE_ENC_TEST_MPEG4:
950         case DCE_ENC_TEST_H263:
951                 if(init_mpeg4_static_params(enc)){
952                         ERROR("MPEG4 encoder static parameter error");
953                         goto bail;
954                 }
955                 if(init_mpeg4_dyn_params(enc)){
956                         ERROR("H264 encoder static parameter error");
957                         goto bail;
958                 }
959                 enc->status = (VIDENC2_Status*) (enc->mpeg4enc_status);
960                 break;
961         default:
962                 ERROR("Unknown codec type");
963                 goto bail;
964         }
965     // XDM_GETBUFINFO
966     // Send Control cmd XDM_GETBUFINFO to get min output and output size
967     err = VIDENC2_control(enc->codec, XDM_GETBUFINFO, enc->dynParams, (VIDENC2_Status*) enc->status);
968     MSG("VIDENC2_control - XDM_GETBUFINFO err %d status numOutBuf %d OutBufSize %d MVBufInfo %d",
969                         err, ((VIDENC2_Status *)(enc->status))->bufInfo.minNumOutBufs,
970                          ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[0].bytes, ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[1].bytes);
971 /*
972  * outBufs handling
973  */
974     enc->outBufs = dce_alloc(sizeof(XDM2_BufDesc));
975         if(!enc->outBufs) goto bail;
976     output_size = ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[0].bytes;
977     mvbufinfo_size = ((VIDENC2_Status *)(enc->status))->bufInfo.minOutBufSize[1].bytes;
979         enc->outBufs->numBufs = (enc->codectype == DCE_ENC_TEST_H264) ? ((VIDENC2_Status *)(enc->h264enc_status))->bufInfo.minNumOutBufs : 1;
981         /*allocate the output buffer*/
982         enc->output_bo = omap_bo_new(enc->dev, output_size, OMAP_BO_WC);
983         enc->cdata = omap_bo_map(enc->output_bo);
984         enc->outBufs->descs[0].buf = (void *)omap_bo_dmabuf(enc->output_bo);
985         dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[0].buf));
986     enc->outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
987     enc->outBufs->descs[0].bufSize.bytes = output_size;
988     MSG("buf %p  fd %p ", enc->output_bo, enc->outBufs->descs[0].buf);
990     if( mvbufinfo_size > 0 ) {
991                 /*Allocate the output mv buffer*/
992                 enc->mv_bo = omap_bo_new(enc->dev, mvbufinfo_size, OMAP_BO_WC);
993                 enc->outBufs->descs[1].buf = (void *)omap_bo_dmabuf(enc->mv_bo);
994                 dce_buf_lock(1, (size_t*) &(enc->outBufs->descs[1].buf));
995                 enc->outBufs->descs[1].memType = XDM_MEMTYPE_RAW;
996                 enc->outBufs->descs[1].bufSize.bytes = mvbufinfo_size;
997                 MSG("mv buf %p  fd %p ", enc->mv_bo, enc->outBufs->descs[1].buf);
998         }
1000         return 0;
1001 bail:
1002         err = encoder_deinit(enc);
1003         return -1;
1006 static int encoder_deinit(encoder *enc)
1009         if(enc->buf.y_bo) {
1010                 dce_buf_unlock(1, (size_t*) &enc->buf.fdy);
1011                 close(enc->buf.fdy);
1012                 omap_bo_del(enc->buf.y_bo);
1013         }
1014         if(enc->buf.uv_bo) {
1015                 dce_buf_unlock(1, (size_t*) &enc->buf.fduv);
1016                 close(enc->buf.fduv);
1017                 omap_bo_del(enc->buf.uv_bo);
1018         }
1020         if(enc->codec) {
1021                 MSG("\nDeleting encoder codec...\n");
1022             VIDENC2_delete(enc->codec);
1023         }
1025     if( enc->output_bo ) {
1026         MSG("\nFreeing output %p \n", enc->output_bo);
1027                 dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[0].buf));
1028                 close((int)(enc->outBufs->descs[0].buf));
1029                 omap_bo_del(enc->output_bo);
1030     }
1031     if( enc->mv_bo ){
1032         MSG("\nFreeing output_mvbuf %p...\n", enc->mv_bo);
1033                 dce_buf_unlock(1, (size_t*) &(enc->outBufs->descs[1].buf));
1034                 close((int)(enc->outBufs->descs[1].buf));
1035                 omap_bo_del(enc->mv_bo);
1036     }
1038     if( enc->params ) {
1039         dce_free(enc->params);
1040     }
1041     if( enc->dynParams ) {
1042         dce_free(enc->dynParams);
1043     }
1044     if( enc->h264enc_status ) {
1045         dce_free(enc->h264enc_status);
1046     }
1047     if( enc->mpeg4enc_status ) {
1048         dce_free(enc->mpeg4enc_status);
1049     }
1050     if( enc->inBufs ) {
1051         dce_free(enc->inBufs);
1052     }
1053     if( enc->outBufs ) {
1054         dce_free(enc->outBufs);
1055     }
1056     if( enc->inArgs ) {
1057         dce_free(enc->inArgs);
1058     }
1059     if( enc->outArgs ) {
1060         dce_free(enc->outArgs);
1061     }
1062     if( enc->engine ) {
1063         Engine_close(enc->engine);
1064     }
1066         if(enc->fin) fclose(enc->fin);
1067         if(enc->fout) fclose(enc->fout);
1068         if(enc->dev) dce_deinit(enc->dev);
1069         if(enc->drmfd) drmClose(enc->drmfd);
1070         memset(enc, 0, sizeof(encoder));
1071         return 0;
1073 /* encoder body */
1074 int main(int argc, char * *argv)
1076     XDAS_Int32      err;
1077         IH264ENC_InArgs *h264enc_inArgs;
1078         IMPEG4ENC_InArgs *mpeg4enc_inArgs;
1079         IH264ENC_OutArgs *h264enc_outArgs;
1080         IMPEG4ENC_OutArgs *mpeg4enc_outArgs;
1082     int             in_cnt = 0, out_cnt = 0, iters = 0;
1083     int             eof = 0;
1084     int             bytesGenerated = 0;
1087         encoder encObj;
1088         memset(&encObj, 0, sizeof(encoder));
1090         if(parse_command(argc, argv, &encObj)){
1091                 goto shutdown;
1092         }
1095         if(encoder_init(&encObj))
1096         {
1097                 MSG("Error during encoder initialization");
1098                 goto shutdown;
1099         }
1101 /*
1102  * codec process
1103  */
1104     while( encObj.inBufs->numPlanes && encObj.outBufs->numBufs ) {
1105         int    n;
1106         MSG("Looping on reading input inBufs->numPlanes %d outBufs->numBufs %d",
1107                                          encObj.inBufs->numPlanes, encObj.outBufs->numBufs);
1109         //Read the NV12 frame to input buffer to be encoded.
1110         n = read_NV12frame(&encObj);
1112         if( n > 0) {
1113             eof = 0;
1114                         /*Pass the FDs for subplanes*/
1115             encObj.inBufs->planeDesc[0].buf = (XDAS_Int8 *)(encObj.buf.fdy);
1116             encObj.inBufs->planeDesc[1].buf = (XDAS_Int8 *)(encObj.buf.fduv);
1117             MSG("inBufs->planeDesc[0].buf %p inBufs->planeDesc[1].buf %p",
1118                                          encObj.inBufs->planeDesc[0].buf, encObj.inBufs->planeDesc[1].buf);
1119             MSG("push: %d (plane[0]= %d + plane[1]= %d = %d bytes) (%p)",
1120                                          in_cnt, encObj.inBufs->planeDesc[0].bufSize.bytes, encObj.inBufs->planeDesc[1].bufSize.bytes, n, &encObj.buf);
1121             in_cnt++;
1123             encObj.inArgs->inputID = in_cnt; // Send frame count as the input ID
1124             /*
1125              * Input buffer has data to be encoded.
1126              */
1127         } else if( n == -1 ) {
1129             // Set EOF as 1 to ensure flush completes
1130             eof = 1;
1131             in_cnt++;
1133             MSG("n == -1 - go to shutdown");
1135             goto shutdown;
1136         } else {
1137             /* end of input..  (n == 0) */
1138             encObj.inBufs->numPlanes = 0;
1139             eof = 1;
1140             MSG("n == 0 - go to shutdown");
1142             goto shutdown;
1144         }
1147         do {
1149             if( encObj.codectype == DCE_ENC_TEST_H264 ) {
1150                 h264enc_inArgs = (IH264ENC_InArgs *) encObj.inArgs;
1151                                 h264enc_outArgs = (IH264ENC_OutArgs *) encObj.outArgs;
1152                 MSG("TEST inArgs->inputID %d h264enc_inArgs->videnc2InArgs.inputID %d",
1153                                                  encObj.inArgs->inputID, h264enc_inArgs->videnc2InArgs.inputID);
1154                 err = VIDENC2_process(encObj.codec, encObj.inBufs, encObj.outBufs, (VIDENC2_InArgs *) h264enc_inArgs, (VIDENC2_OutArgs *) h264enc_outArgs);
1155                 MSG("[DCE_ENC_TEST] VIDENC2_process - err %d", err);
1157                 if( err < 0 ) {
1158                     int    i = 0;
1160                     for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) {
1161                         MSG("DETAIL EXTENDED ERROR h264enc_outArgs->extErrorCode[%d]=%08x", i, (uint)h264enc_outArgs->extErrorCode[i]);
1162                     }
1164                     err = VIDENC2_control(encObj.codec, XDM_GETSTATUS, (VIDENC2_DynamicParams *) encObj.dynParams, (VIDENC2_Status *) encObj.h264enc_status);
1165                     MSG("[DCE_ENC_TEST] VIDENC2_control - XDM_GETSTATUS err %d", err);
1167                     for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) {
1168                         MSG("DETAIL EXTENDED ERROR h264enc_status->extErrorCode[%d]=%08x", i, (uint)encObj.h264enc_status->extErrorCode[i]);
1169                     }
1171                     if( XDM_ISFATALERROR(h264enc_outArgs->videnc2OutArgs.extendedError) ) {
1172                         ERROR("process returned error: %d\n", err);
1173                         ERROR("extendedError: %08x", h264enc_outArgs->videnc2OutArgs.extendedError);
1174                         goto shutdown;
1175                     } else if( eof ) {
1176                         ERROR("Codec_process returned err=%d, extendedError=%08x", err, h264enc_outArgs->videnc2OutArgs.extendedError);
1177                         err = XDM_EFAIL;
1179                         if( err == XDM_EFAIL ) {
1180                             MSG("-------------------- Flush completed------------------------");
1181                         }
1182                     } else {
1183                         ERROR("Non-fatal err=%d, h264enc_outArgs->videnc2OutArgs.extendedError=%08x ", err, h264enc_outArgs->videnc2OutArgs.extendedError);
1184                         err = XDM_EOK;
1185                     }
1186                 }
1188                 MSG("bytesGenerated %d", h264enc_outArgs->videnc2OutArgs.bytesGenerated);
1189                 bytesGenerated = h264enc_outArgs->videnc2OutArgs.bytesGenerated;
1190             } else if( encObj.codectype == DCE_ENC_TEST_MPEG4 || encObj.codectype == DCE_ENC_TEST_H263 ) {
1191                 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) encObj.inArgs;
1192                                 mpeg4enc_outArgs = (IMPEG4ENC_OutArgs *) encObj.outArgs;
1193                 MSG("TEST inArgs->inputID %d mpeg4enc_inArgs->videnc2InArgs.inputID %d", encObj.inArgs->inputID, mpeg4enc_inArgs->videnc2InArgs.inputID);
1194                 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);
1195                 err = VIDENC2_process(encObj.codec, encObj.inBufs, encObj.outBufs, (VIDENC2_InArgs *) mpeg4enc_inArgs, (VIDENC2_OutArgs *) mpeg4enc_outArgs);
1196                 MSG("[DCE_ENC_TEST] VIDENC2_process - err %d", err);
1197                 if( err < 0 ) {
1198                     //TODO error handling on MPEG4/H.263
1199                     ERROR("Codec_process returned err=%d, extendedError=%08x", err, mpeg4enc_outArgs->videnc2OutArgs.extendedError);
1200                     goto shutdown;
1201                 }
1202                 MSG("\n bytesGenerated %d", mpeg4enc_outArgs->videnc2OutArgs.bytesGenerated);
1203                 bytesGenerated = mpeg4enc_outArgs->videnc2OutArgs.bytesGenerated;
1204             }
1207             /*
1208              * Handling of output data from codec
1209              */
1211             /* get the output buffer and write it to file */
1212             if( bytesGenerated ) {
1213                 // write the frames to output file based on the value of frames_to_write on how many frames to write.
1214                 if( out_cnt > encObj.nframes ) goto shutdown;
1215                 INFO("Dumping frame %d", out_cnt);
1216                                 write_output(&encObj, bytesGenerated);
1217             }
1218             out_cnt++;
1219             ++iters; // Guard for infinite VIDENC2_PROCESS loop when codec never return XDM_EFAIL
1220         } while( eof && (err != XDM_EFAIL) && (iters < 1000));  // Multiple VIDENC2_process when eof until err == XDM_EFAIL
1221     }
1222 shutdown:
1223         encoder_deinit(&encObj);
1224         INFO("Encoding complete...\n");
1225     return 0;