Advertisement
Guest User

QSV

a guest
Jan 21st, 2014
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.91 KB | None | 0 0
  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(image->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(image->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.     //Disabling VPP enabled by default ops
  122.     mfxExtVPPDoNotUse dnu;
  123.     memset(&dnu,0,sizeof(mfxExtVPPDoNotUse));
  124.     dnu.Header.BufferId = MFX_EXTBUFF_VPP_DONOTUSE;
  125.     dnu.Header.BufferSz = sizeof(mfxExtVPPDoNotUse);
  126.     dnu.NumAlg = 4;
  127.     dnu.AlgList = malloc(sizeof(mfxU32)*dnu.NumAlg);
  128.     MSDK_CHECK_POINTER(dnu.AlgList, MFX_ERR_MEMORY_ALLOC);
  129.     dnu.AlgList[0] = MFX_EXTBUFF_VPP_DENOISE;
  130.     dnu.AlgList[1] = MFX_EXTBUFF_VPP_SCENE_ANALYSIS;
  131.     dnu.AlgList[2] = MFX_EXTBUFF_VPP_DETAIL;
  132.     dnu.AlgList[3] = MFX_EXTBUFF_VPP_PROCAMP;
  133.    
  134.     //Add the extended buffers
  135.     mfxExtBuffer *dnuBuf[1];
  136.     dnuBuf[0] = (mfxExtBuffer*)&dnu;
  137.     encoder->hwenc.VPPParams.ExtParam = dnuBuf;
  138.     encoder->hwenc.VPPParams.NumExtParam = 1;
  139.    
  140.     //Check VPPParams validity. Adjust if necessary.
  141.     encoder->hwenc.sts = MFXVideoVPP_Query(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,&encoder->hwenc.VPPParams);
  142.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
  143.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  144.    
  145.     //Validation of encoder parameters
  146.     //If parameters are not valid the encoder will adjust the parameters as close as possible to the requested configuration
  147.     encoder->hwenc.sts = MFXVideoENCODE_Query(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams,&encoder->hwenc.ENCParams);
  148.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
  149.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  150.    
  151.     //Ask the encoder how many surfaces it needs with this configuration
  152.     mfxFrameAllocRequest ENCsurfReq;
  153.     memset(&ENCsurfReq,0,sizeof(ENCsurfReq));
  154.     encoder->hwenc.sts = MFXVideoENCODE_QueryIOSurf(encoder->hwenc.ENCses, &encoder->hwenc.ENCParams, &ENCsurfReq);
  155.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  156.    
  157.     encoder->hwenc.nENCSurfs = ENCsurfReq.NumFrameSuggested;
  158.    
  159.     printf("%d surfaces are needed for ENC input.\n",encoder->hwenc.nENCSurfs);
  160.     //Allocate memory to the encoder for required surfaces (surfaces will be shared with VPP output)
  161.     mfxU16 width = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Width);
  162.     mfxU16 height = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Height);
  163.     mfxU8  bitsPerPixel = 12;  // NV12 format is a 12 bits per pixel format
  164.     mfxU32 surfSize = (width * height * bitsPerPixel)>>3;
  165.    
  166.     //Surface ENCODER pointers housekeeping
  167.     encoder->hwenc.ENCsurfbuffs = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nENCSurfs);
  168.    
  169.     encoder->hwenc.ptrENCSurfs = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nENCSurfs);//This is equivalent to mfxFrameSurface1*[encoder->hwenc.nENCSurfs]
  170.     MSDK_CHECK_POINTER(encoder->hwenc.ptrENCSurfs, MFX_ERR_MEMORY_ALLOC);
  171.     for(int i=0; i<encoder->hwenc.nENCSurfs; i++)
  172.     {
  173.         encoder->hwenc.ptrENCSurfs[i] = malloc(sizeof(mfxFrameSurface1));
  174.         memset(encoder->hwenc.ptrENCSurfs[i],0,sizeof(mfxFrameSurface1));
  175.         memcpy(&(encoder->hwenc.ptrENCSurfs[i]->Info), &(encoder->hwenc.ENCParams.mfx.FrameInfo), sizeof(mfxFrameInfo));
  176.         encoder->hwenc.ptrENCSurfs[i]->Data.Y = &encoder->hwenc.ENCsurfbuffs[surfSize * i];
  177.         encoder->hwenc.ptrENCSurfs[i]->Data.U = encoder->hwenc.ptrENCSurfs[i]->Data.Y + target_width * target_height;
  178.         encoder->hwenc.ptrENCSurfs[i]->Data.V = encoder->hwenc.ptrENCSurfs[i]->Data.U + 1;
  179.         encoder->hwenc.ptrENCSurfs[i]->Data.Pitch = target_width;
  180.     }
  181.    
  182.     //Creation of the VPP component and querying for surface buffers
  183.     mfxFrameAllocRequest VPPsurfReq[2];//An array structure where position [0] is for input and [1] is for output
  184.     memset(&VPPsurfReq,0,sizeof(mfxFrameAllocRequest) * 2);
  185.     encoder->hwenc.sts = MFXVideoVPP_QueryIOSurf(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,VPPsurfReq);
  186.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  187.    
  188.     encoder->hwenc.nVPPSurfs[0] = VPPsurfReq[0].NumFrameSuggested;
  189.     encoder->hwenc.nVPPSurfs[1] = VPPsurfReq[1].NumFrameSuggested;
  190.     printf("%d surfaces are needed for VPP input.\n",encoder->hwenc.nVPPSurfs[0]);
  191.     printf("%d surfaces are needed for VPP output.\n",encoder->hwenc.nVPPSurfs[1]);
  192.     //Allocate memory to vpp for input surfaces
  193.     //Both width and height must be 32-bit aligned
  194.     width = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Width);
  195.     height = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Height);
  196.     bitsPerPixel = 32;
  197.     surfSize = (width * height * bitsPerPixel)>>3;
  198.    
  199.    
  200.     //Surface VPP pointers housekeeping
  201.     encoder->hwenc.VPPsurfbuffsIN = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nVPPSurfs[0]);
  202.     encoder->hwenc.ptrVPPSurfsIN = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nVPPSurfs[0]);
  203.     MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsIN,MFX_ERR_MEMORY_ALLOC);
  204.     for(int i=0; i<encoder->hwenc.nVPPSurfs[0]; i++)
  205.     {
  206.         encoder->hwenc.ptrVPPSurfsIN[i] = malloc(sizeof(mfxFrameSurface1));
  207.         memset(encoder->hwenc.ptrVPPSurfsIN[i],0,sizeof(mfxFrameSurface1));
  208.         memcpy(&(encoder->hwenc.ptrVPPSurfsIN[i]->Info), &(encoder->hwenc.VPPParams.vpp.In), sizeof(mfxFrameInfo));
  209.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.B = &encoder->hwenc.VPPsurfbuffsIN[surfSize * i];//Assuming Top-Down layout and little-endian
  210.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.G = encoder->hwenc.ptrVPPSurfsIN[i]->Data.B + 1;
  211.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.R = encoder->hwenc.ptrVPPSurfsIN[i]->Data.G + 1;
  212.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.A = encoder->hwenc.ptrVPPSurfsIN[i]->Data.R + 1;
  213.         encoder->hwenc.ptrVPPSurfsIN[i]->Data.Pitch = image->width*bitsPerPixel>>3;
  214.     }
  215.    
  216.     //Allocate memory to vpp for output surfaces
  217.     //This is a shared resource because this acts as an intermediate buffer between VPP and ENCODE operations
  218.     encoder->hwenc.VPPsurfbuffsOUT = encoder->hwenc.ENCsurfbuffs;
  219.     encoder->hwenc.ptrVPPSurfsOUT = encoder->hwenc.ptrENCSurfs;
  220.     MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsOUT, MFX_ERR_MEMORY_ALLOC);
  221.    
  222.     //Initialize Intel SDK Encoder
  223.     encoder->hwenc.sts = MFXVideoENCODE_Init(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams);
  224.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
  225.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  226.        
  227.     //Retrieve selected settings by encoder
  228.     mfxVideoParam params;
  229.     memset(&params, 0, sizeof(params));
  230.     encoder->hwenc.sts = MFXVideoENCODE_GetVideoParam(encoder->hwenc.ENCses, &params);
  231.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  232.    
  233.     //Prepare the buffer for the H.264 bitstream
  234.     memset(&encoder->hwenc.bitstr, 0, sizeof(encoder->hwenc.bitstr));
  235.     //Assignment of MaxLength parameter is mandatory.
  236.     encoder->hwenc.bitstr.MaxLength = params.mfx.BufferSizeInKB * 1000;
  237.     encoder->hwenc.bitstr.Data = malloc(sizeof(mfxU8)*encoder->hwenc.bitstr.MaxLength);
  238.     MSDK_CHECK_POINTER(encoder->hwenc.bitstr.Data, MFX_ERR_MEMORY_ALLOC);
  239.    
  240.     //Initialize Intel SDK VPP
  241.     encoder->hwenc.sts = MFXVideoVPP_Init(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams);
  242.     //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
  243.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  244.  
  245.     encoder->image = image;
  246.     encoder->width = (int)target_width;//Safe casting
  247.     encoder->height = (int)target_height;//Safe casting
  248.  
  249.     printf("End of initialization.\n");
  250.     return 1;
  251. }
  252.  
  253. int encoder_x264_encode(Encoder_t *encoder) {
  254. #ifdef BENCHMARK.
  255. #ifdef _WIN32
  256.     LARGE_INTEGER tStart, tEnd;
  257.     QueryPerformanceFrequency(&tStart);
  258.     double freq = (double)tStart.QuadPart;
  259.     QueryPerformanceCounter(&tStart);
  260. #endif
  261. #endif
  262.    
  263.     int surfVPPindexIN = 0, surfVPPindexOUT = 0, surfENCindex = 0;
  264.     mfxSyncPoint VPPsync,ENCsync;
  265.     encoder->hwenc.nENCFrame = 0;
  266.     uint8_t* data;
  267.     uint32_t len;
  268.    
  269.     if(encoder->image->bpp == 32)
  270.         len = 4 * encoder->image->width * encoder->image->height;
  271.     else
  272.         len = 3 * encoder->image->width * encoder->image->height;
  273.    
  274.     if (cb_is_empty(&encoder->image->cb))
  275.         return 0;
  276.     printf("Expecting raw frame with size %d.\n",len);
  277.     data = cb_read_direct(&encoder->image->cb, &len);//Or if this doesn't work assign directly to pool
  278.     printf("Got a frame %p, size: %d\n", data, len);
  279.     //Main VPPprocess loop
  280.     while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
  281.     {
  282.         printf("Entering VPP while loop.\n");
  283.         surfVPPindexIN = alloc_surfpool(encoder->hwenc.ptrVPPSurfsIN, encoder->hwenc.nVPPSurfs[0]);
  284.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexIN, MFX_ERR_MEMORY_ALLOC);
  285.        
  286.         //encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN]->Data.A = (mfxU8*)data;//maybe memcpy is needed here
  287.         cb_read(&encoder->image->cb, &encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN]->Data.B, &len);
  288.         surfVPPindexOUT = alloc_surfpool(encoder->hwenc.ptrVPPSurfsOUT, encoder->hwenc.nVPPSurfs[1]);
  289.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexOUT, MFX_ERR_MEMORY_ALLOC);
  290.        
  291.         for(;;)
  292.         {
  293.             printf("Entering VPP for loop.\n");
  294.             encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN], encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
  295.             if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  296.             {
  297.                 printf("Device is busy, retrying...\n");
  298.                 Sleep(1); // Wait if device is busy, then repeat the same call
  299.             }
  300.             else
  301.             {
  302.                 printf("Exiting VPP for loop.\n");
  303.                 break;
  304.             }
  305.         }
  306.        
  307.         if (MFX_ERR_MORE_DATA == encoder->hwenc.sts) // More data is needed
  308.         {
  309.             printf("More data is needed for VPP.\n");
  310.             continue;
  311.         }
  312.        
  313.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  314.         MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  315.        
  316.         encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.VPPses, VPPsync, 10);
  317.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  318.         printf("Exiting VPP while loop.\n");
  319.     }
  320.    
  321.     //Main ENCODERprocess loop
  322.     while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
  323.     {
  324.     printf("Entering ENCODER while loop.\n");
  325.         surfENCindex = alloc_surfpool(encoder->hwenc.ptrENCSurfs, encoder->hwenc.nENCSurfs);
  326.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfENCindex, MFX_ERR_MEMORY_ALLOC);
  327.        
  328.         //if(surfVPPindexOUT != surfENCindex)
  329.             //surfENCindex = surfVPPindexOUT;//Sync of indices
  330.         //Not need to load anything since data appeared to the encoder's input from the VPP's output.
  331.        
  332.         for(;;)
  333.         {
  334.             printf("Entering ENCODER for loop.\n");
  335.             encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,encoder->hwenc.ptrENCSurfs[surfENCindex], &encoder->hwenc.bitstr,NULL,&ENCsync);
  336.            
  337.             if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync)
  338.             {
  339.                 if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
  340.                     Sleep(1); // Wait if device is busy, then repeat the same call          
  341.             }
  342.             else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
  343.             {
  344.                 encoder->hwenc.sts = MFX_ERR_NONE; //Ignore warnings
  345.                 break;
  346.             }
  347.             else if (MFX_ERR_NOT_ENOUGH_BUFFER == encoder->hwenc.sts)
  348.             {
  349.                 printf("Must allocate more memory for output bitstream.\n");
  350.                 //Consider allocating more memory for bitstream output
  351.                 break;
  352.             }
  353.             else
  354.             {
  355.                 printf("Exiting ENCODER for loop.\n");
  356.                 break;
  357.             }
  358.         }
  359.        
  360.         if(MFX_ERR_NONE == encoder->hwenc.sts)
  361.         {
  362.             encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 10); // Synchronize. Wait until encoded frame is ready
  363.             MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  364.  
  365.             //Must send bitstream now
  366.             ++encoder->hwenc.nENCFrame;
  367.             encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
  368.             MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  369.         }
  370.     }
  371.     printf("Exiting ENCODER while loop.\n");
  372.     MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_DATA);
  373.     MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  374.    
  375.     //Draining VPP buffers
  376.     while(MFX_ERR_NONE <= encoder->hwenc.sts)
  377.     {
  378.         surfVPPindexOUT = alloc_surfpool(encoder->hwenc.ptrVPPSurfsOUT, encoder->hwenc.nVPPSurfs[1]);
  379.         MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexOUT, MFX_ERR_MEMORY_ALLOC);
  380.        
  381.         for(;;)
  382.         {
  383.             encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, NULL, encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
  384.             if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)                
  385.                 Sleep(1); // Wait if device is busy, then repeat the same call          
  386.             else
  387.                 break;
  388.         }
  389.        
  390.         MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_SURFACE);
  391.         MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  392.        
  393.         encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.VPPses, VPPsync, 10);
  394.         MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  395.     }
  396.    
  397.     //Draining ENCODER buffers
  398.    
  399.     while (MFX_ERR_NONE <= encoder->hwenc.sts)
  400.     {      
  401.         for (;;)
  402.         {                
  403.             // Encode a frame asychronously (returns immediately)
  404.             encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,NULL, &encoder->hwenc.bitstr,NULL,&ENCsync);
  405.  
  406.             if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync) // Repeat the call if warning and no output
  407.             {
  408.                 if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)                
  409.                     Sleep(1); // Wait if device is busy, then repeat the same call                
  410.             }
  411.             else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)                
  412.             {
  413.                 encoder->hwenc.sts = MFX_ERR_NONE; // Ignore warnings if output is available                                    
  414.                 break;
  415.             }
  416.             else
  417.                 break;
  418.         }            
  419.  
  420.         if(MFX_ERR_NONE == encoder->hwenc.sts)
  421.         {
  422.             encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 10); // Synchronize. Wait until encoded frame is ready
  423.             MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
  424.            
  425.             ++encoder->hwenc.nENCFrame;
  426.             encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
  427.             MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
  428.         }
  429.     }            
  430.    
  431. #ifdef BENCHMARK
  432.     QueryPerformanceCounter(&tEnd);
  433.     double duration = ((double)tEnd.QuadPart - (double)tStart.QuadPart)  / freq;
  434.     printf("\nExecution time: %3.2fs (%3.2ffps)\n", duration, ++encoder->hwenc.nENCFrame/duration);
  435. #endif
  436.    
  437.     return 1;
  438. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement