FFmpeg内存模式和文件模式
0
不用写出文件直接读取编码数据
aliang::media::VideoEncoder encoder(1080, 1080);
// 文件模式
// AVFormatContext* outputCtx = avformat_alloc_context();
// avformat_alloc_output_context2(&outputCtx, NULL, NULL, "D:/tmp/aliang1.mp4");
// AVStream* video_stream = avformat_new_stream(outputCtx, NULL);
// avcodec_parameters_from_context(video_stream->codecpar, encoder.codecCtx);
// avio_open(&outputCtx->pb, "D:/tmp/aliang1.mp4", AVIO_FLAG_WRITE);
// AVDictionary *options = nullptr;
// // frag_keyframe+empty_moov
// // frag_keyframe+empty_moov+default_base_moof
// av_dict_set(&options, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
// avformat_write_header(outputCtx, &options);
// 内存模式
std::ofstream stream_ts;
stream_ts.open("D:/tmp/aliang3.mp4", std::ios_base::binary);
AVFormatContext* outputCtx = avformat_alloc_context();
size_t buf_size = 4096;
uint8_t* buf = new uint8_t[buf_size];
outputCtx->oformat = av_guess_format("mp4", NULL, NULL);
outputCtx->pb = avio_alloc_context(buf, buf_size, 1, &stream_ts, NULL, write_packet, NULL);
AVStream* video_stream = avformat_new_stream(outputCtx, NULL);
avcodec_parameters_from_context(video_stream->codecpar, encoder.codecCtx);
AVDictionary *options = nullptr;
// frag_keyframe+empty_moov
// frag_keyframe+empty_moov+default_base_moof
av_dict_set(&options, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
avformat_write_header(outputCtx, &options);
auto frame{ cv::imread("D:/tmp/bike.jpg") };
size_t length = 0;
std::vector<char> data(4 * 1024 * 1024);
const int width = frame.cols;
const int height = frame.rows;
cv::cvtColor(frame, frame, cv::COLOR_BGR2YUV_I420);
for(int i = 0; i < 100; ++i) {
encoder.enc(width, height, frame.data);
while(encoder.get(data, length)) {
av_write_frame(outputCtx, encoder.packet);
}
}
av_write_trailer(outputCtx);
std::cout << "完成\n";