【问题标题】:PTS and DTS calculation for video and audio frames视频和音频帧的 PTS 和 DTS 计算
【发布时间】:2015-11-02 05:14:31
【问题描述】:

我正在从两个不同的线程接收视频 H264 编码数据和音频 G.711 PCM 编码数据以复用/写入mov 多媒体容器。

编写器函数签名如下:

bool WriteAudio(const unsigned char *pEncodedData, size_t iLength);
bool WriteVideo(const unsigned char *pEncodedData, size_t iLength, bool const bIFrame);

添加音视频流的功能如下:

AVStream* AudioVideoRecorder::AddMediaStream(enum AVCodecID codecID) {
    Log("Adding stream: %s.", avcodec_get_name(codecID));
    AVCodecContext* pCodecCtx;
    AVStream* pStream;

    /* find the encoder */
    AVCodec* codec = avcodec_find_encoder(codecID);
    if (!codec) {
        LogErr("Could not find encoder for %s", avcodec_get_name(codecID));
        return NULL;
    }

    pStream = avformat_new_stream(m_pFormatCtx, codec);
    if (!pStream) {
        LogErr("Could not allocate stream.");
        return NULL;
    }
    pStream->id = m_pFormatCtx->nb_streams - 1;
    pStream->time_base = (AVRational){1, VIDEO_FRAME_RATE};
    pCodecCtx = pStream->codec;


    switch(codec->type) {
    case AVMEDIA_TYPE_VIDEO:
        pCodecCtx->codec_id = codecID;
        pCodecCtx->bit_rate = VIDEO_BIT_RATE;
        pCodecCtx->width = PICTURE_WIDTH;
        pCodecCtx->height = PICTURE_HEIGHT;
        pCodecCtx->gop_size = VIDEO_FRAME_RATE;
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
        m_pVideoStream = pStream;
        break;

    case AVMEDIA_TYPE_AUDIO:
        pCodecCtx->codec_id = codecID;
        pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
        pCodecCtx->bit_rate = 64000;
        pCodecCtx->sample_rate = 8000;
        pCodecCtx->channels = 1;
        m_pAudioStream = pStream;
        break;

    default:
        break;
    }

    /* Some formats want stream headers to be separate. */
    if (m_pOutputFmt->flags & AVFMT_GLOBALHEADER)
        m_pFormatCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

    return pStream;
}

在WriteAudio(..) 和WriteVideo(..) 函数中,我使用av_init_packet(...) 创建AVPakcet 并将pEncodedData 和iLength 设置为packet.data 和packet.size。我打印了packet.pts 和packet.dts,它相当于AV_NOPTS_VALUE。

现在,如何正确计算音频和视频数据的 PTS、DTS 和数据包持续时间(packet.dts、packet.pts 和 packet.duration),以便我可以同步音频和视频并正常播放?我在互联网上看到了很多例子,但没有一个对我有意义。我是ffmpeg 的新手,我的概念在某些情况下可能不正确。我想以适当的方式做到这一点。

提前致谢!

编辑:在我的视频流中,没有 B 帧。所以,我认为 PTS 和 DTS 可以在这里保持不变。

【问题讨论】:

    标签: c++ audio video ffmpeg mux


    【解决方案1】:

    PTS/DTS 是时间戳,应该设置为输入数据的时间戳。我不知道您的日期来自哪里,但任何输入都有某种形式的时间戳与之相关联。通常,输入媒体文件的时间戳或系统时钟派生的指标(如果您从声卡+网络摄像头录制)等等。您应该将这些数字转换为预期的形式,然后将它们分配给AVPacket.pts/dts。

    【讨论】:

    • 感谢您的回复!先生,我已经编辑了我的问题。你能再精确一点吗?一些代码会很有帮助。
    • 您问题中的代码看起来是正确的; pts/dts 应该是 AVStream.time_base 单位。对于音频,您可以使用 1/sample_rate 作为 time_base,但这不是绝对必要的。
    猜你喜欢
    • 2015-11-05
    • 2019-02-17
    • 2022-01-24
    • 2012-11-15
    • 2020-09-15
    • 2014-11-08
    • 2011-12-24
    • 1970-01-01
    • 2015-08-16
    相关资源
    最近更新 更多