Skip to content

Latest commit

 

History

History
168 lines (142 loc) · 5.94 KB

File metadata and controls

168 lines (142 loc) · 5.94 KB

Menu:

1. Introduction

The QC VideoDecoder node provides APIs for video decoding. It calls vidc library to process video frames based on video hardware. This node supports QNX and HGY Linux/Ubuntu platforms.

2. Video Decoder Configuration

2.1 Video Decoder Node Configuration

Parameter Required Type Default Description
name true string The Node unique name.
id true uint32_t The Node unique ID.
width true uint32_t Video frame width.
height true uint32_t Video frame height.
frameRate true uint32_t Frames per second.
format false string h265 The image format, options from [nv12, nv12_ubwc]
output_format false string nv12 The output image format, options from [h264, h265]
bInputDynamicMode false bool true Input frame dynamic mode
bOutputDynamicMode false bool false Output frame dynamic mode
numInputBufferReq false uint32_t 4 Number of input buffers
numOutputBufferReq false uint32_t 4 Number of output buffers
  • Example Configurations
{
    "static": {
        "name": "VDEC0",
        "id": 0,
        "width": 1920,
        "height": 1024,
        "frameRate": 30,
        "format": "h265",
        "output_format": "nv12",
        "bInputDynamicMode": true,
        "bOutputDynamicMode": false,
        "numOutputBufferReq": 4,
        "numInputBufferReq": 4,
    }
}

3. QC VideoDecoder Data Structures

3.1 The details of VideoFrameDescriptor_t

VideoFrameDescriptor_t contains all the parameters of input and output video frame:

  • ImageDescriptor: Image buffer of input video frame
  • timestampNs: Timestamp in nanoseconds of frame data
  • appMarkData: Mark data of frame data
  • frameType: Indication of I/P/B/IDR frame, used by encoder
  • frameFlag: Indication of whether some error occurred during decoding this frame

4. QC VideoDecoder APIs

5. Typical Use Case

5.1 Typical use case of dynamic mode

  • Step 1: Configure parameters
QCStatus_e ret;
char pName[20] = "VidcDecoder";
uint32_t bufferNum = 4;
uint32_t frameNum = 10;

VideoDecoder vidcDecoder;
VideoDecoder_Config_t vidcDecoderConfig;
vidcDecoderConfig.bInputDynamicMode = true;
vidcDecoderConfig.bOutputDynamicMode = true;
vidcDecoderConfig.numInputBuffer = bufferNum;
vidcDecoderConfig.numOutputBuffer = bufferNum;

ImageProps_t inputImgProps;
inputImgProps.batchSize = 1;
inputImgProps.width = 1920;
inputImgProps.height = 1024;
inputImgProps.numPlanes = 1;
inputImgProps.planeBufSize[0] = 2961408;
inputImgProps.format = QC_IMAGE_FORMAT_COMPRESSED_H265;

vidcDecoderConfig.width = 1920;
vidcDecoderConfig.height = 1024;
vidcDecoderConfig.inFormat = QC_IMAGE_FORMAT_COMPRESSED_H265;
vidcDecoderConfig.outFormat = QC_IMAGE_FORMAT_NV12;
vidcDecoderConfig.frameRate = 30;
vidcDecoderConfig.pInputBufferList = nullptr;
vidcDecoderConfig.pOutputBufferList = nullptr;

// Define callback:
void OnDoneCb( conVideoCodec_EventType_e eventId, const void *pEvent, void *pPrivData ) {}
  • Step 2: Allocate buffers
    ret = m_imagePool.Init( name, m_nodeId, LOGGER_LEVEL_INFO, m_numOutputBufferReq, m_width,
                            m_height, m_outFormat, QC_MEMORY_ALLOCATOR_DMA_GPU );

    if ( QC_STATUS_OK == ret )
    {
        ret = m_imagePool.GetBuffers( m_nodeCfg.buffers );
    }
  • Step 3: Init and Register callback
using std::placeholders::_1;
m_nodeCfg.config = m_dataTree.Dump();
m_nodeCfg.callback = std::bind( &SampleVideoDecoder::OnDoneCb, this, _1 );

ret = m_decoder.Initialize( m_nodeCfg );
  • Step 4: Submit input/output frame
for ( uint32_t i = 0; i < bufferNum; i++ )
{
    inputs[bufferIdx].timestampNs = frameInfo.startTime;
    inputs[bufferIdx].appMarkData = i;

    ret = inFrameDesc.SetBuffer( QC_NODE_VIDEO_DECODER_INPUT_BUFF_ID, inputs[bufferIdx] );
    ASSERT_EQ( QC_STATUS_OK, ret );
    //  Process the frame
    ret = pNodeVide->ProcessFrameDescriptor( inFrameDesc );
    ASSERT_EQ( QC_STATUS_OK, ret );

    std::unique_lock<std::mutex> outLock( g_OutMutex );
    g_OutCondVar.wait( outLock );

    //  Set up an output buffer for the frame
    ret = outFrameDesc.SetBuffer( QC_NODE_VIDEO_DECODER_OUTPUT_BUFF_ID, outputs[bufferIdx] );
    ASSERT_EQ( QC_STATUS_OK, ret );
    //  Process the frame
    ret = pNodeVide->ProcessFrameDescriptor( outFrameDesc );
    ASSERT_EQ( QC_STATUS_OK, ret );
}
  • Step 5: Stop and deinitialize the pipeline
ret = vidcDecoder.Stop();
ret = vidcDecoder.Deinit();

for ( auto &output : outputs )
{
    ret = bufMgr.Free( output );
    ASSERT_EQ( QC_STATUS_OK, ret );
}

for ( auto &input : inputs )
{
    ret = bufMgr.Free( input );
    ASSERT_EQ( QC_STATUS_OK, ret );
}