Skip to content

Commit b4a970a

Browse files
committed
for #813
1 parent 5a69055 commit b4a970a

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

config.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
"Vaison-La-Romaine": {"video":"rtsp://176.139.87.16/axis-media/media.amp", "position":"44.238960,5.074610" },
1313

14-
"Orlando": {"video":"rtsp://97.68.104.34/axis-media/media.amp", "position":"28.538340,-81.379240"},
15-
16-
"H265": {"video":"file://h265.mkv"}
14+
"H265": {"video":"file://h265.mkv"}
1715
}
1816
}

inc/livevideosource.h

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ class LiveVideoSource : public VideoDecoder, public T::Callback
110110
webrtc::ArrayView<const uint8_t> data(buffer, size);
111111
std::vector<webrtc::H264::NaluIndex> indexes = webrtc::H264::FindNaluIndices(data);
112112
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData nbNalu:" << indexes.size();
113+
// Support multi-slice IDR: accumulate all IDR slices (and SPS/PPS cfg) into a single access unit
114+
std::vector<uint8_t> idrContent; // holds concatenated IDR slices + config
115+
int idrSliceCount = 0;
113116
for (const webrtc::H264::NaluIndex & index : indexes) {
114117
webrtc::H264::NaluType nalu_type = webrtc::H264::ParseNaluType(buffer[index.payload_start_offset]);
115118
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData NALU type:" << nalu_type << " payload_size:" << index.payload_size << " payload_start_offset:" << index.payload_start_offset << " start_offset:" << index.start_offset;
@@ -137,18 +140,26 @@ class LiveVideoSource : public VideoDecoder, public T::Callback
137140
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData PPS";
138141
m_cfg.insert(m_cfg.end(), buffer + index.start_offset, buffer + index.payload_size + index.payload_start_offset);
139142
}
140-
else if (nalu_type == webrtc::H264::NaluType::kSei)
143+
else if (nalu_type == webrtc::H264::NaluType::kSei)
141144
{
142-
}
145+
}
143146
else
144147
{
145148
webrtc::VideoFrameType frameType = webrtc::VideoFrameType::kVideoFrameDelta;
146149
std::vector<uint8_t> content;
147150
if (nalu_type == webrtc::H264::NaluType::kIdr)
148151
{
152+
// Multi-slice IDR handling: accumulate and defer posting until all slices processed
149153
frameType = webrtc::VideoFrameType::kVideoFrameKey;
150-
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData IDR";
151-
content.insert(content.end(), m_cfg.begin(), m_cfg.end());
154+
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData IDR slice";
155+
if (idrSliceCount == 0) {
156+
// first IDR slice: prepend SPS/PPS config
157+
idrContent.insert(idrContent.end(), m_cfg.begin(), m_cfg.end());
158+
}
159+
idrContent.insert(idrContent.end(), buffer + index.start_offset, buffer + index.payload_size + index.payload_start_offset);
160+
idrSliceCount++;
161+
// do not post yet; continue to gather potential further IDR slices
162+
continue;
152163
}
153164
else
154165
{
@@ -165,11 +176,20 @@ class LiveVideoSource : public VideoDecoder, public T::Callback
165176
}
166177
}
167178
}
179+
// After processing all NALUs, if we collected IDR slices, post them as a single key frame
180+
if (idrSliceCount > 0) {
181+
webrtc::scoped_refptr<webrtc::EncodedImageBuffer> frame = webrtc::EncodedImageBuffer::Create(idrContent.data(), idrContent.size());
182+
PostFrame(frame, ts, webrtc::VideoFrameType::kVideoFrameKey);
183+
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData posted multi-slice IDR frame slices=" << idrSliceCount << " total_size=" << idrContent.size();
184+
}
168185
}
169186

170187
void onH265Data(unsigned char *buffer, ssize_t size, int64_t ts, const std::string & codec) {
171188
std::vector<webrtc::H265::NaluIndex> indexes = webrtc::H265::FindNaluIndices(buffer,size);
172189
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData nbNalu:" << indexes.size();
190+
// Support multi-slice IDR: accumulate all IDR slices (and VPS/SPS/PPS cfg) into a single access unit
191+
std::vector<uint8_t> idrContentH265;
192+
int idrSliceCountH265 = 0;
173193
for (const webrtc::H265::NaluIndex & index : indexes) {
174194
webrtc::H265::NaluType nalu_type = webrtc::H265::ParseNaluType(buffer[index.payload_start_offset]);
175195
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData NALU type:" << nalu_type << " payload_size:" << index.payload_size << " payload_start_offset:" << index.payload_start_offset << " start_offset:" << index.start_offset;
@@ -207,9 +227,17 @@ class LiveVideoSource : public VideoDecoder, public T::Callback
207227
std::vector<uint8_t> content;
208228
if ( (nalu_type == webrtc::H265::NaluType::kIdrWRadl) || (nalu_type == webrtc::H265::NaluType::kIdrNLp) )
209229
{
230+
// Multi-slice IDR handling: accumulate and defer posting until all slices processed
210231
frameType = webrtc::VideoFrameType::kVideoFrameKey;
211-
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData IDR";
212-
content.insert(content.end(), m_cfg.begin(), m_cfg.end());
232+
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData IDR slice";
233+
if (idrSliceCountH265 == 0) {
234+
// first IDR slice: prepend VPS/SPS/PPS config
235+
idrContentH265.insert(idrContentH265.end(), m_cfg.begin(), m_cfg.end());
236+
}
237+
idrContentH265.insert(idrContentH265.end(), buffer + index.start_offset, buffer + index.payload_size + index.payload_start_offset);
238+
idrSliceCountH265++;
239+
// do not post yet; continue to gather potential further IDR slices
240+
continue;
213241
}
214242
else
215243
{
@@ -226,6 +254,12 @@ class LiveVideoSource : public VideoDecoder, public T::Callback
226254
}
227255
}
228256
}
257+
// After processing all NALUs, if we collected IDR slices, post them as a single key frame
258+
if (idrSliceCountH265 > 0) {
259+
webrtc::scoped_refptr<webrtc::EncodedImageBuffer> frame = webrtc::EncodedImageBuffer::Create(idrContentH265.data(), idrContentH265.size());
260+
PostFrame(frame, ts, webrtc::VideoFrameType::kVideoFrameKey);
261+
RTC_LOG(LS_VERBOSE) << "LiveVideoSource:onData posted H265 multi-slice IDR frame slices=" << idrSliceCountH265 << " total_size=" << idrContentH265.size();
262+
}
229263
}
230264

231265
int onJPEGData(unsigned char *buffer, ssize_t size, int64_t ts, const std::string & codec) {

0 commit comments

Comments
 (0)