ffmpeg编码后AVPacket pts和dts为AV_NOPTS_VALUE

After ffmpeg encode, AVPacket pts and dts is AV_NOPTS_VALUE

当我使用编码器(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" opts 可以设置为电影、动画等。但是当我设置 "zerolatency" 参数时,我只能得到一个正常的视频。当我设置其他选项时,视频的比特率很低。

感谢您的回答。

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

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

之前设置 frame->pts = framecount

添加此 framecount 作为您发送以进行编码的帧的简单计数器。每次增加。
希望对您有所帮助。