分析
打开一个H.264文件,可以看到h.264的起始码是0x00 00 00 01或0x00 00 01。
001和0001的区别
当一张图片分成多个slice发送
- 0001——当一帧视频被分为多个slice时,起始的slice是0001
- 001——起始slice后的slice是001
到下一个p帧的slice是0001
错误想法
用fgetc直接读文件,foef来循环。
思考一下为什么有的公司使用性能强大的芯片做出的产品反而没有使用普通芯片做出的产品优秀。
再思考一下对文件进行操作和对内存进行操作的效率不同。
再思考对文件进行操作的弊端。
正确做法应是对内存进行操作
测试代码
.c
#include "LUX_TEST_Get264.h"
typedef unsigned char uint8;
LUX_OSD_DataPoint dataPoint;
LUX_OSD_FilePoint filePoint;
int offset = 0;
/**
* @description: 初始化
* @param [in] void
* @return
*/
int LUX_TEST_Init(void)
{
int ret = LUX_SUCCESS;
int len = 0;
do
{
/*打开264文件*/
filePoint.h264File = fopen(LUX_TEST_File, "r");
if (NULL == filePoint.h264File)
{
printf("fopen h264file failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
/*malloc*/
dataPoint.h264Data = malloc(LUX_TEST_FileSpace);
if (NULL == dataPoint.h264Data)
{
printf("malloc dataPoint.h264Data failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
/*h264实际数据*/
dataPoint.dstData = malloc(128);
if (NULL == dataPoint.dstData)
{
printf("malloc dataPoint.dstData failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
/*存放h264实际数据*/
filePoint.saveH264 = fopen(LUX_TEST_DestFile,"w+");
if(NULL == filePoint.saveH264)
{
printf("fopen LUX_FONT_WRITE_FILE failed\n");
}
/*读入内存*/
len = fread(dataPoint.h264Data, 1, LUX_TEST_FileSpace, filePoint.h264File);
if (0 == len)
{
printf("fread dataPoint.h264Data failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
}while(0);
return ret;
}
/**
* @description: 抓取h264数据并存储
* @param [in] void
* @return
*/
int LUX_TEST_Func(void)
{
int ret = LUX_SUCCESS;
int getDataOffset = 0;
int len = 0;
do{
while(1)
{
if (*(dataPoint.h264Data + offset) == 0 && *(dataPoint.h264Data + offset + 1) == 0)
{
if (*(dataPoint.h264Data + offset + 2) == 1)
{
/*0x 00 00 01*/
printf("++++++++++\n");
break;
}
else if (*(dataPoint.h264Data + offset + 2) == 0 && *(dataPoint.h264Data + offset + 3) == 1)
{
/*0x 00 00 00 01*/
printf("==========\n");
do
{
getDataOffset++;
*(dataPoint.dstData + getDataOffset) = *(dataPoint.h264Data + offset + 3 + getDataOffset);
if (*(dataPoint.h264Data + 3 + getDataOffset + 1) == 0 && *(dataPoint.h264Data + 3 + getDataOffset + 2) == 0 &&
*(dataPoint.h264Data + 3 + getDataOffset + 3) == 0 && *(dataPoint.h264Data + 3 + getDataOffset + 4) == 1)
{
len = fwrite(dataPoint.dstData, 1, LUX_TEST_FileSpace, filePoint.saveH264);
if (len <= 0)
{
printf("fwrite dataPoint.h264Data failed\n");
perror("why");
return LUX_FAILED;
}
break;
}
} while (1);
break;
}
}
offset++;
}
}while(0);
return ret;
}
/**
* @description: 去初始化
* @param [in] void
* @return
*/
int LUX_TEST_DeInit(void)
{
free(dataPoint.h264Data);
free(dataPoint.dstData);
fclose(filePoint.h264File);
}
int main()
{
int ret = LUX_FAILED;
ret = LUX_TEST_Init();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_Init error\n");
return LUX_FAILED;
}
ret = LUX_TEST_Func();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_Func error\n");
return LUX_FAILED;
}
ret = LUX_TEST_DeInit();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_DeInit error\n");
return LUX_FAILED;
}
return LUX_SUCCESS;
}
.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#define LUX_TEST_File "test.264"
#define LUX_TEST_DestFile "destFile"
#define LUX_TEST_FileSpace 0x2040
#define LUX_SUCCESS 0
#define LUX_FAILED -1
typedef struct
{
char *h264Data; //YUV
char *dstData; //dst data
}LUX_OSD_DataPoint;
typedef struct
{
FILE *h264File; //打开264
FILE *saveH264; //存h264实际数据
}LUX_OSD_FilePoint;
/**
* @description: 初始化
* @param [in] void
* @return
*/
int LUX_TEST_Init(void);
/**
* @description: 抓取h264数据并存储
* @param [in] void
* @return
*/
int LUX_TEST_Func(void);
/**
* @description: 去初始化
* @param [in] void
* @return
*/
int LUX_TEST_DeInit(void);
效果
能抓出第一个nalu的数据。
由于我们不知道抓出来的nalu数据有多长,所以空间开的比较大,后面全部是0。这里也不知道后面的三个0是由于内存无数据置0还是没有舍弃掉第二个nalu起始码的0。所以我们需要优化代码。
代码优化分析
一个一个字节往文件里写
.c
#include "LUX_TEST_Get264.h"
typedef unsigned char uint8;
LUX_OSD_DataPoint dataPoint;
LUX_OSD_FilePoint filePoint;
int offset = 0;
/**
* @description: 初始化
* @param [in] void
* @return
*/
int LUX_TEST_Init(void)
{
int ret = LUX_SUCCESS;
int len = 0;
do
{
/*打开264文件*/
filePoint.h264File = fopen(LUX_TEST_File, "r");
if (NULL == filePoint.h264File)
{
printf("fopen h264file failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
/*malloc*/
dataPoint.h264Data = malloc(LUX_TEST_FileSpace);
if (NULL == dataPoint.h264Data)
{
printf("malloc dataPoint.h264Data failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
/*存放h264实际数据*/
filePoint.saveH264 = fopen(LUX_TEST_DestFile,"w+");
if(NULL == filePoint.saveH264)
{
printf("fopen LUX_FONT_WRITE_FILE failed\n");
}
/*读入内存*/
len = fread(dataPoint.h264Data, 1, LUX_TEST_FileSpace, filePoint.h264File);
if (0 == len)
{
printf("fread dataPoint.h264Data failed\n");
perror("why");
ret = LUX_FAILED;
break;
}
}while(0);
return ret;
}
/**
* @description: 抓取h264数据并存储
* @param [in] void
* @return
*/
int LUX_TEST_Func(void)
{
int ret = LUX_SUCCESS;
int getDataOffset = 0;
int len = 0;
do{
while(1)
{
if (*(dataPoint.h264Data + offset) == 0 && *(dataPoint.h264Data + offset + 1) == 0)
{
if (*(dataPoint.h264Data + offset + 2) == 1)
{
/*0x 00 00 01*/
//TODO:和下面一样
break;
}
else if (*(dataPoint.h264Data + offset + 2) == 0 && *(dataPoint.h264Data + offset + 3) == 1)
{
/*0x 00 00 00 01*/
do
{
getDataOffset++;
len = fwrite(dataPoint.h264Data + offset + 3 + getDataOffset, 1, 1, filePoint.saveH264);
if (len <= 0)
{
printf("fwrite dataPoint.h264Data failed\n");
perror("why");
return LUX_FAILED;
}
if (*(dataPoint.h264Data + 3 + getDataOffset + 1) == 0 && *(dataPoint.h264Data + 3 + getDataOffset + 2) == 0 &&
*(dataPoint.h264Data + 3 + getDataOffset + 3) == 0 && *(dataPoint.h264Data + 3 + getDataOffset + 4) == 1)
break;
} while (1);
break;
}
}
offset++;
}
}while(0);
return ret;
}
/**
* @description: 去初始化
* @param [in] void
* @return
*/
int LUX_TEST_DeInit(void)
{
free(dataPoint.h264Data);
fclose(filePoint.h264File);
}
int main()
{
int ret = LUX_FAILED;
ret = LUX_TEST_Init();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_Init error\n");
return LUX_FAILED;
}
ret = LUX_TEST_Func();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_Func error\n");
return LUX_FAILED;
}
ret = LUX_TEST_DeInit();
if(LUX_FAILED == ret)
{
printf("LUX_TEST_DeInit error\n");
return LUX_FAILED;
}
return LUX_SUCCESS;
}
.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#define LUX_TEST_File "test.264"
#define LUX_TEST_DestFile "destFile"
#define LUX_TEST_FileSpace 0x2040
#define LUX_SUCCESS 0
#define LUX_FAILED -1
typedef struct
{
char *h264Data; //YUV
}LUX_OSD_DataPoint;
typedef struct
{
FILE *h264File; //打开264
FILE *saveH264; //存h264实际数据
}LUX_OSD_FilePoint;
/**
* @description: 初始化
* @param [in] void
* @return
*/
int LUX_TEST_Init(void);
/**
* @description: 抓取h264数据并存储
* @param [in] void
* @return
*/
int LUX_TEST_Func(void);
/**
* @description: 去初始化
* @param [in] void
* @return
*/
int LUX_TEST_DeInit(void);
最终效果
拿到想要的数据
思考:要拿出第二个该怎么做