ZigZag Sin
登 陆
上一篇:MP4概述 下一篇:Box 概述

前期准备

Time
2022-2-21 11:39 阅读 1517

前期准备

工具准备:

​ 这里推荐4个比较好用的工具:

  1. MP4 Info

    软件截图:

    image-20211216190231396

  2. Mp4 Explorer

    软件截图:

    image-20211216190404067

  3. 一个16进制文本查看器,这个任意一个软件就行

  4. Python 只需要准备好环境就行,可以用这样对应的黑框就行

    软件截图:

    image-20211216190622265

代码准备:

  1. 我们先自己写一个工具类,用来读取 Buffer 里面的数据。

    因为我们需要分析 MP4 文件里面的数据,当我们把读取到的一部分数据,对这部分数据进行解析操作。

    // TimeBufferStream.h
    
    class TimeBufferStream {
    private:
        void *Buffer;
        unsigned int len;
        unsigned int index=0;
    public:
        TimeBufferStream(void *b, unsigned int len);
    
        bool IsEnd();
    
        void GetLenData(void *dst, unsigned int len);
    
        unsigned char GetUChar();
    
        unsigned short GetUShort();
    
        unsigned int GetUInt();
    };
    
    
    // TimeBufferStream.cpp
    
    TimeBufferStream::TimeBufferStream(void *b, unsigned int len)
            : Buffer(b), len(len) {
    
    }
    
    bool TimeBufferStream::IsEnd() {
        return index >= len;
    }
    
    void TimeBufferStream::GetLenData(void *dst, unsigned int len) {
        auto *_dst = (unsigned char *) dst;
        auto *_src = (unsigned char *) Buffer;
        for (int i = 0; i < len; ++i) {
            if (IsEnd()) return;
            if(_dst){
                _dst[i] = _src[index++];
            }
        }
    }
    
    unsigned char TimeBufferStream::GetUChar() {
        unsigned char temp = 0;
        GetLenData(&temp, 1);
        return temp;
    }
    
    unsigned short TimeBufferStream::GetUShort() {
        unsigned short temp = 0;
        GetLenData(&temp, 2);
        temp = (temp>>8)|(temp&0xff)<<8;;
        return temp;
    }
    
    unsigned int TimeBufferStream::GetUInt() {
        unsigned int temp = 0;
        GetLenData(&temp, 4);
        temp = (temp&0xff000000)>>24|(temp&0xff0000)>>16<<8|(temp&0xff00)>>8<<16|(temp&0xff)<<24;
        return temp;
    

} ```

接口分析:

​ 构造函数:传入对应的 buffer 指针和当前 buffer 的长度。

​ IsEnd():判断 buffer 是否读取完毕。

​ GetLenData(void *dst, unsigned int len):从 buffer 读取 len 个字节到 dst 当中。

​ GetUChar():读取 buffer 一个字节的长度 返回一个无符号字节。

​ GetUShort():读取 buffer 两个字节的长度 返回一个无符号短整形。

​ GetUInt():读取 buffer 两个字节的长度 返回一个无符号整形。

补充

上面涉及到的移位操作,是由于大端模式和小端模式导致的。

这里我简单介绍一下:

比如一个 unsigned char c[4] = {0x0, 0x0, 0x0, 0x5}

0-7bit8-15bit16-23bit24-31bit
0x00x00x00x5

我们知道一个无符号整形的长度也是4个字节,

如果我们直接按照以下代码执行:

unsigned char c[4] = {0x0, 0x0, 0x0, 0x5};
auto * numb = (unsigned int*)c;
printf("numb=%ud", *numb); // print numb=83886080d

结果打印出来的并不是我们想要的5,而是 83886080 这么大,这就是因为在 int 内存排布里面 0x5 在高地址位,在大端模式下 0x05<<24 = 83886080,这不太符合我们的直觉,毕竟我们其实想要的是按照我们的习惯,例如:123,从左到右是百位,十位,个位,从大到小从高位到地位这样排布。内存从左到右,从低位到高位,也要符合我们的习惯,所以便有上面的移位操作进行大端转小端操作。(这里看不太明白也没关系,只要知道可以正确解析出我们的数据即可)

上一篇:MP4概述 下一篇:Box 概述
给我买个键盘吧。。。求打赏。。。
欢迎加群,一起交流~~~