我去年十月份的时候,花了一周把webrtc 在linux上捕获的视频显示到QT界面上,当时参考的博客[1]。当时,本想弄个视频编解码的例子,可惜在能力之外。
现在我再次捡起这个想法,现在关于webrtc的一些开源项目已经很多了,学习起来也容易一些。
事先声明,我这次仍是没有写多少代码,大部分都是从[3]的代码里抄出来的,在此表示感谢。
在这期间遇见一些问题,保存摄像头捕获的yuv数据,内存分配的大小为widthheight3/2。若不是这个大小,用ffmpeg播放,会有闪烁,花屏的现象。还需要将webrtc::VideoFrame中的数据转换成I420。
//https://github.com/SoonyangZhang/video_test/blob/v0.0/my_video_capture/framerecord.cc
webrtc::ConvertFromI420(f, webrtc::kI420, 0, videoImage_.get());
在视频解码的过程中,用以保存视频数据的缓冲区应该比数据长度大一点,不然出现内存越界崩溃。可能是解码的时候,decoder需要在这额外的内存里,写了数据,具体写了什么不是很清楚。
struct EncodedImageBuffer {
EncodedImageBuffer(uint8_t *data, int size) :len_(size) {
data_ = new uint8_t[len_+8];
memcpy(data_, data, len_);
}
~EncodedImageBuffer() { delete data_; }
uint8_t *data_;
int len_;
};
void V_H264Decoder::Run() {
while (running_)
{
webrtc::EncodedImage encoded_image;
encoded_image._buffer = (uint8_t*)pkt->data_;
encoded_image._length = pkt->len_;
encoded_image._size = pkt->len_ + 8;
if (frameType == 7) {
encoded_image._frameType = webrtc::kVideoFrameKey;
}
else {
encoded_image._frameType = webrtc::kVideoFrameDelta;
}
encoded_image._completeFrame = true;
webrtc::RTPFragmentationHeader frag_info;
LOG(LS_INFO) << "decode";
int ret = h264_decoder_->Decode(encoded_image, false, &frag_info);
if (ret != 0)
{
}
}
}
我的代码地址[4],依赖[3]的工程。如果感兴趣的童鞋,不想配置vs工程的库依赖,可以给我发邮件,把vs工程分享出来。
[1]WebRTC学习之九:摄像头的捕捉和显示
[2] webrtc视频捕获并通过QT显示
[3] anyRTC-RTMP-OpenSource
[4][代码地址][https://github.com/SoonyangZhang/video_test/tree/v0.0/my_video_capture]