From 20b38d0fd5fabdb986f6e16824aaf4782c224c3c Mon Sep 17 00:00:00 2001 From: lgomez Date: Thu, 5 Dec 2024 20:09:12 -0600 Subject: [PATCH] -Play video over rtp. WIP. --- .../com/video/VideoDataLink.java | 93 ++++++++++++++++--- 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/windhoverlabs/com/video/VideoDataLink.java b/src/main/java/com/windhoverlabs/com/video/VideoDataLink.java index bf0e903..1f906f3 100644 --- a/src/main/java/com/windhoverlabs/com/video/VideoDataLink.java +++ b/src/main/java/com/windhoverlabs/com/video/VideoDataLink.java @@ -66,7 +66,8 @@ public void init(String instance, String name, YConfiguration config) public void doStart() { if (!isDisabled()) { try { - readVideo(); +// readVideo(); + streamVideoOverRTP(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -96,13 +97,20 @@ public void doStop() { private void streamVideoOverRTP() throws IOException { System.out.println("Starting video streaming over RTP..."); + + av_log_set_level(AV_LOG_DEBUG); + +// av_log_set_callback(); + + avformat_network_init(); +// avdevice_register_all(); int ret, v_stream_idx = -1; String inputFile = "/home/lgomez/Downloads/217115_small.mp4"; + inputFile = "/home/lgomez/Downloads/vecteezy_vancouver-canada-september-16-2023-flight-by-fpv-drone_37202565.mp4"; String outputURL = "rtp://127.0.0.1:5005"; AVFormatContext inputCtx = avformat_alloc_context(); - // AVFormatContext outputCtx = new AVFormatContext(null); AVFormatContext outputCtx = avformat_alloc_context(); @@ -140,6 +148,8 @@ private void streamVideoOverRTP() throws IOException { System.out.println("Allocating codec context..."); AVCodecContext decoderCtx = avcodec_alloc_context3(codec); + + avcodec_parameters_to_context(decoderCtx, inputStream.codecpar()); avcodec_open2(decoderCtx, codec, (PointerPointer) null); @@ -152,38 +162,91 @@ private void streamVideoOverRTP() throws IOException { if (avformat_alloc_output_context2(outputCtx, null, "rtp", outputURL) < 0) { throw new IOException("Failed to create RTP output context"); } + + AVStream outputStream = avformat_new_stream(outputCtx, codec); if (outputStream == null) { throw new IOException("Failed to create output stream"); } + + AVRational q = new AVRational(); + + q.num(1); + q.den(30); System.out.println("Configuring encoder..."); AVCodecContext encoderCtx = avcodec_alloc_context3(codec); System.out.println("Configuring encoder2..."); + System.out.println("codec.id()-->" + codec.id()); + System.out.println("codec.id()-->" + decoderCtx.width()); + System.out.println("codec.id()-->" + decoderCtx.height()); + System.out.println("inputStream.time_num()-->" + inputStream.time_base().num()); + System.out.println("inputStream.time_den()-->" + inputStream.time_base().den()); + System.out.println("av_inv_q(inputStream.time_base())-->" + av_inv_q(inputStream.time_base())); + + + +// Context->width = Config->Width; +// Context->height = Config->Height; +// Context->time_base = (AVRational){1, (int)Config->FramesPerSecond}; +// Context->pix_fmt = Config->PixelFormat; +// Context->framerate = (AVRational){(int)Config->FramesPerSecond, 1}; +// Context->bit_rate = Config->BitRate; +// Context->gop_size = Config->GopSize; +// Context->max_b_frames = Config->MaxBFrames; +// Context->gop_size = Config->GopSize; +// Context->flags |= Config->Flags; + encoderCtx.codec_id(codec.id()); System.out.println("Configuring encoder3..."); encoderCtx.codec_type(AVMEDIA_TYPE_VIDEO); encoderCtx.pix_fmt(AV_PIX_FMT_YUV420P); System.out.println("Configuring encoder4..."); - encoderCtx.width(decoderCtx.width()); - encoderCtx.height(decoderCtx.height()); +// encoderCtx.width(decoderCtx.width()); +// encoderCtx.height(decoderCtx.height()); +// + encoderCtx.width(640); + encoderCtx.height(480); System.out.println("Configuring encoder5..."); - encoderCtx.time_base(av_inv_q(inputStream.time_base())); +// encoderCtx.time_base(av_inv_q(inputStream.time_base())); + encoderCtx.time_base(q); + AVRational fr = new AVRational(); + + fr.den(1); + fr.num(30); + encoderCtx.framerate(q); System.out.println("Configuring encoder6..."); encoderCtx.bit_rate(400000); + encoderCtx.gop_size(30); + encoderCtx.max_b_frames(0); // if (avcodec_open2(encoderCtx, codec, (PointerPointer) null) < 0) { // throw new IOException("Failed to open encoder"); // } +// if (avcodec_open2(encoderCtx, codec, new PointerPointer()) < 0) { +// throw new IOException("Failed to open encoder"); +// } + + + AVBufferRef HWAccelDeviceContext = new AVBufferRef(null); + int avRC = av_hwdevice_ctx_create( + HWAccelDeviceContext, + AV_HWDEVICE_TYPE_CUDA, + "", + new AVDictionary(null), + 0); + + + avcodec_parameters_from_context(outputStream.codecpar(), encoderCtx); if (avcodec_open2(encoderCtx, codec, new PointerPointer()) < 0) { - throw new IOException("Failed to open encoder"); - } + throw new IOException("Failed to open encoder"); + } System.out.println("Configuring encoder7..."); - avcodec_parameters_from_context(outputStream.codecpar(), encoderCtx); + System.out.println("Configuring encoder8..."); // if (avio_open2(outputCtx.pb(), outputURL, AVIO_FLAG_WRITE, null, null) < 0) { @@ -195,9 +258,15 @@ private void streamVideoOverRTP() throws IOException { AVIOContext pb = new AVIOContext(null); - if (avio_open(pb, outputURL, AVIO_FLAG_WRITE) < 0) { - throw new IOException("Failed to open RTP output"); - } +// if (avio_open(pb, outputURL, AVIO_FLAG_WRITE) < 0) { +// throw new IOException("Failed to open RTP output"); +// } + AVDictionary options = new AVDictionary(null); + if (avio_open2(pb, outputURL, AVIO_FLAG_WRITE, null, options) < 0) { + throw new IOException("Failed to open RTP output"); + } + +// avio_open2(pb, filename, AVIO_FLAG_WRITE, null, options) outputCtx.pb(pb); @@ -205,7 +274,7 @@ private void streamVideoOverRTP() throws IOException { // avformat_write_header(outputCtx, new AVDictionary()); - avformat_write_header(outputCtx, new PointerPointer()); + avformat_write_header(outputCtx, new AVDictionary(null)); System.out.println("RTP streaming setup complete, starting frame processing...");