我正在从两个不同的线程接收视频 H264 编码数据和音频 G.711 PCM 编码数据,以复用/写入mov
多媒体容器。
writer 函数签名如下:
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(..)
andWriteVideo(..)
函数内部,我正在AVPakcet
使用av_init_packet(...)
and setpEncodedData
和iLength
aspacket.data
和packet.size
. 我打印了packet.pts
and packet.dts
,它相当于AV_NOPTS_VALUE
.
现在,如何正确计算音频和视频数据的 PTS、DTS 和数据包持续时间(和) packet.dts
,以便我可以同步音频和视频并正确播放?我在互联网上看到了很多例子,但没有一个对我有意义。我是新来的,我的概念在某些情况下可能不正确。我想以适当的方式做到这一点。packet.pts
packet.duration
ffmpeg
提前致谢!
编辑:在我的视频流中,没有 B 帧。所以,我认为 PTS 和 DTS 可以在这里保持不变。