C中Union的巧妙用法

来源:本站
导读:目前正在解读《C中Union的巧妙用法》的相关信息,《C中Union的巧妙用法》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《C中Union的巧妙用法》的详细说明。
简介:union巧妙地实现多字节数据类型之间的转化;使不同数据包兼容。

1 union巧妙地实现多字节数据类型之间的转化

在涉及音视频编解码算法中,经常会涉及一些数据压缩、声音解码、图象的缩放等问题。

这里通过一个例子来推荐一种union绝妙用法(这种方法由Equator公司提供,在我们公司的图象处理算法中用得很多)。在该例子中,利用union结构n64u实现占8个字节n64类型与单字节的c0~c7的相互转换,从而达到数据压缩和分解的目的。

#include <stdio.h>

#define IN

#define OUT

#define INOUT

typedefunsigned long longn64;

typedef unsigned int n32;

typedef unsigned shortn16;

typedef unsigned charn8;

typedef struct_s8t{

unsigned charc0, c1, c2, c3, c4, c5, c6, c7;

}s8t;

typedefunion{

n64n64;

struct {

n32 l0, l1;

}u32;

struct {

long l0, l1;

} s32;

struct {

unsigned short s0, s1, s2, s3;

} u16;

struct {

short s0, s1, s2, s3;

} s16;

struct {

unsigned char c0, c1, c2, c3, c4, c5, c6, c7;

}u8;

struct {

char c0, c1, c2, c3, c4, c5, c6, c7;

} s8;

}n64u;

#defineMAX_DATA_COMPRESSED_NUM8

intcompress64_8(IN constn64* src,IN n16 n,OUT n8* dst);

intuncompress8_64(IN const n8* src,IN n16 n,OUT n64* dst);

intcompress64_8(IN const n64* src,IN n16 n,OUT n8* dst)

{

n64u n64u_data;

registern64* n64ptr=(n64*)src;

registern8* n8ptr=dst;

n16 i=0,num=n;

if(NULL==n64ptr || NULL==n8ptr || n<1)

{

printf("invalid param,src 0x%x,dst 0x%x,n %dn",n64ptr,n8ptr,n);

return 0;

}

for(i=0;i<num;i++)

{

n64u_data.n64 = *n64ptr++;

*n8ptr++ = (n64u_data.u8.c0+n64u_data.u8.c1+n64u_data.u8.c2+

n64u_data.u8.c3+n64u_data.u8.c4+n64u_data.u8.c5+

n64u_data.u8.c6+n64u_data.u8.c7)/(sizeof(n64)/sizeof(n8));

}

return 1;

}

int uncompress8_64(IN const n8* src,IN n16 n,OUT n64* dst)

{

n64u n64u_data;

register n64* n64ptr=dst;

register n8* n8ptr=(n8*)src;

register n8n8data;

n16 i=0,num=n;

if(NULL==n64ptr || NULL==n8ptr || n<1)

{

printf("invalid param,src 0x%x,dst 0x%x,n %dn",n64ptr,n8ptr,n);

return 0;

}

for(i=0;i<num;i++)

{

n8data=*n8ptr++;

n64u_data.u8.c0 = n8data;

n64u_data.u8.c1 = n8data;

n64u_data.u8.c2 = n8data;

n64u_data.u8.c3 = n8data;

n64u_data.u8.c4 = n8data;

n64u_data.u8.c5 = n8data;

n64u_data.u8.c6 = n8data;

n64u_data.u8.c7 = n8data;

*n64ptr++ = n64u_data.n64;

}

}

int main(int argc, char *argv[])

{

n64n64data[MAX_DATA_COMPRESSED_NUM];

n8n8data[MAX_DATA_COMPRESSED_NUM];

s8ts8t_data[MAX_DATA_COMPRESSED_NUM]

=

{

{1,2,3,4,5,6,7,8},

{2,2,3,4,5,6,7,7},

{3,2,3,4,5,6,7,6},

{4,2,3,4,5,6,7,5},

{5,2,3,4,5,6,7,4},

{6,2,3,4,5,6,7,3},

{7,2,3,4,5,6,7,2},

{8,7,6,5,4,3,2,1}

};

n16 i,n=MAX_DATA_COMPRESSED_NUM;

printf("data:n");

for(i=0;i<n;i++)

{

n64data[i] = *(n64*)&s8t_data[i];

printf("%3u %3u %3u %3u %3u %3u %3u %3un",

s8t_data[i].c0,s8t_data[i].c1,s8t_data[i].c2,

s8t_data[i].c3,s8t_data[i].c4,s8t_data[i].c5,

s8t_data[i].c6,s8t_data[i].c7);

}

printf("n");

compress64_8(n64data,n,n8data);

printf("compressed to:n");

for(i=0;i<n;i++)

{

printf("%3u ",n8data[i]);

}

printf("nn");

uncompress8_64(n8data,n,n64data);

printf("uncompressed to:n");

for(i=0;i<n;i++)

{

*(n64*)&s8t_data[i] = n64data[i];

printf("%3u %3u %3u %3u %3u %3u %3u %3un",

s8t_data[i].c0,s8t_data[i].c1,s8t_data[i].c2,

s8t_data[i].c3,s8t_data[i].c4,s8t_data[i].c5,

s8t_data[i].c6,s8t_data[i].c7);

}

printf("n");

}

2.使不同数据包兼容

union的用法如下:

struct _my_struct

{

unsigned int struct_id

typedef union _my_union

{

struct my_struct_1;

struct my_struct_2;

struct my_struct_3;

}my_union;

}my_struct;

我们公司在处理音频视频数据流方面,为了区分音频和视频数据以及来自网络和编解码的数据并减少内存占用使用了下面的数据结构。这种union使用方法在网络应用中特别常见。在数据结构TFrameBufferInfo中,用bufferType标识数据来源。

typedef struct

{

intcodecId;

intpacketNum;

intactualNum;

intpacketLen;

intleftPacketLen;

intframeSample;

inttimeStamp;

intdataLen;

intready;

unsigned char*buffer;

intreserve1;

} TABufferInfoFromCodec;

typedef struct

{

intcodecId;

intbKeyFrame;

intpacketNum;

intactualNum;

intpacketLen;

intleftPacketLen;

inttimeStamp;

intdataLen;

intready;

unsigned char*buffer;

intreserve1;

} TVBufferInfoFromCodec;

typedef struct

{

intcodecId;

intbKeyFrame;

intpacketNum;

intactualNum;

intpacketLen;

intleftPacketLen;

intrtpLen;

inttimeStamp;

intfirstSquence;

intdataLen;

intready;

unsigned char*buffer;

} TVBufferInfoToCodec;

typedef struct

{

intcodecId;

intpacketNum;

intactualNum;

intpacketLen;

intleftPacketLen;

intrtpLen;

inttimeStamp;

intfirstSquence;

intdataLen;

intready;

unsigned char*buffer;

intreserve1;

} TABufferInfoToCodec;

typedef struct

{

intbufferType;

union

{

TVBufferInfoFromCodecbufferInfoFromVCoder;

TABufferInfoFromCodecbufferInfoFromACoder;

TVBufferInfoToCodecbufferInfoFromVNetWork;

TABufferInfoToCodecbufferInfoFromANetWork;

} buffer_info;

} TFrameBufferInfo;

int send_to(void* stream);

intsend_to(void* stream)

{

}

int main(int argc, char *argv[])

{

TFrameBufferInfo tFrameBufferInfo;

TVBufferInfoFromCodec* pVBufferInfoFromCodec;

unsigned char buffer[1200*5];

tFrameBufferInfo.bufferType=4;

pVBufferInfoFromCodec

=&tFrameBufferInfo.buffer_info.bufferInfoFromVCoder;

pVBufferInfoFromCodec->bKeyFrame= 1;

pVBufferInfoFromCodec->packetNum= 2;

pVBufferInfoFromCodec->actualNum= 2;

pVBufferInfoFromCodec->leftPacketLen= 123;

pVBufferInfoFromCodec->dataLen= 1323;

pVBufferInfoFromCodec->ready= 1;

pVBufferInfoFromCodec->buffer= buffer;

send_to((void*)&tFrameBufferInfo);

}

提醒:《C中Union的巧妙用法》最后刷新时间 2024-03-14 00:58:28,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《C中Union的巧妙用法》该内容的真实性请自行鉴别。