在ffmpeg编码后,AVPacket pts和dts为AV_NOPTS_VALUE

时间:2017-11-29 10:01:45

标签: ffmpeg encoder

当我使用编码器(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 docs说"调" opts可以像电影,动画等一样设置。但是当我设置" zerolatency" PARAMS。当我设置其他选项时,视频的比特率非常低。

谢谢你的回答。

1 个答案:

答案 0 :(得分:0)

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

我相信你应事先设定frame->pts 试试这个:
在发送至frame->pts = framecount

之前设置ret = avcodec_send_frame(m_pCodecCtx, frame)

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