From 4b05765174fa2a0750aa8acc252329d6df73c2f1 Mon Sep 17 00:00:00 2001 From: cudawarped <12133430+cudawarped@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:18:42 +0300 Subject: [PATCH] Initial fix to try and return a valid fourcc when _opencv_avcodec_get_name fails. --- modules/videoio/src/cap_ffmpeg_impl.hpp | 20 +++++++++++++++++--- modules/videoio/test/test_ffmpeg.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index d02b045..caeae31 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -1699,7 +1699,7 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const return (double)av_get_picture_type_char(picture->pict_type); case CAP_PROP_FPS: return get_fps(); - case CAP_PROP_FOURCC: + case CAP_PROP_FOURCC: { codec_id = video_st->CV_FFMPEG_CODEC_FIELD->codec_id; codec_tag = (double) video_st->CV_FFMPEG_CODEC_FIELD->codec_tag; @@ -1709,12 +1709,26 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const } codec_fourcc = _opencv_avcodec_get_name(codec_id); - if(!codec_fourcc || strlen(codec_fourcc) < 4 || strcmp(codec_fourcc, "unknown_codec") == 0) + if (!codec_fourcc || strcmp(codec_fourcc, "unknown_codec") == 0 || strlen(codec_fourcc) != 4) { - return codec_tag; + const struct AVCodecTag* fallback_tags[] = { + // APIchanges: + // 2012-01-31 - dd6d3b0 - lavf 54.01.0 + // Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags(). + avformat_get_riff_video_tags(), +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 25, 100) && defined LIBAVFORMAT_VERSION_MICRO && LIBAVFORMAT_VERSION_MICRO >= 100 + // APIchanges: ffmpeg only + // 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h + // Add avformat_get_mov_video_tags() and avformat_get_mov_audio_tags(). + avformat_get_mov_video_tags(), +#endif + codec_bmp_tags, // fallback for avformat < 54.1 + NULL }; + return av_codec_get_tag(fallback_tags, codec_id); } return (double) CV_FOURCC(codec_fourcc[0], codec_fourcc[1], codec_fourcc[2], codec_fourcc[3]); + } case CAP_PROP_SAR_NUM: return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).num; case CAP_PROP_SAR_DEN: diff --git a/modules/videoio/test/test_ffmpeg.cpp b/modules/videoio/test/test_ffmpeg.cpp index 1157057..f59631c 100644 --- a/modules/videoio/test/test_ffmpeg.cpp +++ b/modules/videoio/test/test_ffmpeg.cpp @@ -399,7 +399,32 @@ const ffmpeg_cap_properties_param_t videoio_ffmpeg_properties[] = { INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties)); +typedef tuple ffmpeg_get_fourcc_param_t; +typedef testing::TestWithParam ffmpeg_get_fourcc; +TEST_P(ffmpeg_get_fourcc, check_short_codecs) +{ + const VideoCaptureAPIs api = CAP_FFMPEG; + if (!videoio_registry::hasBackend(api)) + throw SkipTestException("Backend was not found"); + const string fileName = get<0>(GetParam()); + const string fourcc = get<1>(GetParam()); + VideoCapture cap(findDataFile(fileName), api); + if (!cap.isOpened()) + throw SkipTestException("Video stream is not supported"); + ASSERT_EQ(fourccToString(cap.get(CAP_PROP_FOURCC)), fourcc); +} + +const ffmpeg_get_fourcc_param_t ffmpeg_get_fourcc_param[] = +{ + ffmpeg_get_fourcc_param_t("../cv/tracking/faceocc2/data/faceocc2.webm", "VP80"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libvpx-vp9.mp4", "vp09"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libaom-av1.mp4", "av01"), + ffmpeg_get_fourcc_param_t("video/big_buck_bunny.h265", "hevc"), + ffmpeg_get_fourcc_param_t("video/big_buck_bunny.h264", "h264") +}; + +INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_get_fourcc, testing::ValuesIn(ffmpeg_get_fourcc_param)); // related issue: https://github.com/opencv/opencv/issues/15499 TEST(videoio, mp4_orientation_meta_auto) -- 2.7.4