IJKPlayer獲取實時數(shù)據(jù)(中)- 添加軟解碼輸出紋理

1、添加YUVRotate庫

YUVRotate下載地址:###
1-1、將YUVRotate庫引入到項目中


image.png

1-2 、頭文件引用 IJKMediaPlayer.xcodeproj->IJKMediaFramework(TARGETS ) -> Build Settings->Header Search Paths:

add  "$(SRCROOT)/YUVRotate/include"

1-3、進入到ff_ffplay.c,引入頭文件

    #include "libyuv.h"
2、進入到ff_ffplay.c

查找到以下函數(shù)

static int decoder_decode_frame(FFPlayer *ffp, Decoder *d, AVFrame *frame, AVSubtitle *sub)

添加代碼:


image.png
ffp_pixelbuffer_lock(ffp);
CVPixelBufferRef cvImage = NULL;
if (ffp->szt_pixelbuffer)
{
    cvImage = ffp->szt_pixelbuffer;
}
int ret = createCVPixelBuffer(ffp, ffp->is->video_st->codec, frame, &cvImage);
                    
 if (!ret)
{
      ffp->szt_pixelbuffer = cvImage;
}
ffp_pixelbuffer_unlock(ffp);

添加以下代碼:(這兩段代碼要放在decoder_decode_frame 方法之前)

static int copyAVFrameToPixelBuffer(FFPlayer *ffp, AVCodecContext* avctx, const AVFrame* frame, CVPixelBufferRef cv_img, const size_t* plane_strides, const size_t* plane_rows)
{
    int i, j;
    size_t plane_count;
    int status;
    size_t rows;
    unsigned long src_stride;
    unsigned long dst_stride;
    uint8_t *src_addr;
    uint8_t *dst_addr;
    size_t copy_bytes;
    
    status = CVPixelBufferLockBaseAddress(cv_img, 0);
    if (status) {
        av_log(
               avctx,
               AV_LOG_ERROR,
               "Error: Could not lock base address of CVPixelBuffer: %d.\n",
               status
               );
    }
    
    uint8* src_y = frame->data[0];
    uint8* src_u = frame->data[1];
    uint8* src_v = frame->data[2];
    void* addr = CVPixelBufferGetBaseAddress(cv_img);
    
    int src_stride_y = frame->linesize[0];
    int src_stride_u = frame->linesize[1];
    int src_stride_v = frame->linesize[2];
    size_t dst_width = CVPixelBufferGetBytesPerRow(cv_img);
    
    int src_width = frame->width;
    int src_height = frame->height;
    
    I420ToARGB(src_y, src_stride_y,
               src_u, src_stride_u,
               src_v, src_stride_v,
               addr, dst_width,
               src_width, src_height);
    
    status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
    if (status) {
        av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
        return AVERROR_EXTERNAL;
    }
    
    return 0;
}
int createCVPixelBuffer(FFPlayer *ffp, AVCodecContext* avctx, AVFrame* frame, CVPixelBufferRef* cvImage)
{
    size_t widths [AV_NUM_DATA_POINTERS];
    size_t heights[AV_NUM_DATA_POINTERS];
    size_t strides[AV_NUM_DATA_POINTERS];
    int status;
    
    memset(widths,  0, sizeof(widths));
    memset(heights, 0, sizeof(heights));
    memset(strides, 0, sizeof(strides));
    
    widths[0] = avctx->width;
    heights[0] = avctx->height;
    strides[0] = frame ? frame->linesize[0] : avctx->width;
    
    widths[1] = (avctx->width + 1)/2;
    heights[1] = (avctx->height + 1)/2;
    strides[1] = frame? frame->linesize[1] : (avctx ->width + 1)/2;
    
    widths[2] = (avctx->width + 1)/2;
    heights[2] = (avctx->height + 1)/2;
    strides[2] = frame? frame->linesize[2] : (avctx ->width + 1)/2;
    
    if (!ffp->szt_pixelbuffer)
    {
        status = CVPixelBufferCreate(
                                     kCFAllocatorDefault,
                                     frame->width,
                                     frame->height,
                                     kCVPixelFormatType_32BGRA,
                                     NULL,
                                     cvImage
                                     );
        if (status)
        {
            return AVERROR_EXTERNAL;
        }
    }
    
    
    status = copyAVFrameToPixelBuffer(ffp, avctx, frame, *cvImage, strides, heights);
    if (status)
    {
        CFRelease(*cvImage);
        *cvImage = NULL;
        return status;
    }
    
    return 0;
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容