status_t SoftAVC::initDecoder() { // Force decoder to output buffers in display order. if (H264SwDecInit(&mHandle, 0) == H264SWDEC_OK) { return OK; } return UNKNOWN_ERROR; }
u32 broadwayInit() { H264SwDecRet ret; u32 disableOutputReordering = 0; /* Initialize decoder instance. */ ret = H264SwDecInit(&decInst, disableOutputReordering); if (ret != H264SWDEC_OK) { DEBUG(("DECODER INITIALIZATION FAILED\n")); broadwayExit(); return -1; } picDecodeNumber = picDisplayNumber = 1; }
/*------------------------------------------------------------------------------ ------------------------------------------------------------------------------*/ int main(int argc, char **argv) { i32 instCount, instRunning; i32 i; u32 maxNumPics; u32 strmLen; H264SwDecRet ret; u32 numErrors = 0; u32 cropDisplay = 0; u32 disableOutputReordering = 0; FILE *finput; Decoder **decoder; char outFileName[256] = "out.yuv"; if ( argc > 1 && strcmp(argv[1], "-T") == 0 ) { fprintf(stderr, "%s\n", tagName); return 0; } if (argc < 2) { DEBUG(( "Usage: %s [-Nn] [-Ooutfile] [-P] [-U] [-C] [-R] [-T] file1.264 [file2.264] .. [fileN.264]\n", argv[0])); DEBUG(("\t-Nn forces decoding to stop after n pictures\n")); #if defined(_NO_OUT) DEBUG(("\t-Ooutfile output writing disabled at compile time\n")); #else DEBUG(("\t-Ooutfile write output to \"outfile\" (default out.yuv)\n")); DEBUG(("\t-Onone does not write output\n")); #endif DEBUG(("\t-C display cropped image (default decoded image)\n")); DEBUG(("\t-R disable DPB output reordering\n")); DEBUG(("\t-T to print tag name and exit\n")); exit(100); } instCount = argc - 1; /* read command line arguments */ maxNumPics = 0; for (i = 1; i < (argc-1); i++) { if ( strncmp(argv[i], "-N", 2) == 0 ) { maxNumPics = (u32)atoi(argv[i]+2); instCount--; } else if ( strncmp(argv[i], "-O", 2) == 0 ) { strcpy(outFileName, argv[i]+2); instCount--; } else if ( strcmp(argv[i], "-C") == 0 ) { cropDisplay = 1; instCount--; } else if ( strcmp(argv[i], "-R") == 0 ) { disableOutputReordering = 1; instCount--; } } if (instCount < 1) { DEBUG(("No input files\n")); exit(100); } /* allocate memory for multiple decoder instances * one instance for every stream file */ decoder = (Decoder **)malloc(sizeof(Decoder*)*(u32)instCount); if (decoder == NULL) { DEBUG(("Unable to allocate memory\n")); exit(100); } /* prepare each decoder instance */ for (i = 0; i < instCount; i++) { decoder[i] = (Decoder *)calloc(1, sizeof(Decoder)); /* open input file */ finput = fopen(argv[argc-instCount+i],"rb"); if (finput == NULL) { DEBUG(("Unable to open input file <%s>\n", argv[argc-instCount+i])); exit(100); } DEBUG(("Reading input file[%d] %s\n", i, argv[argc-instCount+i])); /* read input stream to buffer */ fseek(finput,0L,SEEK_END); strmLen = (u32)ftell(finput); rewind(finput); decoder[i]->byteStrmStart = (u8 *)malloc(sizeof(u8)*strmLen); if (decoder[i]->byteStrmStart == NULL) { DEBUG(("Unable to allocate memory\n")); exit(100); } fread(decoder[i]->byteStrmStart, sizeof(u8), strmLen, finput); fclose(finput); /* open output file */ if (strcmp(outFileName, "none") != 0) { #if defined(_NO_OUT) decoder[i]->foutput = NULL; #else sprintf(decoder[i]->outFileName, "%s%i", outFileName, i); decoder[i]->foutput = fopen(decoder[i]->outFileName, "wb"); if (decoder[i]->foutput == NULL) { DEBUG(("Unable to open output file\n")); exit(100); } #endif } ret = H264SwDecInit(&(decoder[i]->decInst), disableOutputReordering); if (ret != H264SWDEC_OK) { DEBUG(("Init failed %d\n", ret)); exit(100); } decoder[i]->decInput.pStream = decoder[i]->byteStrmStart; decoder[i]->decInput.dataLen = strmLen; decoder[i]->decInput.intraConcealmentMethod = 0; } /* main decoding loop */ do { /* decode once using each instance */ for (i = 0; i < instCount; i++) { ret = H264SwDecDecode(decoder[i]->decInst, &(decoder[i]->decInput), &(decoder[i]->decOutput)); switch(ret) { case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY: ret = H264SwDecGetInfo(decoder[i]->decInst, &(decoder[i]->decInfo)); if (ret != H264SWDEC_OK) exit(1); if (cropDisplay && decoder[i]->decInfo.croppingFlag) { DEBUG(("Decoder[%d] Cropping params: (%d, %d) %dx%d\n", i, decoder[i]->decInfo.cropParams.cropLeftOffset, decoder[i]->decInfo.cropParams.cropTopOffset, decoder[i]->decInfo.cropParams.cropOutWidth, decoder[i]->decInfo.cropParams.cropOutHeight)); } DEBUG(("Decoder[%d] Width %d Height %d\n", i, decoder[i]->decInfo.picWidth, decoder[i]->decInfo.picHeight)); DEBUG(("Decoder[%d] videoRange %d, matricCoefficients %d\n", i, decoder[i]->decInfo.videoRange, decoder[i]->decInfo.matrixCoefficients)); decoder[i]->decInput.dataLen -= (u32)(decoder[i]->decOutput.pStrmCurrPos - decoder[i]->decInput.pStream); decoder[i]->decInput.pStream = decoder[i]->decOutput.pStrmCurrPos; break; case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY: decoder[i]->decInput.dataLen -= (u32)(decoder[i]->decOutput.pStrmCurrPos - decoder[i]->decInput.pStream); decoder[i]->decInput.pStream = decoder[i]->decOutput.pStrmCurrPos; /* fall through */ case H264SWDEC_PIC_RDY: if (ret == H264SWDEC_PIC_RDY) decoder[i]->decInput.dataLen = 0; ret = H264SwDecGetInfo(decoder[i]->decInst, &(decoder[i]->decInfo)); if (ret != H264SWDEC_OK) exit(1); while (H264SwDecNextPicture(decoder[i]->decInst, &(decoder[i]->decPicture), 0) == H264SWDEC_PIC_RDY) { decoder[i]->picNumber++; numErrors += decoder[i]->decPicture.nbrOfErrMBs; DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n", i, decoder[i]->picNumber, decoder[i]->decPicture.isIdrPicture ? "IDR" : "NON-IDR", decoder[i]->decPicture.nbrOfErrMBs)); fflush(stdout); CropWriteOutput(decoder[i]->foutput, (u8*)decoder[i]->decPicture.pOutputPicture, cropDisplay, &(decoder[i]->decInfo)); } if (maxNumPics && decoder[i]->picNumber == maxNumPics) decoder[i]->decInput.dataLen = 0; break; case H264SWDEC_STRM_PROCESSED: case H264SWDEC_STRM_ERR: case H264SWDEC_PARAM_ERR: decoder[i]->decInput.dataLen = 0; break; default: DEBUG(("Decoder[%d] FATAL ERROR\n", i)); exit(10); break; } } /* check if any of the instances is still running (=has more data) */ instRunning = instCount; for (i = 0; i < instCount; i++) { if (decoder[i]->decInput.dataLen == 0) instRunning--; } } while (instRunning); /* get last frames and close each instance */ for (i = 0; i < instCount; i++) { while (H264SwDecNextPicture(decoder[i]->decInst, &(decoder[i]->decPicture), 1) == H264SWDEC_PIC_RDY) { decoder[i]->picNumber++; DEBUG(("Decoder[%d] PIC %d, type %s, concealed %d\n", i, decoder[i]->picNumber, decoder[i]->decPicture.isIdrPicture ? "IDR" : "NON-IDR", decoder[i]->decPicture.nbrOfErrMBs)); fflush(stdout); CropWriteOutput(decoder[i]->foutput, (u8*)decoder[i]->decPicture.pOutputPicture, cropDisplay, &(decoder[i]->decInfo)); } H264SwDecRelease(decoder[i]->decInst); if (decoder[i]->foutput) fclose(decoder[i]->foutput); free(decoder[i]->byteStrmStart); free(decoder[i]); } free(decoder); if (numErrors) return 1; else return 0; }
MEDIA_STATUS_CODE VideoH264DecOpen(void *param) { H264SwDecCapability rDecCap; H264SwDecRet rCodecRet; H264SwDecMemManageFunc rFunc; H264_DEC_INIT_PARAM_TYPE_T *pInitParam = (H264_DEC_INIT_PARAM_TYPE_T*)param; kal_uint32 u4IntMemAddr = 0, u4IntMemSize = 0, u4NoReordering = 0; #if defined(__MTK_TARGET__) #if defined(MT6236) || defined(MT6236B) kal_uint32* pu4TCMBuff_S = NULL; kal_uint32 u4ValidTCMSize_S = 0; DCM_Load(DYNAMIC_CODE_264DEC_S, &pu4TCMBuff_S, &u4ValidTCMSize_S); #endif #endif drv_trace0(TRACE_GROUP_8, H264DEC_OPEN); drv_trace4(TRACE_GROUP_10, OPEN_API_ENTERVIDEOH264DECOPEN ,pInitParam->ext_mem_addr.p_addr, pInitParam->ext_mem_size,pInitParam->int_mem_addr.p_addr,pInitParam->int_mem_size); if (pInitParam == NULL) { drv_trace1(TRACE_GROUP_8, H264DEC_ARGUMENT_ERROR, __LINE__); ASSERT(0); return VIDEO_ERROR; } rH264SwCtrl.pAdmId = kal_adm_create((void*)pInitParam->ext_mem_addr.p_addr, pInitParam->ext_mem_size, NULL, KAL_FALSE); if (rH264SwCtrl.pAdmId == NULL) { ASSERT(0); } if (H264SWDEC_OK != H264SwDecQueryCapability(&rDecCap, H264SW_QVGA)) { ASSERT(0); } else { rH264SwCtrl.fgBsBufferCacheable = (rDecCap.isBsCacheable == 1) ? KAL_TRUE : KAL_FALSE; rH264SwCtrl.fgFrmBufferCacheable = (rDecCap.isFrameCacheable == 1) ? KAL_TRUE : KAL_FALSE; #if defined(DRV_FEATURE__MM_INTMEM_IF) u4IntMemAddr = OpenAPIGetIntBuffer(rDecCap.intMemSize); u4IntMemSize = rDecCap.intMemSize; #else u4IntMemAddr = pInitParam->int_mem_addr; u4IntMemSize = pInitParam->int_mem_size; #endif } u4NoReordering = (pInitParam->fgDisplayOrderMode) ? 0 : 1; drv_trace0(TRACE_GROUP_8, H264DEC_INIT); rFunc.Malloc = VideoH264DecMalloc; rFunc.Free = VideoH264DecFree; rFunc.Memcpy = VideoH264DecMemcpy; rFunc.Memset = VideoH264DecMemset; rFunc.MallocDPB = VideoH264DecMallocDPB; rFunc.FreeDPB = VideoH264DecFreeDPB; rFunc.ReturnBitstream = VideoH264DecReturnBitstream; rCodecRet = H264SwDecInit(&rH264SwCtrl.prH264DecInst, u4NoReordering, (u8*)u4IntMemAddr, u4IntMemSize, (u32)H264SW_DEC_DPB_SIZE, (u32)0, &rFunc); if (rCodecRet != H264SWDEC_OK) { drv_trace1(TRACE_GROUP_8, H264DEC_INIT_ERROR, rCodecRet); ASSERT(0); return VIDEO_ERROR; } rH264SwCtrl.fgFrmBufferSwitch = KAL_FALSE; rH264SwCtrl.fgIsCodecInit = KAL_TRUE; rH264SwCtrl.u2FrameHeight = 0; rH264SwCtrl.u2FrameWidth = 0; rH264SwCtrl.u2RealHeight = 0; rH264SwCtrl.u2RealWidth = 0; rH264SwCtrl.u4BufferSize = 0; rH264SwCtrl.pfnSetFrameUnReference = pInitParam->pfnSetFrameUnReferenceCallback; rH264SwCtrl.pfnOutputOneFrame = pInitParam->pfnOutputOneFrameCallback; rH264SwCtrl.pfnGetYUVBuffer = pInitParam->pfnGetYUVBufferCallback; rH264SwCtrl.pfnReturnBitstream = pInitParam->pfnReturnBsBufferCallback; if ((rH264SwCtrl.pfnSetFrameUnReference == NULL) || (rH264SwCtrl.pfnOutputOneFrame == NULL) || (rH264SwCtrl.pfnGetYUVBuffer == NULL)) { ASSERT(0); } return MEDIA_STATUS_OK; }
/*------------------------------------------------------------------------------ Function name: main Purpose: main function. Assuming that executable is named 'decoder' the usage is as follows decoder inputFileName , where inputFileName shall be name of file containing h264 stream data. ------------------------------------------------------------------------------*/ int main(int argc, char **argv) { u8 *byteStrmStart; u8 *byteStrm; u32 strmLen; u32 picSize; H264SwDecInst decInst; H264SwDecRet ret; H264SwDecInput decInput; H264SwDecOutput decOutput; H264SwDecPicture decPicture; H264SwDecInfo decInfo; u32 picNumber; FILE *finput; FILE *foutput; /* Check that enough command line arguments given, if not -> print usage * information out */ if (argc < 2) { printf( "Usage: %s file.h264\n", argv[0]); return -1; } /* open output file for writing, output file named out.yuv. If file open * fails -> exit */ foutput = fopen("out.yuv", "wb"); if (foutput == NULL) { printf("UNABLE TO OPEN OUTPUT FILE\n"); return -1; } /* open input file for reading, file name given by user. If file open * fails -> exit */ finput = fopen(argv[argc-1], "rb"); if (finput == NULL) { printf("UNABLE TO OPEN INPUT FILE\n"); return -1; } /* check size of the input file -> length of the stream in bytes */ fseek(finput, 0L, SEEK_END); strmLen = (u32)ftell(finput); rewind(finput); /* allocate memory for stream buffer, exit if unsuccessful */ byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8), strmLen); if (byteStrm == NULL) { printf("UNABLE TO ALLOCATE MEMORY\n"); return -1; } /* read input stream from file to buffer and close input file */ fread(byteStrm, sizeof(u8), strmLen, finput); fclose(finput); /* initialize decoder. If unsuccessful -> exit */ ret = H264SwDecInit(&decInst, 0); if (ret != H264SWDEC_OK) { printf("DECODER INITIALIZATION FAILED\n"); return -1; } /* initialize H264SwDecDecode() input structure */ decInput.pStream = byteStrmStart; decInput.dataLen = strmLen; decInput.intraConcealmentMethod = 0; picNumber = 0; /* For performance measurements, read the start time (in seconds) here. * The decoding time should be measured over several frames and after * that average fps (frames/second) can be calculated. * * startTime = GetTime(); * * To prevent calculating file I/O latensies as a decoding time, * comment out WriteOutput function call. Also prints to stdout might * consume considerable amount of cycles during measurement */ /* main decoding loop */ do { /* call API function to perform decoding */ ret = H264SwDecDecode(decInst, &decInput, &decOutput); switch(ret) { case H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY: /* picture dimensions are available for query now */ ret = H264SwDecGetInfo(decInst, &decInfo); if (ret != H264SWDEC_OK) return -1; /* picture size in pixels */ picSize = decInfo.picWidth * decInfo.picHeight; /* memory needed for YCbCr 4:2:0 picture in bytes */ picSize = (3 * picSize)/2; /* memory needed for 16-bit RGB picture in bytes * picSize = (decInfo.picWidth * decInfo.picHeight) * 2; */ printf("Width %d Height %d\n", decInfo.picWidth, decInfo.picHeight); /* update H264SwDecDecode() input structure, number of bytes * "consumed" is computed as difference between the new stream * pointer and old stream pointer */ decInput.dataLen -= (u32)(decOutput.pStrmCurrPos - decInput.pStream); decInput.pStream = decOutput.pStrmCurrPos; break; case H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY: case H264SWDEC_PIC_RDY: /* update H264SwDecDecode() input structure, number of bytes * "consumed" is computed as difference between the new stream * pointer and old stream pointer */ decInput.dataLen -= (u32)(decOutput.pStrmCurrPos - decInput.pStream); decInput.pStream = decOutput.pStrmCurrPos; /* use function H264SwDecNextPicture() to obtain next picture * in display order. Function is called until no more images * are ready for display */ while (H264SwDecNextPicture(decInst, &decPicture, 0) == H264SWDEC_PIC_RDY) { picNumber++; printf("PIC %d, type %s, concealed %d\n", picNumber, decPicture.isIdrPicture ? "IDR" : "NON-IDR", decPicture.nbrOfErrMBs); fflush(stdout); /* Do color conversion if needed to get display image * in RGB-format * * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */ /* write next display image to output file */ WriteOutput(foutput, (u8*)decPicture.pOutputPicture, picSize); } break; case H264SWDEC_EVALUATION_LIMIT_EXCEEDED: /* evaluation version of the decoder has limited decoding * capabilities */ printf("EVALUATION LIMIT REACHED\n"); goto end; default: printf("UNRECOVERABLE ERROR\n"); return -1; } /* keep decoding until all data from input stream buffer consumed */ } while (decInput.dataLen > 0); end: /* if output in display order is preferred, the decoder shall be forced * to output pictures remaining in decoded picture buffer. Use function * H264SwDecNextPicture() to obtain next picture in display order. Function * is called until no more images are ready for display. Second parameter * for the function is set to '1' to indicate that this is end of the * stream and all pictures shall be output */ while (H264SwDecNextPicture(decInst, &decPicture, 1) == H264SWDEC_PIC_RDY) { picNumber++; printf("PIC %d, type %s, concealed %d\n", picNumber, decPicture.isIdrPicture ? "IDR" : "NON-IDR", decPicture.nbrOfErrMBs); fflush(stdout); /* Do color conversion if needed to get display image * in RGB-format * * YuvToRgb( decPicture.pOutputPicture, pRgbPicture ); */ /* write next display image to output file */ WriteOutput(foutput, (u8*)decPicture.pOutputPicture, picSize); } /* For performance measurements, read the end time (in seconds) here. * * endTime = GetTime(); * * Now the performance can be calculated as frames per second: * fps = picNumber / (endTime - startTime); */ /* release decoder instance */ H264SwDecRelease(decInst); /* close output file */ fclose(foutput); /* free byte stream buffer */ free(byteStrmStart); return 0; }