feat(rtsp-source): packet ring publishing (v0.2 Step 4)
- cuframes::Publisher (C++ wrapper): добавлены enable_packets(), set_codec_extradata(), publish_packet() методы. - cuframes-rtsp-source: новый CLI flag --enable-packet-ring. При его установке после opening stream — pub.enable_packets(codec_id) + set_codec_extradata из vstream->codecpar->extradata. - В main loop: после av_read_frame, до avcodec_send_packet, packet публикуется в packet ring с конверсией pts/dts из stream_tb в ns, AV_PKT_FLAG_KEY/CORRUPT/DISCONTINUITY → CUFRAMES_PKT_FLAG_*. Тест: cuframes-rtsp-source --rtsp rtsp://... --key cam1 --enable-packet-ring # frames consumer'ы продолжают работать через cuframes:// (как v0.1) # record consumer'ы могут brать packets через cuframes_packets:// (Step 5) Связано: #2, PR #4.
This commit is contained in:
@@ -60,6 +60,7 @@ struct Args {
|
||||
bool verbose = false;
|
||||
bool realtime = false; // emulate -re у ffmpeg CLI: sleep по pts
|
||||
bool loop = false; // loop input на eof (для file://)
|
||||
bool enable_packet_ring = false; // v0.2 — публиковать encoded packets
|
||||
};
|
||||
|
||||
static void print_usage() {
|
||||
@@ -75,6 +76,8 @@ static void print_usage() {
|
||||
" --ring N cuframes ring size (default 4, range 2..16)\n"
|
||||
" --realtime pace input по PTS (как ffmpeg -re; полезно для файла)\n"
|
||||
" --loop loop input на EOF (только для file://)\n"
|
||||
" --enable-packet-ring v0.2: дополнительно публиковать encoded packets\n"
|
||||
" (для consumer'ов с -c:v copy, Frigate record path)\n"
|
||||
" --verbose debug logs\n"
|
||||
" -h, --help this help\n";
|
||||
}
|
||||
@@ -92,6 +95,7 @@ static int parse_args(int argc, char **argv, Args &a) {
|
||||
else if (s == "--ring") a.ring_size = std::stoi(next());
|
||||
else if (s == "--realtime") a.realtime = true;
|
||||
else if (s == "--loop") a.loop = true;
|
||||
else if (s == "--enable-packet-ring") a.enable_packet_ring = true;
|
||||
else if (s == "--verbose") a.verbose = true;
|
||||
else if (s == "-h" || s == "--help") { print_usage(); std::exit(0); }
|
||||
else { std::cerr << "Unknown arg: " << s << "\n"; print_usage(); std::exit(1); }
|
||||
@@ -235,6 +239,27 @@ int main(int argc, char **argv) {
|
||||
<< "' ready, ring=" << a.ring_size
|
||||
<< " pool_size=" << frame_size << " bytes/frame\n";
|
||||
|
||||
/* v0.2 — encoded packet ring (опционально). */
|
||||
if (a.enable_packet_ring) {
|
||||
cuframes_packet_ring_options_t pkt_opts{};
|
||||
pkt_opts.codec_id = (uint32_t)vstream->codecpar->codec_id;
|
||||
/* остальные поля = 0 → library использует defaults (64 slots, 8MiB, 2MiB max) */
|
||||
pub.enable_packets(&pkt_opts);
|
||||
|
||||
if (vstream->codecpar->extradata_size > 0 && vstream->codecpar->extradata) {
|
||||
pub.set_codec_extradata(vstream->codecpar->extradata,
|
||||
(size_t)vstream->codecpar->extradata_size);
|
||||
std::cerr << "[cuframes-src] packet ring active, codec_id="
|
||||
<< vstream->codecpar->codec_id
|
||||
<< " extradata=" << vstream->codecpar->extradata_size
|
||||
<< " bytes\n";
|
||||
} else {
|
||||
std::cerr << "[cuframes-src] packet ring active, codec_id="
|
||||
<< vstream->codecpar->codec_id
|
||||
<< " (no extradata in stream — will rely on in-band SPS/PPS)\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Stream для D2D copies */
|
||||
cudaStream_t stream;
|
||||
cudaStreamCreate(&stream);
|
||||
@@ -279,6 +304,29 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* v0.2 — публикуем encoded packet в packet ring ДО decoder. Это позволяет
|
||||
* record-consumer'ам брать packet без второго RTSP-подключения к камере. */
|
||||
if (a.enable_packet_ring) {
|
||||
int64_t pkt_pts_ns = (pkt->pts != AV_NOPTS_VALUE)
|
||||
? av_rescale_q(pkt->pts, stream_tb, AVRational{1, 1000000000})
|
||||
: cuframes::now_ns();
|
||||
int64_t pkt_dts_ns = (pkt->dts != AV_NOPTS_VALUE)
|
||||
? av_rescale_q(pkt->dts, stream_tb, AVRational{1, 1000000000})
|
||||
: pkt_pts_ns;
|
||||
uint32_t pkt_flags = 0;
|
||||
if (pkt->flags & AV_PKT_FLAG_KEY) pkt_flags |= CUFRAMES_PKT_FLAG_KEY;
|
||||
if (pkt->flags & AV_PKT_FLAG_CORRUPT) pkt_flags |= CUFRAMES_PKT_FLAG_CORRUPT;
|
||||
#ifdef AV_PKT_FLAG_DISCONTINUITY
|
||||
if (pkt->flags & AV_PKT_FLAG_DISCONTINUITY) pkt_flags |= CUFRAMES_PKT_FLAG_DISCONTINUITY;
|
||||
#endif
|
||||
int prr = pub.publish_packet(pkt->data, (size_t)pkt->size,
|
||||
pkt_pts_ns, pkt_dts_ns, pkt_flags);
|
||||
if (prr != CUFRAMES_OK && a.verbose) {
|
||||
std::cerr << "[cuframes-src] publish_packet rc=" << prr
|
||||
<< " size=" << pkt->size << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
r = avcodec_send_packet(ctx, pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (r < 0) continue;
|
||||
|
||||
Reference in New Issue
Block a user