- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我用 OpenGL 渲染了一些图像,需要将它们组合成一个视频文件。每个图像都是代表 sRGB 颜色分量的 uint8_t 值序列(图像数组看起来像 ...rgbrgbrgb ...)
我对视频处理知之甚少,根本没有使用 ffmpeg 库的经验。我使用这些资源作为引用做了一个小测试程序:
https://ffmpeg.org/doxygen/trunk/encode_video_8c-example.html
How to convert RGB from YUV420p for ffmpeg encoder?
该测试程序应该制作一个关于生长绿色垂直条纹的视频。我只是想弄清楚如何使用一些原始 RGB 数据源制作视频。
这是我的代码:
#include <iostream>
#include <vector>
#include <algorithm>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
static void encode( AVCodecContext* enc_ctx,
AVFrame* frame, AVPacket* pkt,
FILE* outfile )
{
int ret;
ret = avcodec_send_frame(enc_ctx, frame);
if (ret < 0) {
std::cerr << "Error sending a frame for encoding\n";
return;
}
while (ret >= 0) {
ret = avcodec_receive_packet(enc_ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during encoding\n");
exit(1);
}
fwrite(pkt->data, 1, pkt->size, outfile);
av_packet_unref(pkt);
}
}
static constexpr int w = 1920, h = 1080;
static constexpr float fps = 20.f, time = 5.f;
static constexpr int nFrames = static_cast<int>(fps * time);
static std::vector<uint8_t> imageRGB(w * h * 3, 0);
static void UpdateImageRGB()
{
static int d = 50;
imageRGB.assign(w * h * 3, 0);
for (int i = 0; i < h; ++i)
for ( int j = std::max(0, w / 2 - d);
j < std::min(w, w / 2 + d);
++j )
{
imageRGB[(w * i + j) * 3 + 0] = 50;
imageRGB[(w * i + j) * 3 + 1] = 200;
imageRGB[(w * i + j) * 3 + 2] = 50;
}
d += 5;
}
int main()
{
int ret = 0;
auto filename = "test.mp4";
auto codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!codec) {
std::cerr << "Codec \"x.264\" not found\n";
return 1;
}
auto c = avcodec_alloc_context3(codec);
if (!c) {
std::cerr << "Could not allocate video codec context\n";
return 1;
}
auto pkt = av_packet_alloc();
if (!pkt) return 1;
// 1.8 bits / (pixel * frame)
c->bit_rate = static_cast<int64_t>(1.8f * w * h * fps);
/* resolution must be a multiple of two */
c->width = w;
c->height = h;
/* frames per second */
c->time_base = AVRational{ 1, static_cast<int>(fps) };
c->framerate = AVRational{ static_cast<int>(fps), 1 };
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
av_opt_set(c->priv_data, "preset", "slow", 0);
av_opt_set(c->priv_data, "preset", "slow", 0);
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
char str[AV_ERROR_MAX_STRING_SIZE];
std::cerr << "Could not open codec: "
<< av_make_error_string(str, AV_ERROR_MAX_STRING_SIZE, ret)
<< "\n";
return 1;
}
FILE * f;
fopen_s(&f, filename, "wb");
if (!f) {
std::cerr << "Could not open " << filename << '\n';
return 1;
}
auto frame = av_frame_alloc();
if (!frame) {
std::cerr << "Could not allocate video frame\n";
return 1;
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
std::cerr << stderr, "Could not allocate the video frame data\n";
return 1;
}
SwsContext* ctx = sws_getContext( w, h, AV_PIX_FMT_RGB24,
w, h, AV_PIX_FMT_YUV420P,
0, 0, 0, 0 );
for (int i = 0; i < nFrames; i++)
{
ret = av_frame_make_writable(frame);
UpdateImageRGB();
static const uint8_t* rgbData[1] = { &imageRGB[0] };
static constexpr int rgbLinesize[1] = { 3 * w };
sws_scale( ctx, rgbData, rgbLinesize, 0, h,
frame->data, frame->linesize );
frame->pts = i;
/* encode the image */
encode(c, frame, pkt, f);
}
encode(c, NULL, pkt, f);
fclose(f);
avcodec_free_context(&c);
av_frame_free(&frame);
av_packet_free(&pkt);
return 0;
}
[libx264 @ 0000020c18681800] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0000020c18681800] profile High, level 5.0, 4:2:0, 8-bit
[libx264 @ 0000020c18681800] frame I:11 Avg QP: 0.00 size: 639
[libx264 @ 0000020c18681800] frame P:74 Avg QP: 0.32 size: 174
[libx264 @ 0000020c18681800] frame B:15 Avg QP: 2.26 size: 990
[libx264 @ 0000020c18681800] consecutive B-frames: 70.0% 30.0%
[libx264 @ 0000020c18681800] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0000020c18681800] mb P I16..4: 0.6% 0.0% 0.0% P16..4: 2.1% 0.0% 0.0% 0.0% 0.0% skip:97.3%
[libx264 @ 0000020c18681800] mb B I16..4: 0.1% 0.0% 0.0% B16..8: 0.6% 0.0% 0.0% direct: 0.6% skip:98.7% L0:39.8% L1:60.2% BI: 0.0%
[libx264 @ 0000020c18681800] final ratefactor: -46.47
[libx264 @ 0000020c18681800] 8x8 transform intra:0.0%
[libx264 @ 0000020c18681800] direct mvs spatial:0.0% temporal:100.0%
[libx264 @ 0000020c18681800] coded y,uvDC,uvAC intra: 0.0% 0.1% 0.1% inter: 0.0% 0.1% 0.1%
[libx264 @ 0000020c18681800] i16 v,h,dc,p: 99% 0% 1% 0%
[libx264 @ 0000020c18681800] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 0% 0% 100% 0% 0% 0% 0% 0% 0%
[libx264 @ 0000020c18681800] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 46% 0% 54% 0% 0% 0% 0% 0% 0%
[libx264 @ 0000020c18681800] i8c dc,h,v,p: 96% 1% 3% 0%
[libx264 @ 0000020c18681800] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0000020c18681800] ref P L0: 70.2% 0.0% 29.8% 0.0% 0.0%
[libx264 @ 0000020c18681800] kb/s:55.61
最佳答案
嘿,我通过引用此处使用的方法解决了这个问题。我不知道您是否可以在代码中应用它,但我建议您检查一下:
https://superuser.com/questions/469273/ffmpeg-convert-rgb-images-to-video
关于c++ - 使用 FFMPEG 将 RGB 图像序列保存到 .mp4 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60339670/
我正在阅读 Python 文档以真正深入了解 Python 语言,并遇到了 filter 和 map 函数。我以前使用过过滤器,但从未使用过映射,尽管我在 SO 上的各种 Python 问题中都见过这
当我尝试打印 BST 的级别顺序时,这个问题提示了我。 这是一个 Pre-Order Sequence: 4, 1, 2, 3, 5, 6, 7, 8 In_order Sequence : 1, 2
我的代码在 main(序列测试;)的第一行出现错误,指出它是对 sequence::sequence() 的 undefined reference 。我无法更改 main 中的代码。有谁知道我该如何
这可能很简单,但我在通常的 latex 指南中找不到任何相关内容。在这句话中: {\em hello\/} “\/”的目的是什么? 最佳答案 这就是所谓的斜体校正。其目的是确保斜体文本后有适当的间距。
当我从 Postgresql 表中删除所有记录,然后尝试重置序列以在插入时开始一个编号为 1 的新记录时,我得到不同的结果: SELECT setval('tblname_id_seq', (SELE
在版本10.0.3中,MariaDB引入了一种称为序列的存储引擎。 其ad hoc为操作生成整数序列,然后终止。 该序列包含正整数,以降序或升序排列,并使用起始,结束和递增值。 它不允许在多个查询中
如何在 Groovy 中获取给定数字的序列,例如: def number = 169 // need a method in groovy to find the consecutive number
基本上,如果这是 .NET,它看起来像这样: ISomething { string A { get; } int B { get; } } var somethings = new List
说以下代码部分(同一块): A <= 1 A <= 2 变量 A 总是被赋值为 2 吗?还是会出现竞争条件并分配 1 或 2? 我对非阻塞赋值的理解是,由硬件在 future 分配变量 A,因此它可能
在运行 WiX 设置时,我正在寻找操作列表及其顺序。不知何故,官方网站似乎没有提供任何信息。 基本问题是我想正确安排我的自定义操作。通常我需要使用 regsvr32.exe 注册一个 DLL,而这只能
F#初学者在这里 我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(p
作为构建过程和不断发展的数据库的一部分,我试图创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比所允许的更多的权限。 我的脚本创建了一个过程来删除表/序列,执行该过程,然
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
这个问题已经有答案了: sql ORDER BY multiple values in specific order? (12 个回答) 已关闭 9 年前。 我有一个 sql 语句,我想要ORDER
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
在用java编写代码时,我需要用“],[”分割字符串。下面是我的代码。 try (BufferedReader reader = new BufferedReader(new InputStreamR
这个问题已经有答案了: Project Euler Question 14 (Collatz Problem) (8 个回答) 已关闭 9 年前。 我正在尝试查找数字的 Collatz 序列。以下
我有一个例程函数process_letter_location(const char& c, string &word)。 在我的 main 中,我声明了一系列字符串变量,如下所示: string s
我需要找到最长的多米诺骨牌链,给定一组 12 个随机挑选的多米诺骨牌。我已经递归地生成了多米诺骨牌的所有可能性(使用 0 到 12 的面值有 91 种可能性)。多米诺骨牌由一 block “砖 blo
我有这个数据结构 Seq,它继承了类 vector 但有一些额外的功能。使用这个数据结构 Seq 我有这个预定义的数据结构: typedef Seq > MxInt2d; 我现在想要一个包含多个 Mx
我是一名优秀的程序员,十分优秀!