从NAL UNIT中对rbsp获取的原理如图所示,此为NAL UNIT解析的架构图
头文件
#ifndef __NAL_UNIT_H__
#define __NAL_UNIT_H__
#include <stdio.h>
typedef struct Nal_Unit_Fops {
int (*find_nal_unit_data)(FILE *file);
int (*find_nal_unit_head)(char (*QueueBuf)[],int *pos,char *character,FILE *file);
void (*find_nal_unit_type)(char (*QueueBuf)[],int *pos,char *character,FILE *file);
int (*nal_unit_ebsp_to_rbsp)(char (*QueueBuf)[],int *pos);
} NAL_UNIT_OPS, *P_NAL_UNIT_OPS;
typedef struct File_Fops {
int (*open_file)(FILE **file,const char *file_path);
int (*close_file)(FILE *file);
} FILE_OPS, *P_FILE_OPS;
P_NAL_UNIT_OPS NalUnitOps = NULL;
P_FILE_OPS FileOps = NULL;
#endif
主文件
#include "Nal_Unit.h"
static int nal_unit_ebsp_to_rbsp(char (*QueueBuf)[],int *pos)
{
int IsExtended = 0;
if(((*QueueBuf)[((*pos)+0)%3] == 0) && ((*QueueBuf)[((*pos)+1)%3] == 0) && ((*QueueBuf)[((*pos)+2)%3] == 3)) {
IsExtended = 1;
}
return IsExtended;
}
static void find_nal_unit_type(char (*QueueBuf)[],int *pos,char *character,FILE *file)
{
int Type = 0;
fread(character,1,1,file);
(*QueueBuf)[((*pos)++)%3] = *character;
Type = *character & 0x1F;
}
static int find_nal_unit_head(char (*QueueBuf)[],int *pos,char *character,FILE *file)
{
fread(character,1,1,file);
(*QueueBuf)[((*pos)++)%3] = *character;
if((*pos) < 3) {
return -1;
} else {
if(((*QueueBuf)[((*pos)+0)%3] == 0) && ((*QueueBuf)[((*pos)+1)%3] == 0) && ((*QueueBuf)[((*pos)+2)%3] == 1)) {
return 1;
} else if(((*QueueBuf)[((*pos)+0)%3] == 0) && ((*QueueBuf)[((*pos)+1)%3] == 0) && ((*QueueBuf)[((*pos)+2)%3] == 0)) {
fread(character,1,1,file);
(*QueueBuf)[((*pos)++)%3] = *character;
if(*character == 1) {
return 2;
}
} else;
}
return 0;
}
static int find_nal_unit_data(FILE *file)
{
char QueueBuf[3] = {0};
char character = 0;
int pos = 0;
int retVal = 0;
while(!feof(file) && !ferror(file)) {
retVal = NalUnitOps->find_nal_unit_head(&QueueBuf,&pos,&character,file);
if(retVal == 1 || retVal == 2) {
NalUnitOps->find_nal_unit_type(&QueueBuf,&pos,&character,file);
} else if(retVal == 0) {
if(NalUnitOps->nal_unit_ebsp_to_rbsp(&QueueBuf,&pos));
else
printf("%c",character);
} else;
}
return 0;
}
static int open_file(FILE **file, const char *file_path)
{
int Rval = 0;
if(!(*file = fopen(file_path,"r"))) {
printf("open file failure!\n");
Rval = -1;
}
return Rval;
}
static int close_file(FILE *file)
{
int Rval = 0;
if((Rval = (fclose(file))) != 0) {
printf("close file failure!\n");
Rval = -1;
}
return Rval;
}
NAL_UNIT_OPS nal_unit_fops = {
.find_nal_unit_data = find_nal_unit_data,
.find_nal_unit_head = find_nal_unit_head,
.find_nal_unit_type = find_nal_unit_type,
.nal_unit_ebsp_to_rbsp = nal_unit_ebsp_to_rbsp,
};
FILE_OPS file_fops = {
.open_file = open_file,
.close_file = close_file,
};
int main(int argc,char *argv[])
{
if(argc != 2) {
printf("pleasr input ./elf ./h264_file \n");
return -1;
}
printf("find Nal Unit data\n");
FILE *file = NULL;
FileOps = &file_fops;
NalUnitOps = &nal_unit_fops;
FileOps->open_file(&file,argv[1]);
NalUnitOps->find_nal_unit_data(file);
done:
FileOps->close_file(file);
return 0;
}
|