X265源码解析1-Encode方法

本文介绍了X265编码器的`encode`方法,讲解了如何创建和初始化Frame对象,包括分配内存、设置编码起始时间以及拷贝输入YUV数据。还涉及到编码流程中的WaveFront并行处理策略,以及如何进行码率控制和帧的压缩准备工作。

int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)

Frame *inFrame;
        x265_param* p = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
        if (m_dpb->m_freeList.empty())
        {

如果dpb的中没有free状态的Frame,就会去创建。freeList是一个Frame的pool,这样可以节约内存。

     inFrame = new Frame;

Frame主要包括编码完成的数据,重建帧的YUV数据和要编码的YUV数据。
            inFrame->m_encodeStartTime = x265_mdate();

这一帧的开始时间单位是ms。
            if (inFrame->create(p, pic_in->quantOffsets))
            {

主要是创建了要存储编码YUV数据的PicYUV,后续再详细分析

 /* the first PicYuv created is asked to generate the CU and block unit offset
                 * arrays which are then shared with all subsequent PicYuv (orig and recon) 
                 * allocated by this top level encoder */
             
  if (m_sps.cuOffsetY)
                {
                    inFrame->m_fencPic->m_cuOffsetY = m_sps.cuOffsetY;
                    inFrame->m_fencPic->m_buOffsetY = m_sps.buOffsetY;
                    if (m_param->internalCsp != X265_CSP_I400)
                    {
                        inFrame->m_fencPic->m_cuOffsetC = m_sps.cuOffsetC;
                        inFrame->m_fencPic->m_buOffsetC = m_sps.buOffsetC;
                    }
                }

..........................

      }

.......

}

把要编码的YUV数据拷贝到Frame结构体中
        inFrame->m_fencPic->copyFromPicture(*pic_in, *m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset);

/* The synchronization of slicetypeDecide is managed here.  The findJob() method
 * polls the occupancy of the input queue. If the queue is
 * full, it will run slicetypeDecide() and output a mini-gop of frames to the
 * output queue. If the flush() method has been called (implying no new pictures
 * will be received) then the input queue is considered full if it has even one
 * picture left. getDecidedPicture() removes pictures from the output queue and
 * only blocks as a last resort. It does not start removing pictures until
 * m_filled is true, which occurs after *more than* the lookahead depth of
 * pictures have been input so slicetypeDecide() should have started prior to
 * output pictures being withdrawn. The first slicetypeDecide() will obviously
 * still require a blocking wait, but after this slicetypeDecide() will maintain
 * its lead over the encoder (because one picture is added to the input queue
 * each time one is removed from the output) and decides slice types of pictures
 * just ahead of when the encoder needs them */

 m_lookahead->addPicture(*inFrame, sliceType);

Manages the wave-front processing of a single encoding frame
class FrameEncoder : public WaveFront, public Thread。wave-font是一种并行处理的方式。

 FrameEncoder *curEncoder = m_frameEncoder[m_curEncoder];
         m_curEncoder = (m_curEncoder + 1) % m_param->frameNumThreads;
         int ret = 0;

 /* getEncodedPicture() should block until the FrameEncoder has completed
         * encoding the frame.  This is how back-pressure through the API is
         * accomplished when the encoder is full */

        if (!m_bZeroLatency || pass)
            outFrame = curEncoder->getEncodedPicture(m_nalList);

/* pop a single frame from decided list, then provide to frame encoder
         * curEncoder is guaranteed to be idle at this point */

        if (!pass)
            frameEnc = m_lookahead->getDecidedPicture();

创建要编码的数据结构

frameEnc->allocEncodeData(m_reconfigure ? m_latestParam : m_param, m_sps);
                Slice* slice = frameEnc->m_encData->m_slice;
                slice->m_sps = &m_sps;
                slice->m_pps = &m_pps;
                slice->m_param = m_param;

/* determine references, setup RPS, etc */
            m_dpb->prepareEncode(frameEnc);

码率控制

if (m_param->rc.rateControlMode != X265_RC_CQP)
                m_lookahead->getEstimatedPictureCost(frameEnc);
                slice->m_maxNumMergeCand = m_param->maxNumMergeCand;
                slice->m_endCUAddr = slice->realEndAddress(m_sps.numCUs

/* Allow FrameEncoder::compressFrame() to start in the frame encoder thread */开始压缩帧
            if (!curEncoder->startCompressFrame(frameEnc))

 

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值