Use QUADRA instead of AV_HWDEVICE_TYPE_NI_QUADRA which is an enum. Implement non WallClockTimestamps for encoding

ni_quadra
Isaac Connor 2025-01-08 19:21:50 -05:00
parent 41ec9f7d96
commit a1f9be017b
1 changed files with 58 additions and 25 deletions

View File

@ -43,9 +43,11 @@ extern "C" {
VideoStore::CodecData VideoStore::codec_data[] = {
#if HAVE_LIBAVUTIL_HWCONTEXT_H && LIBAVCODEC_VERSION_CHECK(57, 107, 0, 107, 0)
#ifdef QUADRA
{ AV_CODEC_ID_H265, "h265", "h265_ni_quadra_enc", AV_PIX_FMT_YUV420P, AV_PIX_FMT_NI_QUAD, AV_HWDEVICE_TYPE_NI_QUADRA, "-1" },
{ AV_CODEC_ID_H264, "h264", "h264_ni_quadra_enc", AV_PIX_FMT_YUV420P, AV_PIX_FMT_NI_QUAD, AV_HWDEVICE_TYPE_NI_QUADRA, "-1" },
{ AV_CODEC_ID_AV1, "av1", "av1_ni_quadra_enc", AV_PIX_FMT_YUV420P, AV_PIX_FMT_NI_QUAD, AV_HWDEVICE_TYPE_NI_QUADRA, "-1" },
#endif
{ AV_CODEC_ID_H265, "h265", "hevc_vaapi", AV_PIX_FMT_NV12, AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI, nullptr },
{ AV_CODEC_ID_H265, "h265", "hevc_qsv", AV_PIX_FMT_YUV420P, AV_PIX_FMT_QSV, AV_HWDEVICE_TYPE_QSV, nullptr },
{ AV_CODEC_ID_H265, "h265", "hevc_nvenc", AV_PIX_FMT_NV12, AV_PIX_FMT_NV12, AV_HWDEVICE_TYPE_NONE, nullptr },
@ -472,7 +474,7 @@ bool VideoStore::open() {
} // end foreach codec
if (!video_out_codec) {
Error("Can't open video codec!");
Error("Can't open any video codecs!");
return false;
} // end if can't open codec
Debug(2, "Success opening codec");
@ -1160,22 +1162,11 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
chosen_codec_data->sw_pix_fmt,
video_out_ctx->width,
video_out_ctx->height
);
);
} else if (!zm_packet->in_frame) {
Debug(4, "Have no in_frame");
if (zm_packet->packet->size and !zm_packet->decoded) {
Debug(4, "Decoding");
if (!zm_packet->decode(video_in_ctx)) {
Debug(2, "unable to decode yet.");
return 0;
}
// Go straight to out frame
swscale.Convert(zm_packet->in_frame.get(), out_frame);
} else {
Error("Have neither in_frame or image in packet %d!",
zm_packet->image_index);
return 0;
} // end if has packet or image
Debug(1, "Have neither in_frame or image in packet %d!",
zm_packet->image_index);
return 0;
} else {
// Have in_frame.... may need to convert it to out_frame
swscale.Convert(zm_packet->in_frame.get(), zm_packet->out_frame.get());
@ -1208,18 +1199,19 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
} // end if hwaccel
#endif
if (video_first_pts == AV_NOPTS_VALUE) {
video_first_pts = static_cast<int64>(std::chrono::duration_cast<Microseconds>(zm_packet->timestamp.time_since_epoch()).count());
Debug(2, "No video_first_pts, set to (%" PRId64 ") secs(%.2f)",
if (monitor->WallClockTimestamps() or !(zm_packet->in_frame || zm_packet->packet)) {
if (video_first_pts == AV_NOPTS_VALUE) {
video_first_pts = static_cast<int64>(std::chrono::duration_cast<Microseconds>(zm_packet->timestamp.time_since_epoch()).count());
Debug(2, "No video_first_pts, set to (%" PRId64 ") secs(%.2f)",
video_first_pts,
FPSeconds(zm_packet->timestamp.time_since_epoch()).count());
frame->pts = 0;
} else {
Microseconds useconds = std::chrono::duration_cast<Microseconds>(
zm_packet->timestamp - SystemTimePoint(Microseconds(video_first_pts)));
frame->pts = av_rescale_q(useconds.count(), AV_TIME_BASE_Q, video_out_ctx->time_base);
Debug(2,
frame->pts = 0;
} else {
Microseconds useconds = std::chrono::duration_cast<Microseconds>(
zm_packet->timestamp - SystemTimePoint(Microseconds(video_first_pts)));
frame->pts = av_rescale_q(useconds.count(), AV_TIME_BASE_Q, video_out_ctx->time_base);
Debug(2,
"Setting pts for frame(%d) to (%" PRId64 ") from (zm_packet->timestamp(%" PRIi64 " - first %" PRId64 " us %" PRId64 " ) @ %d/%d",
frame_count,
frame->pts,
@ -1228,6 +1220,47 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
static_cast<int64>(std::chrono::duration_cast<Microseconds>(useconds).count()),
video_out_ctx->time_base.num,
video_out_ctx->time_base.den);
}
} else {
if (zm_packet->in_frame) {
if (video_first_pts == AV_NOPTS_VALUE) {
video_first_pts = zm_packet->in_frame->pts;
Debug(2, "No video_first_pts, set to (%" PRId64 ")", video_first_pts);
frame->pts = 0;
} else {
frame->pts = av_rescale_q(zm_packet->in_frame->pts - video_first_pts, zm_packet->in_frame->time_base, video_out_ctx->time_base);
Debug(2,
"Setting pts for frame(%d) to (%" PRId64 ") from (zm_packet->in_frame(%" PRIi64 " - first %" PRId64 " ) @ %d/%d=>%d/%d",
frame_count,
frame->pts,
zm_packet->in_frame->pts,
video_first_pts,
zm_packet->in_frame->time_base.num,
zm_packet->in_frame->time_base.den,
video_out_ctx->time_base.num,
video_out_ctx->time_base.den);
}
} else if (zm_packet->packet) {
if (video_first_pts == AV_NOPTS_VALUE) {
video_first_pts = zm_packet->packet->pts;
Debug(2, "No video_first_pts, set to (%" PRId64 ")", video_first_pts);
frame->pts = 0;
} else {
frame->pts = av_rescale_q(zm_packet->packet->pts-video_first_pts, video_in_stream->time_base, video_out_ctx->time_base);
Debug(2,
"Setting pts for frame(%d) to (%" PRId64 ") from (zm_packet->in_frame(%" PRIi64 " - first %" PRId64 " ) @ %d/%d=>%d/%d",
frame_count,
frame->pts,
zm_packet->packet->pts,
video_first_pts,
video_in_stream->time_base.num,
video_in_stream->time_base.den,
video_out_ctx->time_base.num,
video_out_ctx->time_base.den);
}
} else {
Error("No pts from any source.");
}
}
// Some hwaccel codecs may get full if we only receive one pkt for one frame