mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 03:10:04 +08:00
修复split 264/265相关逻辑的bug
This commit is contained in:
parent
1067c5a2d3
commit
b649372873
@ -44,20 +44,32 @@ const char *memfind(const char *buf, int len, const char *subbuf, int sublen) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void splitH264(const char *ptr, int len, const std::function<void(const char *, int)> &cb) {
|
void splitH264(const char *ptr, int len, int prefix, const std::function<void(const char *, int, int)> &cb) {
|
||||||
auto nal = ptr;
|
auto start = ptr + prefix;
|
||||||
auto end = ptr + len;
|
auto end = ptr + len;
|
||||||
while(true) {
|
int next_prefix;
|
||||||
auto next_nal = memfind(nal + 3,end - nal - 3,"\x0\x0\x1",3);
|
while (true) {
|
||||||
if(next_nal){
|
auto next_start = memfind(start, end - start, "\x00\x00\x01", 3);
|
||||||
if(*(next_nal - 1) == 0x00){
|
if (next_start) {
|
||||||
next_nal -= 1;
|
//找到下一帧
|
||||||
|
if (*(next_start - 1) == 0x00) {
|
||||||
|
//这个是00 00 00 01开头
|
||||||
|
next_start -= 1;
|
||||||
|
next_prefix = 4;
|
||||||
|
} else {
|
||||||
|
//这个是00 00 01开头
|
||||||
|
next_prefix = 3;
|
||||||
}
|
}
|
||||||
cb(nal,next_nal - nal);
|
//记得加上本帧prefix长度
|
||||||
nal = next_nal;
|
cb(start - prefix, next_start - start + prefix, prefix);
|
||||||
|
//搜索下一帧末尾的起始位置
|
||||||
|
start = next_start + next_prefix;
|
||||||
|
//记录下一帧的prefix长度
|
||||||
|
prefix = next_prefix;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cb(nal,end - nal);
|
//未找到下一帧,这是最后一帧
|
||||||
|
cb(start - prefix, end - start + prefix, prefix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,13 +77,22 @@ void splitH264(const char *ptr, int len, const std::function<void(const char *,
|
|||||||
#if 0
|
#if 0
|
||||||
//splitH264函数测试程序
|
//splitH264函数测试程序
|
||||||
static onceToken s_token([](){
|
static onceToken s_token([](){
|
||||||
char buf[] = "\x00\x00\x00\x01\x12\x23\x34\x45\x56"
|
{
|
||||||
"\x00\x00\x00\x01\x12\x23\x34\x45\x56"
|
char buf[] = "\x00\x00\x00\x01\x12\x23\x34\x45\x56"
|
||||||
"\x00\x00\x00\x01\x12\x23\x34\x45\x56"
|
"\x00\x00\x00\x01\x23\x34\x45\x56"
|
||||||
"\x00\x00\x01\x12\x23\x34\x45\x56";
|
"\x00\x00\x00\x01x34\x45\x56"
|
||||||
splitH264(buf, sizeof(buf) - 1, [](const char *ptr, int len){
|
"\x00\x00\x01\x12\x23\x34\x45\x56";
|
||||||
cout << hexdump(ptr, len) << endl;
|
splitH264(buf, sizeof(buf) - 1, 4, [](const char *ptr, int len, int prefix) {
|
||||||
});
|
cout << prefix << " " << hexdump(ptr, len) << endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char buf[] = "\x00\x00\x00\x01\x12\x23\x34\x45\x56";
|
||||||
|
splitH264(buf, sizeof(buf) - 1, 4, [](const char *ptr, int len, int prefix) {
|
||||||
|
cout << prefix << " " << hexdump(ptr, len) << endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
#endif //0
|
#endif //0
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ using namespace toolkit;
|
|||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
|
||||||
void splitH264(const char *ptr, int len, const std::function<void(const char *, int)> &cb);
|
void splitH264(const char *ptr, int len, int prefix, const std::function<void(const char *, int, int)> &cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 264帧类
|
* 264帧类
|
||||||
@ -243,25 +243,10 @@ public:
|
|||||||
int type = H264_TYPE(*((uint8_t *)frame->data() + frame->prefixSize()));
|
int type = H264_TYPE(*((uint8_t *)frame->data() + frame->prefixSize()));
|
||||||
if(type == H264Frame::NAL_SPS || type == H264Frame::NAL_SEI){
|
if(type == H264Frame::NAL_SPS || type == H264Frame::NAL_SEI){
|
||||||
//有些设备会把SPS PPS IDR帧当做一个帧打包,所以我们要split一下
|
//有些设备会把SPS PPS IDR帧当做一个帧打包,所以我们要split一下
|
||||||
bool first_frame = true;
|
splitH264(frame->data(), frame->size(), frame->prefixSize(), [&](const char *ptr, int len, int prefix) {
|
||||||
splitH264(frame->data() + frame->prefixSize(),
|
H264FrameInternal::Ptr sub_frame = std::make_shared<H264FrameInternal>(frame, (char *)ptr, len, prefix);
|
||||||
frame->size() - frame->prefixSize(),
|
inputFrame_l(sub_frame);
|
||||||
[&](const char *ptr, int len){
|
});
|
||||||
if(first_frame){
|
|
||||||
H264FrameInternal::Ptr sub_frame = std::make_shared<H264FrameInternal>(frame,
|
|
||||||
frame->data(),
|
|
||||||
len + frame->prefixSize(),
|
|
||||||
frame->prefixSize());
|
|
||||||
inputFrame_l(sub_frame);
|
|
||||||
first_frame = false;
|
|
||||||
}else{
|
|
||||||
H264FrameInternal::Ptr sub_frame = std::make_shared<H264FrameInternal>(frame,
|
|
||||||
(char *)ptr,
|
|
||||||
len ,
|
|
||||||
3);
|
|
||||||
inputFrame_l(sub_frame);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else{
|
} else{
|
||||||
inputFrame_l(frame);
|
inputFrame_l(frame);
|
||||||
}
|
}
|
||||||
|
@ -246,28 +246,13 @@ public:
|
|||||||
void inputFrame(const Frame::Ptr &frame) override{
|
void inputFrame(const Frame::Ptr &frame) override{
|
||||||
int type = H265_TYPE(*((uint8_t *)frame->data() + frame->prefixSize()));
|
int type = H265_TYPE(*((uint8_t *)frame->data() + frame->prefixSize()));
|
||||||
if(frame->configFrame()){
|
if(frame->configFrame()){
|
||||||
bool first_frame = true;
|
splitH264(frame->data(), frame->size(), frame->prefixSize(), [&](const char *ptr, int len, int prefix){
|
||||||
splitH264(frame->data() + frame->prefixSize(),
|
H265FrameInternal::Ptr sub_frame = std::make_shared<H265FrameInternal>(frame, (char*)ptr, len, prefix);
|
||||||
frame->size() - frame->prefixSize(),
|
inputFrame_l(sub_frame);
|
||||||
[&](const char *ptr, int len){
|
});
|
||||||
if(first_frame){
|
} else {
|
||||||
H265FrameInternal::Ptr sub_frame = std::make_shared<H265FrameInternal>(frame,
|
inputFrame_l(frame);
|
||||||
frame->data(),
|
}
|
||||||
len + frame->prefixSize(),
|
|
||||||
frame->prefixSize());
|
|
||||||
inputFrame_l(sub_frame);
|
|
||||||
first_frame = false;
|
|
||||||
}else{
|
|
||||||
H265FrameInternal::Ptr sub_frame = std::make_shared<H265FrameInternal>(frame,
|
|
||||||
(char *)ptr,
|
|
||||||
len ,
|
|
||||||
3);
|
|
||||||
inputFrame_l(sub_frame);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
inputFrame_l(frame);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user