mirror of
https://github.com/SunnyQjm/ndn_ffmpeg_rtc.git
synced 2026-10-05 01:15:41 +08:00
74 lines
2.0 KiB
C++
74 lines
2.0 KiB
C++
//
|
|
// Created by mingj on 2019/10/18.
|
|
//
|
|
|
|
#include "EasyVideoEncoder.h"
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
EasyVideoEncoder::EasyVideoEncoder(enum AVCodecID cid): codecId(cid) {
|
|
pCodec = avcodec_find_encoder(codecId);
|
|
avcodec_register(pCodec);
|
|
if (!pCodec) {
|
|
EasyVideoEncoder::throwException("Could not find encoder");
|
|
}
|
|
pCodecContext = avcodec_alloc_context3(pCodec);
|
|
if (!pCodecContext) {
|
|
EasyVideoEncoder::throwException("Could not allocate video codec context");
|
|
}
|
|
|
|
if (codecId == AV_CODEC_ID_H264) {
|
|
av_opt_set(pCodecContext->priv_data, "preset", "slow", 0);
|
|
av_opt_set(pCodecContext->priv_data, "tune", "zerolatency", 0);
|
|
}
|
|
}
|
|
|
|
|
|
EasyVideoEncoder::~EasyVideoEncoder() {
|
|
avcodec_close(pCodecContext);
|
|
av_free(pCodecContext);
|
|
}
|
|
|
|
EasyVideoEncoder *EasyVideoEncoder::initCodecParam(const CodecContextParam ¶m) {
|
|
pCodecContext->bit_rate = param.bit_rate;
|
|
pCodecContext->width = param.width;
|
|
pCodecContext->height = param.height;
|
|
pCodecContext->time_base = param.time_base;
|
|
pCodecContext->gop_size = param.gop_size;
|
|
pCodecContext->max_b_frames = param.max_b_frames;
|
|
pCodecContext->pix_fmt = param.pix_fmt;
|
|
return this;
|
|
}
|
|
|
|
EasyVideoEncoder *EasyVideoEncoder::prepareEncode() {
|
|
|
|
|
|
// 打开编码器
|
|
if (avcodec_open2(pCodecContext, pCodec, nullptr) < 0) {
|
|
EasyVideoEncoder::throwException("Could not open codec");
|
|
}
|
|
return this;
|
|
}
|
|
|
|
void EasyVideoEncoder::throwException(const std::string &msg) {
|
|
std::string logMsg = "EasyVideoEncoder -> " + msg;
|
|
throw FFmpegFailedException(logMsg);
|
|
}
|
|
|
|
EasyVideoEncoder *EasyVideoEncoder::encode(AVFrame *pFrame, const EasyVideoEncoder::EncodeCallbackFunc &callback) {
|
|
av_init_packet(&pkt);
|
|
pkt.data = nullptr;
|
|
pkt.size = 0;
|
|
int ret = avcodec_send_frame(pCodecContext, pFrame);
|
|
if (ret != 0) {
|
|
return this;
|
|
}
|
|
while (avcodec_receive_packet(pCodecContext, &pkt) >= 0) {
|
|
callback(&pkt);
|
|
}
|
|
av_packet_unref(&pkt);
|
|
return this;
|
|
}
|
|
|