#ifdef WIN32 #include #endif #include #include #include "TAppEncTop.h" #include "TLibCommon/Debug.h" #include "TLibEncoder/TEncAnalyze.h" #include "bpgenc.h" #define ARGV_MAX 128 static void add_opt(int *pargc, char **argv, const char *str) { int argc; argc = *pargc; if (argc >= ARGV_MAX) abort(); argv[argc++] = strdup(str); *pargc = argc; } /* return the encoded data in *pbuf and the size. Return < 0 if error */ int jctvc_encode_picture(uint8_t **pbuf, Image *img, const HEVCEncodeParams *params) { TAppEncTop cTAppEncTop; int argc; char *argv[ARGV_MAX + 1]; char buf[1024], infilename[1024], outfilename[1024]; const char *str; FILE *f; uint8_t *out_buf; int out_buf_len, i; #ifdef WIN32 if (GetTempPath(sizeof(buf), buf) > sizeof(buf) - 1) { fprintf(stderr, "Temporary path too long\n"); return -1; } #else strcpy(buf, "/tmp/"); #endif snprintf(infilename, sizeof(infilename), "%sout%d.yuv", buf, getpid()); snprintf(outfilename, sizeof(outfilename), "%sout%d.bin", buf, getpid()); save_yuv(img, infilename); m_gcAnalyzeAll.clear(); m_gcAnalyzeI.clear(); m_gcAnalyzeP.clear(); m_gcAnalyzeB.clear(); m_gcAnalyzeAll_in.clear(); cTAppEncTop.create(); argc = 0; add_opt(&argc, argv, "jctvc"); /* dummy executable name */ snprintf(buf, sizeof(buf),"--InputFile=%s", infilename); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--BitstreamFile=%s", outfilename); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--SourceWidth=%d", img->w); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--SourceWidth=%d", img->w); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--SourceHeight=%d", img->h); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--InputBitDepth=%d", img->bit_depth); add_opt(&argc, argv, buf); switch(img->format) { case BPG_FORMAT_GRAY: str = "400"; break; case BPG_FORMAT_420: str = "420"; break; case BPG_FORMAT_422: str = "422"; break; case BPG_FORMAT_444: str = "444"; break; default: abort(); } snprintf(buf, sizeof(buf),"--InputChromaFormat=%s", str); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--QP=%d", params->qp); add_opt(&argc, argv, buf); snprintf(buf, sizeof(buf),"--SEIDecodedPictureHash=%d", params->sei_decoded_picture_hash); add_opt(&argc, argv, buf); if (!params->verbose) add_opt(&argc, argv, "--Verbose=0"); /* single frame */ add_opt(&argc, argv, "--FramesToBeEncoded=1"); /* no padding necessary (it is done before) */ add_opt(&argc, argv, "--ConformanceWindowMode=0"); /* dummy frame rate */ add_opt(&argc, argv, "--FrameRate=25"); /* general config */ add_opt(&argc, argv, "--Profile=main_444_16_intra"); add_opt(&argc, argv, "--QuadtreeTULog2MaxSize=5"); add_opt(&argc, argv, "--QuadtreeTUMaxDepthIntra=3"); add_opt(&argc, argv, "--IntraPeriod=1"); add_opt(&argc, argv, "--GOPSize=1"); add_opt(&argc, argv, "--TransformSkip=1"); add_opt(&argc, argv, "--TransformSkipFast=1"); /* Note: Format Range extension */ if (img->format == BPG_FORMAT_444) { add_opt(&argc, argv, "--CrossComponentPrediction=1"); } if (params->lossless) { add_opt(&argc, argv, "--CostMode=lossless"); add_opt(&argc, argv, "--SAO=0"); add_opt(&argc, argv, "--LoopFilterDisable"); add_opt(&argc, argv, "--TransquantBypassEnableFlag"); add_opt(&argc, argv, "--CUTransquantBypassFlagForce"); add_opt(&argc, argv, "--ImplicitResidualDPCM"); add_opt(&argc, argv, "--GolombRiceParameterAdaptation"); add_opt(&argc, argv, "--HadamardME=0"); } /* trailing NULL */ argv[argc] = NULL; if (params->verbose >= 2) { int i; printf("Encode options:"); for(i = 0; i < argc; i++) { printf(" %s", argv[i]); } printf("\n"); } if(!cTAppEncTop.parseCfg( argc, argv )) { fprintf(stderr, "Error while parsing options\n"); cTAppEncTop.destroy(); return -1; } cTAppEncTop.encode(); cTAppEncTop.destroy(); for(i = 0; i < argc; i++) free(argv[i]); unlink(infilename); /* read output bitstream */ f = fopen(outfilename, "rb"); if (!f) { fprintf(stderr, "Could not open '%s'\n", outfilename); return -1; } fseek(f, 0, SEEK_END); out_buf_len = ftell(f); fseek(f, 0, SEEK_SET); out_buf = (uint8_t *)malloc(out_buf_len); if (fread(out_buf, 1, out_buf_len, f) != out_buf_len) { fprintf(stderr, "read error\n"); fclose(f); free(out_buf); return -1; } fclose(f); unlink(outfilename); *pbuf = out_buf; return out_buf_len; }