1. 程式人生 > >協議按位賦值及解析總結

協議按位賦值及解析總結

 

技術在於交流、溝通,轉載請註明出處並保持作品的完整性。

原文:https://blog.csdn.net/hiwubihe/article/details/80736848

 

在協議開發時,經常需要按位賦值,如開發PS流封裝時有一段PTS值賦值如下

 

本篇以此欄位為例子,總結一下賦值及解析的過程,程式碼部分參考VLC程式碼。直接上程式碼


/*******************************************************************************
Copyright (c) wubihe Tech. Co., Ltd. All rights reserved.
--------------------------------------------------------------------------------

Date Created:	2014-10-25
Author:			wubihe QQ:1269122125 Email:
[email protected]
Description: 按位操作,賦值及解析 -------------------------------------------------------------------------------- Modification History DATE AUTHOR DESCRIPTION -------------------------------------------------------------------------------- ********************************************************************************/ /******************************************************************************* MPEG2-PS中有一段是對PES的PTS賦值到位元組流中 |----Type----|--Length(bit)--------------|--Description--------| | '0010' | 4 | 型別 | |PTS[32..30] | 3 |PTS的30-32bit賦值 | |marker_bit | 1 |標記位1 | |PTS[29..15] | 15 | |marker_bit | 1 | |PTS[14..0] | 15 | |marker_bit | 1 | ********************************************************************************/ #include <stdio.h> #include <string.h> #include "bits.h" #define BYTE_ORDER LITTLE_ENDIAN #define BUFFER_SIZE (64) /////這是解析用的結構體 打包資料採用網路位元組序即大端方式組包 接收端如果是大端,則與網路位元組序相同 #pragma pack(1) typedef struct {// ts total 33 bits //接收端如果是小端 則定義與協議中規定相反,因為協議是按照網路位元組序組包的 #if (BYTE_ORDER == LITTLE_ENDIAN) unsigned char fixed2 : 1; // 固定為1 unsigned char ts1 : 3; // bit30-32 unsigned char fixed1 : 4; // DTS為0x01, PTS為0x02, PTS+DTS則PTS為0x03 unsigned char ts2; // bit22-29 unsigned char fixed3 : 1; // 固定為1 unsigned char ts3 : 7; // bit15-21 unsigned char ts4; // bit7-14 unsigned char fixed4 : 1; // 固定為1 unsigned char ts5 : 7; // bit0-6 //大端的情況 直接和協議網路位元組序相同 #elif (BYTE_ORDER == BIG_ENDIAN) unsigned char fixed1 : 4; // DTS為0x01, PTS為0x02, PTS+DTS則PTS為0x03 unsigned char ts1 : 3; // bit30-32 unsigned char fixed2 : 1; // 固定為1 unsigned char ts2; // bit22-29 unsigned char ts3 : 7; // bit15-21 unsigned char fixed3 : 1; // 固定為1 unsigned char ts4; // bit7-14 unsigned char ts5 : 7; // bit0-6 unsigned char fixed4 : 1; // 固定為1 #endif } PES_PTS_S; #pragma pack() //#define FIRST__ int main() { /////////////////////////第一種賦值方式/////////////////////// #ifdef FIRST__ char szBuffer[BUFFER_SIZE]; memset(szBuffer,0,sizeof(szBuffer)); size_t sDataLen = sizeof(PES_PTS_S); long long llPts = 786709; //這種賦值方式 安裝大端賦值 網路位元組序賦值 bits_buffer_t bw; bits_initwrite (&bw, sDataLen, szBuffer); bits_write (&bw, 4, 0x01); bits_write (&bw, 3, (llPts >> 30)&0x07); bits_write (&bw, 1, 1); bits_write (&bw, 15, (llPts >> 15)&0x07FFF); bits_write (&bw, 1, 1); bits_write (&bw, 15, (llPts )&0x07FFF); bits_write (&bw, 1, 1); memcpy(szBuffer, bw.p_data, sDataLen); //取值過程 PES_PTS_S stPts; memcpy(&stPts,szBuffer,sDataLen); long long llPtsValue; llPtsValue = (stPts.ts1 << 30)|(stPts.ts2 << 22) |(stPts.ts3 << 15)|(stPts.ts4 << 7)|(stPts.ts5 ); printf("解析值:%ld\n",llPtsValue); #else /////////////////////////第二種賦值方式/////////////////////// char szBuffer[BUFFER_SIZE]; memset(szBuffer,0,sizeof(szBuffer)); size_t sDataLen = sizeof(PES_PTS_S); long long llPts = 786709; PES_PTS_S sPts; sPts.fixed1 = 0x01; sPts.fixed2 = 0x01; sPts.fixed3 = 0x01; sPts.fixed4 = 0x01; sPts.ts1 = (llPts >> 30)&0x07; sPts.ts2 = (llPts >> 22)&0xFF; sPts.ts3 = (llPts >> 15)&0x7F; sPts.ts4 = (llPts >> 7)&0xFF; sPts.ts5 = (llPts )&0x7F; memcpy(szBuffer,&sPts,sDataLen); //取值過程 PES_PTS_S stPts; memcpy(&stPts,szBuffer,sDataLen); long long llPtsValue; llPtsValue = (stPts.ts1 << 30)|(stPts.ts2 << 22) |(stPts.ts3 << 15)|(stPts.ts4 << 7)|(stPts.ts5 ); printf("解析值:%ld\n",llPtsValue); #endif getchar(); }

 

 

 

 

 

編譯環境:   Win7_64bit+VS2008

DEMO下載地址:https://download.csdn.net/download/hiwubihe/10505021

大小端讀取快取示例

#include "stdint.h"
int avio_r8(unsigned char **p)

{

	return *(*p)++;

}







//讀取小端16

unsigned int avio_rl16(unsigned char **p)

{

	unsigned int val;

	val = avio_r8(p);

	val |= avio_r8(p) << 8;

	return val;

}

//讀取小端16

unsigned int avio_rl24(unsigned char **p)

{

	unsigned int val;

	val = avio_rl16(p);

	val |= avio_r8(p) << 16;

	return val;

}



unsigned int avio_rl32(unsigned char **p)

{

	unsigned int val;

	val = avio_rl16(p);

	val |= avio_rl16(p) << 16;

	return val;

}



uint64_t avio_rl64(unsigned char **p)

{

	uint64_t val;

	val = (uint64_t)avio_rl32(p);

	val |= (uint64_t)avio_rl32(p) << 32;

	return val;

}



unsigned int avio_rb16(unsigned char **p)

{

	unsigned int val;

	val = avio_r8(p) << 8;

	val |= avio_r8(p);

	return val;

}



unsigned int avio_rb24(unsigned char **p)

{

	unsigned int val;

	val = avio_rb16(p) << 8;

	val |= avio_r8(p);

	return val;

}

unsigned int avio_rb32(unsigned char **p)

{

	unsigned int val;

	val = avio_rb16(p) << 16;

	val |= avio_rb16(p);

	return val;

}