【问题标题】:After ffmpeg encode, AVPacket pts and dts is AV_NOPTS_VALUEffmpeg 编码后,AVPacket pts 和 dts 为 AV_NOPTS_VALUE
【发布时间】:2018-05-12 23:51:42
【问题描述】:

我在使用编码器(x264)时想问一个关于ffmpeg的问题。

这是我的代码:

int
FFVideoEncoder::init(AVCodecID codecId, int bitrate, int fps, int gopSize,
                     int width, int height, AVPixelFormat format) {
    release();

    const AVCodec *codec = avcodec_find_encoder(codecId);
    m_pCodecCtx = avcodec_alloc_context3(codec);
    m_pCodecCtx->width = width;
    m_pCodecCtx->height = height;
    m_pCodecCtx->pix_fmt = format;
    m_pCodecCtx->bit_rate = bitrate;
    m_pCodecCtx->thread_count = 5;
    m_pCodecCtx->max_b_frames = 0;
    m_pCodecCtx->gop_size = gopSize;

    m_pCodecCtx->time_base.num = 1;
    m_pCodecCtx->time_base.den = fps;

    //H.264
    if (m_pCodecCtx->codec_id == AV_CODEC_ID_H264) {
//        av_dict_set(&opts, "preset", "slow", 0);
        av_dict_set(&m_pEncoderOpts, "preset", "superfast", 0);
        av_dict_set(&m_pEncoderOpts, "tune", "zerolatency", 0);

        m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
        m_pCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
    }
    int ret = avcodec_open2(m_pCodecCtx, m_pCodecCtx->codec, &m_pEncoderOpts);
    if (ret == 0) {
        LOGI("open avcodec success!");
    } else {
        LOGE("open avcodec error!");
        return -1;
    }
    return ret;
}

int FFVideoEncoder::encode(const Frame &inFrame, AVPacket *outPacket) {
    AVFrame *frame = av_frame_alloc();
//    avpicture_fill((AVPicture *) frame, inFrame.getData(), AV_PIX_FMT_YUV420P, inFrame.getWidth(),
//                   inFrame.getHeight());
    av_image_fill_arrays(frame->data, frame->linesize, inFrame.getData(), m_pCodecCtx->pix_fmt,
                         inFrame.getWidth(), inFrame.getHeight(), 1);

    int ret = 0;
    ret = avcodec_send_frame(m_pCodecCtx, frame);
    if (ret != 0) {
        LOGE("send frame error! %s", av_err2str(ret));
    } else {
        ret = avcodec_receive_packet(m_pCodecCtx, outPacket);
        LOGI("extract data size = %d", m_pCodecCtx->extradata_size);
        if (ret != 0) {
            LOGE("receive packet error! %s", av_err2str(ret));
        }
    };
    av_frame_free(&frame);
    return ret;
}

我希望 AVPacket 将携带有关此帧的 pts 和 dts。

但实际上,我只能得到编码的帧数据和大小。

//=====================================

除了这个问题,我还有一个问题:

x264 文档说“tune”选项可以像电影、动画等一样设置。但是当我设置“zerolatency”参数时,我只能获得正常的视频。当我设置其他选项时,视频的比特率非常低。

谢谢你的回答。

【问题讨论】:

    标签: ffmpeg encoder


    【解决方案1】:

    这是一个简单的例子,看看它是否有效:

    我相信你应该事先设置frame->pts
    试试这个:
    在发送到ret = avcodec_send_frame(m_pCodecCtx, frame)之前设置frame->pts = framecount

    将此framecount 添加为您发送用于编码的帧的简单计数器。每次都增加。
    希望对您有所帮助。

    【讨论】:

    • 天啊。谢谢你的帮助。实际上我有每一帧的分。当我将 pts 设置到 AVFrame 中时,它可以工作!!!
    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 2018-07-04
    • 2015-11-05
    • 2018-08-08
    • 2022-01-24
    • 2014-01-21
    • 2018-03-27
    • 2012-04-18
    相关资源
    最近更新 更多