From 9c70041f377ea46b3825455b9e277fe26175d2a7 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Tue, 14 May 2024 11:40:31 +0530 Subject: [PATCH 01/13] added sample example to create thumbnail from mp4 video --- base/CMakeLists.txt | 2 + samples/CMakeLists.txt | 10 ++ .../CMakeLists.txt | 52 ++++++++++ .../GenerateThumbnailsPipeline.h | 15 +++ .../generate_thumbnail_from_mp4_video.cpp | 94 +++++++++++++++++++ ...test_generate_thumbnail_from_mp4_video.cpp | 18 ++++ 6 files changed, 191 insertions(+) create mode 100644 samples/CMakeLists.txt create mode 100644 samples/create_thumbnail_from_mp4_video/CMakeLists.txt create mode 100644 samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h create mode 100644 samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp create mode 100644 samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index 9f2cd1470..ba5a36776 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -588,6 +588,8 @@ ENDIF (ENABLE_CUDA) find_library(OPENH264_LIB NAMES openh264.lib libopenh264.a REQUIRED) find_library(LIBMP4_LIB NAMES mp4lib.lib libmp4lib.a REQUIRED) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../samples ${CMAKE_CURRENT_BINARY_DIR}/samples) + target_link_libraries(aprapipesut aprapipes ${JPEG_LIBRARIES} diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt new file mode 100644 index 000000000..56e4855e6 --- /dev/null +++ b/samples/CMakeLists.txt @@ -0,0 +1,10 @@ +#dependencies + +find_package(Threads REQUIRED) + +include_directories( +../base +${CMAKE_CURRENT_SOURCE_DIR} +) + +add_subdirectory(create_thumbnail_from_mp4_video) \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt new file mode 100644 index 000000000..f30f87f9f --- /dev/null +++ b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt @@ -0,0 +1,52 @@ +set(TARGET create_thumbnail_from_mp4_video) +SET(CORE_FILES + generate_thumbnail_from_mp4_video.cpp +) +SET(CORE_FILES_H + GenerateThumbnailsPipeline.h +) +SET(SOURCE + ${CORE_FILES} + ${CORE_FILES_H} +) +set(UT_FILE + test_generate_thumbnail_from_mp4_video.cpp +) +add_library(example_aprapipes STATIC ${SOURCE}) +add_executable(${TARGET} ${UT_FILE}) +target_include_directories ( example_aprapipes PRIVATE + ${JETSON_MULTIMEDIA_LIB_INCLUDE} + ${FFMPEG_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBMP4_INC_DIR} + ${BARESIP_INC_DIR} + ${LIBRE_INC_DIR} + ${NVCODEC_INCLUDE_DIR} +) +target_include_directories ( ${TARGET} PUBLIC + ${JETSON_MULTIMEDIA_LIB_INCLUDE} + ${FFMPEG_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBMP4_INC_DIR} + ${BARESIP_INC_DIR} + ${LIBRE_INC_DIR} + ${NVCODEC_INCLUDE_DIR} +) +target_link_libraries( + ${TARGET} + aprapipes + ${JPEG_LIBRARIES} + ${LIBMP4_LIB} + ${OPENH264_LIB} + ${Boost_LIBRARIES} + ${FFMPEG_LIBRARIES} + ${OpenCV_LIBRARIES} + ${JETSON_LIBS} + ${NVCUDAToolkit_LIBS} + ${NVCODEC_LIB} + ${NVJPEGLIB_L4T} + ${CURSES_LIBRARIES} + example_aprapipes + ) \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h new file mode 100644 index 000000000..dbf4a6fe8 --- /dev/null +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h @@ -0,0 +1,15 @@ +#include +#include + +class GenerateThumbnailsPipeline +{ +public: + GenerateThumbnailsPipeline(); + bool setUpPipeLine(); + bool startPipeLine(); + bool stopPipeLine(); + +private: + PipeLine pipeLine; + boost::shared_ptr valve; +}; \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp new file mode 100644 index 000000000..f280cf81c --- /dev/null +++ b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp @@ -0,0 +1,94 @@ + +#include "GenerateThumbnailsPipeline.h" +#include "FrameMetadata.h" +#include "H264Metadata.h" +#include "Mp4ReaderSource.h" +#include "Mp4VideoMetadata.h" +#include "H264Decoder.h" +#include "ValveModule.h" +#include "ColorConversionXForm.h" +#include "CudaMemCopy.h" +#include "FileWriterModule.h" +#include "JPEGEncoderNVJPEG.h" + +GenerateThumbnailsPipeline::GenerateThumbnailsPipeline() : pipeLine("pipeline") { + +} +bool GenerateThumbnailsPipeline::setUpPipeLine() { + // Implementation + std::string videoPath = "../.././data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; + std::string outPath = "../.././data/mp4Reader_saveOrCompare/h264/frame_000???.jpg"; + + bool parseFS = false; + auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); + auto frameType = FrameMetadata::FrameType::H264_DATA; + auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, false, false); + auto mp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); + mp4Reader->addOutPutPin(h264ImageMetadata); + + auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); + mp4Reader->addOutPutPin(mp4Metadata); + + std::vector mImagePin; + mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + + auto decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + mp4Reader->setNext(decoder, mImagePin); + + valve = boost::shared_ptr(new ValveModule(ValveModuleProps(2))); + decoder->setNext(valve); + + auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; + auto metadata = framemetadata_sp(new RawImagePlanarMetadata(1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); + auto colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); + valve->setNext(colorchange); + + auto stream = cudastream_sp(new ApraCudaStream); + auto copy = boost::shared_ptr(new CudaMemCopy(CudaMemCopyProps(cudaMemcpyHostToDevice, stream))); + colorchange->setNext(copy); + + auto m2 = boost::shared_ptr(new JPEGEncoderNVJPEG(JPEGEncoderNVJPEGProps(stream))); + copy->setNext(m2); + + /*auto valve = boost::shared_ptr(new ValveModule(ValveModuleProps(10))); + m2->setNext(valve);*/ + + auto fileWriter = boost::shared_ptr(new FileWriterModule(FileWriterModuleProps(outPath))); + m2->setNext(fileWriter); + + pipeLine.appendModule(mp4Reader); + pipeLine.init(); + return true; +} + +bool GenerateThumbnailsPipeline::startPipeLine() { + pipeLine.run_all_threaded(); + valve->allowFrames(1); + return true; +} + +bool GenerateThumbnailsPipeline::stopPipeLine() { + pipeLine.stop(); + pipeLine.term(); + pipeLine.wait_for_all(); + return true; +} +int main() { + GenerateThumbnailsPipeline pipelineInstance; + if (!pipelineInstance.setUpPipeLine()) { + std::cerr << "Failed to setup pipeline." << std::endl; + return 1; + } + if (!pipelineInstance.startPipeLine()) { + std::cerr << "Failed to start pipeline." << std::endl; + return 1; // Or any error code indicating failure + } + // Wait for the pipeline to run for 10 seconds + boost::this_thread::sleep_for(boost::chrono::seconds(10)); + // Stop the pipeline + if (!pipelineInstance.stopPipeLine()) { + std::cerr << "Failed to stop pipeline." << std::endl; + return 1; // Or any error code indicating failure + } + return 0; // Or any success code +} diff --git a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp new file mode 100644 index 000000000..74022d2a3 --- /dev/null +++ b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp @@ -0,0 +1,18 @@ +#include + +#include "GenerateThumbnailsPipeline.h" + +BOOST_AUTO_TEST_SUITE(generateThumbnails) + +BOOST_AUTO_TEST_CASE(generateThumbnails_from_mp4) +{ + auto generateThumbnailPipeline = boost::shared_ptr(new GenerateThumbnailsPipeline()); + generateThumbnailPipeline->setUpPipeLine(); + generateThumbnailPipeline->startPipeLine(); + + boost::this_thread::sleep_for(boost::chrono::seconds(5)); + + generateThumbnailPipeline->stopPipeLine(); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 738763b8e3cf91fb2293399fd6c46963e88fc95d Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Wed, 15 May 2024 12:46:04 +0530 Subject: [PATCH 02/13] reduced thread sleep seconds --- .../generate_thumbnail_from_mp4_video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp index f280cf81c..393f38cb5 100644 --- a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp @@ -84,7 +84,7 @@ int main() { return 1; // Or any error code indicating failure } // Wait for the pipeline to run for 10 seconds - boost::this_thread::sleep_for(boost::chrono::seconds(10)); + boost::this_thread::sleep_for(boost::chrono::seconds(5)); // Stop the pipeline if (!pipelineInstance.stopPipeLine()) { std::cerr << "Failed to stop pipeline." << std::endl; From ab3f182647ee41e42448c93db912600ba354992d Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Fri, 17 May 2024 13:07:28 +0530 Subject: [PATCH 03/13] added new sample which will start video from beginning using flushAllQueues and seek feature --- samples/CMakeLists.txt | 3 +- samples/play_mp4_from_begining/CMakeLists.txt | 52 ++++++++++ .../PlayMp4VideoFromBeginning.h | 17 ++++ .../play_mp4_video_from_begining.cpp | 97 +++++++++++++++++++ .../test_play_mp4_video_from_begining.cpp | 18 ++++ 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 samples/play_mp4_from_begining/CMakeLists.txt create mode 100644 samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h create mode 100644 samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp create mode 100644 samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 56e4855e6..e4364c078 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -7,4 +7,5 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) -add_subdirectory(create_thumbnail_from_mp4_video) \ No newline at end of file +add_subdirectory(create_thumbnail_from_mp4_video) +add_subdirectory(play_mp4_from_begining) diff --git a/samples/play_mp4_from_begining/CMakeLists.txt b/samples/play_mp4_from_begining/CMakeLists.txt new file mode 100644 index 000000000..8c825c4c8 --- /dev/null +++ b/samples/play_mp4_from_begining/CMakeLists.txt @@ -0,0 +1,52 @@ +set(TARGET play_mp4_from_begining) +SET(CORE_FILES + play_mp4_video_from_begining.cpp +) +SET(CORE_FILES_H + PlayMp4VideoFromBegining.h +) +SET(SOURCE + ${CORE_FILES} + ${CORE_FILES_H} +) +set(UT_FILE + test_play_mp4_video_from_begining.cpp +) +add_library(example_aprapipes1 STATIC ${SOURCE}) +add_executable(${TARGET} ${UT_FILE}) +target_include_directories ( example_aprapipes1 PRIVATE + ${JETSON_MULTIMEDIA_LIB_INCLUDE} + ${FFMPEG_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBMP4_INC_DIR} + ${BARESIP_INC_DIR} + ${LIBRE_INC_DIR} + ${NVCODEC_INCLUDE_DIR} +) +target_include_directories ( ${TARGET} PUBLIC + ${JETSON_MULTIMEDIA_LIB_INCLUDE} + ${FFMPEG_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${LIBMP4_INC_DIR} + ${BARESIP_INC_DIR} + ${LIBRE_INC_DIR} + ${NVCODEC_INCLUDE_DIR} +) +target_link_libraries( + ${TARGET} + aprapipes + ${JPEG_LIBRARIES} + ${LIBMP4_LIB} + ${OPENH264_LIB} + ${Boost_LIBRARIES} + ${FFMPEG_LIBRARIES} + ${OpenCV_LIBRARIES} + ${JETSON_LIBS} + ${NVCUDAToolkit_LIBS} + ${NVCODEC_LIB} + ${NVJPEGLIB_L4T} + ${CURSES_LIBRARIES} + example_aprapipes1 + ) \ No newline at end of file diff --git a/samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h b/samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h new file mode 100644 index 000000000..f831aa0cc --- /dev/null +++ b/samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h @@ -0,0 +1,17 @@ +#include +#include "Mp4ReaderSource.h" +#include "ImageViewerModule.h" + +class PlayMp4VideoFromBeginning { +public: + PlayMp4VideoFromBeginning(); + bool setUpPipeLine(); + bool startPipeLine(); + bool stopPipeLine(); + bool flushQueuesAndSeek(); + +private: + PipeLine pipeLine; + boost::shared_ptr mp4Reader; + boost::shared_ptr sink; +}; \ No newline at end of file diff --git a/samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp b/samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp new file mode 100644 index 000000000..844b20ed2 --- /dev/null +++ b/samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp @@ -0,0 +1,97 @@ + +#include "PlayMp4VideoFromBeginning.h" +#include "FrameMetadata.h" +#include "H264Metadata.h" +#include "Mp4ReaderSource.h" +#include "Mp4VideoMetadata.h" +#include "H264Decoder.h" +#include "ValveModule.h" +#include "ColorConversionXForm.h" +#include "CudaMemCopy.h" +#include "FileWriterModule.h" +#include "JPEGEncoderNVJPEG.h" +#include "ImageViewerModule.h" + + +PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() : pipeLine("pipeline") { + +} +bool PlayMp4VideoFromBeginning::setUpPipeLine() { + // Implementation + std::string videoPath = "../.././data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; + std::string outPath = "../.././data/mp4Reader_saveOrCompare/h264/frame_000???.jpg"; + + bool parseFS = false; + auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); + auto frameType = FrameMetadata::FrameType::H264_DATA; + auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, true, false); + mp4ReaderProps.fps = 24; + mp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); + mp4Reader->addOutPutPin(h264ImageMetadata); + + auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); + mp4Reader->addOutPutPin(mp4Metadata); + + std::vector mImagePin; + mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + + auto decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + mp4Reader->setNext(decoder, mImagePin); + + auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; + auto metadata = framemetadata_sp(new RawImagePlanarMetadata(1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); + auto colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); + decoder->setNext(colorchange); + + sink = boost::shared_ptr( + new ImageViewerModule(ImageViewerModuleProps("imageview"))); + colorchange->setNext(sink); + + pipeLine.appendModule(mp4Reader); + pipeLine.init(); + return true; +} + +bool PlayMp4VideoFromBeginning::startPipeLine() { + pipeLine.run_all_threaded(); + return true; +} + +bool PlayMp4VideoFromBeginning::stopPipeLine() { + pipeLine.stop(); + pipeLine.term(); + pipeLine.wait_for_all(); + return true; +} + +bool PlayMp4VideoFromBeginning::flushQueuesAndSeek() { + pipeLine.flushAllQueues(); + mp4Reader->randomSeek(1686723796848, false); + return true; +} + +int main() { + PlayMp4VideoFromBeginning pipelineInstance; + if (!pipelineInstance.setUpPipeLine()) { + std::cerr << "Failed to setup pipeline." << std::endl; + return 1; + } + if (!pipelineInstance.startPipeLine()) { + std::cerr << "Failed to start pipeline." << std::endl; + return 1; // Or any error code indicating failure + } + // Wait for the pipeline to run for 10 seconds + boost::this_thread::sleep_for(boost::chrono::seconds(3)); + if (!pipelineInstance.flushQueuesAndSeek()) { + std::cerr << "Failed to flush Queues." << std::endl; + return 1; + } + boost::this_thread::sleep_for(boost::chrono::seconds(5)); + // Stop the pipeline + if (!pipelineInstance.stopPipeLine()) { + std::cerr << "Failed to stop pipeline." << std::endl; + return 1; // Or any error code indicating failure + } + + return 0; // Or any success code +} diff --git a/samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp b/samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp new file mode 100644 index 000000000..5dc3d8c5e --- /dev/null +++ b/samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp @@ -0,0 +1,18 @@ +#include + +#include "PlayMp4VideoFromBeginning.h" + +BOOST_AUTO_TEST_SUITE(start_video_from_beginning) + +BOOST_AUTO_TEST_CASE(start_from_beginning) +{ + auto playMp4VideoFromBeginning = boost::shared_ptr(new PlayMp4VideoFromBeginning()); + playMp4VideoFromBeginning->setUpPipeLine(); + playMp4VideoFromBeginning->startPipeLine(); + + boost::this_thread::sleep_for(boost::chrono::seconds(10)); + + playMp4VideoFromBeginning->stopPipeLine(); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From f1d8cc0690651e36e79dfe0d2f43fdf5281c4f9e Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Fri, 17 May 2024 16:21:45 +0530 Subject: [PATCH 04/13] refactored CMake list and renamed files --- samples/CMakeLists.txt | 2 +- .../create_thumbnail_from_mp4_video/CMakeLists.txt | 6 +++--- .../CMakeLists.txt | 14 +++++++------- .../PlayMp4VideoFromBeginning.h | 0 .../play_mp4_video_from_beginning.cpp} | 0 .../test_play_mp4_video_from_beginning.cpp} | 0 6 files changed, 11 insertions(+), 11 deletions(-) rename samples/{play_mp4_from_begining => play_mp4_from_beginning}/CMakeLists.txt (73%) rename samples/{play_mp4_from_begining => play_mp4_from_beginning}/PlayMp4VideoFromBeginning.h (100%) rename samples/{play_mp4_from_begining/play_mp4_video_from_begining.cpp => play_mp4_from_beginning/play_mp4_video_from_beginning.cpp} (100%) rename samples/{play_mp4_from_begining/test_play_mp4_video_from_begining.cpp => play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp} (100%) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index e4364c078..9da737abf 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -8,4 +8,4 @@ ${CMAKE_CURRENT_SOURCE_DIR} ) add_subdirectory(create_thumbnail_from_mp4_video) -add_subdirectory(play_mp4_from_begining) +add_subdirectory(play_mp4_from_beginning) diff --git a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt index f30f87f9f..23aee9cfa 100644 --- a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt +++ b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt @@ -12,9 +12,9 @@ SET(SOURCE set(UT_FILE test_generate_thumbnail_from_mp4_video.cpp ) -add_library(example_aprapipes STATIC ${SOURCE}) +add_library(create_thumbnail_from_mp4_video_source STATIC ${SOURCE}) add_executable(${TARGET} ${UT_FILE}) -target_include_directories ( example_aprapipes PRIVATE +target_include_directories ( create_thumbnail_from_mp4_video_source PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} @@ -48,5 +48,5 @@ target_link_libraries( ${NVCODEC_LIB} ${NVJPEGLIB_L4T} ${CURSES_LIBRARIES} - example_aprapipes + create_thumbnail_from_mp4_video_source ) \ No newline at end of file diff --git a/samples/play_mp4_from_begining/CMakeLists.txt b/samples/play_mp4_from_beginning/CMakeLists.txt similarity index 73% rename from samples/play_mp4_from_begining/CMakeLists.txt rename to samples/play_mp4_from_beginning/CMakeLists.txt index 8c825c4c8..43e1b3063 100644 --- a/samples/play_mp4_from_begining/CMakeLists.txt +++ b/samples/play_mp4_from_beginning/CMakeLists.txt @@ -1,20 +1,20 @@ -set(TARGET play_mp4_from_begining) +set(TARGET play_mp4_from_beginning) SET(CORE_FILES - play_mp4_video_from_begining.cpp + play_mp4_video_from_beginning.cpp ) SET(CORE_FILES_H - PlayMp4VideoFromBegining.h + PlayMp4VideoFromBeginning.h ) SET(SOURCE ${CORE_FILES} ${CORE_FILES_H} ) set(UT_FILE - test_play_mp4_video_from_begining.cpp + test_play_mp4_video_from_beginning.cpp ) -add_library(example_aprapipes1 STATIC ${SOURCE}) +add_library(play_mp4_from_beginning_source STATIC ${SOURCE}) add_executable(${TARGET} ${UT_FILE}) -target_include_directories ( example_aprapipes1 PRIVATE +target_include_directories ( play_mp4_from_beginning_source PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} @@ -48,5 +48,5 @@ target_link_libraries( ${NVCODEC_LIB} ${NVJPEGLIB_L4T} ${CURSES_LIBRARIES} - example_aprapipes1 + play_mp4_from_beginning_source ) \ No newline at end of file diff --git a/samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h similarity index 100% rename from samples/play_mp4_from_begining/PlayMp4VideoFromBeginning.h rename to samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h diff --git a/samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp similarity index 100% rename from samples/play_mp4_from_begining/play_mp4_video_from_begining.cpp rename to samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp diff --git a/samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp similarity index 100% rename from samples/play_mp4_from_begining/test_play_mp4_video_from_begining.cpp rename to samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp From da51b44eddbdd641b32a74831cf89c3a9c49d1de Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 20 May 2024 13:18:56 +0530 Subject: [PATCH 05/13] using resolved time stamp when seeking --- base/src/Mp4ReaderSource.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/src/Mp4ReaderSource.cpp b/base/src/Mp4ReaderSource.cpp index e67b26624..94e272f49 100644 --- a/base/src/Mp4ReaderSource.cpp +++ b/base/src/Mp4ReaderSource.cpp @@ -571,20 +571,20 @@ class Mp4ReaderDetailAbs { int seekedToFrame = -1; uint64_t skipMsecsInFile = 0; - - if (!mState.startTimeStampFromFile) + + if (!mState.resolvedStartingTS) { LOG_ERROR << "Start timestamp is not saved in the file. Can't support seeking with timestamps."; return false; } - if (skipTS < mState.startTimeStampFromFile) + if (skipTS < mState.resolvedStartingTS) { LOG_INFO << "seek time outside range. Seeking to start of video."; skipMsecsInFile = 0; } else { - skipMsecsInFile = skipTS - mState.startTimeStampFromFile; + skipMsecsInFile = skipTS - mState.resolvedStartingTS; } LOG_INFO << "Attempting seek <" << mState.mVideoPath << "> @skipMsecsInFile <" << skipMsecsInFile << ">"; From 79355331ddb071ce39a3ce10876c44454ced1d60 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 27 May 2024 18:25:22 +0530 Subject: [PATCH 06/13] added test thumbnail sample --- .../CMakeLists.txt | 22 +-- .../GenerateThumbnailsPipeline.h | 18 ++- .../generate_thumbnail_from_mp4_video.cpp | 142 ++++++++++-------- ...test_generate_thumbnail_from_mp4_video.cpp | 14 +- 4 files changed, 115 insertions(+), 81 deletions(-) diff --git a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt index 23aee9cfa..73e3a6910 100644 --- a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt +++ b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt @@ -1,30 +1,19 @@ +cmake_minimum_required(VERSION 3.22) set(TARGET create_thumbnail_from_mp4_video) SET(CORE_FILES generate_thumbnail_from_mp4_video.cpp + ../../base/test/test_utils.cpp ) SET(CORE_FILES_H GenerateThumbnailsPipeline.h + ../../base/test/test_utils.h ) SET(SOURCE ${CORE_FILES} ${CORE_FILES_H} ) -set(UT_FILE - test_generate_thumbnail_from_mp4_video.cpp -) -add_library(create_thumbnail_from_mp4_video_source STATIC ${SOURCE}) -add_executable(${TARGET} ${UT_FILE}) -target_include_directories ( create_thumbnail_from_mp4_video_source PRIVATE - ${JETSON_MULTIMEDIA_LIB_INCLUDE} - ${FFMPEG_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${LIBMP4_INC_DIR} - ${BARESIP_INC_DIR} - ${LIBRE_INC_DIR} - ${NVCODEC_INCLUDE_DIR} -) -target_include_directories ( ${TARGET} PUBLIC +add_executable(${TARGET} ${SOURCE}) +target_include_directories ( ${TARGET} PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} @@ -48,5 +37,4 @@ target_link_libraries( ${NVCODEC_LIB} ${NVJPEGLIB_L4T} ${CURSES_LIBRARIES} - create_thumbnail_from_mp4_video_source ) \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h index dbf4a6fe8..2137e6d62 100644 --- a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h @@ -1,5 +1,13 @@ #include #include +#include "Mp4ReaderSource.h" +#include "H264Decoder.h" +#include "ColorConversionXForm.h" +#include "CudaMemCopy.h" +#include "FileWriterModule.h" +#include "JPEGEncoderNVJPEG.h" + + class GenerateThumbnailsPipeline { @@ -8,8 +16,16 @@ class GenerateThumbnailsPipeline bool setUpPipeLine(); bool startPipeLine(); bool stopPipeLine(); + bool testPipeLine(); private: PipeLine pipeLine; boost::shared_ptr valve; -}; \ No newline at end of file + boost::shared_ptr mp4Reader; + boost::shared_ptr decoder; + boost::shared_ptr colorchange; + boost::shared_ptr cudaCopy; + boost::shared_ptr jpegEncoder; + boost::shared_ptr fileWriter; +}; + diff --git a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp index 393f38cb5..73ab50b04 100644 --- a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp @@ -1,90 +1,108 @@ -#include "GenerateThumbnailsPipeline.h" +#include "ColorConversionXForm.h" +#include "CudaMemCopy.h" +#include "ExternalSinkModule.h" +#include "FileReaderModule.h" +#include "FileWriterModule.h" #include "FrameMetadata.h" +#include "GenerateThumbnailsPipeline.h" +#include "H264Decoder.h" #include "H264Metadata.h" +#include "JPEGEncoderNVJPEG.h" #include "Mp4ReaderSource.h" #include "Mp4VideoMetadata.h" -#include "H264Decoder.h" #include "ValveModule.h" -#include "ColorConversionXForm.h" -#include "CudaMemCopy.h" -#include "FileWriterModule.h" -#include "JPEGEncoderNVJPEG.h" -GenerateThumbnailsPipeline::GenerateThumbnailsPipeline() : pipeLine("pipeline") { -} + +GenerateThumbnailsPipeline::GenerateThumbnailsPipeline() + : pipeLine("pipeline") {} + + bool GenerateThumbnailsPipeline::setUpPipeLine() { - // Implementation - std::string videoPath = "../.././data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; - std::string outPath = "../.././data/mp4Reader_saveOrCompare/h264/frame_000???.jpg"; - - bool parseFS = false; - auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); - auto frameType = FrameMetadata::FrameType::H264_DATA; - auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, false, false); - auto mp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); - mp4Reader->addOutPutPin(h264ImageMetadata); - - auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); - mp4Reader->addOutPutPin(mp4Metadata); - - std::vector mImagePin; - mImagePin = mp4Reader->getAllOutputPinsByType(frameType); - - auto decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); - mp4Reader->setNext(decoder, mImagePin); - - valve = boost::shared_ptr(new ValveModule(ValveModuleProps(2))); - decoder->setNext(valve); - - auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; - auto metadata = framemetadata_sp(new RawImagePlanarMetadata(1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); - auto colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); - valve->setNext(colorchange); - - auto stream = cudastream_sp(new ApraCudaStream); - auto copy = boost::shared_ptr(new CudaMemCopy(CudaMemCopyProps(cudaMemcpyHostToDevice, stream))); - colorchange->setNext(copy); - - auto m2 = boost::shared_ptr(new JPEGEncoderNVJPEG(JPEGEncoderNVJPEGProps(stream))); - copy->setNext(m2); - - /*auto valve = boost::shared_ptr(new ValveModule(ValveModuleProps(10))); - m2->setNext(valve);*/ - - auto fileWriter = boost::shared_ptr(new FileWriterModule(FileWriterModuleProps(outPath))); - m2->setNext(fileWriter); - - pipeLine.appendModule(mp4Reader); - pipeLine.init(); - return true; + // Implementation + std::string videoPath = "./data/Mp4_videos/h264_video_metadata/" + "20230514/0011/1686723796848.mp4"; + std::string outPath = + "./data/mp4Reader_saveOrCompare/h264/thumbnail.jpg"; + + bool parseFS = false; + auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); + auto frameType = FrameMetadata::FrameType::H264_DATA; + auto mp4ReaderProps = + Mp4ReaderSourceProps(videoPath, parseFS, 0, true, false, false); + mp4Reader = + boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); + mp4Reader->addOutPutPin(h264ImageMetadata); + + auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); + mp4Reader->addOutPutPin(mp4Metadata); + + std::vector mImagePin; + mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + + decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + mp4Reader->setNext(decoder, mImagePin); + + valve = boost::shared_ptr(new ValveModule(ValveModuleProps(0))); + decoder->setNext(valve); + + /* auto conversionType = + ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; auto metadata = + framemetadata_sp(new RawImagePlanarMetadata(1280, 720, + ImageMetadata::ImageType::YUV420,size_t(0), + CV_8U,FrameMetadata::MemType::CUDA_DEVICE));*/ + /* colorchange = boost::shared_ptr(new + ColorConversion(ColorConversionProps(conversionType))); + valve->setNext(colorchange);*/ + + auto stream = cudastream_sp(new ApraCudaStream); + cudaCopy = boost::shared_ptr( + new CudaMemCopy(CudaMemCopyProps(cudaMemcpyHostToDevice, stream))); + valve->setNext(cudaCopy); + + jpegEncoder = boost::shared_ptr( + new JPEGEncoderNVJPEG(JPEGEncoderNVJPEGProps(stream))); + cudaCopy->setNext(jpegEncoder); + + fileWriter = boost::shared_ptr( + new FileWriterModule(FileWriterModuleProps(outPath))); + jpegEncoder->setNext(fileWriter); + + return true; } bool GenerateThumbnailsPipeline::startPipeLine() { - pipeLine.run_all_threaded(); - valve->allowFrames(1); - return true; + pipeLine.appendModule(mp4Reader); + pipeLine.init(); + pipeLine.run_all_threaded(); + valve->allowFrames(1); + + return true; } bool GenerateThumbnailsPipeline::stopPipeLine() { - pipeLine.stop(); - pipeLine.term(); - pipeLine.wait_for_all(); - return true; + pipeLine.stop(); + pipeLine.term(); + pipeLine.wait_for_all(); + return true; } -int main() { - GenerateThumbnailsPipeline pipelineInstance; +int main() { + GenerateThumbnailsPipeline pipelineInstance; if (!pipelineInstance.setUpPipeLine()) { - std::cerr << "Failed to setup pipeline." << std::endl; + std::cerr << "Failed to setup pipeline." << std::endl; return 1; } + + if (!pipelineInstance.startPipeLine()) { std::cerr << "Failed to start pipeline." << std::endl; return 1; // Or any error code indicating failure } + // Wait for the pipeline to run for 10 seconds boost::this_thread::sleep_for(boost::chrono::seconds(5)); + // Stop the pipeline if (!pipelineInstance.stopPipeLine()) { std::cerr << "Failed to stop pipeline." << std::endl; diff --git a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp index 74022d2a3..60b8830fe 100644 --- a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp @@ -1,5 +1,6 @@ #include - +#include +#include "../../base/test/test_utils.h" #include "GenerateThumbnailsPipeline.h" BOOST_AUTO_TEST_SUITE(generateThumbnails) @@ -12,6 +13,17 @@ BOOST_AUTO_TEST_CASE(generateThumbnails_from_mp4) boost::this_thread::sleep_for(boost::chrono::seconds(5)); + const uint8_t *pReadDataTest = nullptr; + unsigned int readDataSizeTest = 0U; + + BOOST_TEST( + Test_Utils::readFile("./data/thumbnail/sample_thumbnail.jpg", + pReadDataTest, readDataSizeTest)); + Test_Utils::saveOrCompare( + "./data/mp4Reader_saveOrCompare/h264/test_thumbnail.jpg", + pReadDataTest, readDataSizeTest, 0); + + generateThumbnailPipeline->stopPipeLine(); } From c38f63f6d7a49bf0a8a95eefa76b3668f0b0fbf0 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 27 May 2024 19:06:22 +0530 Subject: [PATCH 07/13] test for play mp4 from beginning --- .../play_mp4_from_beginning/CMakeLists.txt | 21 +---- .../PlayMp4VideoFromBeginning.h | 9 +- .../play_mp4_video_from_beginning.cpp | 93 +++++++++++++++++-- .../test_play_mp4_video_from_beginning.cpp | 2 +- 4 files changed, 100 insertions(+), 25 deletions(-) diff --git a/samples/play_mp4_from_beginning/CMakeLists.txt b/samples/play_mp4_from_beginning/CMakeLists.txt index 43e1b3063..e5fb1bd53 100644 --- a/samples/play_mp4_from_beginning/CMakeLists.txt +++ b/samples/play_mp4_from_beginning/CMakeLists.txt @@ -1,30 +1,18 @@ set(TARGET play_mp4_from_beginning) SET(CORE_FILES play_mp4_video_from_beginning.cpp + ../../base/test/test_utils.cpp ) SET(CORE_FILES_H PlayMp4VideoFromBeginning.h + ../../base/test/test_utils.h ) SET(SOURCE ${CORE_FILES} ${CORE_FILES_H} ) -set(UT_FILE - test_play_mp4_video_from_beginning.cpp -) -add_library(play_mp4_from_beginning_source STATIC ${SOURCE}) -add_executable(${TARGET} ${UT_FILE}) -target_include_directories ( play_mp4_from_beginning_source PRIVATE - ${JETSON_MULTIMEDIA_LIB_INCLUDE} - ${FFMPEG_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${LIBMP4_INC_DIR} - ${BARESIP_INC_DIR} - ${LIBRE_INC_DIR} - ${NVCODEC_INCLUDE_DIR} -) -target_include_directories ( ${TARGET} PUBLIC +add_executable(${TARGET} ${SOURCE}) +target_include_directories ( ${TARGET} PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} @@ -48,5 +36,4 @@ target_link_libraries( ${NVCODEC_LIB} ${NVJPEGLIB_L4T} ${CURSES_LIBRARIES} - play_mp4_from_beginning_source ) \ No newline at end of file diff --git a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h index f831aa0cc..6fa0c45bc 100644 --- a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h +++ b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h @@ -1,6 +1,9 @@ #include #include "Mp4ReaderSource.h" #include "ImageViewerModule.h" +#include "ColorConversionXForm.h" +#include "H264Decoder.h" + class PlayMp4VideoFromBeginning { public: @@ -9,9 +12,13 @@ class PlayMp4VideoFromBeginning { bool startPipeLine(); bool stopPipeLine(); bool flushQueuesAndSeek(); + bool testPipeLineForFlushQue(); + bool testPipeLineForSeek(); private: PipeLine pipeLine; boost::shared_ptr mp4Reader; - boost::shared_ptr sink; + boost::shared_ptr imageViewerSink; + boost::shared_ptr decoder; + boost::shared_ptr colorchange; }; \ No newline at end of file diff --git a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp index 844b20ed2..0a78e2364 100644 --- a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp +++ b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp @@ -10,12 +10,85 @@ #include "CudaMemCopy.h" #include "FileWriterModule.h" #include "JPEGEncoderNVJPEG.h" +#include "ExternalSinkModule.h" #include "ImageViewerModule.h" +#include +#include +#include "Frame.h" +#include "FrameContainerQueue.h" +#include "../../base/test/test_utils.h" +class SinkModuleProps : public ModuleProps { +public: + SinkModuleProps() : ModuleProps(){}; +}; + +class SinkModule : public Module { +public: + SinkModule(SinkModuleProps props) : Module(SINK, "sinkModule", props){}; + boost::shared_ptr getQue() { return Module::getQue(); } + frame_container pop() { return Module::pop(); } + +protected: + bool process() { return false; } + bool validateOutputPins() { return true; } + bool validateInputPins() { return true; } +}; PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() : pipeLine("pipeline") { } + +bool PlayMp4VideoFromBeginning::testPipeLineForFlushQue() { + auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); + colorchange->setNext(sink); + + BOOST_CHECK(mp4Reader->init()); + BOOST_CHECK(decoder->init()); + BOOST_CHECK(colorchange->init()); + BOOST_CHECK(sink->init()); + + for (int i = 0; i <= 20; i++) { + mp4Reader->step(); + decoder->step(); + } + colorchange->step(); + + auto frames = sink->pop(); + auto sinkQue = sink->getQue(); + BOOST_TEST(sinkQue->size() == 1); + sinkQue->flush(); + BOOST_TEST(sinkQue->size() == 0); + frame_sp outputFrame = frames.cbegin()->second; + + + + Test_Utils::saveOrCompare("../.././data/mp4Reader_saveOrCompare/h264/testplay.raw", const_cast(static_cast(outputFrame->data())), outputFrame->size(), 0); + return true; +} +bool PlayMp4VideoFromBeginning::testPipeLineForSeek() { + auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); + mp4Reader->setNext(sink); + + BOOST_CHECK(mp4Reader->init()); + BOOST_CHECK(decoder->init()); + BOOST_CHECK(colorchange->init()); + BOOST_CHECK(sink->init()); + + mp4Reader->step(); + + auto frames = sink->pop(); + auto imgFrame = frames.begin()->second; + + uint64_t skipTS = 1686723797848; + mp4Reader->randomSeek(skipTS, false); + mp4Reader->step(); + BOOST_TEST(imgFrame->timestamp == 1686723797856); + LOG_INFO << "Found next available frame " << imgFrame->timestamp - skipTS + << " msecs later from skipTS"; + + return true; +} bool PlayMp4VideoFromBeginning::setUpPipeLine() { // Implementation std::string videoPath = "../.././data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; @@ -35,24 +108,24 @@ bool PlayMp4VideoFromBeginning::setUpPipeLine() { std::vector mImagePin; mImagePin = mp4Reader->getAllOutputPinsByType(frameType); - auto decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); mp4Reader->setNext(decoder, mImagePin); auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; auto metadata = framemetadata_sp(new RawImagePlanarMetadata(1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); - auto colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); + colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); decoder->setNext(colorchange); - sink = boost::shared_ptr( + imageViewerSink = boost::shared_ptr( new ImageViewerModule(ImageViewerModuleProps("imageview"))); - colorchange->setNext(sink); + colorchange->setNext(imageViewerSink); - pipeLine.appendModule(mp4Reader); - pipeLine.init(); return true; } bool PlayMp4VideoFromBeginning::startPipeLine() { + pipeLine.appendModule(mp4Reader); + pipeLine.init(); pipeLine.run_all_threaded(); return true; } @@ -76,6 +149,14 @@ int main() { std::cerr << "Failed to setup pipeline." << std::endl; return 1; } + if (!pipelineInstance.testPipeLineForFlushQue()) { + std::cerr << "Failed to test pipeline." << std::endl; + return 1; + } + if (!pipelineInstance.testPipeLineForSeek()) { + std::cerr << "Failed to test pipeline." << std::endl; + return 1; + } if (!pipelineInstance.startPipeLine()) { std::cerr << "Failed to start pipeline." << std::endl; return 1; // Or any error code indicating failure diff --git a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp index 5dc3d8c5e..8586303be 100644 --- a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp +++ b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp @@ -4,7 +4,7 @@ BOOST_AUTO_TEST_SUITE(start_video_from_beginning) -BOOST_AUTO_TEST_CASE(start_from_beginning) +BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_flush_queue_test) { auto playMp4VideoFromBeginning = boost::shared_ptr(new PlayMp4VideoFromBeginning()); playMp4VideoFromBeginning->setUpPipeLine(); From 41ff3ae470da5c41932801489f8d0b218cf21fd6 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 27 May 2024 19:07:26 +0530 Subject: [PATCH 08/13] updated main CMake --- base/CMakeLists.txt | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index d6dadadde..74a575e41 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -163,6 +163,7 @@ SET(CORE_FILES src/MotionVectorExtractor.cpp src/OverlayModule.cpp src/OrderedCacheOfFiles.cpp + .././samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp .././samples/timelapse-sample/timelapse_summary.h ) @@ -225,6 +226,7 @@ SET(CORE_FILES_H include/OverlayModule.h include/OrderedCacheOfFiles.h include/TestSignalGeneratorSrc.h + .././samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h .././samples/timelapse-sample/timelapse_summary.cpp ) @@ -458,6 +460,7 @@ ${LIBMP4_INC_DIR} ${BARESIP_INC_DIR} ${LIBRE_INC_DIR} ${NVCODEC_INCLUDE_DIR} +.././samples/create_thumbnail_from_mp4_video ./../samples/timelapse-sample ) @@ -570,7 +573,10 @@ SET(UT_FILES ) SET(SAMPLE_UT_FILES -.././samples/timelapse-sample/timelapse_summary_test.cpp + test/test_utils.cpp + test/test_utils.h + .././samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp + .././samples/play_mp4_from_beginningtest_play_mp4_video_from_beginning.cpp ) IF(ENABLE_LINUX) list(APPEND UT_FILES @@ -581,7 +587,6 @@ ENDIF(ENABLE_LINUX) add_executable(aprapipesut ${UT_FILES}) - add_executable(aprapipessampleut ${SAMPLE_UT_FILES}) IF(ENABLE_ARM64) @@ -596,6 +601,29 @@ ENDIF (ENABLE_CUDA) find_library(OPENH264_LIB NAMES openh264.lib libopenh264.a REQUIRED) find_library(LIBMP4_LIB NAMES mp4lib.lib libmp4lib.a REQUIRED) +target_link_libraries(aprapipessampleut + aprapipes + ${JPEG_LIBRARIES} + ${LIBMP4_LIB} + ${OPENH264_LIB} + ${Boost_LIBRARIES} + ${FFMPEG_LIBRARIES} + ${OpenCV_LIBRARIES} + ${JETSON_LIBS} + ${NVCUDAToolkit_LIBS} + ${NVCODEC_LIB} + ${NVJPEGLIB_L4T} + ${CURSES_LIBRARIES} + ZXing::Core + ZXing::ZXing + BZip2::BZip2 + ZLIB::ZLIB + liblzma::liblzma + bigint::bigint + sfml-audio + whisper::whisper + ) + target_link_libraries(aprapipessampleut aprapipes ${JPEG_LIBRARIES} From 744d40d6700d05370df80d98a71347b5eb8e5d82 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 27 May 2024 19:24:51 +0530 Subject: [PATCH 09/13] refactored test and CMake file --- .../play_mp4_from_beginning/CMakeLists.txt | 5 ++-- .../play_mp4_video_from_beginning.cpp | 26 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/samples/play_mp4_from_beginning/CMakeLists.txt b/samples/play_mp4_from_beginning/CMakeLists.txt index e5fb1bd53..69878b0b5 100644 --- a/samples/play_mp4_from_beginning/CMakeLists.txt +++ b/samples/play_mp4_from_beginning/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.22) set(TARGET play_mp4_from_beginning) SET(CORE_FILES play_mp4_video_from_beginning.cpp @@ -11,8 +12,8 @@ SET(SOURCE ${CORE_FILES} ${CORE_FILES_H} ) -add_executable(${TARGET} ${SOURCE}) -target_include_directories ( ${TARGET} PRIVATE +add_executable(${TARGET} ${SOURCE}) +target_include_directories ( ${TARGET} PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} diff --git a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp index 0a78e2364..70eda7a5a 100644 --- a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp +++ b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp @@ -55,14 +55,12 @@ bool PlayMp4VideoFromBeginning::testPipeLineForFlushQue() { colorchange->step(); auto frames = sink->pop(); + auto frame = frames.size(); auto sinkQue = sink->getQue(); - BOOST_TEST(sinkQue->size() == 1); + BOOST_CHECK_EQUAL(frames.size(), 1); sinkQue->flush(); - BOOST_TEST(sinkQue->size() == 0); - frame_sp outputFrame = frames.cbegin()->second; - - - + BOOST_CHECK_EQUAL(sinkQue->size(), 0); + frame_sp outputFrame = frames.cbegin()->second; Test_Utils::saveOrCompare("../.././data/mp4Reader_saveOrCompare/h264/testplay.raw", const_cast(static_cast(outputFrame->data())), outputFrame->size(), 0); return true; } @@ -153,14 +151,14 @@ int main() { std::cerr << "Failed to test pipeline." << std::endl; return 1; } - if (!pipelineInstance.testPipeLineForSeek()) { - std::cerr << "Failed to test pipeline." << std::endl; - return 1; - } - if (!pipelineInstance.startPipeLine()) { - std::cerr << "Failed to start pipeline." << std::endl; - return 1; // Or any error code indicating failure - } + //if (!pipelineInstance.testPipeLineForSeek()) { + // std::cerr << "Failed to test pipeline." << std::endl; + // return 1; + //} + //if (!pipelineInstance.startPipeLine()) { + // std::cerr << "Failed to start pipeline." << std::endl; + // return 1; // Or any error code indicating failure + //} // Wait for the pipeline to run for 10 seconds boost::this_thread::sleep_for(boost::chrono::seconds(3)); if (!pipelineInstance.flushQueuesAndSeek()) { From f499d5f493cabc6d56817a49beda579c0b1355cf Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 3 Jun 2024 19:19:03 +0530 Subject: [PATCH 10/13] refactored CMake and file structure for thumbnail samples --- .../CMakeLists.txt | 7 ++- ...deo.cpp => GenerateThumbnailsPipeline.cpp} | 48 ++----------------- .../GenerateThumbnailsPipeline.h | 3 +- .../pipelineMain.cpp | 30 ++++++++++++ ...test_generate_thumbnail_from_mp4_video.cpp | 37 +++++++------- 5 files changed, 58 insertions(+), 67 deletions(-) rename samples/create_thumbnail_from_mp4_video/{generate_thumbnail_from_mp4_video.cpp => GenerateThumbnailsPipeline.cpp} (58%) create mode 100644 samples/create_thumbnail_from_mp4_video/pipelineMain.cpp diff --git a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt index 73e3a6910..0a210d28f 100644 --- a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt +++ b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt @@ -1,12 +1,11 @@ cmake_minimum_required(VERSION 3.22) -set(TARGET create_thumbnail_from_mp4_video) +set(TARGET generateThumbnailFromMp4Video) SET(CORE_FILES - generate_thumbnail_from_mp4_video.cpp - ../../base/test/test_utils.cpp + GenerateThumbnailsPipeline.cpp + pipelineMain.cpp ) SET(CORE_FILES_H GenerateThumbnailsPipeline.h - ../../base/test/test_utils.h ) SET(SOURCE ${CORE_FILES} diff --git a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp similarity index 58% rename from samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp rename to samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp index 73ab50b04..a0bba2abd 100644 --- a/samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp @@ -1,30 +1,24 @@ -#include "ColorConversionXForm.h" +#include "GenerateThumbnailsPipeline.h" #include "CudaMemCopy.h" #include "ExternalSinkModule.h" #include "FileReaderModule.h" #include "FileWriterModule.h" #include "FrameMetadata.h" -#include "GenerateThumbnailsPipeline.h" #include "H264Decoder.h" #include "H264Metadata.h" #include "JPEGEncoderNVJPEG.h" #include "Mp4ReaderSource.h" #include "Mp4VideoMetadata.h" #include "ValveModule.h" - - +#include GenerateThumbnailsPipeline::GenerateThumbnailsPipeline() : pipeLine("pipeline") {} - -bool GenerateThumbnailsPipeline::setUpPipeLine() { +bool GenerateThumbnailsPipeline::setUpPipeLine( + const std::string &videoPath, const std::string &outFolderPath) { // Implementation - std::string videoPath = "./data/Mp4_videos/h264_video_metadata/" - "20230514/0011/1686723796848.mp4"; - std::string outPath = - "./data/mp4Reader_saveOrCompare/h264/thumbnail.jpg"; bool parseFS = false; auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); @@ -47,15 +41,6 @@ bool GenerateThumbnailsPipeline::setUpPipeLine() { valve = boost::shared_ptr(new ValveModule(ValveModuleProps(0))); decoder->setNext(valve); - /* auto conversionType = - ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; auto metadata = - framemetadata_sp(new RawImagePlanarMetadata(1280, 720, - ImageMetadata::ImageType::YUV420,size_t(0), - CV_8U,FrameMetadata::MemType::CUDA_DEVICE));*/ - /* colorchange = boost::shared_ptr(new - ColorConversion(ColorConversionProps(conversionType))); - valve->setNext(colorchange);*/ - auto stream = cudastream_sp(new ApraCudaStream); cudaCopy = boost::shared_ptr( new CudaMemCopy(CudaMemCopyProps(cudaMemcpyHostToDevice, stream))); @@ -66,7 +51,7 @@ bool GenerateThumbnailsPipeline::setUpPipeLine() { cudaCopy->setNext(jpegEncoder); fileWriter = boost::shared_ptr( - new FileWriterModule(FileWriterModuleProps(outPath))); + new FileWriterModule(FileWriterModuleProps(outFolderPath))); jpegEncoder->setNext(fileWriter); return true; @@ -87,26 +72,3 @@ bool GenerateThumbnailsPipeline::stopPipeLine() { pipeLine.wait_for_all(); return true; } -int main() { - GenerateThumbnailsPipeline pipelineInstance; - if (!pipelineInstance.setUpPipeLine()) { - std::cerr << "Failed to setup pipeline." << std::endl; - return 1; - } - - - if (!pipelineInstance.startPipeLine()) { - std::cerr << "Failed to start pipeline." << std::endl; - return 1; // Or any error code indicating failure - } - - // Wait for the pipeline to run for 10 seconds - boost::this_thread::sleep_for(boost::chrono::seconds(5)); - - // Stop the pipeline - if (!pipelineInstance.stopPipeLine()) { - std::cerr << "Failed to stop pipeline." << std::endl; - return 1; // Or any error code indicating failure - } - return 0; // Or any success code -} diff --git a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h index 2137e6d62..cabeeff16 100644 --- a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h @@ -13,10 +13,9 @@ class GenerateThumbnailsPipeline { public: GenerateThumbnailsPipeline(); - bool setUpPipeLine(); + bool setUpPipeLine(const std::string &videoPath,const std::string &outFolderPath); bool startPipeLine(); bool stopPipeLine(); - bool testPipeLine(); private: PipeLine pipeLine; diff --git a/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp b/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp new file mode 100644 index 000000000..759d47475 --- /dev/null +++ b/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp @@ -0,0 +1,30 @@ +#include "GenerateThumbnailsPipeline.h" +#include +#include + +void main(int argc, char *argv[]) { + if (argc < 3) { + std::cerr << "Usage: " << argv[0] << " " + << std::endl; + } + + std::string videoPath = argv[argc - 2]; + std::string outFolderPath = argv[argc - 1]; + + GenerateThumbnailsPipeline pipelineInstance; + if (!pipelineInstance.setUpPipeLine(videoPath, outFolderPath)) { + std::cerr << "Failed to setup pipeline." << std::endl; + } + + if (!pipelineInstance.startPipeLine()) { + std::cerr << "Failed to start pipeline." << std::endl; + } + + // Wait for the pipeline to run for 10 seconds + boost::this_thread::sleep_for(boost::chrono::seconds(5)); + + // Stop the pipeline + if (!pipelineInstance.stopPipeLine()) { + std::cerr << "Failed to stop pipeline." << std::endl; + } +} \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp index 60b8830fe..9246eb4b8 100644 --- a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp @@ -1,30 +1,31 @@ +#include "GenerateThumbnailsPipeline.h" +#include "test_utils.h" #include #include -#include "../../base/test/test_utils.h" -#include "GenerateThumbnailsPipeline.h" BOOST_AUTO_TEST_SUITE(generateThumbnails) -BOOST_AUTO_TEST_CASE(generateThumbnails_from_mp4) -{ - auto generateThumbnailPipeline = boost::shared_ptr(new GenerateThumbnailsPipeline()); - generateThumbnailPipeline->setUpPipeLine(); - generateThumbnailPipeline->startPipeLine(); - - boost::this_thread::sleep_for(boost::chrono::seconds(5)); +BOOST_AUTO_TEST_CASE(generateThumbnails_from_mp4) { + auto generateThumbnailPipeline = + boost::shared_ptr( + new GenerateThumbnailsPipeline()); + std::string videoPath = "C:/APRA/fork/ApraPipes/data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; + std::string outFolderPath = "C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/generated_thumbnail/thumbnail_????.jpg"; + generateThumbnailPipeline->setUpPipeLine(videoPath, outFolderPath); + generateThumbnailPipeline->startPipeLine(); - const uint8_t *pReadDataTest = nullptr; - unsigned int readDataSizeTest = 0U; + boost::this_thread::sleep_for(boost::chrono::seconds(5)); - BOOST_TEST( - Test_Utils::readFile("./data/thumbnail/sample_thumbnail.jpg", - pReadDataTest, readDataSizeTest)); - Test_Utils::saveOrCompare( - "./data/mp4Reader_saveOrCompare/h264/test_thumbnail.jpg", - pReadDataTest, readDataSizeTest, 0); + const uint8_t *pReadDataTest = nullptr; + unsigned int readDataSizeTest = 0U; + BOOST_TEST(Test_Utils::readFile("C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/test_thumbnail/sample_thumbnail.jpg", + pReadDataTest, readDataSizeTest)); + Test_Utils::saveOrCompare( + "C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/generated_thumbnail/thumbnail_0000.jpg", pReadDataTest, + readDataSizeTest, 0); - generateThumbnailPipeline->stopPipeLine(); + generateThumbnailPipeline->stopPipeLine(); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 53a3c59c2c7f671ca85a4212eb81352464661ad5 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 3 Jun 2024 19:21:17 +0530 Subject: [PATCH 11/13] refactored CMake and file structure for play mp4 from beginning sample --- .../play_mp4_from_beginning/CMakeLists.txt | 5 +- .../PlayMp4VideoFromBeginning.cpp | 74 ++++++++ .../PlayMp4VideoFromBeginning.h | 30 +-- .../play_mp4_from_beginning/pipelineMain.cpp | 31 +++ .../play_mp4_video_from_beginning.cpp | 176 ------------------ .../test_play_mp4_video_from_beginning.cpp | 87 ++++++++- 6 files changed, 200 insertions(+), 203 deletions(-) create mode 100644 samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp create mode 100644 samples/play_mp4_from_beginning/pipelineMain.cpp delete mode 100644 samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp diff --git a/samples/play_mp4_from_beginning/CMakeLists.txt b/samples/play_mp4_from_beginning/CMakeLists.txt index 69878b0b5..8d14c5e00 100644 --- a/samples/play_mp4_from_beginning/CMakeLists.txt +++ b/samples/play_mp4_from_beginning/CMakeLists.txt @@ -1,12 +1,11 @@ cmake_minimum_required(VERSION 3.22) set(TARGET play_mp4_from_beginning) SET(CORE_FILES - play_mp4_video_from_beginning.cpp - ../../base/test/test_utils.cpp + PlayMp4VideoFromBeginning.cpp + pipelineMain.cpp ) SET(CORE_FILES_H PlayMp4VideoFromBeginning.h - ../../base/test/test_utils.h ) SET(SOURCE ${CORE_FILES} diff --git a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp new file mode 100644 index 000000000..7b6a011a1 --- /dev/null +++ b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp @@ -0,0 +1,74 @@ + +#include "PlayMp4VideoFromBeginning.h" +#include "ColorConversionXForm.h" +#include "CudaMemCopy.h" +#include "ExternalSinkModule.h" +#include "FileWriterModule.h" +#include "Frame.h" +#include "FrameContainerQueue.h" +#include "FrameMetadata.h" +#include "H264Decoder.h" +#include "H264Metadata.h" +#include "ImageViewerModule.h" +#include "JPEGEncoderNVJPEG.h" +#include "Mp4ReaderSource.h" +#include "Mp4VideoMetadata.h" +#include + +PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() : pipeLine("pipeline") {} + +bool PlayMp4VideoFromBeginning::setUpPipeLine(const std::string &videoPath) { + // Implementation + bool parseFS = false; + auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); + auto frameType = FrameMetadata::FrameType::H264_DATA; + auto mp4ReaderProps = + Mp4ReaderSourceProps(videoPath, parseFS, 0, true, true, false); + mp4ReaderProps.fps = 24; + mp4Reader = + boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); + mp4Reader->addOutPutPin(h264ImageMetadata); + + auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); + mp4Reader->addOutPutPin(mp4Metadata); + + std::vector mImagePin; + mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + + decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + mp4Reader->setNext(decoder, mImagePin); + + auto conversionType = + ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; + auto metadata = framemetadata_sp(new RawImagePlanarMetadata( + 1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); + colorchange = boost::shared_ptr( + new ColorConversion(ColorConversionProps(conversionType))); + decoder->setNext(colorchange); + + imageViewerSink = boost::shared_ptr( + new ImageViewerModule(ImageViewerModuleProps("imageview"))); + colorchange->setNext(imageViewerSink); + + return true; +} + +bool PlayMp4VideoFromBeginning::startPipeLine() { + pipeLine.appendModule(mp4Reader); + pipeLine.init(); + pipeLine.run_all_threaded(); + return true; +} + +bool PlayMp4VideoFromBeginning::stopPipeLine() { + pipeLine.stop(); + pipeLine.term(); + pipeLine.wait_for_all(); + return true; +} + +bool PlayMp4VideoFromBeginning::flushQueuesAndSeek() { + pipeLine.flushAllQueues(); + mp4Reader->randomSeek(1686723796848, false); + return true; +} diff --git a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h index 6fa0c45bc..6f4458452 100644 --- a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h +++ b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h @@ -1,24 +1,24 @@ -#include -#include "Mp4ReaderSource.h" -#include "ImageViewerModule.h" #include "ColorConversionXForm.h" #include "H264Decoder.h" +#include "ImageViewerModule.h" +#include "Mp4ReaderSource.h" +#include class PlayMp4VideoFromBeginning { public: - PlayMp4VideoFromBeginning(); - bool setUpPipeLine(); - bool startPipeLine(); - bool stopPipeLine(); - bool flushQueuesAndSeek(); - bool testPipeLineForFlushQue(); - bool testPipeLineForSeek(); + PlayMp4VideoFromBeginning(); + bool setUpPipeLine(const std::string &videoPath); + bool startPipeLine(); + bool stopPipeLine(); + bool flushQueuesAndSeek(); + + + boost::shared_ptr mp4Reader; + boost::shared_ptr imageViewerSink; + boost::shared_ptr decoder; + boost::shared_ptr colorchange; private: - PipeLine pipeLine; - boost::shared_ptr mp4Reader; - boost::shared_ptr imageViewerSink; - boost::shared_ptr decoder; - boost::shared_ptr colorchange; + PipeLine pipeLine; }; \ No newline at end of file diff --git a/samples/play_mp4_from_beginning/pipelineMain.cpp b/samples/play_mp4_from_beginning/pipelineMain.cpp new file mode 100644 index 000000000..6eba9548b --- /dev/null +++ b/samples/play_mp4_from_beginning/pipelineMain.cpp @@ -0,0 +1,31 @@ +#include "PlayMp4VideoFromBeginning.h" +#include +#include + +void main(int argc, char *argv[]) { + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " " + << std::endl; + } + std::string videoPath = argv[argc - 1]; + + PlayMp4VideoFromBeginning pipelineInstance; + + + if (!pipelineInstance.setUpPipeLine(videoPath)){ + std::cerr << "Failed to setup pipeline." << std::endl; + } + if (!pipelineInstance.startPipeLine()) { + std::cerr << "Failed to start pipeline." << std::endl; + } + // Wait for the pipeline to run for 10 seconds + boost::this_thread::sleep_for(boost::chrono::seconds(3)); + if (!pipelineInstance.flushQueuesAndSeek()) { + std::cerr << "Failed to flush Queues." << std::endl; + } + boost::this_thread::sleep_for(boost::chrono::seconds(5)); + // Stop the pipeline + if (!pipelineInstance.stopPipeLine()) { + std::cerr << "Failed to stop pipeline." << std::endl; + } +} \ No newline at end of file diff --git a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp deleted file mode 100644 index 70eda7a5a..000000000 --- a/samples/play_mp4_from_beginning/play_mp4_video_from_beginning.cpp +++ /dev/null @@ -1,176 +0,0 @@ - -#include "PlayMp4VideoFromBeginning.h" -#include "FrameMetadata.h" -#include "H264Metadata.h" -#include "Mp4ReaderSource.h" -#include "Mp4VideoMetadata.h" -#include "H264Decoder.h" -#include "ValveModule.h" -#include "ColorConversionXForm.h" -#include "CudaMemCopy.h" -#include "FileWriterModule.h" -#include "JPEGEncoderNVJPEG.h" -#include "ExternalSinkModule.h" -#include "ImageViewerModule.h" -#include -#include -#include "Frame.h" -#include "FrameContainerQueue.h" -#include "../../base/test/test_utils.h" - -class SinkModuleProps : public ModuleProps { -public: - SinkModuleProps() : ModuleProps(){}; -}; - -class SinkModule : public Module { -public: - SinkModule(SinkModuleProps props) : Module(SINK, "sinkModule", props){}; - boost::shared_ptr getQue() { return Module::getQue(); } - frame_container pop() { return Module::pop(); } - -protected: - bool process() { return false; } - bool validateOutputPins() { return true; } - bool validateInputPins() { return true; } -}; - -PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() : pipeLine("pipeline") { - -} - -bool PlayMp4VideoFromBeginning::testPipeLineForFlushQue() { - auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); - colorchange->setNext(sink); - - BOOST_CHECK(mp4Reader->init()); - BOOST_CHECK(decoder->init()); - BOOST_CHECK(colorchange->init()); - BOOST_CHECK(sink->init()); - - for (int i = 0; i <= 20; i++) { - mp4Reader->step(); - decoder->step(); - } - colorchange->step(); - - auto frames = sink->pop(); - auto frame = frames.size(); - auto sinkQue = sink->getQue(); - BOOST_CHECK_EQUAL(frames.size(), 1); - sinkQue->flush(); - BOOST_CHECK_EQUAL(sinkQue->size(), 0); - frame_sp outputFrame = frames.cbegin()->second; - Test_Utils::saveOrCompare("../.././data/mp4Reader_saveOrCompare/h264/testplay.raw", const_cast(static_cast(outputFrame->data())), outputFrame->size(), 0); - return true; -} -bool PlayMp4VideoFromBeginning::testPipeLineForSeek() { - auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); - mp4Reader->setNext(sink); - - BOOST_CHECK(mp4Reader->init()); - BOOST_CHECK(decoder->init()); - BOOST_CHECK(colorchange->init()); - BOOST_CHECK(sink->init()); - - mp4Reader->step(); - - auto frames = sink->pop(); - auto imgFrame = frames.begin()->second; - - uint64_t skipTS = 1686723797848; - mp4Reader->randomSeek(skipTS, false); - mp4Reader->step(); - BOOST_TEST(imgFrame->timestamp == 1686723797856); - LOG_INFO << "Found next available frame " << imgFrame->timestamp - skipTS - << " msecs later from skipTS"; - - return true; -} -bool PlayMp4VideoFromBeginning::setUpPipeLine() { - // Implementation - std::string videoPath = "../.././data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; - std::string outPath = "../.././data/mp4Reader_saveOrCompare/h264/frame_000???.jpg"; - - bool parseFS = false; - auto h264ImageMetadata = framemetadata_sp(new H264Metadata(0, 0)); - auto frameType = FrameMetadata::FrameType::H264_DATA; - auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, true, false); - mp4ReaderProps.fps = 24; - mp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); - mp4Reader->addOutPutPin(h264ImageMetadata); - - auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); - mp4Reader->addOutPutPin(mp4Metadata); - - std::vector mImagePin; - mImagePin = mp4Reader->getAllOutputPinsByType(frameType); - - decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); - mp4Reader->setNext(decoder, mImagePin); - - auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; - auto metadata = framemetadata_sp(new RawImagePlanarMetadata(1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); - colorchange = boost::shared_ptr(new ColorConversion(ColorConversionProps(conversionType))); - decoder->setNext(colorchange); - - imageViewerSink = boost::shared_ptr( - new ImageViewerModule(ImageViewerModuleProps("imageview"))); - colorchange->setNext(imageViewerSink); - - return true; -} - -bool PlayMp4VideoFromBeginning::startPipeLine() { - pipeLine.appendModule(mp4Reader); - pipeLine.init(); - pipeLine.run_all_threaded(); - return true; -} - -bool PlayMp4VideoFromBeginning::stopPipeLine() { - pipeLine.stop(); - pipeLine.term(); - pipeLine.wait_for_all(); - return true; -} - -bool PlayMp4VideoFromBeginning::flushQueuesAndSeek() { - pipeLine.flushAllQueues(); - mp4Reader->randomSeek(1686723796848, false); - return true; -} - -int main() { - PlayMp4VideoFromBeginning pipelineInstance; - if (!pipelineInstance.setUpPipeLine()) { - std::cerr << "Failed to setup pipeline." << std::endl; - return 1; - } - if (!pipelineInstance.testPipeLineForFlushQue()) { - std::cerr << "Failed to test pipeline." << std::endl; - return 1; - } - //if (!pipelineInstance.testPipeLineForSeek()) { - // std::cerr << "Failed to test pipeline." << std::endl; - // return 1; - //} - //if (!pipelineInstance.startPipeLine()) { - // std::cerr << "Failed to start pipeline." << std::endl; - // return 1; // Or any error code indicating failure - //} - // Wait for the pipeline to run for 10 seconds - boost::this_thread::sleep_for(boost::chrono::seconds(3)); - if (!pipelineInstance.flushQueuesAndSeek()) { - std::cerr << "Failed to flush Queues." << std::endl; - return 1; - } - boost::this_thread::sleep_for(boost::chrono::seconds(5)); - // Stop the pipeline - if (!pipelineInstance.stopPipeLine()) { - std::cerr << "Failed to stop pipeline." << std::endl; - return 1; // Or any error code indicating failure - } - - return 0; // Or any success code -} diff --git a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp index 8586303be..e99a02cc4 100644 --- a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp +++ b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp @@ -1,18 +1,87 @@ -#include - +#include "Frame.h" +#include "FrameContainerQueue.h" #include "PlayMp4VideoFromBeginning.h" +#include "test_utils.h" +#include BOOST_AUTO_TEST_SUITE(start_video_from_beginning) +class SinkModuleProps : public ModuleProps { +public: + SinkModuleProps() : ModuleProps(){}; +}; + +class SinkModule : public Module { +public: + SinkModule(SinkModuleProps props) : Module(SINK, "sinkModule", props){}; + boost::shared_ptr getQue() { return Module::getQue(); } + frame_container pop() { return Module::pop(); } + +protected: + bool process() { return false; } + bool validateOutputPins() { return true; } + bool validateInputPins() { return true; } +}; + +BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_flush_queue_test) { + auto playMp4VideoFromBeginning = boost::shared_ptr( + new PlayMp4VideoFromBeginning()); + std::string videoPath = "C:/APRA/fork/ApraPipes/data/Mp4_videos/" + "h264_video_metadata/20230514/0011/1686723796848.mp4"; + playMp4VideoFromBeginning->setUpPipeLine(videoPath); + + auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); + playMp4VideoFromBeginning->colorchange->setNext(sink); + BOOST_CHECK(playMp4VideoFromBeginning->mp4Reader->init()); + BOOST_CHECK(playMp4VideoFromBeginning->decoder->init()); + BOOST_CHECK(playMp4VideoFromBeginning->colorchange->init()); + BOOST_CHECK(sink->init()); + + for (int i = 0; i <= 20; i++) { + playMp4VideoFromBeginning->mp4Reader->step(); + playMp4VideoFromBeginning->decoder->step(); + } + playMp4VideoFromBeginning->colorchange->step(); + + auto frames = sink->pop(); + auto frame = frames.size(); + auto sinkQue = sink->getQue(); + BOOST_CHECK_EQUAL(frames.size(), 1); + sinkQue->flush(); + BOOST_CHECK_EQUAL(sinkQue->size(), 0); + frame_sp outputFrame = frames.cbegin()->second; + Test_Utils::saveOrCompare( + "./data/mp4Reader_saveOrCompare/h264/testplay.raw", + const_cast(static_cast(outputFrame->data())), + outputFrame->size(), 0); +} + +BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_seek_test) { + auto playMp4VideoFromBeginning = boost::shared_ptr( + new PlayMp4VideoFromBeginning()); + std::string videoPath = "C:/APRA/fork/ApraPipes/data/Mp4_videos/" + "h264_video_metadata/20230514/0011/1686723796848.mp4"; + playMp4VideoFromBeginning->setUpPipeLine(videoPath); + auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); + playMp4VideoFromBeginning->mp4Reader->setNext(sink); + + BOOST_CHECK(playMp4VideoFromBeginning->mp4Reader->init()); + BOOST_CHECK(playMp4VideoFromBeginning->decoder->init()); + BOOST_CHECK(playMp4VideoFromBeginning->colorchange->init()); + BOOST_CHECK(sink->init()); -BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_flush_queue_test) -{ - auto playMp4VideoFromBeginning = boost::shared_ptr(new PlayMp4VideoFromBeginning()); - playMp4VideoFromBeginning->setUpPipeLine(); - playMp4VideoFromBeginning->startPipeLine(); + playMp4VideoFromBeginning->mp4Reader->step(); - boost::this_thread::sleep_for(boost::chrono::seconds(10)); + auto frames = sink->pop(); + auto imgFrame = frames.begin()->second; - playMp4VideoFromBeginning->stopPipeLine(); + uint64_t skipTS = 1686723796848; + playMp4VideoFromBeginning->mp4Reader->randomSeek(skipTS, false); + playMp4VideoFromBeginning->mp4Reader->step(); + frames = sink->pop(); + imgFrame = frames.begin()->second; + BOOST_TEST(imgFrame->timestamp == 1686723796848); + LOG_INFO << "Found next available frame " << imgFrame->timestamp - skipTS + << " msecs later from skipTS"; } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From b26a87197e1ea237d21799821dc39745917b7ea0 Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 3 Jun 2024 19:25:04 +0530 Subject: [PATCH 12/13] base CMake changes --- base/CMakeLists.txt | 61 +++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index 74a575e41..e41315ed6 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -163,8 +163,6 @@ SET(CORE_FILES src/MotionVectorExtractor.cpp src/OverlayModule.cpp src/OrderedCacheOfFiles.cpp - .././samples/create_thumbnail_from_mp4_video/generate_thumbnail_from_mp4_video.cpp - .././samples/timelapse-sample/timelapse_summary.h ) SET(CORE_FILES_H @@ -226,8 +224,6 @@ SET(CORE_FILES_H include/OverlayModule.h include/OrderedCacheOfFiles.h include/TestSignalGeneratorSrc.h - .././samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h - .././samples/timelapse-sample/timelapse_summary.cpp ) IF(ENABLE_WINDOWS) @@ -460,8 +456,6 @@ ${LIBMP4_INC_DIR} ${BARESIP_INC_DIR} ${LIBRE_INC_DIR} ${NVCODEC_INCLUDE_DIR} -.././samples/create_thumbnail_from_mp4_video -./../samples/timelapse-sample ) @@ -573,11 +567,25 @@ SET(UT_FILES ) SET(SAMPLE_UT_FILES + test/utmain.cpp test/test_utils.cpp test/test_utils.h - .././samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp - .././samples/play_mp4_from_beginningtest_play_mp4_video_from_beginning.cpp + ../samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp + ../samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp +) + +SET(SAMPLE_CORE_FILES + ../samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h + ../samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp + ../samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h + ../samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp +) + +SET(SAMPLE_SOURCE + ${SAMPLE_CORE_FILES} + ${SAMPLE_UT_FILES} ) + IF(ENABLE_LINUX) list(APPEND UT_FILES test/virtualcamerasink_tests.cpp @@ -585,9 +593,20 @@ IF(ENABLE_LINUX) ) ENDIF(ENABLE_LINUX) - add_executable(aprapipesut ${UT_FILES}) -add_executable(aprapipessampleut ${SAMPLE_UT_FILES}) +add_executable(aprapipessampleut ${SAMPLE_SOURCE}) + +target_include_directories ( aprapipessampleut PRIVATE +${JETSON_MULTIMEDIA_LIB_INCLUDE} +${FFMPEG_INCLUDE_DIRS} +${OpenCV_INCLUDE_DIRS} +${Boost_INCLUDE_DIRS} +${LIBMP4_INC_DIR} +${BARESIP_INC_DIR} +${LIBRE_INC_DIR} +${NVCODEC_INCLUDE_DIR} +test +) IF(ENABLE_ARM64) target_include_directories ( aprapipesut PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_ROOT} ${JPEG_INCLUDE_DIR}) @@ -601,28 +620,6 @@ ENDIF (ENABLE_CUDA) find_library(OPENH264_LIB NAMES openh264.lib libopenh264.a REQUIRED) find_library(LIBMP4_LIB NAMES mp4lib.lib libmp4lib.a REQUIRED) -target_link_libraries(aprapipessampleut - aprapipes - ${JPEG_LIBRARIES} - ${LIBMP4_LIB} - ${OPENH264_LIB} - ${Boost_LIBRARIES} - ${FFMPEG_LIBRARIES} - ${OpenCV_LIBRARIES} - ${JETSON_LIBS} - ${NVCUDAToolkit_LIBS} - ${NVCODEC_LIB} - ${NVJPEGLIB_L4T} - ${CURSES_LIBRARIES} - ZXing::Core - ZXing::ZXing - BZip2::BZip2 - ZLIB::ZLIB - liblzma::liblzma - bigint::bigint - sfml-audio - whisper::whisper - ) target_link_libraries(aprapipessampleut aprapipes From fab05b3b2683c8b170ab3720533d0674e701b89f Mon Sep 17 00:00:00 2001 From: SatwikSShanbhag Date: Mon, 24 Jun 2024 20:10:45 +0530 Subject: [PATCH 13/13] restored files --- .../CMakeLists.txt | 13 ++--- .../GenerateThumbnailsPipeline.cpp | 51 ++++++++++++------- .../GenerateThumbnailsPipeline.h | 14 ++--- .../pipelineMain.cpp | 10 ++-- ...test_generate_thumbnail_from_mp4_video.cpp | 12 ++--- .../play_mp4_from_beginning/CMakeLists.txt | 22 +++----- .../PlayMp4VideoFromBeginning.cpp | 41 ++++++++++----- .../PlayMp4VideoFromBeginning.h | 8 +-- .../play_mp4_from_beginning/pipelineMain.cpp | 3 +- .../test_play_mp4_video_from_beginning.cpp | 28 +++++----- 10 files changed, 110 insertions(+), 92 deletions(-) diff --git a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt index 0a210d28f..f80673668 100644 --- a/samples/create_thumbnail_from_mp4_video/CMakeLists.txt +++ b/samples/create_thumbnail_from_mp4_video/CMakeLists.txt @@ -1,25 +1,22 @@ cmake_minimum_required(VERSION 3.22) set(TARGET generateThumbnailFromMp4Video) -SET(CORE_FILES +SET(SAMPLE_FILES GenerateThumbnailsPipeline.cpp pipelineMain.cpp ) -SET(CORE_FILES_H +SET(SAMPLE_FILES_H GenerateThumbnailsPipeline.h ) SET(SOURCE - ${CORE_FILES} - ${CORE_FILES_H} + ${SAMPLE_FILES} + ${SAMPLE_FILES_H} ) add_executable(${TARGET} ${SOURCE}) target_include_directories ( ${TARGET} PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} - ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${LIBMP4_INC_DIR} - ${BARESIP_INC_DIR} - ${LIBRE_INC_DIR} ${NVCODEC_INCLUDE_DIR} ) target_link_libraries( @@ -31,9 +28,7 @@ target_link_libraries( ${Boost_LIBRARIES} ${FFMPEG_LIBRARIES} ${OpenCV_LIBRARIES} - ${JETSON_LIBS} ${NVCUDAToolkit_LIBS} ${NVCODEC_LIB} ${NVJPEGLIB_L4T} - ${CURSES_LIBRARIES} ) \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp index a0bba2abd..16ffe45cb 100644 --- a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.cpp @@ -8,13 +8,14 @@ #include "H264Decoder.h" #include "H264Metadata.h" #include "JPEGEncoderNVJPEG.h" +#include "Logger.h" #include "Mp4ReaderSource.h" #include "Mp4VideoMetadata.h" #include "ValveModule.h" #include GenerateThumbnailsPipeline::GenerateThumbnailsPipeline() - : pipeLine("pipeline") {} + : pipeLine("thumnailSamplePipeline") {} bool GenerateThumbnailsPipeline::setUpPipeLine( const std::string &videoPath, const std::string &outFolderPath) { @@ -25,43 +26,57 @@ bool GenerateThumbnailsPipeline::setUpPipeLine( auto frameType = FrameMetadata::FrameType::H264_DATA; auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, false, false); - mp4Reader = + //initializing source Mp4 reader to read Mp4 video + mMp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); - mp4Reader->addOutPutPin(h264ImageMetadata); + mMp4Reader->addOutPutPin(h264ImageMetadata); auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); - mp4Reader->addOutPutPin(mp4Metadata); + mMp4Reader->addOutPutPin(mp4Metadata); std::vector mImagePin; - mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + mImagePin = mMp4Reader->getAllOutputPinsByType(frameType); - decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); - mp4Reader->setNext(decoder, mImagePin); + //initializing H264 decoder to decode frame in H264 format + mDecoder = + boost::shared_ptr(new H264Decoder(H264DecoderProps())); + //Selecting an image pin of H264 data frame type is necessary because the decoder processes H264 frames for decoding. + mMp4Reader->setNext(mDecoder, mImagePin); - valve = boost::shared_ptr(new ValveModule(ValveModuleProps(0))); - decoder->setNext(valve); + //Initializing the valve to send only one frame. It is currently set to 0, meaning no frames are captured. + mValve = boost::shared_ptr(new ValveModule(ValveModuleProps(0))); + mDecoder->setNext(mValve); + //initialize cuda memory auto stream = cudastream_sp(new ApraCudaStream); - cudaCopy = boost::shared_ptr( + mCudaCopy = boost::shared_ptr( new CudaMemCopy(CudaMemCopyProps(cudaMemcpyHostToDevice, stream))); - valve->setNext(cudaCopy); + mValve->setNext(mCudaCopy); - jpegEncoder = boost::shared_ptr( + //initializing Jpeg encoder to encode the frame in jpeg format + mJpegEncoder = boost::shared_ptr( new JPEGEncoderNVJPEG(JPEGEncoderNVJPEGProps(stream))); - cudaCopy->setNext(jpegEncoder); + mCudaCopy->setNext(mJpegEncoder); - fileWriter = boost::shared_ptr( + //initilizing file writer as sink to write frame at given path + mFileWriter = boost::shared_ptr( new FileWriterModule(FileWriterModuleProps(outFolderPath))); - jpegEncoder->setNext(fileWriter); + mJpegEncoder->setNext(mFileWriter); return true; } bool GenerateThumbnailsPipeline::startPipeLine() { - pipeLine.appendModule(mp4Reader); - pipeLine.init(); + pipeLine.appendModule(mMp4Reader); + if (!pipeLine.init()) { + throw AIPException( + AIP_FATAL, + "Engine Pipeline init failed. Check IPEngine Logs for more details."); + return false; + } pipeLine.run_all_threaded(); - valve->allowFrames(1); + //allowing only one frame to get captured. + mValve->allowFrames(1); return true; } diff --git a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h index cabeeff16..b421c74f0 100644 --- a/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h +++ b/samples/create_thumbnail_from_mp4_video/GenerateThumbnailsPipeline.h @@ -19,12 +19,12 @@ class GenerateThumbnailsPipeline private: PipeLine pipeLine; - boost::shared_ptr valve; - boost::shared_ptr mp4Reader; - boost::shared_ptr decoder; - boost::shared_ptr colorchange; - boost::shared_ptr cudaCopy; - boost::shared_ptr jpegEncoder; - boost::shared_ptr fileWriter; + boost::shared_ptr mValve; + boost::shared_ptr mMp4Reader; + boost::shared_ptr mDecoder; + boost::shared_ptr mColorchange; + boost::shared_ptr mCudaCopy; + boost::shared_ptr mJpegEncoder; + boost::shared_ptr mFileWriter; }; diff --git a/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp b/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp index 759d47475..0b0d4f11b 100644 --- a/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp +++ b/samples/create_thumbnail_from_mp4_video/pipelineMain.cpp @@ -11,12 +11,12 @@ void main(int argc, char *argv[]) { std::string videoPath = argv[argc - 2]; std::string outFolderPath = argv[argc - 1]; - GenerateThumbnailsPipeline pipelineInstance; - if (!pipelineInstance.setUpPipeLine(videoPath, outFolderPath)) { + GenerateThumbnailsPipeline thumbnailPipeline; + if (!thumbnailPipeline.setUpPipeLine(videoPath, outFolderPath)) { std::cerr << "Failed to setup pipeline." << std::endl; } - if (!pipelineInstance.startPipeLine()) { + if (!thumbnailPipeline.startPipeLine()) { std::cerr << "Failed to start pipeline." << std::endl; } @@ -24,7 +24,9 @@ void main(int argc, char *argv[]) { boost::this_thread::sleep_for(boost::chrono::seconds(5)); // Stop the pipeline - if (!pipelineInstance.stopPipeLine()) { + if (!thumbnailPipeline.stopPipeLine()) { std::cerr << "Failed to stop pipeline." << std::endl; + } else { + std::cerr << "Saved Generated Thumbnail in <" << outFolderPath << ">"; } } \ No newline at end of file diff --git a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp index 9246eb4b8..a4232aa65 100644 --- a/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp +++ b/samples/create_thumbnail_from_mp4_video/test_generate_thumbnail_from_mp4_video.cpp @@ -9,20 +9,20 @@ BOOST_AUTO_TEST_CASE(generateThumbnails_from_mp4) { auto generateThumbnailPipeline = boost::shared_ptr( new GenerateThumbnailsPipeline()); - std::string videoPath = "C:/APRA/fork/ApraPipes/data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; - std::string outFolderPath = "C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/generated_thumbnail/thumbnail_????.jpg"; - generateThumbnailPipeline->setUpPipeLine(videoPath, outFolderPath); - generateThumbnailPipeline->startPipeLine(); + std::string videoPath = "../../data/Mp4_videos/h264_video_metadata/20230514/0011/1686723796848.mp4"; + std::string outFolderPath = "data/generated_thumbnail/thumbnail_????.jpg"; + BOOST_CHECK_NO_THROW(generateThumbnailPipeline->setUpPipeLine(videoPath, outFolderPath)); + BOOST_CHECK_NO_THROW(generateThumbnailPipeline->startPipeLine()); boost::this_thread::sleep_for(boost::chrono::seconds(5)); const uint8_t *pReadDataTest = nullptr; unsigned int readDataSizeTest = 0U; - BOOST_TEST(Test_Utils::readFile("C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/test_thumbnail/sample_thumbnail.jpg", + BOOST_TEST(Test_Utils::readFile("data/test_thumbnail/sample_thumbnail.jpg", pReadDataTest, readDataSizeTest)); Test_Utils::saveOrCompare( - "C:/APRA/fork/ApraPipes/samples/create_thumbnail_from_mp4_video/data/generated_thumbnail/thumbnail_0000.jpg", pReadDataTest, + "data/generated_thumbnail/thumbnail_0000.jpg", pReadDataTest, readDataSizeTest, 0); generateThumbnailPipeline->stopPipeLine(); diff --git a/samples/play_mp4_from_beginning/CMakeLists.txt b/samples/play_mp4_from_beginning/CMakeLists.txt index 8d14c5e00..7d46995bc 100644 --- a/samples/play_mp4_from_beginning/CMakeLists.txt +++ b/samples/play_mp4_from_beginning/CMakeLists.txt @@ -1,26 +1,21 @@ cmake_minimum_required(VERSION 3.22) set(TARGET play_mp4_from_beginning) -SET(CORE_FILES +SET(SAMPLE_FILES PlayMp4VideoFromBeginning.cpp pipelineMain.cpp ) -SET(CORE_FILES_H +SET(SAMPLE_FILES_H PlayMp4VideoFromBeginning.h ) SET(SOURCE - ${CORE_FILES} - ${CORE_FILES_H} + ${SAMPLE_FILES} + ${SAMPLE_FILES_H} ) add_executable(${TARGET} ${SOURCE}) target_include_directories ( ${TARGET} PRIVATE - ${JETSON_MULTIMEDIA_LIB_INCLUDE} - ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${LIBMP4_INC_DIR} - ${BARESIP_INC_DIR} - ${LIBRE_INC_DIR} - ${NVCODEC_INCLUDE_DIR} ) target_link_libraries( ${TARGET} @@ -29,11 +24,10 @@ target_link_libraries( ${LIBMP4_LIB} ${OPENH264_LIB} ${Boost_LIBRARIES} - ${FFMPEG_LIBRARIES} ${OpenCV_LIBRARIES} - ${JETSON_LIBS} ${NVCUDAToolkit_LIBS} - ${NVCODEC_LIB} ${NVJPEGLIB_L4T} - ${CURSES_LIBRARIES} - ) \ No newline at end of file + ${NVCODEC_LIB} + ${FFMPEG_LIBRARIES} + ) + \ No newline at end of file diff --git a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp index 7b6a011a1..a3d9a0892 100644 --- a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp +++ b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.cpp @@ -15,7 +15,8 @@ #include "Mp4VideoMetadata.h" #include -PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() : pipeLine("pipeline") {} +PlayMp4VideoFromBeginning::PlayMp4VideoFromBeginning() + : pipeLine("PlayMp4videoFromBeginingSamplePipline") {} bool PlayMp4VideoFromBeginning::setUpPipeLine(const std::string &videoPath) { // Implementation @@ -25,37 +26,49 @@ bool PlayMp4VideoFromBeginning::setUpPipeLine(const std::string &videoPath) { auto mp4ReaderProps = Mp4ReaderSourceProps(videoPath, parseFS, 0, true, true, false); mp4ReaderProps.fps = 24; - mp4Reader = + // initializing source Mp4 reader to read Mp4 video + mMp4Reader = boost::shared_ptr(new Mp4ReaderSource(mp4ReaderProps)); - mp4Reader->addOutPutPin(h264ImageMetadata); + mMp4Reader->addOutPutPin(h264ImageMetadata); auto mp4Metadata = framemetadata_sp(new Mp4VideoMetadata("v_1")); - mp4Reader->addOutPutPin(mp4Metadata); + mMp4Reader->addOutPutPin(mp4Metadata); std::vector mImagePin; - mImagePin = mp4Reader->getAllOutputPinsByType(frameType); + mImagePin = mMp4Reader->getAllOutputPinsByType(frameType); - decoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); - mp4Reader->setNext(decoder, mImagePin); + // initializing H264 decoder to decode frame in H264 format + mDecoder = boost::shared_ptr(new H264Decoder(H264DecoderProps())); + // Selecting an image pin of H264 data frame type is necessary because the + // decoder processes H264 frames for decoding. + mMp4Reader->setNext(mDecoder, mImagePin); + + //initializing conversion type module to convert YUV420 frame to RGB auto conversionType = ColorConversionProps::ConversionType::YUV420PLANAR_TO_RGB; auto metadata = framemetadata_sp(new RawImagePlanarMetadata( 1280, 720, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U)); - colorchange = boost::shared_ptr( + mColorchange = boost::shared_ptr( new ColorConversion(ColorConversionProps(conversionType))); - decoder->setNext(colorchange); + mDecoder->setNext(mColorchange); - imageViewerSink = boost::shared_ptr( + //initializing imageViewer module as sink to show video on screen + mImageViewerSink = boost::shared_ptr( new ImageViewerModule(ImageViewerModuleProps("imageview"))); - colorchange->setNext(imageViewerSink); + mColorchange->setNext(mImageViewerSink); return true; } bool PlayMp4VideoFromBeginning::startPipeLine() { - pipeLine.appendModule(mp4Reader); - pipeLine.init(); + pipeLine.appendModule(mMp4Reader); + if (!pipeLine.init()) { + throw AIPException( + AIP_FATAL, + "Engine Pipeline init failed. Check IPEngine Logs for more details."); + return false; + } pipeLine.run_all_threaded(); return true; } @@ -69,6 +82,6 @@ bool PlayMp4VideoFromBeginning::stopPipeLine() { bool PlayMp4VideoFromBeginning::flushQueuesAndSeek() { pipeLine.flushAllQueues(); - mp4Reader->randomSeek(1686723796848, false); + mMp4Reader->randomSeek(1686723796848, false); return true; } diff --git a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h index 6f4458452..d489e752c 100644 --- a/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h +++ b/samples/play_mp4_from_beginning/PlayMp4VideoFromBeginning.h @@ -14,10 +14,10 @@ class PlayMp4VideoFromBeginning { bool flushQueuesAndSeek(); - boost::shared_ptr mp4Reader; - boost::shared_ptr imageViewerSink; - boost::shared_ptr decoder; - boost::shared_ptr colorchange; + boost::shared_ptr mMp4Reader; + boost::shared_ptr mImageViewerSink; + boost::shared_ptr mDecoder; + boost::shared_ptr mColorchange; private: PipeLine pipeLine; diff --git a/samples/play_mp4_from_beginning/pipelineMain.cpp b/samples/play_mp4_from_beginning/pipelineMain.cpp index 6eba9548b..3274cf83e 100644 --- a/samples/play_mp4_from_beginning/pipelineMain.cpp +++ b/samples/play_mp4_from_beginning/pipelineMain.cpp @@ -11,8 +11,7 @@ void main(int argc, char *argv[]) { PlayMp4VideoFromBeginning pipelineInstance; - - if (!pipelineInstance.setUpPipeLine(videoPath)){ + if (!pipelineInstance.setUpPipeLine(videoPath)) { std::cerr << "Failed to setup pipeline." << std::endl; } if (!pipelineInstance.startPipeLine()) { diff --git a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp index e99a02cc4..e3e170a23 100644 --- a/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp +++ b/samples/play_mp4_from_beginning/test_play_mp4_video_from_beginning.cpp @@ -30,17 +30,17 @@ BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_flush_queue_test) { playMp4VideoFromBeginning->setUpPipeLine(videoPath); auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); - playMp4VideoFromBeginning->colorchange->setNext(sink); - BOOST_CHECK(playMp4VideoFromBeginning->mp4Reader->init()); - BOOST_CHECK(playMp4VideoFromBeginning->decoder->init()); - BOOST_CHECK(playMp4VideoFromBeginning->colorchange->init()); + playMp4VideoFromBeginning->mColorchange->setNext(sink); + BOOST_CHECK(playMp4VideoFromBeginning->mMp4Reader->init()); + BOOST_CHECK(playMp4VideoFromBeginning->mDecoder->init()); + BOOST_CHECK(playMp4VideoFromBeginning->mColorchange->init()); BOOST_CHECK(sink->init()); for (int i = 0; i <= 20; i++) { - playMp4VideoFromBeginning->mp4Reader->step(); - playMp4VideoFromBeginning->decoder->step(); + playMp4VideoFromBeginning->mMp4Reader->step(); + playMp4VideoFromBeginning->mDecoder->step(); } - playMp4VideoFromBeginning->colorchange->step(); + playMp4VideoFromBeginning->mColorchange->step(); auto frames = sink->pop(); auto frame = frames.size(); @@ -62,21 +62,21 @@ BOOST_AUTO_TEST_CASE(play_mp4_from_beginning_seek_test) { "h264_video_metadata/20230514/0011/1686723796848.mp4"; playMp4VideoFromBeginning->setUpPipeLine(videoPath); auto sink = boost::shared_ptr(new SinkModule(SinkModuleProps())); - playMp4VideoFromBeginning->mp4Reader->setNext(sink); + playMp4VideoFromBeginning->mMp4Reader->setNext(sink); - BOOST_CHECK(playMp4VideoFromBeginning->mp4Reader->init()); - BOOST_CHECK(playMp4VideoFromBeginning->decoder->init()); - BOOST_CHECK(playMp4VideoFromBeginning->colorchange->init()); + BOOST_CHECK(playMp4VideoFromBeginning->mMp4Reader->init()); + BOOST_CHECK(playMp4VideoFromBeginning->mDecoder->init()); + BOOST_CHECK(playMp4VideoFromBeginning->mColorchange->init()); BOOST_CHECK(sink->init()); - playMp4VideoFromBeginning->mp4Reader->step(); + playMp4VideoFromBeginning->mMp4Reader->step(); auto frames = sink->pop(); auto imgFrame = frames.begin()->second; uint64_t skipTS = 1686723796848; - playMp4VideoFromBeginning->mp4Reader->randomSeek(skipTS, false); - playMp4VideoFromBeginning->mp4Reader->step(); + playMp4VideoFromBeginning->mMp4Reader->randomSeek(skipTS, false); + playMp4VideoFromBeginning->mMp4Reader->step(); frames = sink->pop(); imgFrame = frames.begin()->second; BOOST_TEST(imgFrame->timestamp == 1686723796848);