diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index 5ebb7aee0be3..982bc5c87df0 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -1707,14 +1707,36 @@ bool CvCapture_FFMPEG::retrieveHWFrame(cv::OutputArray output) #endif } +static inline double getCodecTag(const AVCodecID codec_id) { + 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); +} + +static inline double getCodecIdFourcc(const AVCodecID codec_id) +{ + if (codec_id == AV_CODEC_ID_NONE) return -1; + const char* codec_fourcc = _opencv_avcodec_get_name(codec_id); + if (!codec_fourcc || strcmp(codec_fourcc, "unknown_codec") == 0 || strlen(codec_fourcc) != 4) + return getCodecTag(codec_id); + return (double)CV_FOURCC(codec_fourcc[0], codec_fourcc[1], codec_fourcc[2], codec_fourcc[3]); +} + double CvCapture_FFMPEG::getProperty( int property_id ) const { if( !video_st || !context ) return 0; - double codec_tag = 0; - CV_CODEC_ID codec_id = AV_CODEC_ID_NONE; - const char* codec_fourcc = NULL; - switch( property_id ) { case CAP_PROP_POS_MSEC: @@ -1738,34 +1760,11 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const case CAP_PROP_FPS: return get_fps(); 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; - - if(codec_tag || codec_id == AV_CODEC_ID_NONE) - { - return codec_tag; - } - - codec_fourcc = _opencv_avcodec_get_name(codec_id); - if (!codec_fourcc || strcmp(codec_fourcc, "unknown_codec") == 0 || strlen(codec_fourcc) != 4) - { - 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]); + const double fourcc = getCodecIdFourcc(video_st->CV_FFMPEG_CODEC_FIELD->codec_id); + if (fourcc != -1) return fourcc; + const double codec_tag = (double)video_st->CV_FFMPEG_CODEC_FIELD->codec_tag; + if (codec_tag) return codec_tag; + else return -1; } case CAP_PROP_SAR_NUM: return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).num; diff --git a/modules/videoio/test/test_ffmpeg.cpp b/modules/videoio/test/test_ffmpeg.cpp index d3f0d5b8fc0e..e0c2a4407571 100644 --- a/modules/videoio/test/test_ffmpeg.cpp +++ b/modules/videoio/test/test_ffmpeg.cpp @@ -226,7 +226,11 @@ const videoio_container_params_t videoio_container_params[] = videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264", "h264", "h264", "I420"), videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265", "h265", "hevc", "I420"), videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "mjpg.avi", "mjpg", "MJPG", "I420"), +#ifdef _WIN32 // handle old FFmpeg backend - remove when windows shared library is updated videoio_container_params_t(CAP_FFMPEG, "video/sample_322x242_15frames.yuv420p.libx264", "mp4", "h264", "avc1", "I420") +#else + videoio_container_params_t(CAP_FFMPEG, "video/sample_322x242_15frames.yuv420p.libx264", "mp4", "h264", "h264", "I420") +#endif //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mkv", "mkv.h264", "h264", "I420"), //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265.mkv", "mkv.h265", "hevc", "I420"), //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mp4", "mp4.avc1", "avc1", "I420"), @@ -448,10 +452,21 @@ TEST_P(ffmpeg_get_fourcc, check_short_codecs) 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") + ffmpeg_get_fourcc_param_t("video/big_buck_bunny.h264", "h264"), +#ifdef _WIN32 // handle old FFmpeg backend - remove when windows shared library is updated + 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") +#else + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libvpx-vp9.mp4", "VP90"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libaom-av1.mp4", "AV01"), + ffmpeg_get_fourcc_param_t("video/big_buck_bunny.mp4", "FMP4"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.mpeg2video.mp4", "mpg2"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.mjpeg.mp4", "MJPG"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libxvid.mp4", "FMP4"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libx265.mp4", "hevc"), + ffmpeg_get_fourcc_param_t("video/sample_322x242_15frames.yuv420p.libx264.mp4", "h264") +#endif }; INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_get_fourcc, testing::ValuesIn(ffmpeg_get_fourcc_param));