update hikvision camera

This commit is contained in:
linbo 2026-07-23 10:40:58 +08:00
parent b585cb6601
commit f8961c4e7a
2 changed files with 48 additions and 3 deletions

View File

@ -1,6 +1,7 @@
#ifndef CMVR_ES_HIKVISION_CAMERA_H #ifndef CMVR_ES_HIKVISION_CAMERA_H
#define CMVR_ES_HIKVISION_CAMERA_H #define CMVR_ES_HIKVISION_CAMERA_H
#include <atomic>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -49,6 +50,7 @@ private:
bool login_(); bool login_();
bool startPreview_(); bool startPreview_();
void stopPreview_(); void stopPreview_();
bool requestKeyFrame_();
void stopRecordingUnlocked_(); void stopRecordingUnlocked_();
void fillIntrinsics_(Rs2Intrinsics& intrinsics) const; void fillIntrinsics_(Rs2Intrinsics& intrinsics) const;
void setError_(const std::string& message); void setError_(const std::string& message);
@ -87,6 +89,7 @@ private:
std::mutex stream_mtx_; std::mutex stream_mtx_;
std::vector<uint8_t> es_stream_header_; std::vector<uint8_t> es_stream_header_;
bool has_es_stream_header_ = false; bool has_es_stream_header_ = false;
std::atomic<bool> awaiting_key_frame_{false};
int stream_count_ = 0; int stream_count_ = 0;
}; };

View File

@ -334,6 +334,7 @@ bool HikvisionCamera::stop()
stopRecordingUnlocked_(); stopRecordingUnlocked_();
} }
state_.is_streaming = false; state_.is_streaming = false;
awaiting_key_frame_.store(false, std::memory_order_release);
stream_count_ = 0; stream_count_ = 0;
resetStreamState_(); resetStreamState_();
stopPreview_(); stopPreview_();
@ -462,12 +463,19 @@ bool HikvisionCamera::startStreaming()
return false; return false;
} }
if (stream_count_ == 0 && stream_frame_buffer_) { const bool first_stream = stream_count_ == 0;
if (first_stream) {
if (stream_frame_buffer_) {
stream_frame_buffer_->clear(); stream_frame_buffer_->clear();
} }
awaiting_key_frame_.store(true, std::memory_order_release);
}
state_.is_streaming = true; state_.is_streaming = true;
++stream_count_; ++stream_count_;
if (first_stream && !requestKeyFrame_()) {
awaiting_key_frame_.store(false, std::memory_order_release);
}
return true; return true;
} }
@ -479,6 +487,7 @@ void HikvisionCamera::stopStreaming()
} }
if (stream_count_ == 0) { if (stream_count_ == 0) {
state_.is_streaming = false; state_.is_streaming = false;
awaiting_key_frame_.store(false, std::memory_order_release);
} }
} }
@ -508,6 +517,30 @@ bool HikvisionCamera::controlPtz(PtzCommand command, bool stop, int speed)
return true; return true;
} }
bool HikvisionCamera::requestKeyFrame_()
{
if (user_id_ < 0) {
CMVR_LOG(WARNING) << "[HikvisionCamera] skip key frame request: camera not logged in";
return false;
}
const bool is_sub_stream = stream_type_ == 1;
const BOOL success = is_sub_stream
? NET_DVR_MakeKeyFrameSub(user_id_, channel_)
: NET_DVR_MakeKeyFrame(user_id_, channel_);
if (!success) {
CMVR_LOG(WARNING) << "[HikvisionCamera] "
<< (is_sub_stream ? "NET_DVR_MakeKeyFrameSub" : "NET_DVR_MakeKeyFrame")
<< " failed, error_code=" << NET_DVR_GetLastError();
return false;
}
CMVR_LOG(INFO) << "[HikvisionCamera] requested key frame"
<< ", channel=" << channel_
<< ", stream_type=" << stream_type_;
return true;
}
bool HikvisionCamera::executeJsonCommand(const std::string& request_json, std::string& response_json) bool HikvisionCamera::executeJsonCommand(const std::string& request_json, std::string& response_json)
{ {
Json::Value root; Json::Value root;
@ -605,9 +638,18 @@ void HikvisionCamera::onEsData(
return; return;
} }
const bool is_key_frame = packet_type == kHikvisionPacketVideoIFrame;
if (awaiting_key_frame_.load(std::memory_order_acquire)) {
if (!is_key_frame) {
return;
}
awaiting_key_frame_.store(false, std::memory_order_release);
CMVR_LOG(INFO) << "[HikvisionCamera] received first key frame after stream start";
}
pushEncodedFrame_(buffer, pushEncodedFrame_(buffer,
buffer_size, buffer_size,
packet_type == kHikvisionPacketVideoIFrame, is_key_frame,
packet_width, packet_width,
packet_height); packet_height);
} }