我尝试使用libav将原始图像数据编码为x264:
AVPacket vpkt = { 0 };
av_init_packet(&vpkt);
int got;
int ret = avcodec_encode_video2(vcodec, &vpkt, frameyuv.get(), &got);
if (!ret && got && vpkt.size) {
if (vpkt.pts != AV_NOPTS_VALUE) {
vpkt.pts = av_rescale_q(vpkt.pts, vcodec->time_base, videost->time_base);
}
if (vpkt.dts != AV_NOPTS_VALUE) {
vpkt.dts = av_rescale_q(vpkt.dts, vcodec->time_base, videost->time_base);
}
vpkt.stream_index = videost->index;
if(vcodec->coded_frame->key_frame) {
vpkt.flags |= AV_PKT_FLAG_KEY;
}
/* -> will return -22 if max_b_frames > 0 */
ret = av_interleaved_write_frame(oc, &vpkt);
}
当vcodec-> max_b_frames设置为0时运行正常,但在任何其他值上av_interleaved_write_frame返回-22(无效参数)。
/* will fail */
c->max_b_frames = 3;
/* -> ok*/
c->max_b_frames = 0;
为什么呢?我错过了什么吗?
编解码器选项
AVDictionary *opts = NULL;
av_dict_set(&opts, "vprofile", "baseline", 0);
/* ... */
c->codec_type = AVMEDIA_TYPE_VIDEO;
c->bit_rate = 500 * 1000;
c->width = VideoWidth;
c->height = VideoHeight;
c->time_base.den = fps;
c->time_base.num = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
容器格式为mp4。
答案 0 :(得分:0)
您需要将av_rescale_q放入输出上下文的时基,而不是视频流。您正在做的事情与av_rescale_q无关。尝试:
av_rescale_q(vpkt.pts, vcodec->time_base, [output context]->time_base);
如果您继续遇到问题,几乎总是B帧问题表明DTS值不好。考虑将DTS设置为AV_NOPTS_VALUE,让解复用器自行解决。
请记住解码一个B帧,你必须知道它的两侧的帧,因此它们必须首先被解复用,考虑3帧:
I B I
必须首先解码第一帧,然后是第三帧,最后是第二帧。此信息来自DTS。
最后,通过跟随this stack overflow找出你获得-22的原因。如果它不是“非单调增加的PTS / DTS”错误,我会感到震惊。