Skip to content

Commit a0803b5

Browse files
H265: Demux sps for log print and statistic streams.(#3271) (#3286)
* BitBuffer: add method to implement bit read operation. * Codec: demux hevc sps for profile level resolution. * Statistic: refine hevc profile level resolution. * Kernel: return error code for demux hevc. * Kernel: check bitstream length for hevc sps. * UTest: add BitBuffer read bits utest. * Kernel: refine print log and utest. * Kernel: add comment for hevc sps. Co-authored-by: winlin <[email protected]>
1 parent e6c395e commit a0803b5

File tree

9 files changed

+729
-19
lines changed

9 files changed

+729
-19
lines changed

trunk/src/app/srs_app_source.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,9 +1074,10 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se
10741074
c->width, c->height, c->video_data_rate / 1000, c->frame_rate, c->duration);
10751075
#ifdef SRS_H265
10761076
} else if (c->id == SrsVideoCodecIdHEVC) {
1077-
// TODO: FIXME: Use the correct information for HEVC.
1078-
err = stat->on_video_info(req_, c->id, c->avc_profile, c->avc_level, c->width, c->height);
1079-
srs_trace("%dB video sh, codec(%d)", msg->size, c->id);
1077+
err = stat->on_video_info(req_, c->id, c->hevc_profile, c->hevc_level, c->width, c->height);
1078+
srs_trace("%dB video sh, codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %.1ffps, %.1fs)",
1079+
msg->size, c->id, srs_hevc_profile2str(c->hevc_profile).c_str(), srs_hevc_level2str(c->hevc_level).c_str(),
1080+
c->width, c->height, c->video_data_rate / 1000, c->frame_rate, c->duration);
10801081
#endif
10811082
}
10821083
if (err != srs_success) {

trunk/src/app/srs_app_statistic.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,20 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
143143
obj->set("video", video);
144144

145145
video->set("codec", SrsJsonAny::str(srs_video_codec_id2str(vcodec).c_str()));
146-
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
147-
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
146+
147+
if (vcodec == SrsVideoCodecIdAVC) {
148+
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
149+
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
150+
#ifdef SRS_H265
151+
} else if (vcodec == SrsVideoCodecIdHEVC) {
152+
video->set("profile", SrsJsonAny::str(srs_hevc_profile2str(hevc_profile).c_str()));
153+
video->set("level", SrsJsonAny::str(srs_hevc_level2str(hevc_level).c_str()));
154+
#endif
155+
} else {
156+
video->set("profile", SrsJsonAny::str("Other"));
157+
video->set("level", SrsJsonAny::str("Other"));
158+
}
159+
148160
video->set("width", SrsJsonAny::integer(width));
149161
video->set("height", SrsJsonAny::integer(height));
150162
}
@@ -335,7 +347,7 @@ SrsStatisticClient* SrsStatistic::find_client(string client_id)
335347
return NULL;
336348
}
337349

338-
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height)
350+
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, int profile, int level, int width, int height)
339351
{
340352
srs_error_t err = srs_success;
341353

@@ -344,9 +356,20 @@ srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec,
344356

345357
stream->has_video = true;
346358
stream->vcodec = vcodec;
347-
stream->avc_profile = avc_profile;
348-
stream->avc_level = avc_level;
349-
359+
360+
if (vcodec == SrsVideoCodecIdAVC) {
361+
stream->avc_profile = (SrsAvcProfile)profile;
362+
stream->avc_level = (SrsAvcLevel)level;
363+
#ifdef SRS_H265
364+
} else if (vcodec == SrsVideoCodecIdHEVC) {
365+
stream->hevc_profile = (SrsHevcProfile)profile;
366+
stream->hevc_level = (SrsHevcLevel)level;
367+
#endif
368+
} else {
369+
stream->avc_profile = (SrsAvcProfile)profile;
370+
stream->avc_level = (SrsAvcLevel)level;
371+
}
372+
350373
stream->width = width;
351374
stream->height = height;
352375

trunk/src/app/srs_app_statistic.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ struct SrsStatisticStream
7070
SrsAvcProfile avc_profile;
7171
// The level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45.
7272
SrsAvcLevel avc_level;
73+
#ifdef SRS_H265
74+
// The profile_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 559.
75+
SrsHevcProfile hevc_profile;
76+
// The level_idc, T-REC-H.265-202108-I!!PDF-E.pdf, page 684.
77+
SrsHevcLevel hevc_level;
78+
#endif
7379
// The width and height in codec info.
7480
int width;
7581
int height;
@@ -157,8 +163,7 @@ class SrsStatistic
157163
virtual SrsStatisticClient* find_client(std::string client_id);
158164
public:
159165
// When got video info for stream.
160-
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile,
161-
SrsAvcLevel avc_level, int width, int height);
166+
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height);
162167
// When got audio info for stream.
163168
virtual srs_error_t on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate,
164169
SrsAudioChannels asound_type, SrsAacObjectType aac_object);

trunk/src/kernel/srs_kernel_buffer.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,15 @@ bool SrsBitBuffer::empty() {
379379
return stream->empty();
380380
}
381381

382+
bool SrsBitBuffer::require_bits(int n)
383+
{
384+
if (n < 0) {
385+
return false;
386+
}
387+
388+
return n <= left_bits();
389+
}
390+
382391
int8_t SrsBitBuffer::read_bit() {
383392
if (!cb_left) {
384393
srs_assert(!stream->empty());
@@ -391,3 +400,75 @@ int8_t SrsBitBuffer::read_bit() {
391400
return v;
392401
}
393402

403+
int SrsBitBuffer::left_bits()
404+
{
405+
return cb_left + stream->left() * 8;
406+
}
407+
408+
void SrsBitBuffer::skip_bits(int n)
409+
{
410+
srs_assert(n <= left_bits());
411+
412+
for (int i = 0; i < n; i++) {
413+
read_bit();
414+
}
415+
}
416+
417+
int32_t SrsBitBuffer::read_bits(int n)
418+
{
419+
srs_assert(n <= left_bits());
420+
421+
int32_t v = 0;
422+
for (int i = 0; i < n; i++) {
423+
v |= (read_bit() << (n - i - 1));
424+
}
425+
return v;
426+
}
427+
428+
int8_t SrsBitBuffer::read_8bits()
429+
{
430+
// FAST_8
431+
if (!cb_left) {
432+
srs_assert(!stream->empty());
433+
return stream->read_1bytes();
434+
}
435+
436+
return read_bits(8);
437+
}
438+
439+
int16_t SrsBitBuffer::read_16bits()
440+
{
441+
// FAST_16
442+
if (!cb_left) {
443+
srs_assert(!stream->empty());
444+
return stream->read_2bytes();
445+
}
446+
447+
return read_bits(16);
448+
}
449+
450+
int32_t SrsBitBuffer::read_32bits()
451+
{
452+
// FAST_32
453+
if (!cb_left) {
454+
srs_assert(!stream->empty());
455+
return stream->read_4bytes();
456+
}
457+
458+
return read_bits(32);
459+
}
460+
461+
int32_t SrsBitBuffer::read_bits_ue()
462+
{
463+
int32_t r = 0;
464+
int i = 0;
465+
466+
while((read_bit() == 0) && (i < 32) && (left_bits() > 0) ) {
467+
i++;
468+
}
469+
470+
r = read_bits(i);
471+
r += (1 << i) - 1;
472+
473+
return r;
474+
}

trunk/src/kernel/srs_kernel_buffer.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ class SrsBitBuffer
174174
public:
175175
bool empty();
176176
int8_t read_bit();
177+
bool require_bits(int n);
178+
int left_bits();
179+
void skip_bits(int n);
180+
int32_t read_bits(int n);
181+
int8_t read_8bits();
182+
int16_t read_16bits();
183+
int32_t read_32bits();
184+
int32_t read_bits_ue();
177185
};
178186

179187
#endif

0 commit comments

Comments
 (0)