AVStream * video_st;
int input_pix_fmt;
unsigned char * aligned_input;
+ size_t aligned_input_size;
int frame_width, frame_height;
int frame_idx;
bool ok;
video_st = 0;
input_pix_fmt = 0;
aligned_input = NULL;
+ aligned_input_size = 0;
img_convert_ctx = 0;
frame_width = frame_height = 0;
frame_idx = 0;
#endif
// FFmpeg contains SIMD optimizations which can sometimes read data past
- // the supplied input buffer. To ensure that doesn't happen, we pad the
- // step to a multiple of 32 (that's the minimal alignment for which Valgrind
- // doesn't raise any warnings).
- const int STEP_ALIGNMENT = 32;
- if( step % STEP_ALIGNMENT != 0 )
+ // the supplied input buffer.
+ // Related info: https://trac.ffmpeg.org/ticket/6763
+ // 1. To ensure that doesn't happen, we pad the step to a multiple of 32
+ // (that's the minimal alignment for which Valgrind doesn't raise any warnings).
+ // 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)