草庐IT

android - FFMPEG sws_scale 在 Android 上崩溃

coder 2023-12-13 原文

我有一个将图像转换为视频的应用程序,在 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 参数。

最后一件事:无需使用 avpicture_fill 填充您的 pFrame。您只需 av_frame_alloc() 它,avcodec_decode_video2 将负责填充它。

关于android - FFMPEG sws_scale 在 Android 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25797051/

有关android - FFMPEG sws_scale 在 Android 上崩溃的更多相关文章

  1. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  2. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  5. ruby - 执行过期异常使 Ruby 线程崩溃,但处理了 Timeout::Error - 2

    任何人都可以解释为什么当对方法的调用看起来像这样时我可能会看到这个堆栈(由HTTParty::post请求引起):beginresponse=HTTParty::post(url,options)rescuelogger.warn("Couldnotpostto#{url}")rescueTimeout::Errorlogger.warn("Couldnotpostto#{url}:timeout")end堆栈:/usr/local/lib/ruby/1.8/timeout.rb:64:in`timeout'/usr/local/lib/ruby/1.8/net/protocol.rb

  6. ruby - vim 使用 AutoComplPop 插件崩溃 - 2

    我使用vim编辑ruby​​文件,但是当我输入“.”时它崩溃了。我发现它是由AutoComplPop插件引起的。我该怎么办? 最佳答案 我找到了一种使用autocomplpop和filetype=ruby来防止vim崩溃的方法。将以下行放入您的.vimrcletg:acp_behaviorRubyOmniMethodLength=-1这将防止在您键入“.”时触发autocomplpop。(期间)这不是解决办法。(我不是vim插件程序员)祝你好运! 关于ruby-vim使用AutoComp

  7. ruby-on-rails - 自动加载路径和嵌套服务类在 Ruby 中崩溃 - 2

    我在Rails5项目的app/services文件夹下有多个加载/需要类的问题,我开始放弃这个问题。首先要明确的是,services/是我在整个项目中使用的简单PORO类,用于从Controller、模型等中抽象出大部分业务逻辑。树看起来像这样app/services/my_service/base.rbfunny_name.rbmy_service.rbmodels/funny_name.rb失败#1首先,当我尝试使用MyService.const_get('FunnyName')时,它从我的模型目录中获取了FunnyName。当我直接执行MyService::FunnyName时,

  8. ruby - unicorn 与 Ruby 2.4.1 导致奇怪的崩溃 - 2

    我正在从Ruby2.3.1升级到Ruby2.4.1,这样做之后,Unicorn似乎与新版本不兼容。我收到以下错误。我正在使用Unicorn5.1.0并尝试过Unicorn5.3.1无济于事。我是否需要使用不同的库而不是XCode工具进行编译?我在使用foremanstart和Procfile启动服务器后立即收到错误:webpack:bin/webpack-dev-servergulp:gulpredis:./scripts/start_redis_server.shsidekiq:bundleexecsidekiq-Cconfig/sidekiq.ymlannotations_serv

  9. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  10. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

随机推荐