From b649372873732106316e8e767b6d45523a195845 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Thu, 30 Apr 2020 10:00:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dsplit=20264/265=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/H264.cpp | 55 +++++++++++++++++++++++++++++------------- src/Extension/H264.h | 25 ++++--------------- src/Extension/H265.h | 29 ++++++---------------- 3 files changed, 50 insertions(+), 59 deletions(-) diff --git a/src/Extension/H264.cpp b/src/Extension/H264.cpp index 7cfb086a..0a5314ae 100644 --- a/src/Extension/H264.cpp +++ b/src/Extension/H264.cpp @@ -44,20 +44,32 @@ const char *memfind(const char *buf, int len, const char *subbuf, int sublen) { return NULL; } -void splitH264(const char *ptr, int len, const std::function &cb) { - auto nal = ptr; +void splitH264(const char *ptr, int len, int prefix, const std::function &cb) { + auto start = ptr + prefix; auto end = ptr + len; - while(true) { - auto next_nal = memfind(nal + 3,end - nal - 3,"\x0\x0\x1",3); - if(next_nal){ - if(*(next_nal - 1) == 0x00){ - next_nal -= 1; + int next_prefix; + while (true) { + auto next_start = memfind(start, end - start, "\x00\x00\x01", 3); + if (next_start) { + //找到下一帧 + 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); - nal = next_nal; + //记得加上本帧prefix长度 + cb(start - prefix, next_start - start + prefix, prefix); + //搜索下一帧末尾的起始位置 + start = next_start + next_prefix; + //记录下一帧的prefix长度 + prefix = next_prefix; continue; } - cb(nal,end - nal); + //未找到下一帧,这是最后一帧 + cb(start - prefix, end - start + prefix, prefix); break; } } @@ -65,13 +77,22 @@ void splitH264(const char *ptr, int len, const std::function &cb); +void splitH264(const char *ptr, int len, int prefix, const std::function &cb); /** * 264帧类 @@ -243,25 +243,10 @@ public: int type = H264_TYPE(*((uint8_t *)frame->data() + frame->prefixSize())); if(type == H264Frame::NAL_SPS || type == H264Frame::NAL_SEI){ //有些设备会把SPS PPS IDR帧当做一个帧打包,所以我们要split一下 - bool first_frame = true; - splitH264(frame->data() + frame->prefixSize(), - frame->size() - frame->prefixSize(), - [&](const char *ptr, int len){ - if(first_frame){ - H264FrameInternal::Ptr sub_frame = std::make_shared(frame, - frame->data(), - len + frame->prefixSize(), - frame->prefixSize()); - inputFrame_l(sub_frame); - first_frame = false; - }else{ - H264FrameInternal::Ptr sub_frame = std::make_shared(frame, - (char *)ptr, - len , - 3); - inputFrame_l(sub_frame); - } - }); + splitH264(frame->data(), frame->size(), frame->prefixSize(), [&](const char *ptr, int len, int prefix) { + H264FrameInternal::Ptr sub_frame = std::make_shared(frame, (char *)ptr, len, prefix); + inputFrame_l(sub_frame); + }); } else{ inputFrame_l(frame); } diff --git a/src/Extension/H265.h b/src/Extension/H265.h index fca162c3..676af0b2 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -246,28 +246,13 @@ public: void inputFrame(const Frame::Ptr &frame) override{ int type = H265_TYPE(*((uint8_t *)frame->data() + frame->prefixSize())); if(frame->configFrame()){ - bool first_frame = true; - splitH264(frame->data() + frame->prefixSize(), - frame->size() - frame->prefixSize(), - [&](const char *ptr, int len){ - if(first_frame){ - H265FrameInternal::Ptr sub_frame = std::make_shared(frame, - frame->data(), - len + frame->prefixSize(), - frame->prefixSize()); - inputFrame_l(sub_frame); - first_frame = false; - }else{ - H265FrameInternal::Ptr sub_frame = std::make_shared(frame, - (char *)ptr, - len , - 3); - inputFrame_l(sub_frame); - } - }); - }else{ - inputFrame_l(frame); - } + splitH264(frame->data(), frame->size(), frame->prefixSize(), [&](const char *ptr, int len, int prefix){ + H265FrameInternal::Ptr sub_frame = std::make_shared(frame, (char*)ptr, len, prefix); + inputFrame_l(sub_frame); + }); + } else { + inputFrame_l(frame); + } } private: