谁能给这个X265,7.1声道5.1版本声道音箱pcba做个精调

11260人阅读
x265代码注释(73)
注:问号以及未注释部分 会在x265-1.8版本内更新
/*****************************************************************************
* Copyright (C)
* Authors: Steve Borho &steve@borho.org&
* This prog you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software F either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* alo if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02111, USA.
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @ .
*****************************************************************************/
#ifndef X265_ENCODER_H
#define X265_ENCODER_H
#include &common.h&
#include &slice.h&
#include &scalinglist.h&
#include &x265.h&
#include &nal.h&
struct x265_encoder {};
namespace x265 {
// private namespace
extern const char g_sliceTypeToChar[3];
struct EncStats
m_psnrSumY;
m_psnrSumU;
m_psnrSumV;
m_totalQp;
EncStats()
m_psnrSumY = m_psnrSumU = m_psnrSumV = m_globalSsim = 0;
m_accBits = 0;
m_numPics = 0;
m_totalQp = 0;
void addQP(double aveQp);
void addPsnr(double psnrY, double psnrU, double psnrV);
void addBits(uint64_t bits);
void addSsim(double ssim);
class FrameE
class DPB;
class RateC
class ThreadP
class Encoder : public x265_encoder
// 当前已经读入的视频帧数(从0开始计数,初始化为-1)time index (POC)
m_encodedFrameN // 计数当前编码的帧数 (从1开始计数)
m_bframeD//延迟帧数:p-&bframes ? (p-&bBPyramid ? 2 : 1) : 0;
//第一帧,其值等于最先进入的pts号(一般等于0)
m_bframeDelayT//延迟的pts号个数 一般等于2
m_prevReorderedPts[2];//存储前两帧的PTS,用于计算DTS
ThreadPool*
FrameEncoder*
m_frameEncoder[X265_MAX_FRAME_THREADS];//存储frame并行的个数,用于帧级编码的多线程
m_exportedP
m_curE//记录当前是哪个FrmaeEncoder,每完成一个m_curEncoder = (m_curEncoder + 1) % m_param-&frameNumT
/* cached PicYuv offset arrays, shared by all instances of
* PicYuv created by this encoder */
//当前只为指针,其存储空间在某一个frame的m_fencPic中,整个空间在编码器中只申请一次
/*如:一幅图像416x240 总过有7x4个LCU
m_cuOffsetY[0] = 0 m_cuOffsetY[1] = 64 m_cuOffsetY[2]= 128 m_cuOffsetY[7] = 40960 = 640*64 (640是步长含有扩边值)
m_cuOffsetC[0] = 0 m_cuOffsetC[1] = 32 m_cuOffsetC[2]= 64
m_cuOffsetC[7] = 13312 = 416*64 (416是步长含有扩边值)
m_buOffsetY[0] = 0 m_buOffsetY[1] =
4 m_buOffsetY[2]= 2560 (按照4x4块计算 zigzag排序
2560 = 640*4)
m_buOffsetC[0] = 0 m_buOffsetC[1] =
2 m_buOffsetY[2]= 832 (按照2x2块计算 zigzag排序
m_cuOffsetY; //申请空间为一帧LCU个数,按照行列对应亮度LCU的pixel地址
m_cuOffsetC; //申请空间为一帧LCU个数,按照行列对应色度LCU的pixel地址
m_buOffsetY; //申请空间为一个LCU的part个数(默认256个4x4),为当前亮度位置与LCU首地址的偏移地址 (按照zigzag4x4排序)
m_buOffsetC; //申请空间为一个LCU的part个数(默认256个4x4),为当前色度位置与LCU首地址的偏移地址 (按照zigzag2x2排序)
/* Collect statistics globally */
m_analyzeA
m_analyzeI;
m_analyzeP;
m_analyzeB;
m_encodeStartT
// weighted prediction
m_numLumaWPF
// number of P frames with weighted luma reference
m_numChromaWPF
// number of P frames with weighted chroma reference
m_numLumaWPBiF
// number of B frames with weighted luma reference
m_numChromaWPBiF // number of B frames with weighted chroma reference
m_analysisF
m_conformanceM
ScalingList
m_scalingL
// quantization matrix information
m_lastBPSEI;
m_numDelayedP//当前列表中有多少帧未编码 每当读入一帧++,每当编码完毕一帧减--
x265_param*
x265_param*
RateControl*
Lookahead*
//用于帧类型决策以及framecost计算
m_conformanceW
// x265_encoder_encode() returns NALs for the input picture, zero lag
// 用于检错处理,出错(如内存申请失败等)置为true
初始化为false fatal error detected
// reconfigure of encoder detected
Encoder();
~Encoder() {}
void create();
void stopJobs();
void destroy();
int encode(const x265_picture* pic, x265_picture *pic_out);
int reconfigureParam(x265_param* encParam, x265_param* param);
void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs);
void fetchStats(x265_stats* stats, size_t statsSizeBytes);
void writeLog(int argc, char **argv);
void printSummary();
char* statsString(EncStats&, char*);
char* statsCSVString(EncStats& stat, char* buffer);
void configure(x265_param *param);
void updateVbvPlan(RateControl* rc);
void allocAnalysis(x265_analysis_data* analysis);
void freeAnalysis(x265_analysis_data* analysis);
void readAnalysisFile(x265_analysis_data* analysis, int poc);
void writeAnalysisFile(x265_analysis_data* pic);
void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, uint64_t bits);
protected:
void initVPS(VPS *vps);
void initSPS(SPS *sps);
void initPPS(PPS *pps);
#endif // ifndef X265_ENCODER_H
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1562653次
积分:16044
积分:16044
排名:第701名
原创:249篇
转载:143篇
评论:191条
2016年度CSDN博客之星 xiaoc@
(6)(4)(2)(4)(6)(1)(1)(2)(11)(5)(4)(6)(5)(62)(31)(22)(40)(91)(35)(19)(13)(14)(8)11154人阅读
x265代码注释(73)
注:问号以及未注释部分 会在x265-1.8版本内更新
/*****************************************************************************
* Copyright (C)
* Authors: Steve Borho &steve@borho.org&
* This prog you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software F either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* alo if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02111, USA.
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @ .
*****************************************************************************/
#ifndef X265_MOTIONESTIMATE_H
#define X265_MOTIONESTIMATE_H
#include &primitives.h&
#include &reference.h&
#include &mv.h&
#include &bitcost.h&
#include &yuv.h&
namespace x265 {
// private x265 namespace
class MotionEstimate : public BitCost
protected:
intptr_t blockO//搜索块首地址相对于帧首地址的偏移量
int absPartI
// part index of PU, including CU offset within CTU
int searchM //ME搜索算法
int subpelR //subme强度
//当前搜索块的宽度
//在x265框架中暂时没有任何用途
//用于计算块的SAD值 (src, srcStride, dst, dstStride,);
pixelcmp_x3_t sad_x3;//同时计算3个MV对应的3个SAD值template&int lx, int ly& void sad_x3(const pixel* pix1, const pixel* pix2, const pixel* pix3, const pixel* pix4, intptr_t frefstride, int32_t* res)
pixelcmp_x4_t sad_x4;//同时计算4个MV对应的4个SAD值 template&int lx, int ly& oid sad_x4(const pixel* pix1, const pixel* pix2, const pixel* pix3, const pixel* pix4, const pixel* pix5, intptr_t frefstride, int32_t* res)
//计算SATD值,计算过程可以查看satd_4x4函数(fencIntra, cuSize, prediction, cuSize)
pixelcmp_t chromaS
MotionEstimate& operator =(const MotionEstimate&);
static const int COST_MAX = 1 && 28;
Yuv fencPUY
//待搜索块的缓存,大小为64x64,将来搜索块会先copy到此缓存
bool bChromaSATD; // 是否计算chroma分量的satd。只有在subpelRefine大于2时,在分像素ME时才会计算chroma的satd
/** 函数功能
:初始化ME,searchMethod 默认hex,subme 默认2
:null * */
MotionEstimate();
/** 函数功能
:释放内存
:null * */
~MotionEstimate();
static void initScales();
static int hpelIterationCount(int subme);
/** 函数功能
: 初始化搜索算法、创建待搜索块的缓存
method: 搜索方法
refine: subme强度
: null */
void init(int method, int refine, int csp);
/* Methods called at slice setup */
/** 函数功能
: 设置me对应的asm函数,copy待搜索块数据到待搜索块的缓存
fencY: 当前编码帧的帧首地址
stride: 原始帧步长
offset: 当前搜索块首地址相对于帧首地址的偏移量
pwidth: 当前搜索块的宽度
/*\参数 pheight: 当前搜索块的高度
: null */
void setSourcePU(pixel *fencY, intptr_t stride, intptr_t offset, int pwidth, int pheight);
void setSourcePU(const Yuv& srcFencYuv, int ctuAddr, int cuPartIdx, int puPartIdx, int pwidth, int pheight);
/* buf*() and motionEstimate() methods all use cached fenc pixels and thus
* require setSourcePU() to be called prior. */
inline int bufSAD(const pixel* fref, intptr_t stride)
{ return sad(fencPUYuv.m_buf[0], FENC_STRIDE, fref, stride); }
/** 函数功能
: 计算当前块与参考块的SATD值
fref: 参考块首地址
stride: 参考块步长步长
: 当前块与参考块的SATD值 */
inline int bufSATD(const pixel* fref, intptr_t stride) { return satd(fencPUYuv.m_buf[0], FENC_STRIDE, fref, stride); }
inline int bufChromaSATD(const Yuv& refYuv, int puPartIdx)
return chromaSatd(refYuv.getCbAddr(puPartIdx), refYuv.m_csize, fencPUYuv.m_buf[1], fencPUYuv.m_csize) +
chromaSatd(refYuv.getCrAddr(puPartIdx), refYuv.m_csize, fencPUYuv.m_buf[2], fencPUYuv.m_csize);
int motionEstimate(ReferencePlanes* ref, const MV & mvmin, const MV & mvmax, const MV & qmvp, int numCandidates, const MV * mvc, int merange, MV & outQMv);
int subpelCompare(ReferencePlanes* ref, const MV &qmv, pixelcmp_t);
protected:
* 函数功能:星形ME搜索
只在MotionEstimate::motionEstimate函数中被调用
输出的实际搜索范围(左边界和上边界)
输出的实际搜索范围(下边界和右边界)
从AMVP得到的预测MV,并返回最优的MV
预测MV对应的cost,并返回最优的cost
返回最优的MV对应的位置标号,该位置标号在下面ME的搜索模板中标出
返回最优的MV对应的步长
earlyExitIters 提前跳出的迭代次数
输入的ME搜索范围
inline void StarPatternSearch(ReferencePlanes *ref,
const MV &
const MV &
bDistance,
earlyExitIters,
#endif // ifndef X265_MOTIONESTIMATE_H
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1562655次
积分:16044
积分:16044
排名:第701名
原创:249篇
转载:143篇
评论:191条
2016年度CSDN博客之星 xiaoc@
(6)(4)(2)(4)(6)(1)(1)(2)(11)(5)(4)(6)(5)(62)(31)(22)(40)(91)(35)(19)(13)(14)(8)11011人阅读
x265代码注释(73)
注:问号以及未注释部分 会在x265-1.8版本内更新
/*****************************************************************************
* Copyright (C)
* Authors: Steve Borho &steve@borho.org&
* This prog you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software F either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* alo if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02111, USA.
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @
*****************************************************************************/
#ifndef X265_THREADING_H
#define X265_THREADING_H
#include &common.h&
#include &x265.h&
#ifdef _WIN32
#include &windows.h&
#include &winxp.h&
// XP workarounds for CONDITION_VARIABLE and ATOMIC_OR
#include &pthread.h&
#include &semaphore.h&
#include &errno.h&
#include &fcntl.h&
#include &sys/param.h&
#include &sys/sysctl.h&
#ifdef __GNUC__
/* GCCs builtin atomics */
#include &sys/time.h&
#include &unistd.h&
#define CLZ(id, x)
id = (unsigned long)__builtin_clz(x) ^ 31
#define CTZ(id, x)
id = (unsigned long)__builtin_ctz(x)
#define ATOMIC_OR(ptr, mask)
__sync_fetch_and_or(ptr, mask)
#define ATOMIC_AND(ptr, mask) __sync_fetch_and_and(ptr, mask)
#define ATOMIC_INC(ptr)
__sync_add_and_fetch((volatile int32_t*)ptr, 1)
#define ATOMIC_DEC(ptr)
__sync_add_and_fetch((volatile int32_t*)ptr, -1)
#define ATOMIC_ADD(ptr, val)
__sync_fetch_and_add((volatile int32_t*)ptr, val)
#define GIVE_UP_TIME()
#elif defined(_MSC_VER)
/* Windows atomic intrinsics */
#include &intrin.h&
#define CLZ(id, x)
_BitScanReverse(&id, x)
#define CTZ(id, x)
_BitScanForward(&id, x)
#define ATOMIC_INC(ptr)
InterlockedIncrement((volatile LONG*)ptr) //原子锁,自加一
#define ATOMIC_DEC(ptr)
InterlockedDecrement((volatile LONG*)ptr)
#define ATOMIC_ADD(ptr, val)
InterlockedExchangeAdd((volatile LONG*)ptr, val)
#define ATOMIC_OR(ptr, mask)
_InterlockedOr((volatile LONG*)ptr, (LONG)mask)
#define ATOMIC_AND(ptr, mask) _InterlockedAnd((volatile LONG*)ptr, (LONG)mask)
#define GIVE_UP_TIME()
#endif // ifdef __GNUC__
namespace x265 {
// x265 private namespace
#ifdef _WIN32
typedef HANDLE ThreadH
class Lock //用于加锁 被Lookahead、BondedTaskGroup所使用
InitializeCriticalSection(&this-&handle);
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection ):函数功能初始化一个临界资源对象。“临界区”CCriticalSection [1] 是临界资源对象指针。该函数无返回值。单进程的各个线程可以使用临界资源对象来解决同步互斥问题,该对象不能保证哪个线程能够获得到临界资源对象,该系统能公平的对待每一个线程
DeleteCriticalSection(&this-&handle);//删除临界资源变量
void acquire()
EnterCriticalSection(&this-&handle);
函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中  的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性
void release()
LeaveCriticalSection(&this-&handle);//同上
protected:
CRITICAL_SECTION
不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。每个线程中访问临界资源的那段代码称为临界区(Critical Section)。
每个线程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个线程使用的共享资源)。每次只准许一个线程进入临界区,进入后不允许其他线程进入。不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。
多个线程中涉及到同一个临界资源的临界区称为相关临界区。
线程进入临界区的调度原则是: ①如果有若干线程要求进入空闲的临界区,一次仅允许一个线程进入。②任何时候,处于临界区内的线程不可多于一个。如已有线程进入自己的临界区,则其它所有试图进入临界区的线程必须等待。③进入临界区的线程要在有限时间内退出,以便其它线程能及时进入自己的临界区。④如果线程不能进入自己的临界区,则应让出CPU,避免线程出现“忙等”现象。
临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。
class Event //只在FrameEncoder和Lookahead中应用
this-&handle = CreateEvent(NULL, FALSE, FALSE, NULL);
/*CreateEvent是一个Windows API函数。它用来创建或打开一个命名的或无名的事件对象
分别为:安全属性、 复位方式、初始状态、对象名称
安全属性:是NULL,此句柄不能被继承。
复位方式: 指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态。
初始状态:指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。
对象名称:如果lpName为NULL,将创建一个无名的事件对象。
CloseHandle(this-&handle);
/*关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。
若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。
void wait()
WaitForSingleObject(this-&handle, INFINITE);
dwMilliseconds[in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。
bool timedWait(uint32_t milliseconds)
/* returns true if the wait timed out */
return WaitForSingleObject(this-&handle, milliseconds) == WAIT_TIMEOUT; //是否等待超时
void trigger()//触发
SetEvent(this-&handle);//有信号是触发, 因为我们设置的是自动,一旦触发完毕立马变为false
线程中SetEvent及WaitForSingleObject用法
SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号。
WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象。 当你创建一个线程时,其实那个线程是一个循环,不像上面那样只运行一次的。这样就带来了一个问题,在那个死循环里要找到合适的条件退出那个死循环,那么是怎么样实现它的呢,在Windows里往往是采用事件的方式,当然还可以采用其它的方式。在这里先介绍采用事件的方式来通知从线程运行函数退出来,它的实现原理是这样,在那个死循环里不断地使用WaitForSingleObject函数来检查事件是否满足,如果满足就退出线程,不满足就继续运行。当在线程里运行阻塞的函数时,就需要在退出线程时,先要把阻塞状态变成非阻塞状态,比如使用一个线程去接收网络数据,[2] 同时使用阻塞的SOCKET时,那么要先关闭SOCKET,再发送事件信号,才可以退出线程的。
当然我感觉重要应用方面还是用来锁定,实现所谓的pv功能。
在调用的过程中,所有线程都可以在一个等待函数中指定事件对象句柄。当指定的对象的状态被置为有信号状态时,单对象等待函数将返回。
对于多对象等待函数,可以指定为任意或所有指定的对象被置为有信号状态。当等待函数返回时,等待线程将被释放去继续运行。
初始状态在bInitialState参数中进行设置。使用SetEvent函数将事件对象的状态置为有信号状态。使用ResetEvent函数将事件对象的状态置为无信号状态。
当一个手动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至明确调用ResetEvent函数将其置为无符号状态。
当事件的对象被置为有信号状态时,任意数量的等待中线程,以及随后开始等待的线程均会被释放。
当一个自动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至一个等待线程被释放;系统将自动将此函数置为无符号状态。如果没有等待线程正在等待,事件对象的状态将保持有信号状态。
多个进程可持有同一个事件对象的多个句柄,可以通过使用此对象来实现进程间的同步。下面的对象共享机制是可行的:
·在CreateEvent函数中,lpEventAttributes参数指定句柄可被继承时,通过CreateProcess函数创建的子进程继承的事件对象句柄。
·一个进程可以在DuplicateHandle函数中指定事件对象句柄,从而获得一个复制的句柄,此句柄可以被其它进程使用。
·一个进程可以在OpenEvent或CreateEvent函数中指定一个名字,从而获得一个有名的事件对象句柄。
使用CloseHandle函数关闭句柄。当进程停止时,系统将自动关闭句柄。当最后一个句柄被关闭后,事件对象将被销毁。
protected:
HANDLE//句柄
//线程一只是循环,开始设定为无信号,一旦有信号,则立即触发,如果设置为自动,触发完毕立即停止
/* This class is intended for use in signaling state changes safely between CPU
* cores. One thread should be a writer and multiple threads may be readers. The
* mutex's main purpose is to serve as a memory fence to ensure writes made by
* the writer thread are visible prior to readers seeing the m_val change. Its
* secondary purpose is for use with the condition variable for blocking waits */
class ThreadSafeInteger //用于防止多线程破坏的安全计数
/*我们已经看到,当想让写入者线程和读取者线程以独占的方式或共享的方式访问一个资源的时候,可以使用SRWLock。在这些情况下,如果读取者线程没有数据可以读取,那么它应该将锁释放并等待,直到写入者线程产生了新的数据为止。如果用来接收写入者线程产生的数据结构已满,那么写入者同样应该释放SRWLock并进入睡眠状态,直到读取这线程把数据结构清空为止。
我们希望线程以原子的方式把锁释放并将自己阻塞,直到某一个条件成立为止。要实现这样的线程同步是比较复杂的。Windows通过SleepConditionVariableCS(critical section) 或者SleepConditionVariableSRW 函数,提供了一种 条件变量 帮助我们完成这项工作。
当线程检测到相应的条件满足的时候(比如,有数据供读取者使用),它会调用 WakeConditionVariable 或
WakeAllConditionVariable,这样阻塞在Sleep*函数中的线程就会被唤醒。
ThreadSafeInteger()//初始化
m_val = 0;
InitializeCriticalSection(&m_cs);
InitializeConditionVariable(&m_cv);
~ThreadSafeInteger()//释放
DeleteCriticalSection(&m_cs);
XP_CONDITION_VAR_FREE(&m_cv);
int waitForChange(int prev)//获取改变后的值,等到线程已经更新当前数据
参见linux函数pthread_mutex_lock
如果互斥锁类型为 PTHREAD_MUTEX_NORMAL,则不提供死锁检测。尝试重新锁定互斥锁会导致死锁。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或未锁定,则将产生不确定的行为。
如果互斥锁类型为 PTHREAD_MUTEX_ERRORCHECK,则会提供错误检查。如果某个线程尝试重新锁定的互斥锁已经由该线程锁定,则将返回错误。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
如果互斥锁类型为 PTHREAD_MUTEX_RECURSIVE,则该互斥锁会保留锁定计数这一概念。线程首次成功获取互斥锁时,锁定计数会设置为 1。线程每重新锁定该互斥锁一次,锁定计数就增加 1。线程每解除锁定该互斥锁一次,锁定计数就减小 1。 锁定计数达到 0 时,该互斥锁即可供其他线程获取。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
如果互斥锁类型是 PTHREAD_MUTEX_DEFAULT,则尝试以递归方式锁定该互斥锁将产生不确定的行为。对于不是由调用线程锁定的互斥锁,如果尝试解除对它的锁定,则会产生不确定的行为。如果尝试解除锁定尚未锁定的互斥锁,则会产生不确定的行为。
PTHREAD_MUTEX_DEFAULT 描述: 如果尝试以递归方式锁定此类型的互斥锁,则会产生不确定的行为。对于不是由调用线程锁定的此类型互斥锁,如果尝试对它解除锁定,则会产生不确定的行为。对于尚未锁定的此类型互斥锁,如果尝试对它解除锁定,也会产生不确定的行为。允许在实现中将该互斥锁映射到其他互斥锁类型之一。
等待条件有两种方式:条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。
EnterCriticalSection(&m_cs);
if (m_val == prev)
SleepConditionVariableCS(&m_cv, &m_cs, INFINITE);
LeaveCriticalSection(&m_cs);
int get()//获取当前的值
EnterCriticalSection(&m_cs);
int ret = m_
LeaveCriticalSection(&m_cs);
void set(int newval)//设置数据
EnterCriticalSection(&m_cs);
WakeAllConditionVariable(&m_cv);
LeaveCriticalSection(&m_cs);
void poke(void)//唤醒所有阻塞
/* awaken all waiting threads, but make no change */
EnterCriticalSection(&m_cs);
WakeAllConditionVariable(&m_cv);
LeaveCriticalSection(&m_cs);
void incr()//累加1
EnterCriticalSection(&m_cs);
WakeAllConditionVariable(&m_cv);
LeaveCriticalSection(&m_cs);
protected:
CRITICAL_SECTION
m_//互斥量,锁
CONDITION_VARIABLE m_//状态参量
m_//用于计数
#else /* POSIX / pthreads */
typedef pthread_t ThreadH
class Lock
pthread_mutex_init(&this-&handle, NULL);
pthread_mutex_destroy(&this-&handle);
void acquire()
pthread_mutex_lock(&this-&handle);
void release()
pthread_mutex_unlock(&this-&handle);
protected:
pthread_mutex_
class Event
m_counter = 0;
if (pthread_mutex_init(&m_mutex, NULL) ||
pthread_cond_init(&m_cond, NULL))
x265_log(NULL, X265_LOG_ERROR, &fatal: unable to initialize conditional variable\n&);
pthread_cond_destroy(&m_cond);
pthread_mutex_destroy(&m_mutex);
void wait()
pthread_mutex_lock(&m_mutex);
/* blocking wait on conditional variable, mutex is atomically released
* while blocked. When condition is signaled, mutex is re-acquired */
while (!m_counter)
pthread_cond_wait(&m_cond, &m_mutex);
m_counter--;
pthread_mutex_unlock(&m_mutex);
bool timedWait(uint32_t waitms)
bool bTimedOut =
pthread_mutex_lock(&m_mutex);
if (!m_counter)
gettimeofday(&tv, NULL);
/* convert current time from (sec, usec) to (sec, nsec) */
ts.tv_sec = tv.tv_
ts.tv_nsec = tv.tv_usec * 1000;
ts.tv_nsec += 1000 * 1000 * (waitms % 1000);
/* add ms to tv_nsec */
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000); /* overflow tv_nsec */
ts.tv_nsec %= (1000 * 1000 * 1000);
/* clamp tv_nsec */
ts.tv_sec += waitms / 1000;
/* add seconds */
/* blocking wait on conditional variable, mutex is atomically released
* while blocked. When condition is signaled, mutex is re-acquired.
* ts is absolute time to stop waiting */
bTimedOut = pthread_cond_timedwait(&m_cond, &m_mutex, &ts) == ETIMEDOUT;
if (m_counter & 0)
m_counter--;
bTimedOut =
pthread_mutex_unlock(&m_mutex);
return bTimedO
void trigger()
pthread_mutex_lock(&m_mutex);
if (m_counter & UINT_MAX)
m_counter++;
/* Signal a single blocking thread */
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
protected:
pthread_mutex_t m_
pthread_cond_t
/* This class is intended for use in signaling state changes safely between CPU
* cores. One thread should be a writer and multiple threads may be readers. The
* mutex's main purpose is to serve as a memory fence to ensure writes made by
* the writer thread are visible prior to readers seeing the m_val change. Its
* secondary purpose is for use with the condition variable for blocking waits */
class ThreadSafeInteger
ThreadSafeInteger()
m_val = 0;
if (pthread_mutex_init(&m_mutex, NULL) ||
pthread_cond_init(&m_cond, NULL))
x265_log(NULL, X265_LOG_ERROR, &fatal: unable to initialize conditional variable\n&);
~ThreadSafeInteger()
pthread_cond_destroy(&m_cond);
pthread_mutex_destroy(&m_mutex);
int waitForChange(int prev)
pthread_mutex_lock(&m_mutex);
if (m_val == prev)
pthread_cond_wait(&m_cond, &m_mutex);
pthread_mutex_unlock(&m_mutex);
pthread_mutex_lock(&m_mutex);
int ret = m_
pthread_mutex_unlock(&m_mutex);
void set(int newval)
pthread_mutex_lock(&m_mutex);
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
void poke(void)
/* awaken all waiting threads, but make no change */
pthread_mutex_lock(&m_mutex);
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
void incr()
pthread_mutex_lock(&m_mutex);
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
protected:
pthread_mutex_t m_
pthread_cond_t
#endif // ifdef _WIN32
class ScopedLock //用于局部锁
ScopedLock(Lock &instance) : inst(instance)
this-&inst.acquire();
~ScopedLock()
this-&inst.release();
protected:
// do not allow assignments
ScopedLock &operator =(const ScopedLock &);
Lock &//一个引用类型,用于临时变量操作所需要的lock 创建时,acquire,释放时 release
// Utility class which adds elapsed time of the scope of the object into the
// accumulator provided to the constructor
struct ScopedElapsedTime //用于统计时间的锁
ScopedElapsedTime(int64_t& accum) : accumlatedTime(accum) { startTime = x265_mdate(); }
~ScopedElapsedTime() { accumlatedTime += x265_mdate() - startT }
protected:
int64_t& accumlatedT
// do not allow assignments
ScopedElapsedTime &operator =(const ScopedElapsedTime &);
//& Simplistic portable thread class.
Shutdown signalling left to derived class
class Thread //用于多线程 继承它的有:Y4MInput,YUVInput,FrameEncoder,WorkerThread
线程start 一般在encoder.create中可以找到
ThreadH//类型: HANDLE 一个句柄
HANDLE(句柄)是Windows操作系统中的一个概念。在Windows程序中,有各种各样的资源(窗口、图标、光标等),
系统在创建这些资源时会为它们分配内存,并返回标示这些资源的标示号,即句柄。句柄指的是一个核心对象在某一个进程中的唯一索引,
而不是指针。由于地址空间的限制,句柄所标识的内容对进程是不可见的,只能由操作系统通过进程句柄列表来进行维护。
句柄列表:每个进程都要创建一个句柄列表,这些句柄指向各种系统资源,比如信号量,线程,和文件等,进程中的所有线程都可以访问这些资源。
virtual ~Thread();
//& Derived class must implement ThreadMain.
virtual void threadMain() = 0;//其子类定义,虚函数:Y4MInput,YUVInput,FrameEncoder,WorkerThread
//& Returns true if thread was successfully created
bool start();
创建线程,其子类会调用,一般只在encoder中调用
并开始调用对应子类的 threadMain()
内容:thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadShim, this, 0, &threadId);
Windows API函数。该函数在主线程的基础上创建一个新线程。微软在Windows API中提供了建立新的线程的函数CreateThread。
NULL,使用默认安全性,
0,设置初始栈的大小,以字节为单位,如果为0,那么默认将使用与调用该函数的线程相同的栈空间大小。任何情况下,Windows根据需要动态延长堆栈的大小。
(LPTHREAD_START_ROUTINE)ThreadShim: 指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
DWORD WINAPI 函数名 (LPVOID lpParam) ,格式不正确将无法调用成功。/但lpStartAddress要这样通过LPTHREAD_START_ROUTINE转换如: (LPTHREAD_START_ROUTINE)MyVoid
this:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
dwCreationFlags :线程标志,可取值如下0:表示创建后立即激活。
threadId:保存新线程的id。
void stop();//stop,其子类会调用,一般只在encoder中调用
} // end namespace x265
#endif // ifndef X265_THREADING_H
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1562658次
积分:16044
积分:16044
排名:第701名
原创:249篇
转载:143篇
评论:191条
2016年度CSDN博客之星 xiaoc@
(6)(4)(2)(4)(6)(1)(1)(2)(11)(5)(4)(6)(5)(62)(31)(22)(40)(91)(35)(19)(13)(14)(8)

我要回帖

更多关于 5.1版本声道音箱pcba 的文章

 

随机推荐