heyJoie 2019-10-27 13:16 采纳率: 0%
浏览 988
已结题

用ffmpeg先解码视频文件,再将解码后的AFream数据调整分辨率后重新编码(为了压缩视频),输入输出都是在内存中,编码后视频无法播放,编码参数应该怎么调整?

大神们求帮忙看看,
实在无解了,我试着修改编码的上下文参数,也没找到原因

AVFrame *pFrame = NULL, *pFrameYUV = NULL;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();

uint8_t *out_buffer;
out_buffer = new uint8_t[avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, m_codecEnCtx->width, m_codecEnCtx->height);
pFrameYUV->format = AV_PIX_FMT_YUV420P;
pFrameYUV->width = m_codecEnCtx->width;
pFrameYUV->height = m_codecEnCtx->height;

AVPacket *depacket = (AVPacket*)av_malloc(sizeof(AVPacket)); //存储AVFrame解码后生成的数据
AVPacket *enpacket = (AVPacket*)av_malloc(sizeof(AVPacket));; //存储AVFrame编码后生成的数据
int nSizeAfterDecode = m_codecDeCtx->width * m_codecDeCtx->height;
int nSizeAfterEncode = m_codecEnCtx->width * m_codecEnCtx->height;
av_new_packet(depacket, nSizeAfterDecode);
av_new_packet(enpacket, nSizeAfterEncode);

int ret, got_picture;
struct SwsContext *img_convert_ctx;
int pts = 0;
while (av_read_frame(m_pInFormatCtx, depacket) >= 0)
{
    if (depacket->stream_index == nVideoIndex)
    {
        ret = avcodec_decode_video2(m_codecDeCtx, pFrame, &got_picture, depacket); //解码
        if (ret < 0)
        {
            printf("avcodec_decode_video2 error\n.");
        }
        if (got_picture) //解码成功后,先filter,然后encode
        {
            //分辨率转化
            img_convert_ctx = sws_getContext(m_codecDeCtx->width, m_codecDeCtx->height, ConvertDeprecatedFormat(m_codecDeCtx->pix_fmt), m_codecEnCtx->width, m_codecEnCtx->height, m_codecEnCtx->pix_fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);//SWS_BICUBIC
            sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pFrame->height, pFrameYUV->data, pFrameYUV->linesize);
            if (img_convert_ctx)
            {
                sws_freeContext(img_convert_ctx);
            }
            else
            {
                printf("sws_getContext failed \n");
            }

            /* ------开始编码YUV数据----*/
            //通过AVFrame数据进行编码

            pFrameYUV->pts = pts++;
            ret = avcodec_encode_video2(m_codecEnCtx, enpacket, pFrameYUV, &got_picture);
            if (ret < 0)
            {
                printf("avcodec_encode_video2 failed. \n");
            }
            if (got_picture)
            {
                enpacket->stream_index = m_streamEncode->index;
                ret = av_write_frame(m_pOutFormatCtx, enpacket);
                if (ret < 0)
                {
                    printf("Write frame error \n");
                }
                av_free_packet(enpacket);
            }   
        }
    }
}
av_packet_free(&depacket);
av_packet_free(&enpacket);
av_write_trailer(m_pOutFormatCtx); //写入数据流尾部到输出
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
  • 写回答

3条回答

  • dabocaiqq 2019-10-27 22:50
    关注
    评论

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3