From a58c18696b19fe540ae99b4fb88b07ead8ca28a3 Mon Sep 17 00:00:00 2001 From: Kjos Date: Thu, 7 Nov 2019 15:52:26 +0100 Subject: [PATCH 1/4] Update VideoFileReader.h Null will be returned when stream has finished. However with BitmapData null was not passed through. Checking on framecounter alone can lead to issues, so Bitmap should be returned even when using BitmapData. --- .../Accord.Video.FFMPEG.GPL/VideoFileReader.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileReader.h b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileReader.h index c2c5ed4b4..8ea6a1f2a 100644 --- a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileReader.h +++ b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileReader.h @@ -2,13 +2,13 @@ // The Accord.NET Framework // http://accord-framework.net // -// Copyright © AForge.NET, 2009-2011 +// Copyright © AForge.NET, 2009-2011 // contacts@aforgenet.com // -// Copyright © MelvinGr, 2016-2017 +// Copyright © MelvinGr, 2016-2017 // https://github.com/MelvinGr // -// Copyright © César Souza, 2009-2017 +// Copyright © César Souza, 2009-2017 // cesarsouza at gmail.com // // This program is free software; you can redistribute it and/or modify @@ -381,9 +381,9 @@ namespace Accord { /// Thrown if no video file was open. /// A error occurred while reading next video frame. See exception message. /// - void ReadVideoFrame(BitmapData^ output) + Bitmap^ ReadVideoFrame(BitmapData^ output) { - readVideoFrame(-1, output, nullptr); + return readVideoFrame(-1, output, nullptr); } /// @@ -396,9 +396,9 @@ namespace Accord { /// Thrown if no video file was open. /// A error occurred while reading next video frame. See exception message. /// - void ReadVideoFrame(int frameIndex, BitmapData^ output) + Bitmap^ ReadVideoFrame(int frameIndex, BitmapData^ output) { - readVideoFrame(frameIndex, output, nullptr); + return readVideoFrame(frameIndex, output, nullptr); } @@ -443,9 +443,9 @@ namespace Accord { /// Thrown if no video file was open. /// A error occurred while reading next video frame. See exception message. /// - void ReadVideoFrame(BitmapData^ output, System::Collections::Generic::IList^ audio) + Bitmap^ ReadVideoFrame(BitmapData^ output, System::Collections::Generic::IList^ audio) { - readVideoFrame(-1, output, audio); + return readVideoFrame(-1, output, audio); } /// @@ -458,9 +458,9 @@ namespace Accord { /// Thrown if no video file was open. /// A error occurred while reading next video frame. See exception message. /// - void ReadVideoFrame(int frameIndex, BitmapData^ output, System::Collections::Generic::IList^ audio) + Bitmap^ ReadVideoFrame(int frameIndex, BitmapData^ output, System::Collections::Generic::IList^ audio) { - readVideoFrame(frameIndex, output, audio); + return readVideoFrame(frameIndex, output, audio); } From 0303a047d45b65860b9d7c4fafb43421f8b4f3d0 Mon Sep 17 00:00:00 2001 From: Kjos Date: Fri, 22 Nov 2019 13:33:32 +0100 Subject: [PATCH 2/4] Bugfix multi channels Signal Sample size was incorrect when Signal.channels was not 1. --- Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp index 3efc8a53f..92ddcc34a 100644 --- a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp +++ b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp @@ -593,7 +593,7 @@ namespace Accord { uint8_t* q = (uint8_t*)ost->tmp_frame->data[0]; int remainingNumberOfSamplesPerChannel = length; - size_t sampleSize = m_input_audio_sample_size; + size_t sampleSize = m_input_audio_sample_size * this->m_input_audio_channels; while (remainingNumberOfSamplesPerChannel > 0) { From dcf4424ed773c366d1831997f8d04f008a5dea1e Mon Sep 17 00:00:00 2001 From: Kjos Date: Fri, 22 Nov 2019 23:21:36 +0100 Subject: [PATCH 3/4] Remove got_packet check The got_packet checks fails consistently at start when encoding with the H264 encoder. When this happens, the same frame is encoded several times avcodec_encode_video2. This will result in duplicated frames at start of the output video, as well as the error message "non monotonic PTS" for the first couple of frames. Some more research might be required in how got_packet should be handled, however as I am experiencing myself, removing the check works better than leaving it (as the audio codec doesn't have this problem, audio and video will be unaligned) --- .../VideoFileWriter.cpp | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp index 92ddcc34a..3cd802f2a 100644 --- a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp +++ b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp @@ -372,16 +372,11 @@ namespace Accord { // encode the image CHECK(avcodec_encode_video2(c, &pkt, frame, &got_packet), "Error encoding video frame"); - if (got_packet) - { - pkt.duration = ost->next_pts - frame->pts; - pkt.pts = ost->frame->pts; - pkt.dts = ost->frame->pts; - CHECK(write_frame(oc, &c->time_base, ost->st, &pkt), "Error while writing video frame"); - return true; - } - - return false; + pkt.duration = ost->next_pts - frame->pts; + pkt.pts = ost->frame->pts; + pkt.dts = ost->frame->pts; + CHECK(write_frame(oc, &c->time_base, ost->st, &pkt), "Error while writing video frame"); + return true; } /// @@ -401,16 +396,11 @@ namespace Accord { // encode the signal CHECK(avcodec_encode_audio2(c, &pkt, frame, &got_packet), "Error encoding audio frame"); - if (got_packet) - { - pkt.duration = ost->next_pts - frame->pts; - pkt.pts = ost->frame->pts; - pkt.dts = ost->frame->pts; - CHECK(write_frame(oc, &c->time_base, ost->st, &pkt), "Error while writing audio frame"); - return true; - } - - return false; + pkt.duration = ost->next_pts - frame->pts; + pkt.pts = ost->frame->pts; + pkt.dts = ost->frame->pts; + CHECK(write_frame(oc, &c->time_base, ost->st, &pkt), "Error while writing audio frame"); + return true; } From 21e425f348bcbd192e4c8d1bf7a0e1fcb34f51d1 Mon Sep 17 00:00:00 2001 From: Kjos Date: Mon, 25 Nov 2019 11:52:45 +0100 Subject: [PATCH 4/4] Added flush Flushes successfully for H264 video. --- .../VideoFileWriter.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp index 3cd802f2a..c16d15b40 100644 --- a/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp +++ b/Sources/Extras/Accord.Video.FFMPEG.GPL/VideoFileWriter.cpp @@ -432,6 +432,27 @@ namespace Accord { void close() { + if (have_video) { + int got_output = 0; + int ret = 0; + + for (got_output = 1; got_output;) { + AVPacket pkt; + av_init_packet(&pkt); + + ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); + if (got_output) { + pkt.duration = 1; + pkt.pts = video_st.next_pts; + pkt.dts = pkt.pts; + + CHECK(write_frame(oc, &c->time_base, video_st.st, &pkt), "Error while writing video frame"); + av_free_packet(&pkt); + + video_st.next_pts++; + } + } + } // Write the trailer, if any. The trailer must be written before you // close the CodecContexts open when you wrote the header; otherwise // av_write_trailer() may try to use memory that was freed on