Skip to content

Commit a1479cc

Browse files
committed
Merge pull request opencv#10148 from alalek:fix_ffmpeg_sws_scale_crash
2 parents 2feb0c2 + 559235a commit a1479cc

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

modules/videoio/src/cap_ffmpeg_impl.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,7 @@ struct CvVideoWriter_FFMPEG
13171317
AVStream * video_st;
13181318
int input_pix_fmt;
13191319
unsigned char * aligned_input;
1320+
size_t aligned_input_size;
13201321
int frame_width, frame_height;
13211322
int frame_idx;
13221323
bool ok;
@@ -1394,6 +1395,7 @@ void CvVideoWriter_FFMPEG::init()
13941395
video_st = 0;
13951396
input_pix_fmt = 0;
13961397
aligned_input = NULL;
1398+
aligned_input_size = 0;
13971399
img_convert_ctx = 0;
13981400
frame_width = frame_height = 0;
13991401
frame_idx = 0;
@@ -1702,17 +1704,28 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
17021704
#endif
17031705

17041706
// FFmpeg contains SIMD optimizations which can sometimes read data past
1705-
// the supplied input buffer. To ensure that doesn't happen, we pad the
1706-
// step to a multiple of 32 (that's the minimal alignment for which Valgrind
1707-
// doesn't raise any warnings).
1708-
const int STEP_ALIGNMENT = 32;
1709-
if( step % STEP_ALIGNMENT != 0 )
1707+
// the supplied input buffer.
1708+
// Related info: https://trac.ffmpeg.org/ticket/6763
1709+
// 1. To ensure that doesn't happen, we pad the step to a multiple of 32
1710+
// (that's the minimal alignment for which Valgrind doesn't raise any warnings).
1711+
// 2. (dataend - SIMD_SIZE) and (dataend + SIMD_SIZE) is from the same 4k page
1712+
const int CV_STEP_ALIGNMENT = 32;
1713+
const size_t CV_SIMD_SIZE = 32;
1714+
const size_t CV_PAGE_MASK = ~(4096 - 1);
1715+
const uchar* dataend = data + ((size_t)height * step);
1716+
if (step % CV_STEP_ALIGNMENT != 0 ||
1717+
(((size_t)dataend - CV_SIMD_SIZE) & CV_PAGE_MASK) != (((size_t)dataend + CV_SIMD_SIZE) & CV_PAGE_MASK))
17101718
{
1711-
int aligned_step = (step + STEP_ALIGNMENT - 1) & -STEP_ALIGNMENT;
1719+
int aligned_step = (step + CV_STEP_ALIGNMENT - 1) & ~(CV_STEP_ALIGNMENT - 1);
17121720

1713-
if( !aligned_input )
1721+
size_t new_size = (aligned_step * height + CV_SIMD_SIZE);
1722+
1723+
if (!aligned_input || aligned_input_size < new_size)
17141724
{
1715-
aligned_input = (unsigned char*)av_mallocz(aligned_step * height);
1725+
if (aligned_input)
1726+
av_freep(&aligned_input);
1727+
aligned_input_size = new_size;
1728+
aligned_input = (unsigned char*)av_mallocz(aligned_input_size);
17161729
}
17171730

17181731
if (origin == 1)

platforms/scripts/valgrind_3rdparty.supp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,12 @@
111111
...
112112
obj:/usr/lib/libgdal.so.1.17.1
113113
}
114+
115+
{
116+
FFMPEG-sws_scale
117+
Memcheck:Addr16
118+
...
119+
fun:sws_scale
120+
...
121+
fun:cvWriteFrame_FFMPEG
122+
}

0 commit comments

Comments
 (0)