Skip to content

Commit

Permalink
Handle error conditions such as no ndi device found. cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
glenne committed May 23, 2024
1 parent a69b0bf commit 993c610
Show file tree
Hide file tree
Showing 23 changed files with 412 additions and 212 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ npm-debug.log.*
*.scss.d.ts
*.mp4
query.json
log.txt
6 changes: 6 additions & 0 deletions native/recorder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ option(USE_FFMPEG "Use OpenCV features" ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(${TARGET_NAME} PRIVATE /W4)
endif()

message(STATUS "${CMAKE_PREFIX_PATH}")
message(STATUS "updated:${CMAKE_PREFIX_PATH}")

Expand Down
15 changes: 7 additions & 8 deletions native/recorder/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { HandlerResponse } from '../../src/renderer/msgbus/MsgbusTypes';
import { RecorderMessage } from '../../src/renderer/recorder/RecorderTypes';
import {
RecorderMessageResponseType,
RecorderMessageTypes,
} from '../../src/renderer/recorder/RecorderTypes';

/**
* This module provides native C++ functionality as a Node.js addon,
Expand All @@ -8,12 +10,8 @@ import { RecorderMessage } from '../../src/renderer/recorder/RecorderTypes';
*/
declare module 'crewtimer_video_recorder' {
export function nativeVideoRecorder(
message: RecorderMessage,
): HandlerResponse;

export function nativeVideoRecorder(
message: RecorderMessage,
): HandlerResponse;
message: RecorderMessageTypes,
): RecorderMessageResponseType;

type CallbackFunc = ({
sender,
Expand All @@ -23,4 +21,5 @@ declare module 'crewtimer_video_recorder' {
content: { [key: string]: any };
}) => void;
export function setNativeMessageCallback(func: CallbackFunc): void;
export function shutdownRecorder(): void;
}
3 changes: 2 additions & 1 deletion native/recorder/src/BaslerReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class BaslerReader : public VideoReader, public CImageEventHandler {
public:
BaslerReader() { formatConverter.OutputPixelFormat = PixelType_BGR8packed; }
virtual std::string
open(std::shared_ptr<FrameProcessor> frameProcessor) override {
start(std::string srcName,
std::shared_ptr<FrameProcessor> frameProcessor) override {
std::string ret = "";
PylonInitialize();

Expand Down
84 changes: 52 additions & 32 deletions native/recorder/src/FFRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ extern "C" {

class FFVideoRecorder : public VideoRecorder {
int frame_index;
AVFrame *pFrame;
AVPacket *pkt;
struct SwsContext *sws_ctx;
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVStream *video_st;
AVFrame *pFrame = nullptr;
AVPacket *pkt = nullptr;
struct SwsContext *sws_ctx = nullptr;
AVFormatContext *pFormatCtx = nullptr;
AVCodecContext *pCodecCtx = nullptr;
AVStream *video_st = nullptr;
std::string outputFile;
std::string tmpFile;
std::string codecName;
Expand Down Expand Up @@ -264,32 +264,33 @@ class FFVideoRecorder : public VideoRecorder {
}

std::string stop() {
if (video_st == nullptr) {
return "";
}
// Flush the encoder
if (avcodec_send_frame(pCodecCtx, NULL) < 0) {
auto msg = "Error sending a frame for encoding";
std::cerr << msg << std::endl;
return msg;
std::string retval = "";
if (pCodecCtx) {
// Flush the encoder
if (avcodec_send_frame(pCodecCtx, NULL) < 0) {
auto msg = "Error sending a frame for encoding";
std::cerr << msg << std::endl;
retval = msg;
}
}

// If pkt is null, it is uninitialized so we haven't read anything yet.
if (pkt) {

while (1) {
int ret = avcodec_receive_packet(pCodecCtx, pkt);
if (ret == AVERROR_EOF)
break;
else if (ret < 0) {
auto msg = "Error during encoding";
std::cerr << msg << std::endl;
return msg;
retval = msg;
break;
}
if (av_interleaved_write_frame(pFormatCtx, pkt) < 0) {
auto msg = "Error while writing video frame.";
std::cerr << msg << std::endl;
return msg;
retval = msg;
break;
}
av_packet_unref(pkt);
}
Expand All @@ -301,24 +302,43 @@ class FFVideoRecorder : public VideoRecorder {
}
}

avcodec_free_context(&pCodecCtx);
avformat_free_context(pFormatCtx);
av_frame_free(&pFrame);
av_packet_free(&pkt);
sws_freeContext(sws_ctx);
if (pCodecCtx) {
avcodec_free_context(&pCodecCtx);
}
if (pFormatCtx) {
avformat_free_context(pFormatCtx);
}
if (pFrame) {
av_frame_free(&pFrame);
}
if (pkt) {
av_packet_free(&pkt);
}
if (sws_ctx) {
sws_freeContext(sws_ctx);
}

pCodecCtx = nullptr;
pFormatCtx = nullptr;
pFrame = nullptr;
pkt = nullptr;
sws_ctx = nullptr;
video_st = nullptr;

// Attempt to rename the file
if (std::rename(tmpFile.c_str(), outputFile.c_str()) == 0) {
// std::cout << "File successfully renamed from " << tmpFile << " to "
// << outputFile << std::endl;
} else {
// If renaming failed, print an error message
auto msg = "Error renaming file";
std::cerr << msg << std::endl;
return msg;
if (tmpFile.length() > 0) {
// Attempt to rename the file
if (std::rename(tmpFile.c_str(), outputFile.c_str()) == 0) {
// std::cout << "File successfully renamed from " << tmpFile << " to "
// << outputFile << std::endl;
} else {
// If renaming failed, print an error message
auto msg = "Error renaming file";
std::cerr << msg << std::endl;
retval = msg;
}
tmpFile = "";
}
return "";
return retval;
}
~FFVideoRecorder() {}
};
Expand Down
9 changes: 2 additions & 7 deletions native/recorder/src/FrameProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,8 @@ void FrameProcessor::stop() {
frameQueue.pop();
}

if (videoRecorder) {
videoRecorder->stop();
}
videoRecorder = nullptr;
lastFrame = nullptr;
videoRecorder = nullptr;
}

/**
Expand All @@ -50,10 +47,10 @@ FrameProcessor::StatusInfo FrameProcessor::getStatus() {

void FrameProcessor::addFrame(FramePtr video_frame) {
std::unique_lock<std::mutex> lock(queueMutex);
lastFrame = video_frame;
if (!running) {
return;
}
lastFrame = video_frame;
frameQueue.push(video_frame);
frameAvailable.notify_one();
}
Expand All @@ -65,7 +62,6 @@ FramePtr FrameProcessor::getLastFrame() {

void FrameProcessor::processFrames() {
SystemEventQueue::push("fproc", "Starting frame processor");
int64_t lastTS = 0;
int64_t frameCount = 0;
int count = 0;
auto start = high_resolution_clock::now();
Expand Down Expand Up @@ -147,7 +143,6 @@ void FrameProcessor::processFrames() {
frameCount = 0;
}

lastTS = video_frame->timestamp;
auto err = videoRecorder->writeVideoFrame(video_frame);
if (!err.empty()) {
errorMessage = err;
Expand Down
Loading

0 comments on commit 993c610

Please sign in to comment.