Ticket #7226: 11_fix_vf_blend_unaligned_crash.patch

File 11_fix_vf_blend_unaligned_crash.patch, 7.8 KB (added by Lastique, 8 years ago)

The patch to fix unaligned memory access in vf_blend

  • libavfilter/vf_blend.c

    https://trac.ffmpeg.org/ticket/7226
    
    old new  
    2222#include "libavutil/eval.h"
    2323#include "libavutil/opt.h"
    2424#include "libavutil/pixfmt.h"
     25#include "libavutil/intreadwrite.h"
    2526#include "avfilter.h"
    2627#include "bufferqueue.h"
    2728#include "formats.h"
    static void blend_normal_16bit(const uin  
    173174
    174175    for (i = 0; i < height; i++) {
    175176        for (j = 0; j < width; j++) {
    176             dst[j] = top[j] * opacity + bottom[j] * (1. - opacity);
     177            uint16_t top_v = AV_RN16(top + j);
     178            uint16_t bottom_v = AV_RN16(bottom + j);
     179            uint16_t dst_v = top_v * opacity + bottom_v * (1. - opacity);
     180            AV_WN16(dst + j, dst_v);
    177181        }
    178182        dst    += dst_linesize;
    179183        top    += top_linesize;
    static void blend_## name##_8bit(const u  
    193197                                                                               \
    194198    for (i = 0; i < height; i++) {                                             \
    195199        for (j = 0; j < width; j++) {                                          \
    196             dst[j] = top[j] + ((expr) - top[j]) * opacity;                     \
     200            uint8_t top_v = top[j];                                            \
     201            uint8_t bottom_v = bottom[j];                                      \
     202            dst[j] = top_v + ((expr) - top_v) * opacity;                       \
    197203        }                                                                      \
    198204        dst    += dst_linesize;                                                \
    199205        top    += top_linesize;                                                \
    static void blend_## name##_16bit(const  
    219225                                                                               \
    220226    for (i = 0; i < height; i++) {                                             \
    221227        for (j = 0; j < width; j++) {                                          \
    222             dst[j] = top[j] + ((expr) - top[j]) * opacity;                     \
     228            uint16_t top_v = AV_RN16(top + j);                                 \
     229            uint16_t bottom_v = AV_RN16(bottom + j);                           \
     230            uint16_t dst_v = top_v + ((expr) - top_v) * opacity;               \
     231            AV_WN16(dst + j, dst_v);                                           \
    223232        }                                                                      \
    224233        dst    += dst_linesize;                                                \
    225234        top    += top_linesize;                                                \
    static void blend_## name##_16bit(const  
    227236    }                                                                          \
    228237}
    229238
    230 #define A top[j]
    231 #define B bottom[j]
     239#define A top_v
     240#define B bottom_v
    232241
    233242#define MULTIPLY(x, a, b) ((x) * (((a) * (b)) / 255))
    234243#define SCREEN(x, a, b)   (255 - (x) * ((255 - (a)) * (255 - (b)) / 255))
    DEFINE_BLEND16(xor, A ^ B)  
    311320DEFINE_BLEND16(vividlight, (A < 32768) ? BURN(2 * A, B) : DODGE(2 * (A - 32768), B))
    312321DEFINE_BLEND16(linearlight,av_clip_uint16((B < 32768) ? B + 2 * A - 65535 : B + 2 * (A - 32768)))
    313322
    314 #define DEFINE_BLEND_EXPR(type, name, div)                                     \
    315 static void blend_expr_## name(const uint8_t *_top, ptrdiff_t top_linesize,          \
    316                                const uint8_t *_bottom, ptrdiff_t bottom_linesize,    \
    317                                uint8_t *_dst, ptrdiff_t dst_linesize,                \
    318                                ptrdiff_t width, ptrdiff_t height,              \
    319                                FilterParams *param, double *values, int starty) \
    320 {                                                                              \
    321     const type *top = (type*)_top;                                             \
    322     const type *bottom = (type*)_bottom;                                       \
    323     type *dst = (type*)_dst;                                                   \
    324     AVExpr *e = param->e;                                                      \
    325     int y, x;                                                                  \
    326     dst_linesize /= div;                                                       \
    327     top_linesize /= div;                                                       \
    328     bottom_linesize /= div;                                                    \
    329                                                                                \
    330     for (y = 0; y < height; y++) {                                             \
    331         values[VAR_Y] = y + starty;                                            \
    332         for (x = 0; x < width; x++) {                                          \
    333             values[VAR_X]      = x;                                            \
    334             values[VAR_TOP]    = values[VAR_A] = top[x];                       \
    335             values[VAR_BOTTOM] = values[VAR_B] = bottom[x];                    \
    336             dst[x] = av_expr_eval(e, values, NULL);                            \
    337         }                                                                      \
    338         dst    += dst_linesize;                                                \
    339         top    += top_linesize;                                                \
    340         bottom += bottom_linesize;                                             \
    341     }                                                                          \
     323static void blend_expr_8bit(const uint8_t *top, ptrdiff_t top_linesize,
     324                               const uint8_t *bottom, ptrdiff_t bottom_linesize,
     325                               uint8_t *dst, ptrdiff_t dst_linesize,
     326                               ptrdiff_t width, ptrdiff_t height,
     327                               FilterParams *param, double *values, int starty)
     328{
     329    AVExpr *e = param->e;
     330    int y, x;
     331
     332    for (y = 0; y < height; y++) {
     333        values[VAR_Y] = y + starty;
     334        for (x = 0; x < width; x++) {
     335            values[VAR_X]      = x;
     336            values[VAR_TOP]    = values[VAR_A] = top[x];
     337            values[VAR_BOTTOM] = values[VAR_B] = bottom[x];
     338            dst[x] = av_expr_eval(e, values, NULL);
     339        }
     340        dst    += dst_linesize;
     341        top    += top_linesize;
     342        bottom += bottom_linesize;
     343    }
    342344}
    343345
    344 DEFINE_BLEND_EXPR(uint8_t, 8bit, 1)
    345 DEFINE_BLEND_EXPR(uint16_t, 16bit, 2)
     346static void blend_expr_16bit(const uint8_t *_top, ptrdiff_t top_linesize,
     347                               const uint8_t *_bottom, ptrdiff_t bottom_linesize,
     348                               uint8_t *_dst, ptrdiff_t dst_linesize,
     349                               ptrdiff_t width, ptrdiff_t height,
     350                               FilterParams *param, double *values, int starty)
     351{
     352    const uint16_t *top = (uint16_t*)_top;
     353    const uint16_t *bottom = (uint16_t*)_bottom;
     354    uint16_t *dst = (uint16_t*)_dst;
     355    AVExpr *e = param->e;
     356    int y, x;
     357    dst_linesize /= 2;
     358    top_linesize /= 2;
     359    bottom_linesize /= 2;
     360
     361    for (y = 0; y < height; y++) {
     362        values[VAR_Y] = y + starty;
     363        for (x = 0; x < width; x++) {
     364            uint16_t dst_v;
     365            values[VAR_X]      = x;
     366            values[VAR_TOP]    = values[VAR_A] = AV_RN16(top + x);
     367            values[VAR_BOTTOM] = values[VAR_B] = AV_RN16(bottom + x);
     368            dst_v = av_expr_eval(e, values, NULL);
     369            AV_WN16(dst + x, dst_v);
     370        }
     371        dst    += dst_linesize;
     372        top    += top_linesize;
     373        bottom += bottom_linesize;
     374    }
     375}
    346376
    347377static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
    348378{