diff --git a/cmvr-es/devices/camera/common/include/camera_stream_encoder.h b/cmvr-es/devices/camera/common/include/camera_stream_encoder.h index 15c4ffa8..32390ddb 100644 --- a/cmvr-es/devices/camera/common/include/camera_stream_encoder.h +++ b/cmvr-es/devices/camera/common/include/camera_stream_encoder.h @@ -47,7 +47,8 @@ public: static bool encode(std::shared_ptr& encoder, const AVFrame* frame, std::vector& encoded_frame, - bool& is_key); + bool& is_key, + const CameraStreamEncodeOptions& options = {}); }; } // namespace cmvr::device diff --git a/cmvr-es/devices/camera/common/src/camera_stream_encoder.cpp b/cmvr-es/devices/camera/common/src/camera_stream_encoder.cpp index 700dc9d4..f9ef2f76 100644 --- a/cmvr-es/devices/camera/common/src/camera_stream_encoder.cpp +++ b/cmvr-es/devices/camera/common/src/camera_stream_encoder.cpp @@ -337,7 +337,8 @@ bool CameraStreamEncoder::encode(std::shared_ptr& encoder, bool CameraStreamEncoder::encode(std::shared_ptr& encoder, const AVFrame* frame, std::vector& encoded_frame, - bool& is_key) + bool& is_key, + const CameraStreamEncodeOptions& options) { encoded_frame.clear(); is_key = false; @@ -426,6 +427,28 @@ bool CameraStreamEncoder::encode(std::shared_ptr& encoder, return false; } + if (options.draw_timestamp) { + const auto output_format = static_cast(encoder->frame->format); + if (output_format != AV_PIX_FMT_NV12 && output_format != AV_PIX_FMT_YUV420P) { + const char* format_name = av_get_pix_fmt_name(output_format); + CMVR_LOG(ERROR) << "[CameraStreamEncoder] cannot draw timestamp on pixel format " + << (format_name ? format_name : "unknown"); + return false; + } + if (!encoder->frame->data[0] + || encoder->frame->linesize[0] < encoder->frame->width) { + CMVR_LOG(ERROR) << "[CameraStreamEncoder] invalid luma plane for timestamp"; + return false; + } + cv::Mat luma_plane( + encoder->frame->height, + encoder->frame->width, + CV_8UC1, + encoder->frame->data[0], + static_cast(encoder->frame->linesize[0])); + drawTimeStamp(luma_plane); + } + return encodePreparedFrame(*encoder, encoded_frame, is_key); } diff --git a/cmvr-es/devices/camera/uvc_camera/src/uvc_camera.cpp b/cmvr-es/devices/camera/uvc_camera/src/uvc_camera.cpp index 75b2d1ca..2105d234 100644 --- a/cmvr-es/devices/camera/uvc_camera/src/uvc_camera.cpp +++ b/cmvr-es/devices/camera/uvc_camera/src/uvc_camera.cpp @@ -1055,33 +1055,15 @@ void UVCCamera::streaming_worker_() { // 以下为编码部分,用于流模式 StreamFrameData frame_data; // 保存图像数据 - cv::Mat bgr_to_encode; const auto copy_end_time = std::chrono::steady_clock::now(); // rgb图像编码 - if (enable_stream_timestamp_) { - success = convert_capture_frame_to_bgr_(frame, bgr_to_encode); - if (success && encode_width_ > 0 && encode_height_ > 0 && - (bgr_to_encode.cols != encode_width_ || bgr_to_encode.rows != encode_height_)) { - cv::resize(bgr_to_encode, - bgr_to_encode, - cv::Size(encode_width_, encode_height_), - 0.0, - 0.0, - cv::INTER_LINEAR); - } - } const auto resize_end_time = std::chrono::steady_clock::now(); - if (enable_stream_timestamp_) { - CameraStreamEncodeOptions encode_options; - encode_options.draw_timestamp = true; - success = success && CameraStreamEncoder::encode( - rgbEncoder_, bgr_to_encode, frame_data.rgbFrame, frame_data.bKey, encode_options); - } else { - success = CameraStreamEncoder::encode( - rgbEncoder_, frame, frame_data.rgbFrame, frame_data.bKey); - } + CameraStreamEncodeOptions encode_options; + encode_options.draw_timestamp = enable_stream_timestamp_; + success = CameraStreamEncoder::encode( + rgbEncoder_, frame, frame_data.rgbFrame, frame_data.bKey, encode_options); const auto encode_end_time = std::chrono::steady_clock::now(); if (success) {