協議按位賦值及解析總結
阿新 • • 發佈:2018-11-11
技術在於交流、溝通,轉載請註明出處並保持作品的完整性。
原文: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; }