我目前正在开发一个应用程序,该应用程序使用 Qt Designer 工具和 C++ 下的 V4L2 和 ffmpeg 库在 Linux 上从网络摄像头捕获视频,使用 lib V4L2 捕获图像没有问题,并且由于图片已准备好我将其发送到基于 ffmpeg 库的编码器,最初编码器创建一个视频文件,并接收图像以将其编码到该文件中,我的问题如下:编码正常完成,但如果我开始播放录制的视频文件,速度似乎比常规速度更快!所以很清楚,问题出在视频编码中,我的问题是,有没有一种方法或函数可以管理 ffmpeg 编码速度图片?????感谢您的帮助。
3 回答
使用 FFMpeg 创建自定义编码视频时,您实际上需要在写入输出文件的每个 AVPacket 上设置 PTS。设置 AVCodecContext 的 time_base 只会告诉容器会发生什么。PTS(演示时间戳)告诉解码器(当您查看视频时)何时实际显示该特定帧。
例如:
我有一个从 FFMpeg 的 V4L2 部分获得的 AVFrame。首先,使用 av_picture_copy 复制此图像更安全。(因此编码器不会查看 AVFrame 结构中的所有额外信息。)
av_picture_copy( (AVPicture*) picture, (AVPicture*) pFrame, c->pix_fmt, c->width, c->height );
picture->pts = numFrames;
现在根据编码帧数设置 pts
pDestFrame->pts = numFrames;
现在编码
numEncodedBytes = avcodec_encode_video( AVCodecCtx, buffer, bufferSize, pDestFrame );
现在创建一个 AVPacket 并在重新缩放后再次设置时间戳
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = av_rescale_q( c->coded_frame->pts, c->time_base, mpVideoStr->time_base );
if ( c->coded_frame->key_frame ) pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = mpVideoStr->index;
pkt.data = outbuf;
pkt.size = out_size;
最后,您可以将数据包写出来
av_write_frame( formatCtx, &pkt );
我知道这适用于 H264 视频编码,但我不能 100% 确定它适用于其他类型的视频,因为我在写这篇文章时只关心 H264。
我认为您需要为图片添加时间戳。
FFMpeg 将尽可能快地进行编码/解码。您需要自己编写同步。通常在视频解码和播放中,您的帧会附加时间戳,或者至少您可以使用音频时钟和帧速率创建一些时间戳。
但这在很大程度上取决于您希望如何同步以及如何实现它。
也许FFMpeg的教程会给你一些额外的提示
当您创建 ffmpeg 文件时,您必须指定帧速率取决于您使用的库,但寻找类似的东西
pCodecContext->time_base.den = frames_per_second;
pCodecContext->time_base.num = 1;
否则,如果您从网络摄像头生成 10-15fps 但文件中的默认值为 30 fps,它将快速播放。
有关Qt ffmpeg 包装器,请参阅http://code.google.com/p/qtffmpegwrapper/