FFmpeg,通过Unity运行时对av_frame_free的访问冲突

时间:2016-10-27 20:52:39

标签: c# c++ unity3d memory-leaks ffmpeg

我正在使用ffmpeg为Unity制作视频录制插件。我是视频编码领域的新手,今天就让我的代码工作了。但我认为可能有一些内存泄漏并试图修复它们会导致Unity崩溃。

该插件是用c ++编写的(作为外部“C”代码),并通过简单的DllImport以c#脚本统一导入。同样,这也不是我的舒适区域,但它确实有效。

当渲染一个屏幕缓冲区时,我放入一个RGB24缓冲区并将其发送到我的c ++函数,这个:

int encode_frame(uint8_t* rgb24Data)
{
    AVFrame *frame = av_frame_alloc();
    if (!frame)
        return COULD_NOT_ALLOCATE_FRAME;

    frame->format = codec_context->pix_fmt;
    frame->width = codec_context->width;
    frame->height = codec_context->height;

    int ret = av_image_alloc(frame->data, frame->linesize, codec_context->width, codec_context->height, codec_context->pix_fmt, 32);
    if (ret < 0)
        return COULD_NOT_ALLOCATE_PIC_BUF;

    SwsContext * ctx = sws_getContext(codec_context->width, codec_context->height,
        AV_PIX_FMT_RGB24, codec_context->width, codec_context->height,
        AV_PIX_FMT_YUV420P, 0, 0, 0, 0);


    uint8_t * inData[1] = { rgb24Data };
    int inLinesize[1] = { 3 * codec_context->width };

    sws_scale(ctx, inData, inLinesize, 0, codec_context->height, frame->data, frame->linesize); // From RGB to YUV

    frame->pts = frame_counter++;

    ret = avcodec_send_frame(codec_context, frame);
    if (ret < 0)
        return ERROR_ENCODING_FRAME_SEND;

    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;

    while (true)
    {
        ret = avcodec_receive_packet(codec_context, &pkt);
        if (!ret)
        {
            if (pkt.pts != AV_NOPTS_VALUE)
                pkt.pts = av_rescale_q(pkt.pts, codec_context->time_base, video_st->time_base);
            if (pkt.dts != AV_NOPTS_VALUE)
                pkt.dts = av_rescale_q(pkt.dts, codec_context->time_base, video_st->time_base);

            av_write_frame(outctx, &pkt);
            av_packet_unref(&pkt);
        }
        else if (ret == AVERROR(EAGAIN))
        {
            frame->pts = frame_counter++;
            ret = avcodec_send_frame(codec_context, frame);
            if (ret < 0)
                return ERROR_ENCODING_FRAME_SEND;
        }
        else if (ret < 0)
            return ERROR_ENCODING_FRAME_RECEIVE;
        else
            break;
    }

    // This one
    av_frame_free(&frame);
}

现在,这段代码可能有很多我不知道的问题,如果你愿意,可以自由指出它们。但是给我错误的行是av_frame_free(&frame);

如果我在c ++中的合成测试应用程序中运行它,它就可以了。我甚至可以在一个c#综合测试应用程序中运行它(就像c ++一样),它可以工作。但如果我通过Unity运行它,它会在第一帧崩溃。日志显示“从位置fe7f8097读取导致访问冲突。”。

我尝试过使用av_freep()av_free()。不确定究竟是什么使它们不同(不同的示例代码使用不同的代码),但都没有效果。

那么,我错过了什么? frame如果我没有正确释放它会泄漏吗?但为什么它会在Unity中崩溃?

如果我没有av_frame_free(&frame);,整个过程在Unity中运行良好。结果视频看起来很棒!

PS。我知道(据我所知)如果出现故障并且返回错误代码,框架也会泄漏。但有一点是一次。

0 个答案:

没有答案