- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
两天以来,我一直被一个看似简单的计算所困扰。但我就是不明白。
我正在使用压缩算法对音频文件进行编码。
整个音频文件被分成 960 字节的“ block ”。每个 block 被压缩为 60 字节。
我的未压缩文件长 1480320 字节。我的编码文件长 46320 字节。
似乎有些不对劲。我试图根据编码音频的文件大小计算理论上的未压缩文件大小。
文件的编码方式如下:
short *m_in;
short *m_out;
unsigned char *m_data;
unsigned char *m_fbytes;
int m_max_frame_size;
int m_frame_size;
int m_sampling_rate;
int m_max_payload_bytes;
int m_bitrate_bps;
int m_iByteLen1FrameEncoded;
int m_iByteLen1FrameDecoded;
m_sampling_rate=48000;
m_max_frame_size = 960*6;
m_max_payload_bytes=1500;
m_bitrate_bps= 24000;
m_iByteLen1FrameEncoded=60;
m_iByteLen1FrameDecoded=960;
m_in = (short*)malloc(m_max_frame_size*sizeof(short));
m_out = (short*)malloc(m_max_frame_size*sizeof(short));
m_data = (unsigned char*)calloc(m_max_payload_bytes,sizeof(char));
m_fbytes = (unsigned char*)malloc(m_iByteLen1FrameDecoded*sizeof(short));
FILE *fin= fopen(uPathInput.c_str(), "rb");
FILE *fout=fopen(uPathOutput.c_str(), "wb");
int curr_read=0;
int stop=0;
while (!stop)
{
int err;
err = fread(m_fbytes, sizeof(short), 960, fin);
curr_read = err;
for(int i=0;i<curr_read;i++)
{
opus_int32 s;
s=m_fbytes[2*i+1]<<8|m_fbytes[2*i];
s=((s&0xFFFF)^0x8000)-0x8000;
m_in[i]=s;
}
if (curr_read < 960)
{
for (int i=curr_read;i<960;i++)
{
m_in[i] = 0;
}
stop = 1;
}
//iLen will always return 60, so I guess the 960 bytes are compressed to 60 bytes, right?
int iLen = opus_encode(m_enc, m_in, m_iByteLen1FrameDecoded, m_data, m_max_payload_bytes);
if (fwrite(m_data, 1, iLen, fout) !=iLen)
{
fprintf(stderr, "Error writing.\n");
}
}
fclose(fin);
fclose(fout);
}
压缩率好像是960/60 = 16
所以我计算了46320字节*16。但这让我达到了 741120 字节。那不合适。我预计它是 1480320 字节。
我试图找出我计算中的错误,但我就是找不到。
有人看到我哪里错了吗?
非常感谢您的帮助!
最佳答案
好的,扩展我的评论。问题出在这里:
fread(m_fbytes, sizeof(short), 960, fin);
您正在读取 960 个 short
,这应该是 2 个字节宽,所以您实际上正在读取 1920
个字节。如果 opus_encode()
以字节为单位返回压缩后的大小,那么正如 Robert 观察到的那样,压缩率将达到 32
。
我还会简化处理 block 的代码:
size_t ITEM_SIZE = sizeof(short);
int ITEM_COUNT = 960;
// fread should first return a short item count, then zero
size_t shorts_read = 0;
while (shorts_read = fread(m_fbytes, ITEM_SIZE, ITEM_COUNT, fin)) {
size_t i = 0;
for (; i<read; i++) {
opus_int32 s;
// etc.
}
for (; i < ITEM_COUNT; i++) {
m_in[i] = 0;
}
// opus_encode() etc
}
您摆脱了无用的停止标志和嵌套级别,并且该结构符合“读到不能为止”的惯用语。 (参见 this SO question。)
我收回我提到的关于代码是假的,我认为 fread
返回读取的字节,而不是读取的项目。
关于C++算法压缩比计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16652872/
请注意:我意识到这是一个非常复杂的问题,其中包含大约一百万级的细微差别,我正试图将其简化为一个数字... 我即将承担一个使用 H.264 编码的大型视频编码项目。我们正在尝试创建多个比特率配置文件,以
我一直在玩弄 Android 位图,发现 PNG 压缩比最高质量的 JPEG 压缩需要更多的时间。更多。在我的设备上,相对于 1 而言,它可能大约长达 10 秒。 AFAIK,PNG 基本上是用 de
我是一名优秀的程序员,十分优秀!