美文网首页
编码图片动画为视频

编码图片动画为视频

作者: 阿斯顿英朗 | 来源:发表于2020-07-16 16:48 被阅读0次

已解决:问题出在我Java层的buffer和NDK的buffer是共享的,然后我为了加快速度,主线程截图和NDK的编码过程多线程进行,导致主线程获取出下一帧时污染了部分正在转换的数据。。。

解决过程:仙人掌D 的文章给了我解决方法,就是用ffplay打开编码前的rgb帧和yuv帧的数据,后来又对比了Java层的bmp数据,才突然意识到Java层的bmp没问题,为何传到NDK后,rgb就有问题了呢,最神奇的是rgb帧和yuv帧的问题还不一样,应该是污染程度不一样,yuv污染更严重,我猜应该是因为sws转换过程时间较长,上面一部分没污染,下面一部分污染了

另外编译FFmpeg和x264也使用了仙人掌D 的文章,特此感谢!


// 1、查找编码器

    AVCodec *avcodec = avcodec_find_encoder(AV_CODEC_ID_H264);

    if (avcodec == NULL){

        return JNI_FALSE;

    }

    //1、获取编码器上下文

    AVCodecContext *avcodec_context = avcodec_alloc_context3(avcodec);

    //2、设置编解码器上下文参数

    avcodec_context->pix_fmt = AV_PIX_FMT_YUV420P;

    avcodec_context->width = width;

    avcodec_context->height = width;

    // 设置帧率25fps

    avcodec_context->time_base = (AVRational){1, 25};

    avcodec_context->framerate = (AVRational){25, 1};

    // 设置码率

    avcodec_context->bit_rate = 4096000;

    // 设置GOP

    avcodec_context->gop_size = 250;

    avcodec_context->max_b_frames = 0; //必须是0,否则Mac&iOS无法播放

    if (avcodec->id == AV_CODEC_ID_H264) {

        av_opt_set(avcodec_context->priv_data, "preset", "slow", 0);

        av_opt_set(avcodec_context->priv_data, "tune", "film", 0);

    }

    int openRet = avcodec_open2(avcodec_context, avcodec, NULL);

    if (openRet < 0) {

        return JNI_FALSE;

    }

// 2、内存空间填充

AVFrame *rgbFrame = av_frame_alloc();

rgbFrame->format =AV_PIX_FMT_BGRA; //AV_PIX_FMT_RGBA,AV_PIX_FMT_ABGR,AV_PIX_FMT_ARGB

rgbFrame->width = width;

rgbFrame->height = width;

AVFrame *yuvFrame = av_frame_alloc();

yuvFrame->format = avcodec_context->pix_fmt;

yuvFrame->width = width;

yuvFrame->height = width;

av_frame_get_buffer(rgbFrame, 32);

av_frame_get_buffer(yuvFrame, 32);

SwsContext *img_convert_ctx = sws_getContext(avcodec_context->width,

                                            avcodec_context->height,

                                            static_cast(rgbFrame->format),

                                            avcodec_context->width,

                                            avcodec_context->height,

                                            avcodec_context->pix_fmt,

                                            SWS_BICUBIC, NULL, NULL, NULL);

循环处理图片序列:

while ... {

int *bmpIntData = env->GetIntArrayElements(bmpIntArray, &isCopy);

        const uint8_t *bmpData = (const uint8_t *)bmpIntData;

        av_image_fill_arrays(rgbFrame->data,

                            rgbFrame->linesize,

                            bmpData,

                            static_cast(rgbFrame->format),

                            rgbFrame->width,

                            rgbFrame->height,

                            1);

        int ret = sws_scale(img_convert_ctx, rgbFrame->data, rgbFrame->linesize, 0, avcodec_context->height, yuvFrame->data, yuvFrame->linesize);

        if (0 > ret) {

status =JNI_FALSE;

break;

        }

        yuvFrame->pts = i;

        encodeFrame(avcodec_context, yuvFrame, av_packet, h264Output);

}

//其他一些收尾工作

//mergeH264AndAacToMp4 封装成mp4

下面是视频里图片淡入淡出过程的截图,有奇怪的半块灰色蒙层

相关文章

  • 编码图片动画为视频

    已解决:问题出在我Java层的buffer和NDK的buffer是共享的,然后我为了加快速度,主线程截图和NDK的...

  • Android开源框架Glide的使用

    Gilde是google官方推荐的加载图片和视频的库。可以加载本地图片和远程图片。可以加载图片,动图,视频。 添加...

  • 将图片转成带音乐背景的视频,调研的三种方式

    图片转视频 为什么想将图片转视频? 是这样的,我打造的任性动图软件,在编辑制作GIF动图方面,已经基本完善。现在想...

  • H264编码原理之帧间预测与帧内预测

    H264基本概念 视频的本质就是很多帧图片,在视频采集过程中其实就是图片采集,而h264编码就是对这些图片进行压缩...

  • 音视频 直播 滤镜

    视频 视频实质:纯粹的视频(不包括音频)实质上就是一组帧图片,经过视频编码成为视频(video)文件再把音频(au...

  • iOS视频开发

    视频实质: 纯粹的视频(不包括音频)实质上就是一组帧图片,经过视频编码成为视频(video)文件再把音频(audi...

  • iOS视频开发基础

    视频实质:纯粹的视频(不包括音频)实质上就是一组帧图片,经过视频编码成为视频(video)文件再把音频(audio...

  • MediaCodec API,完成视频 H.264 的硬编、硬解

    一、编码基础概念 1.1 为什么要进行视频编码 视频是由一帧帧图像组成,就如常见的gif图片,如果打开一张gif图...

  • 视频学习之一:基础知识

    基础知识积累: 视频实质: 纯粹的视频(不包括音频)实质上就是一组帧图片,经过视频编码成为视频(video)文件再...

  • 数据安全

    一.Base64编码 1.概念 Base64编码是一种对二进制数据编码的方式,可以把源数据(文本,图片,视频音频等...

网友评论

      本文标题:编码图片动画为视频

      本文链接:https://www.haomeiwen.com/subject/rptqdctx.html