当我从mp4写入moof box时,ASCII码是相反的

问题描述 投票:0回答:1

我正在尝试从 isobmff 格式的电影框中提取“moof”框。

// It is assumed that the movie box contains fragment data.
ISOMovie moov;
MP4MovieFragmentAtomPtr moof;

FILE *fp;
fp = fopen("test_moof_mdat.m4v","w");
movie = (MP4PrivateMovieRecordPtr)moov;
if((movie->moovAtomPtr)->type ==MP4MovieFragmentAtomType)
{
   // movie fragment box 
   moof = (MP4MovieFragmentAtomPtr)movie->moovAtomPtr;
   
   // calculate `moof` box size
   movie->moovAtomPtr->calculateSize(movie->moovAtomPtr);
}
fwrite(moof,moof->size,1,fp2);

当我从mp4写入moof box时,ASCII码是相反的。

如您所见,ASCII 码是颠倒过来的。
mp4 盒子的 ASCII 码和大小是大端格式吗?

(*参考:我的电脑 CPU:Intel(R) Xeon(R) Gold 6238R CPU @ 2.20GHz。)

c video ascii mp4 endianness
1个回答
1
投票

“MP4盒子的ASCII码和大小是用big-endian格式写的吗?”

是的。 MP4 结构的所有数据(原子、值等)均应以 Big Endian 格式写入。

通过快速研究,您使用的库似乎确实为 MP4 输出编写了 Big-Endian。它还允许将 PCM 音频添加到 MP4,这是它处理 Little-Endian 代码的唯一一次。

问题可能在于 fwrite() 本身如何工作。
图书馆可能没有做错任何事。

可能的解决方案:

1.尝试将

fopen
输出设置为二进制模式“wb”(不仅仅是“w”)。
如果幸运的话,获取 Big-Endian 格式的数据可能就足够了。检查输出现在是否已修复?

fp = fopen("test_moof_mdat.m4v","wb");

2. 您可能需要创建一个自定义函数来转换每个 16 位、24 位或 32 位整数的字节序。如果您不知道如何操作,请查看这篇文章作为起点:

https://developer.ibm.com/articles/au-endianc/
(特别是这部分:“清单 4. 强制字节顺序”)。

PS:尚不清楚(代码的)

moof =
部分是否为您提供了字节值数组(eg:
uint32_t
)。我的意思是,您是否处于可以轻松手动反转整数的阶段?

3. 最终的解决方案是自己从文件(或字节流)中手动提取原子。如果您需要一些帮助,我可以稍后扩展这部分(这里没有 C++ 来测试),但这个概念的简短版本是:

  • 将 MOOV 字节获取到可以使用 While 循环逐一读取它们的程度。

  • 通过递增

    idx
    向前搜索uint_8数组的槽(例如:读取单个字节)。

  • 如果槽有一个字节与匹配的起始值,则检查其他接下来的 3 个字节是否也匹配。

  • 如果全部匹配,您现在已经在

    moof
    原子中找到了“moof”文本的起始位置。

  • 从新的

    pos_moof
    向后移动 -4 个字节,然后将
    size
    读取为 32 位 Big-Endian uint。

  • 从输入字节中提取一个新数组(从

    pos_moof
    开始,长度为
    (size + 4)
    等)。

下面是一个使用伪代码的快速 “搜索字节序列”示例...

//### about the required vars...

byte[] my_MOOV_Bytes_Array //# provides input byte values (could be an Array or FileStream, etc)

int pos_idx = 0; //# for the index (pos) within the bytes

//### search process is simple with a While loop...

while (true)
{
    //# end While loop if reached end of bytes Array
    if( pos_idx >= my_MOOV_Bytes_Array.length ) { break; }
    
    //# find "m"
    if( my_MOOV_Bytes_Array[ pos_idx ] == 0x6D )                
    {
        if( 
            ( my_MOOV_Bytes_Array[ pos_idx + 1 ] == 0x6F ) &&   //# find "o"
            ( my_MOOV_Bytes_Array[ pos_idx + 2 ] == 0x6F ) &&   //# find "o"
            ( my_MOOV_Bytes_Array[ pos_idx + 3 ] == 0x66 )      //# find "f"
        )
        {
            cout << "MOOF atom found at : " << pos_idx << endl;
            break; //# or can Return pos_idx if used inside a search function
        }
    }
    
    pos_idx++; //# just keep incrementing...
}
© www.soinside.com 2019 - 2024. All rights reserved.