diff --git a/modules/videoio/include/opencv2/videoio/videoio_c.h b/modules/videoio/include/opencv2/videoio/videoio_c.h index 6d7bd640c6..ae0259fe7a 100644 --- a/modules/videoio/include/opencv2/videoio/videoio_c.h +++ b/modules/videoio/include/opencv2/videoio/videoio_c.h @@ -190,6 +190,8 @@ enum CV_CAP_PROP_SETTINGS =37, CV_CAP_PROP_BUFFERSIZE =38, CV_CAP_PROP_AUTOFOCUS =39, + CV_CAP_PROP_SAR_NUM =40, + CV_CAP_PROP_SAR_DEN =41, CV_CAP_PROP_AUTOGRAB =1024, // property for videoio class CvCapture_Android only CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING=1025, // readonly, tricky property, returns cpnst char* indeed diff --git a/modules/videoio/src/cap_ffmpeg_api.hpp b/modules/videoio/src/cap_ffmpeg_api.hpp index e7a956063c..0b7f45c8bf 100644 --- a/modules/videoio/src/cap_ffmpeg_api.hpp +++ b/modules/videoio/src/cap_ffmpeg_api.hpp @@ -23,7 +23,9 @@ enum CV_FFMPEG_CAP_PROP_FRAME_HEIGHT=4, CV_FFMPEG_CAP_PROP_FPS=5, CV_FFMPEG_CAP_PROP_FOURCC=6, - CV_FFMPEG_CAP_PROP_FRAME_COUNT=7 + CV_FFMPEG_CAP_PROP_FRAME_COUNT=7, + CV_FFMPEG_CAP_PROP_SAR_NUM=40, + CV_FFMPEG_CAP_PROP_SAR_DEN=41 }; diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index 2615f3a493..ee1447e0ff 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -250,6 +250,7 @@ struct CvCapture_FFMPEG double get_duration_sec() const; double get_fps() const; int get_bitrate() const; + AVRational get_sample_aspect_ratio(AVStream *stream) const; double r2d(AVRational r) const; int64_t dts_to_frame_number(int64_t dts); @@ -836,6 +837,10 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const #else return (double)video_st->codec.codec_tag; #endif + case CV_FFMPEG_CAP_PROP_SAR_NUM: + return get_sample_aspect_ratio(ic->streams[video_stream]).num; + case CV_FFMPEG_CAP_PROP_SAR_DEN: + return get_sample_aspect_ratio(ic->streams[video_stream]).den; default: break; } @@ -910,6 +915,28 @@ int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts) return (int64_t)(get_fps() * sec + 0.5); } +AVRational CvCapture_FFMPEG::get_sample_aspect_ratio(AVStream *stream) const +{ + AVRational undef = {0, 1}; + AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef; + AVRational frame_sample_aspect_ratio = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef; + + av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den, + stream_sample_aspect_ratio.num, stream_sample_aspect_ratio.den, INT_MAX); + if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0) + stream_sample_aspect_ratio = undef; + + av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den, + frame_sample_aspect_ratio.num, frame_sample_aspect_ratio.den, INT_MAX); + if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0) + frame_sample_aspect_ratio = undef; + + if (stream_sample_aspect_ratio.num) + return stream_sample_aspect_ratio; + else + return frame_sample_aspect_ratio; +} + double CvCapture_FFMPEG::dts_to_sec(int64_t dts) { return (double)(dts - ic->streams[video_stream]->start_time) *