Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2014
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. int encoder_x264_init(Encoder_t *encoder, Image_t *image) {
  2.     encoder->sps_data = NULL;
  3.     encoder->sps_data_size = 0;
  4.     encoder->pps_data = NULL;
  5.     encoder->pps_data_size = 0;
  6.     encoder->hwenc.sts = MFX_ERR_NONE;
  7.     const mfxIMPL hwimpl[] = {MFX_IMPL_HARDWARE_ANY, MFX_IMPL_HARDWARE};;
  8.     mfxVersion vers = {
  9.                         .Minor = 0,
  10.                         .Major = 1}; //Legacy support
  11.     mfxU16 target_width = (image->width > 1920 ? 1920 : image->width);
  12.     mfxU16 target_height = (image->height > 1080 ? 1080 : image->height);
  13.  
  14.     //Initialization of Intel Media SDK ENCODER session
  15.     for(int i=0; i < sizeof(hwimpl)/sizeof(hwimpl[0]);i++)
  16.     {
  17.         encoder->hwenc.sts = MFXInit(hwimpl[i], &vers, &encoder->hwenc.ENCses);
  18.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  19.         if(encoder->hwenc.sts == MFX_ERR_NONE)
  20.         {
  21.             MFXQueryVersion(encoder->hwenc.ENCses,&encoder->hwenc.ver);
  22.             printf("Asked for version %d.%d.\n",vers.Major,vers.Minor);
  23.             printf("SDK version loaded for the ENCODER session is %d.%d.\n",encoder->hwenc.ver.Major,encoder->hwenc.ver.Minor);
  24.             break;
  25.         }
  26.     }
  27.    
  28.    
  29.     //Initialization of VPP session for format conversion and potential scaling
  30.     for(int i=0; i < sizeof(hwimpl)/sizeof(hwimpl[0]);i++)
  31.     {
  32.     encoder->hwenc.sts = MFXInit(hwimpl[i], &vers,&encoder->hwenc.VPPses);
  33.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  34.         if(encoder->hwenc.sts == MFX_ERR_NONE)
  35.         {
  36.             MFXQueryVersion(encoder->hwenc.ENCses,&encoder->hwenc.ver);
  37.             printf("SDK version loaded for the VPP session is %d.%d.\n",encoder->hwenc.ver.Major,encoder->hwenc.ver.Minor);
  38.             break;
  39.         }
  40.     }
  41.    
  42.     //Initialization of encoder parameters
  43.     memset(&encoder->hwenc.ENCParams,0,sizeof(encoder->hwenc.ENCParams));
  44.     encoder->hwenc.ENCParams.mfx.CodecId                    = MFX_CODEC_AVC;
  45.     encoder->hwenc.ENCParams.mfx.TargetUsage                = MFX_TARGETUSAGE_BALANCED;
  46.     encoder->hwenc.ENCParams.mfx.TargetKbps                 = 2000; //Investigation required
  47.     encoder->hwenc.ENCParams.mfx.RateControlMethod          = MFX_RATECONTROL_VBR;
  48.     encoder->hwenc.ENCParams.mfx.FrameInfo.FrameRateExtN    = 30;
  49.     encoder->hwenc.ENCParams.mfx.FrameInfo.FrameRateExtD    = 1;
  50.     encoder->hwenc.ENCParams.mfx.FrameInfo.FourCC           = MFX_FOURCC_NV12;
  51.     encoder->hwenc.ENCParams.mfx.FrameInfo.ChromaFormat     = MFX_CHROMAFORMAT_YUV420;
  52.     encoder->hwenc.ENCParams.mfx.FrameInfo.PicStruct        = MFX_PICSTRUCT_PROGRESSIVE;
  53.     encoder->hwenc.ENCParams.mfx.FrameInfo.CropX            = 0;
  54.     encoder->hwenc.ENCParams.mfx.FrameInfo.CropY            = 0;
  55.     encoder->hwenc.ENCParams.mfx.FrameInfo.CropW            = target_width;
  56.     encoder->hwenc.ENCParams.mfx.FrameInfo.CropH            = target_height;
  57.    
  58.     //Width is aligned as a multiple of 16
  59.     encoder->hwenc.ENCParams.mfx.FrameInfo.Width = MSDK_ALIGN16(target_width);
  60.    
  61.     //Same applies for height unless it's a field picture so it is a multiple of 32
  62.     encoder->hwenc.ENCParams.mfx.FrameInfo.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.ENCParams.mfx.FrameInfo.PicStruct)?
  63.         MSDK_ALIGN16(target_height) : MSDK_ALIGN32(target_height);
  64.    
  65.     encoder->hwenc.ENCParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
  66.    
  67.     //Additional ENCODER configuration for low latency
  68.     encoder->hwenc.ENCParams.AsyncDepth = 1;
  69.     encoder->hwenc.ENCParams.mfx.GopRefDist = 1;//B-frames disabled
  70.    
  71.     mfxExtCodingOption extras;
  72.     memset(&extras,0,sizeof(extras));
  73.     extras.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
  74.     extras.Header.BufferSz = sizeof(extras);
  75.     extras.MaxDecFrameBuffering = 1;
  76.     mfxExtBuffer *extrasBuf[1];
  77.     extrasBuf[0] = (mfxExtBuffer*)&extras;
  78.     encoder->hwenc.ENCParams.ExtParam = extrasBuf;
  79.     encoder->hwenc.ENCParams.NumExtParam = 1;
  80.    
  81.     //Initialization of VPP parameters (input)
  82.     memset(&encoder->hwenc.VPPParams,0,sizeof(encoder->hwenc.VPPParams));
  83.     encoder->hwenc.VPPParams.vpp.In.FourCC          = MFX_FOURCC_RGB4;
  84.     encoder->hwenc.VPPParams.vpp.In.ChromaFormat    = MFX_CHROMAFORMAT_YUV420;
  85.     encoder->hwenc.VPPParams.vpp.In.CropX           = 0;
  86.     encoder->hwenc.VPPParams.vpp.In.CropY           = 0;
  87.     encoder->hwenc.VPPParams.vpp.In.CropW           = image->width;
  88.     encoder->hwenc.VPPParams.vpp.In.CropH           = image->height;
  89.     encoder->hwenc.VPPParams.vpp.In.PicStruct       = MFX_PICSTRUCT_PROGRESSIVE;
  90.     encoder->hwenc.VPPParams.vpp.In.FrameRateExtN   = 30;
  91.     encoder->hwenc.VPPParams.vpp.In.FrameRateExtD   = 1;
  92.    
  93.     //Width is aligned as a multiple of 16 
  94.     encoder->hwenc.VPPParams.vpp.In.Width = MSDK_ALIGN16(image->width);
  95.    
  96.     //Same applies for height unless it's a field picture so it is a multiple of 32
  97.     encoder->hwenc.VPPParams.vpp.In.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.VPPParams.vpp.In.PicStruct) ?
  98.         MSDK_ALIGN16(image->width) : MSDK_ALIGN32(image->height);
  99.    
  100.     //Initialization of VPP parameters (output)
  101.     encoder->hwenc.VPPParams.vpp.Out.FourCC         = MFX_FOURCC_NV12;
  102.     encoder->hwenc.VPPParams.vpp.Out.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
  103.     encoder->hwenc.VPPParams.vpp.Out.CropX          = 0;
  104.     encoder->hwenc.VPPParams.vpp.Out.CropY          = 0;
  105.     encoder->hwenc.VPPParams.vpp.Out.CropW          = target_width;
  106.     encoder->hwenc.VPPParams.vpp.Out.CropH          = target_height;
  107.     encoder->hwenc.VPPParams.vpp.Out.PicStruct      = MFX_PICSTRUCT_PROGRESSIVE;
  108.     encoder->hwenc.VPPParams.vpp.Out.FrameRateExtN  = 30;
  109.     encoder->hwenc.VPPParams.vpp.Out.FrameRateExtD  = 1;
  110.  
  111.     //Width is aligned as a multiple of 16 
  112.     encoder->hwenc.VPPParams.vpp.Out.Width = MSDK_ALIGN16(target_width);
  113.    
  114.     //Same applies for height unless it's a field picture so it is a multiple of 32
  115.     encoder->hwenc.VPPParams.vpp.Out.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.VPPParams.vpp.Out.PicStruct) ?
  116.         MSDK_ALIGN16(image->width) : MSDK_ALIGN32(target_height);
  117.    
  118.     encoder->hwenc.VPPParams.AsyncDepth = 1;
  119.     encoder->hwenc.VPPParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY | MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
  120.    
  121.    
  122.     //Disabling VPP enabled by default ops
  123.     mfxExtVPPDoNotUse dnu;
  124.     memset(&dnu,0,sizeof(mfxExtVPPDoNotUse));
  125.     dnu.Header.BufferId = MFX_EXTBUFF_VPP_DONOTUSE;
  126.     dnu.Header.BufferSz = sizeof(mfxExtVPPDoNotUse);
  127.     dnu.NumAlg = 4;
  128.     dnu.AlgList = malloc(sizeof(mfxU32)*dnu.NumAlg);
  129.     MSDK_CHECK_POINTER(dnu.AlgList, MFX_ERR_MEMORY_ALLOC);
  130.     dnu.AlgList[0] = MFX_EXTBUFF_VPP_DENOISE;
  131.     dnu.AlgList[1] = MFX_EXTBUFF_VPP_SCENE_ANALYSIS;
  132.     dnu.AlgList[2] = MFX_EXTBUFF_VPP_DETAIL;
  133.     dnu.AlgList[3] = MFX_EXTBUFF_VPP_PROCAMP;
  134.    
  135.     //Add the extended buffers
  136.     mfxExtBuffer *dnuBuf[1];
  137.     dnuBuf[0] = (mfxExtBuffer*)&dnu;
  138.     encoder->hwenc.VPPParams.ExtParam = dnuBuf;
  139.     encoder->hwenc.VPPParams.NumExtParam = 1;
  140.    
  141.     //Check VPPParams validity. Adjust if necessary.
  142.     encoder->hwenc.sts = MFXVideoVPP_Query(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,&encoder->hwenc.VPPParams);
  143.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
  144.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  145.    
  146.     //Validation of encoder parameters
  147.     //If parameters are not valid the encoder will adjust the parameters as close as possible to the requested configuration
  148.     encoder->hwenc.sts = MFXVideoENCODE_Query(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams,&encoder->hwenc.ENCParams);
  149.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
  150.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  151.    
  152.     //Ask the encoder how many surfaces it needs with this configuration
  153.     mfxFrameAllocRequest ENCsurfReq;
  154.     memset(&ENCsurfReq,0,sizeof(ENCsurfReq));
  155.     encoder->hwenc.sts = MFXVideoENCODE_QueryIOSurf(encoder->hwenc.ENCses, &encoder->hwenc.ENCParams, &ENCsurfReq);
  156.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  157.    
  158.     //Creation of the VPP component and querying for surface buffers
  159.     mfxFrameAllocRequest VPPsurfReq[2];//An array structure where position [0] is for input and [1] is for output
  160.     memset(&VPPsurfReq,0,sizeof(mfxFrameAllocRequest) * 2);
  161.     encoder->hwenc.sts = MFXVideoVPP_QueryIOSurf(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,VPPsurfReq);
  162.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  163.    
  164.     ENCsurfReq.Type |= MFX_MEMTYPE_FROM_VPPOUT; //Shared memory block for VPP out and ENCODER in
  165.        
  166.     encoder->hwenc.nVPPSurfs[0] = VPPsurfReq[0].NumFrameSuggested;
  167.     encoder->hwenc.nVPPSurfs[1] = VPPsurfReq[1].NumFrameSuggested;
  168.     printf("%d surfaces are needed for VPP input.\n",encoder->hwenc.nVPPSurfs[0]);
  169.     encoder->hwenc.nENCSurfs = ENCsurfReq.NumFrameSuggested + encoder->hwenc.nVPPSurfs[1];
  170.     encoder->hwenc.nVPPSurfs[1] = encoder->hwenc.nENCSurfs;
  171.     printf("%d surfaces are needed for ENC input.\n",encoder->hwenc.nENCSurfs);
  172.    
  173.     //Allocate memory to vpp for input surfaces
  174.     //Both width and height must be 32-bit aligned
  175.     mfxU16 width = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Width);
  176.     mfxU16 height = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Height);
  177.     mfxU8  bitsPerPixel = 32;
  178.     mfxU32 surfSize = (width * height * bitsPerPixel)>>3;
  179.    
  180.    
  181.     //Surface VPP pointers housekeeping
  182.     encoder->hwenc.VPPsurfbuffsIN = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nVPPSurfs[0]);
  183.     encoder->hwenc.ptrVPPSurfsIN = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nVPPSurfs[0]);
  184.     MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsIN,MFX_ERR_MEMORY_ALLOC);
  185.     for(int i=0; i<encoder->hwenc.nVPPSurfs[0]; i++)
  186.     {
  187.         encoder->hwenc.ptrVPPSurfsIN[i] = malloc(sizeof(mfxFrameSurface1));
  188.         memset(encoder->hwenc.ptrVPPSurfsIN[i],0,sizeof(mfxFrameSurface1));
  189.         memcpy(&(encoder->hwenc.ptrVPPSurfsIN[i]->Info), &(encoder->hwenc.VPPParams.vpp.In), sizeof(mfxFrameInfo));
  190.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.B = &encoder->hwenc.VPPsurfbuffsIN[surfSize * i];//Assuming Top-Down layout and little-endian
  191.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.G = encoder->hwenc.ptrVPPSurfsIN[i]->Data.B + 1;
  192.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.R = encoder->hwenc.ptrVPPSurfsIN[i]->Data.G + 1;
  193.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.A = encoder->hwenc.ptrVPPSurfsIN[i]->Data.R + 1;
  194.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.Pitch = image->width*bitsPerPixel>>3;
  195.     }  
  196.    
  197.     //Allocate memory to the encoder for required surfaces (surfaces will be shared with VPP output)
  198.     width = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Width);
  199.     height = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Height);
  200.     bitsPerPixel = 12;  // NV12 format is a 12 bits per pixel format
  201.     surfSize = (width * height * bitsPerPixel)>>3;
  202.    
  203.     //Surface VPP & ENCODER pointers housekeeping
  204.     encoder->hwenc.VPPsurfbuffsOUT = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nENCSurfs);
  205.     MSDK_CHECK_POINTER(encoder->hwenc.VPPsurfbuffsOUT, MFX_ERR_MEMORY_ALLOC);
  206.     encoder->hwenc.ENCsurfbuffs = encoder->hwenc.VPPsurfbuffsOUT;
  207.     encoder->hwenc.ptrVPPSurfsOUT = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nENCSurfs);//This is equivalent to mfxFrameSurface1*[encoder->hwenc.nENCSurfs]
  208.     encoder->hwenc.ptrENCSurfs = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nENCSurfs);
  209.     MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsOUT, MFX_ERR_MEMORY_ALLOC);
  210.     for(int i=0; i<encoder->hwenc.nENCSurfs; i++)
  211.     {
  212.         encoder->hwenc.ptrVPPSurfsOUT[i] = malloc(sizeof(mfxFrameSurface1));
  213.         memset(encoder->hwenc.ptrVPPSurfsOUT[i],0,sizeof(mfxFrameSurface1));
  214.         memcpy(&(encoder->hwenc.ptrVPPSurfsOUT[i]->Info), &(encoder->hwenc.VPPParams.vpp.Out), sizeof(mfxFrameInfo));
  215.         encoder->hwenc.ptrVPPSurfsOUT[i]->Data.Y = &encoder->hwenc.VPPsurfbuffsOUT[surfSize * i];
  216.         encoder->hwenc.ptrVPPSurfsOUT[i]->Data.U = encoder->hwenc.ptrVPPSurfsOUT[i]->Data.Y + target_width * target_height;
  217.         encoder->hwenc.ptrVPPSurfsOUT[i]->Data.V = encoder->hwenc.ptrVPPSurfsOUT[i]->Data.U + 1;
  218.         encoder->hwenc.ptrVPPSurfsOUT[i]->Data.Pitch = target_width;
  219.         encoder->hwenc.ptrENCSurfs[i] = malloc(sizeof(mfxFrameSurface1));
  220.         memcpy(&(encoder->hwenc.ptrENCSurfs[i]->Info), &(encoder->hwenc.ENCParams.mfx.FrameInfo), sizeof(mfxFrameInfo));
  221.         memcpy(&(encoder->hwenc.ptrENCSurfs[i]->Data), &(encoder->hwenc.ptrVPPSurfsOUT[i]->Data), sizeof(mfxFrameData));
  222.     }
  223.    
  224.     //Allocate memory to vpp for output surfaces
  225.     //This is a shared resource because this acts as an intermediate buffer between VPP and ENCODE operations
  226.     encoder->hwenc.ENCsurfbuffs = encoder->hwenc.VPPsurfbuffsOUT;
  227.     MSDK_CHECK_POINTER(encoder->hwenc.ptrENCSurfs, MFX_ERR_MEMORY_ALLOC);
  228.     MSDK_CHECK_POINTER(encoder->hwenc.ENCsurfbuffs, MFX_ERR_MEMORY_ALLOC);
  229.  
  230.     //Initialize Intel SDK VPP
  231.     encoder->hwenc.sts = MFXVideoVPP_Init(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams);
  232.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
  233.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  234.    
  235.     //Initialize Intel SDK Encoder
  236.     encoder->hwenc.sts = MFXVideoENCODE_Init(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams);
  237.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
  238.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  239.        
  240.     //Retrieve selected settings by encoder
  241.     mfxVideoParam params;
  242.     memset(&params, 0, sizeof(params));
  243.     encoder->hwenc.sts = MFXVideoENCODE_GetVideoParam(encoder->hwenc.ENCses, &params);
  244.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  245.    
  246.     //Prepare the buffer for the H.264 bitstream
  247.     memset(&encoder->hwenc.bitstr, 0, sizeof(encoder->hwenc.bitstr));
  248.     //Assignment of MaxLength parameter is mandatory.
  249.     encoder->hwenc.bitstr.MaxLength = params.mfx.BufferSizeInKB * 1000;
  250.     encoder->hwenc.bitstr.Data = malloc(sizeof(mfxU8)*encoder->hwenc.bitstr.MaxLength);
  251.     MSDK_CHECK_POINTER(encoder->hwenc.bitstr.Data, MFX_ERR_MEMORY_ALLOC);
  252.    
  253.     encoder->image = image;
  254.     encoder->width = (int)target_width;//Safe casting
  255.     encoder->height = (int)target_height;//Safe casting
  256.     printf("End of initialization.\n");
  257.     return 1;
  258. }
  259.  
  260. int encoder_x264_encode(Encoder_t *encoder) {
  261. #ifdef BENCHMARK
  262. #ifdef _WIN32
  263.     LARGE_INTEGER tStart, tEnd;
  264.     QueryPerformanceFrequency(&tStart);
  265.     double freq = (double)tStart.QuadPart;
  266.     QueryPerformanceCounter(&tStart);
  267. #endif
  268. #endif
  269.    
  270.     int surfVPPindexIN = 0, surfVPPindexOUT = 0, surfENCindex = 0;
  271.     mfxSyncPoint VPPsync,ENCsync;
  272.     encoder->hwenc.nENCFrame = 0;
  273.     encoder->hwenc.sts = MFX_ERR_NONE;
  274.     uint8_t* data;
  275.     uint32_t len;
  276.    
  277.     if(encoder->image->bpp == 32)
  278.         len = 4 * encoder->image->width * encoder->image->height;
  279.     else
  280.         len = 3 * encoder->image->width * encoder->image->height;
  281.    
  282.     if (cb_is_empty(&encoder->image->cb))
  283.         return 0;
  284.     printf("Expecting raw frame with size %d.\n",len);
  285.     data = cb_read_direct(&encoder->image->cb, &len);
  286.     printf("Got a frame %p, size: %d\n", data, len);
  287.  
  288.     //Main VPP & ENNCODING process loop
  289.     while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
  290.     {
  291.         printf("Entering 1st while loop.\n");
  292.         surfVPPindexIN = alloc_surfpool(encoder->hwenc.ptrVPPSurfsIN, encoder->hwenc.nVPPSurfs[0]);
  293.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexIN, MFX_ERR_MEMORY_ALLOC);
  294.         printf("Surface index for VPP in is %d.\n", surfVPPindexIN);
  295.        
  296.         cb_read(&encoder->image->cb, &encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN]->Data.B, &len);
  297.         surfVPPindexOUT = alloc_surfpool(encoder->hwenc.ptrVPPSurfsOUT, encoder->hwenc.nVPPSurfs[1]);
  298.         surfENCindex = surfVPPindexOUT;
  299.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexOUT, MFX_ERR_MEMORY_ALLOC);
  300.         printf("Surface index for VPP out is %d.\n", surfVPPindexOUT);
  301.  
  302.     for(;;)
  303.         {
  304.             printf("Entering VPP for loop.\n");
  305.             encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN], encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
  306.             if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  307.             {
  308.                 printf("Device is busy, retrying...\n");
  309.                 Sleep(1); // Wait if device is busy, then repeat the same call
  310.             }
  311.             else
  312.             {
  313.                 printf("Exiting VPP for loop with status code %d.\n",encoder->hwenc.sts);
  314.                 break;
  315.             }
  316.         }
  317.        
  318.         if (MFX_ERR_MORE_DATA == encoder->hwenc.sts) // More data is needed
  319.         {
  320.             printf("More data is needed for VPP.\n");
  321.             continue;
  322.         }
  323.        
  324.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  325.         MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  326.        
  327.         for(;;)
  328.         {
  329.             printf("Entering ENCODER for loop.\n");
  330.             encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,NULL,encoder->hwenc.ptrENCSurfs[surfENCindex], &encoder->hwenc.bitstr,&ENCsync);
  331.            
  332.             if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync)
  333.             {
  334.                 if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  335.                     Sleep(1); // Wait if device is busy, then repeat the same call          
  336.             }
  337.             else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
  338.             {
  339.                 printf("There are warnings but they are ignored.\n");
  340.                 encoder->hwenc.sts = MFX_ERR_NONE; //Ignore warnings
  341.                 break;
  342.             }
  343.             else if (MFX_ERR_NOT_ENOUGH_BUFFER == encoder->hwenc.sts)
  344.             {
  345.                 printf("Must allocate more memory for output bitstream.\n");
  346.                 //Consider allocating more memory for bitstream output
  347.                 break;
  348.             }
  349.             else
  350.             {              
  351.                 printf("Exiting ENCODER for loop with status code %d.\n",encoder->hwenc.sts);
  352.                 break;
  353.             }
  354.         }
  355.        
  356.         if(MFX_ERR_NONE == encoder->hwenc.sts)
  357.         {
  358.             printf("Waiting for ENCODE operation to sync.\n");
  359.             encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 60000); // Synchronize. Wait until encoded frame is ready
  360.             if(encoder->hwenc.sts == MFX_ERR_NONE) printf("ENCODE operation synchronized successfully\n");
  361.             MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  362.  
  363.             //Must send bitstream now
  364.             ++encoder->hwenc.nENCFrame;
  365.             printf("Sending bitstream.\n");
  366.             encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
  367.             printf("Bitstream exited with status code %d.\n",encoder->hwenc.sts);
  368.             MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  369.         }
  370.        
  371.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  372.         printf("Exiting 1st while loop.\n");
  373.     }
  374.    
  375.     //Draining the VPP buffer
  376.     while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
  377.     {
  378.         printf("Entering 2nd while loop.\n");
  379.         surfENCindex = alloc_surfpool(encoder->hwenc.ptrENCSurfs, encoder->hwenc.nENCSurfs);
  380.         surfVPPindexOUT = surfENCindex;
  381.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfENCindex, MFX_ERR_MEMORY_ALLOC);
  382.        
  383.         for(;;)
  384.         {
  385.             printf("Entering VPP for loop.\n");
  386.             encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, NULL, encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
  387.             if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  388.             {
  389.                 printf("Device is busy, retrying...\n");
  390.                 Sleep(1); // Wait if device is busy, then repeat the same call
  391.             }
  392.             else
  393.             {
  394.                 printf("Exiting VPP for loop.\n");
  395.                 break;
  396.             }
  397.         }
  398.        
  399.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  400.         MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  401.        
  402.         for(;;)
  403.         {
  404.             printf("Entering ENCODER for loop.\n");
  405.             encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,NULL, NULL, &encoder->hwenc.bitstr,&ENCsync);
  406.            
  407.             if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync)
  408.             {
  409.                 if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  410.                     Sleep(1); // Wait if device is busy, then repeat the same call          
  411.             }
  412.             else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
  413.             {
  414.                 encoder->hwenc.sts = MFX_ERR_NONE; //Ignore warnings
  415.                 break;
  416.             }
  417.             else if (MFX_ERR_NOT_ENOUGH_BUFFER == encoder->hwenc.sts)
  418.             {
  419.                 printf("Must allocate more memory for output bitstream.\n");
  420.                 //Consider allocating more memory for bitstream output
  421.                 break;
  422.             }
  423.             else
  424.             {
  425.                 printf("Exiting ENCODER for loop.\n");
  426.                 break;
  427.             }
  428.            
  429.         if(MFX_ERR_NONE == encoder->hwenc.sts)
  430.         {
  431.             encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 50); // Synchronize. Wait until encoded frame is ready
  432.             MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  433.  
  434.             //Must send bitstream now
  435.             ++encoder->hwenc.nENCFrame;
  436.             encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
  437.             MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  438.         }
  439.     }
  440.         printf("Exiting 2nd while loop.\n");
  441.         MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_DATA);
  442.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  443.     }
  444.     //Draining ENCODER buffer
  445.     while(MFX_ERR_NONE <= encoder->hwenc.sts)
  446.     {
  447.         printf("Entering 3rd while loop.\n");
  448.         for(;;)
  449.         {
  450.             encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses, NULL, NULL, &encoder->hwenc.bitstr,&ENCsync);
  451.             if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync)
  452.             {
  453.                 if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  454.                     Sleep(1); // Wait if device is busy, then repeat the same call          
  455.             }
  456.             else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
  457.             {
  458.                 encoder->hwenc.sts = MFX_ERR_NONE; //Ignore warnings
  459.                 break;
  460.             }
  461.             else if (MFX_ERR_NOT_ENOUGH_BUFFER == encoder->hwenc.sts)
  462.             {
  463.                 printf("Must allocate more memory for output bitstream.\n");
  464.                 //Consider allocating more memory for bitstream output
  465.                 break;
  466.             }
  467.             else
  468.             {
  469.                 printf("Exiting ENCODER for loop.\n");
  470.                 break;
  471.             }
  472.         }
  473.        
  474.         if(MFX_ERR_NONE == encoder->hwenc.sts)
  475.         {
  476.             encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 50); // Synchronize. Wait until encoded frame is ready
  477.             MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  478.  
  479.             //Must send bitstream now
  480.             ++encoder->hwenc.nENCFrame;
  481.             encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
  482.             MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  483.         }
  484.     }
  485.    
  486.     MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_SURFACE);
  487.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  488.    
  489. #ifdef BENCHMARK
  490.     QueryPerformanceCounter(&tEnd);
  491.     double duration = ((double)tEnd.QuadPart - (double)tStart.QuadPart)  / freq;
  492.     printf("\nExecution time: %3.2fs (%3.2ffps)\n", duration, ++encoder->hwenc.nENCFrame/duration);
  493. #endif
  494.    
  495.     return 1;
  496. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement