Ticket #5654: fix-5654.patch

File fix-5654.patch, 3.8 KB (added by kernrj, 17 months ago)
  • libavdevice/avfoundation.m

    From e465b8e9291625db999a20b2a977b2a2d21f31f2 Mon Sep 17 00:00:00 2001
    From: Rick Kern <kernrj@gmail.com>
    Date: Fri, 24 Jun 2016 11:00:17 -0400
    Subject: [PATCH] lavd/avfoundation: Fix skewed video output
    
    Fixes #5654.
    The linesize can be greater than the minimum required. This copies the
    frame taking linesize into account.
    
    Signed-off-by: Rick Kern <kernrj@gmail.com>
    ---
     libavdevice/avfoundation.m | 56 ++++++++++++++++++++++++++++++++++++++++------
     1 file changed, 49 insertions(+), 7 deletions(-)
    
    diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
    index e2ddf47..8b92308 100644
    a b  
    3535#include "libavutil/internal.h" 
    3636#include "libavutil/parseutils.h" 
    3737#include "libavutil/time.h" 
     38#include "libavutil/imgutils.h" 
    3839#include "avdevice.h" 
    3940 
    4041static const int avf_time_base = 1000000; 
    fail: 
    892893    return AVERROR(EIO); 
    893894} 
    894895 
     896static int copy_cvpixelbuffer(AVFormatContext *s, 
     897                               CVPixelBufferRef image_buffer, 
     898                               AVPacket *pkt) 
     899{ 
     900    AVFContext *ctx = s->priv_data; 
     901    int src_linesize[4]; 
     902    const uint8_t *src_data[4]; 
     903    int width  = CVPixelBufferGetWidth(image_buffer); 
     904    int height = CVPixelBufferGetHeight(image_buffer); 
     905    int status; 
     906 
     907    memset(src_linesize, 0, sizeof(src_linesize)); 
     908    memset(src_data, 0, sizeof(src_data)); 
     909 
     910    status = CVPixelBufferLockBaseAddress(image_buffer, 0); 
     911    if (status != kCVReturnSuccess) { 
     912        av_log(s, AV_LOG_ERROR, "Could not lock base address: %d\n", status); 
     913        return AVERROR_EXTERNAL; 
     914    } 
     915 
     916    if (CVPixelBufferIsPlanar(image_buffer)) { 
     917        size_t plane_count = CVPixelBufferGetPlaneCount(image_buffer); 
     918        int i; 
     919        for(i = 0; i < plane_count; i++){ 
     920            src_linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(image_buffer, i); 
     921            src_data[i] = CVPixelBufferGetBaseAddressOfPlane(image_buffer, i); 
     922        } 
     923    } else { 
     924        src_linesize[0] = CVPixelBufferGetBytesPerRow(image_buffer); 
     925        src_data[0] = CVPixelBufferGetBaseAddress(image_buffer); 
     926    } 
     927 
     928    status = av_image_copy_to_buffer(pkt->data, pkt->size, 
     929                                     src_data, src_linesize, 
     930                                     ctx->pixel_format, width, height, 1); 
     931 
     932 
     933 
     934    CVPixelBufferUnlockBaseAddress(image_buffer, 0); 
     935 
     936    return status; 
     937} 
     938 
    895939static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) 
    896940{ 
    897941    AVFContext* ctx = (AVFContext*)s->priv_data; 
    static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) 
    903947        image_buffer = CMSampleBufferGetImageBuffer(ctx->current_frame); 
    904948 
    905949        if (ctx->current_frame != nil) { 
    906             void *data; 
     950            int status; 
    907951            if (av_new_packet(pkt, (int)CVPixelBufferGetDataSize(image_buffer)) < 0) { 
    908952                return AVERROR(EIO); 
    909953            } 
    static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) 
    919963            pkt->stream_index  = ctx->video_stream_index; 
    920964            pkt->flags        |= AV_PKT_FLAG_KEY; 
    921965 
    922             CVPixelBufferLockBaseAddress(image_buffer, 0); 
    923  
    924             data = CVPixelBufferGetBaseAddress(image_buffer); 
    925             memcpy(pkt->data, data, pkt->size); 
    926  
    927             CVPixelBufferUnlockBaseAddress(image_buffer, 0); 
     966            status = copy_cvpixelbuffer(s, image_buffer, pkt); 
    928967            CFRelease(ctx->current_frame); 
    929968            ctx->current_frame = nil; 
     969 
     970            if (status < 0) 
     971                return status; 
    930972        } else if (ctx->current_audio_frame != nil) { 
    931973            CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame); 
    932974            int block_buffer_size         = CMBlockBufferGetDataLength(block_buffer);