otream的write多字节问题

目录

  • 目录
  • 编译信息
  • 说明
  • 问题及现象
  • 解决方法

编译信息

作者:xzf

创建时间:2022/4/13

更新时间:2022/4/14

说明

在学习音频解码的时候,当从 MP4 解码出音频原始数据 PCM 时,写入的数据不对,而且长度也不对。但是用 FILEfwrite写入的数据是对的,所以应该是std::ostream::write,但是没找具体原因。后面发现是std::ostream::open的问题,因为之前已经曾经出现过一次,所以记录下来。防止重复犯错。

问题及现象

在参考了官方文档大佬的文档后,大概理解了解码音频基本和解码视频流程差不多,唯一不同就是视频流还是音频流,解码器的不同,为了验证需要把解码出来的PCM写入到文件里,但是两种都时使用C的方法写入文件,即用fwrite,但是使用C++,会需要添加_CRT_SECURE_NO_WARNINGS,所以我用C++的std::ostream但是,出现了数据长度不对,和波形也不对。

具体现象:

原始数据的音频帧数是1295。封装AAC采样1024.采样率22050

| 类型     | 帧数 | 帧采样数 | 采样率 | 通道数 | 格式  | 文件大小(字节) |
| -------- | ---- | -------- | ------ | ------ | ----- | -------------- |
| `fwrite` | 1295 | 1024     | 22050  | 2      | f32le | 10608640       |
| `write`  | 1295 | 1024     | 22050  | 2      | f32le | 10644172       |

计算:

大小=帧数*帧采样数*通道数*格式占的字节=1295*1024*2*4 = 10608640,所以fwrite写入的才是对的

write不对。

而且波形也不对。

上面是fwrite,下面是write

解决方法

std::fstream::open时需要以二进制的形式打开。不然报错。修改后,长度和波形都正确 。

#include <fstream>

int main()
{
    std::string path = "audio_decode_f32le.pcm";
    std::fstream f;
    // 错误
    //f.open(path, std::ios::out);
    // 正确
    f.open(path, std::ios::out | std::ios::binary);
    f.write(reinterpret_cast<char*>(frame->data[ch] + numBytes * i), numBytes);
    f.colse();
}
tag(s): none
show comments · back · home
Edit with Markdown