簡體   English   中英

FFMPEG sws_scale在Android上崩潰

[英]FFMPEG sws_scale Crash on Android

我有一個將圖像轉換為視頻的應用程序,在Google Play中,我看到以下崩潰(我得到的唯一詳細信息是函數的名稱,其余的我一無所知):

backtrace:
#00 pc 0000cc78 /data/app-lib/com.myapp-1/libswscale.so (sws_scale+204)
#01 pc 000012af /data/app-lib/com.myapp-1/libffmpeg.so (OpenImage+322)

code around pc:
79065c58 e58d8068 e58d2070 e58d3074 059d00b0 

該代碼指向功能sws_scale ,該代碼幾乎始終在我的設備上運行(Nexus 5),但是即使在同一設備上出現此問題,我仍然看到很多報告。 知道為什么會發生這種情況嗎?

AVFrame* OpenImage(const char* imageFileName, int W_VIDEO, int H_VIDEO, int* numBytes)
{
    AVFormatContext *pFormatCtx;
    AVCodecContext *pCodecCtx;
    AVCodec *pCodec;
    AVFrame *pFrame;
    int frameFinished;
    uint8_t *buffer;
    AVPacket packet;
    int srcBytes;

    AVFrame* frame2 = NULL;// scaled frame
    uint8_t* frame2_buffer;
    struct SwsContext *resize;

    if(av_open_input_file(&pFormatCtx, imageFileName, NULL, 0, NULL)!=0)
    {
        LOGI("Can't open image file '%s'\n", imageFileName);
        return NULL;
    }
    //dump_format(pFormatCtx, 0, imageFileName, 0);
    if (av_find_stream_info(pFormatCtx) < 0)
    {
        LOGI("Can't find stream info.");
        return NULL;
    }
    pCodecCtx = pFormatCtx->streams[0]->codec;
    pCodecCtx->pix_fmt = PIX_FMT_YUV420P;

    // Find the decoder for the video stream
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if (!pCodec)
    {
        LOGI("Codec not found\n");
        return NULL;
    }

    // Open codec
    if(avcodec_open(pCodecCtx, pCodec)<0)
    {
        LOGI("Could not open codec\n");
        return NULL;
    }
    pFrame = avcodec_alloc_frame();
    if (!pFrame)
    {
        LOGI("Can't allocate memory for AVFrame\n");
        return NULL;
    }

    // Determine required buffer size and allocate buffer
    srcBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    buffer = (uint8_t *) av_malloc(srcBytes * sizeof(uint8_t));
    avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);

    // Read frame
    if (av_read_frame(pFormatCtx, &packet) >= 0)
    {
        int ret;
//      if(packet.stream_index != 0)
//          continue;
        ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
        if (ret > 0)
        {
            //LOGI("Frame is decoded, size %d\n", ret);
            pFrame->quality = 4;

            // Create another frame for resized result
            frame2 = avcodec_alloc_frame();
            *numBytes = avpicture_get_size(PIX_FMT_YUV420P, W_VIDEO, H_VIDEO);
            frame2_buffer = (uint8_t *)av_malloc(*numBytes * sizeof(uint8_t));
            avpicture_fill((AVPicture*)frame2, frame2_buffer, PIX_FMT_YUV420P, W_VIDEO, H_VIDEO);

            // Get resize context
            resize = sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, W_VIDEO, H_VIDEO, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

            // frame2 should be filled with resized samples
            ret = sws_scale(resize, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, frame2->data, frame2->linesize);
            sws_freeContext(resize);
        }
        else
            LOGI("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
    }
    av_free(pFrame);
    av_free_packet(&packet);
    avcodec_close(pCodecCtx);
    //av_free(pCodecCtx);
    av_close_input_file(pFormatCtx);
    return frame2;
}

avcodec_decode_video2 ,請勿僅檢查ret 您還需要檢查frameFinished 如果frameFinished == 0 ,則不應使用您的框架(因為未填充)。 我不知道圖像,但是當您解碼視頻時,它經常發生。 您需要讀取下一個數據包,然后進行下一個avcodec_decode_video2調用。

附帶說明一下:為什么要強制pCodecCtx->pix_fmt = PIX_FMT_YUV420P av_find_stream_info會自動將其設置為正確的格式,您應該將其用作sws_getContext參數。

最后一件事:無需填寫你pFrameavpicture_fill 您只需要av_frame_alloc()avcodec_decode_video2將負責填充它。

在這行之后

*numBytes = avpicture_get_size(PIX_FMT_YUV420P, W_VIDEO, H_VIDEO);

您尚未檢查返回值。

avpicture_get_size describe

"Returns:
the computed picture buffer size or a negative error code in case of error"

當您檢查*numBytes (和srcBytesbufferframe2_buffer )值時,可能會更好...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM