Commit a1479cc2 authored by Maksim Shabunin's avatar Maksim Shabunin

Merge pull request #10148 from alalek:fix_ffmpeg_sws_scale_crash

parents 2feb0c2f 559235ac
...@@ -1317,6 +1317,7 @@ struct CvVideoWriter_FFMPEG ...@@ -1317,6 +1317,7 @@ struct CvVideoWriter_FFMPEG
AVStream * video_st; AVStream * video_st;
int input_pix_fmt; int input_pix_fmt;
unsigned char * aligned_input; unsigned char * aligned_input;
size_t aligned_input_size;
int frame_width, frame_height; int frame_width, frame_height;
int frame_idx; int frame_idx;
bool ok; bool ok;
...@@ -1394,6 +1395,7 @@ void CvVideoWriter_FFMPEG::init() ...@@ -1394,6 +1395,7 @@ void CvVideoWriter_FFMPEG::init()
video_st = 0; video_st = 0;
input_pix_fmt = 0; input_pix_fmt = 0;
aligned_input = NULL; aligned_input = NULL;
aligned_input_size = 0;
img_convert_ctx = 0; img_convert_ctx = 0;
frame_width = frame_height = 0; frame_width = frame_height = 0;
frame_idx = 0; frame_idx = 0;
...@@ -1702,17 +1704,28 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int ...@@ -1702,17 +1704,28 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
#endif #endif
// FFmpeg contains SIMD optimizations which can sometimes read data past // FFmpeg contains SIMD optimizations which can sometimes read data past
// the supplied input buffer. To ensure that doesn't happen, we pad the // the supplied input buffer.
// step to a multiple of 32 (that's the minimal alignment for which Valgrind // Related info: https://trac.ffmpeg.org/ticket/6763
// doesn't raise any warnings). // 1. To ensure that doesn't happen, we pad the step to a multiple of 32
const int STEP_ALIGNMENT = 32; // (that's the minimal alignment for which Valgrind doesn't raise any warnings).
if( step % STEP_ALIGNMENT != 0 ) // 2. (dataend - SIMD_SIZE) and (dataend + SIMD_SIZE) is from the same 4k page
const int CV_STEP_ALIGNMENT = 32;
const size_t CV_SIMD_SIZE = 32;
const size_t CV_PAGE_MASK = ~(4096 - 1);
const uchar* dataend = data + ((size_t)height * step);
if (step % CV_STEP_ALIGNMENT != 0 ||
(((size_t)dataend - CV_SIMD_SIZE) & CV_PAGE_MASK) != (((size_t)dataend + CV_SIMD_SIZE) & CV_PAGE_MASK))
{ {
int aligned_step = (step + STEP_ALIGNMENT - 1) & -STEP_ALIGNMENT; int aligned_step = (step + CV_STEP_ALIGNMENT - 1) & ~(CV_STEP_ALIGNMENT - 1);
if( !aligned_input ) size_t new_size = (aligned_step * height + CV_SIMD_SIZE);
if (!aligned_input || aligned_input_size < new_size)
{ {
aligned_input = (unsigned char*)av_mallocz(aligned_step * height); if (aligned_input)
av_freep(&aligned_input);
aligned_input_size = new_size;
aligned_input = (unsigned char*)av_mallocz(aligned_input_size);
} }
if (origin == 1) if (origin == 1)
......
...@@ -111,3 +111,12 @@ ...@@ -111,3 +111,12 @@
... ...
obj:/usr/lib/libgdal.so.1.17.1 obj:/usr/lib/libgdal.so.1.17.1
} }
{
FFMPEG-sws_scale
Memcheck:Addr16
...
fun:sws_scale
...
fun:cvWriteFrame_FFMPEG
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment