基本步骤:
1、打开编码器
void open_codecer(int width, int heigth,AVCodecContext **enc_ctx){
int ret = 0 ;
AVCodec *codec = NULL;
codec = avcodec_find_decoder_by_name("libx264");
if (!codec) {
printf("codec libx264 not found\n");
exit(1);
}
*enc_ctx = avcodec_alloc_context3(codec);
if (!enc_ctx) {
printf("could not alloc video codec context\n");
exit(1);
}
//SPS/PPS
(*enc_ctx)->profile = FF_PROFILE_H264_HIGH_444;
(*enc_ctx)->level = 50; //表示LEVEL5.0
//设置分辨率
(*enc_ctx)->width = width;//宽
(*enc_ctx)->height = heigth;//高
//设置GOP(分组)
(*enc_ctx)->gop_size = 25;
(*enc_ctx)->keyint_min = 3; //最小插入I帧的间隔(可选)
//设置B帧的数量
(*enc_ctx)->max_b_frames = 3;// 一般不超过3帧(可选)
(*enc_ctx)->has_b_frames = 1;// (可选)
//参考帧数量
(*enc_ctx)->refs = 3; // 参考帧数量(可选)
//设置输入YUV格式
(*enc_ctx)->pix_fmt = AV_PIX_FMT_YUV420P;
//设置码率
(*enc_ctx)->bit_rate = 600*1000; // 600kbps
//设置帧率
(*enc_ctx)->time_base = (AVRational){1,25};//帧与帧之间的间隔
(*enc_ctx)->framerate = (AVRational){25,1};//帧率,每秒25帧
// 打卡编码器
ret = avcodec_open2((*enc_ctx), codec, NULL);
if (ret<0) {
printf("failed to open codecer: %s!\n ",av_err2str(ret));
exit(1);
}
}
2、转换NV12到YUV420,这是因为FFmpeg的x264编码器只支持YUV420
while (ret=av_read_frame(ps, &pkt)==0) {
//YYYYYYYYUVUV NV12
//YYYYYYYYUUVV YUV420
memcpy(fram->data[0], pkt->size, 307200);
for (i=0; i<307200/4; i++) {
fram->data[1][i] = pkt->data[307200+i*2];
fram->data[2][i] = pkt->data[307201+i*2];
}
//把YUV写入文件
fwrite(fram->data[0], 1, 307200, yuvoutfile);
fwrite(fram->data[1], 1, 307200/4, yuvoutfile);
fwrite(fram->data[2], 1, 307200/4, yuvoutfile);
av_packet_unref(pkt);
}
3、准备编码数据AVFrame
创建frame:
static AVFrame* create_frame(int width, int height){
int ret = 0;
AVFrame* frame = NULL;
frame = av_frame_alloc();
if (!frame) {
printf("");
}
//设置参数
frame->width = width;
frame->height = height;
frame->format = AV_PIX_FMT_YUV420P;
//获取frame
ret = av_frame_get_buffer(frame, 32); //按32位对齐
if (ret<0) {
printf("");
}
return frame;
}
创建AVPacket:
AVPacket* pck = av_packet_alloc();
4、H264编码
avcodec_send_frame(<#AVCodecContext *avctx#>, <#const AVFrame *frame#>)
avcodec_receive_packet(<#AVCodecContext *avctx#>, <#AVPacket *avpkt#>)
static void encoder(AVCodecContext *enc_ctx,AVFrame *frame,
AVPacket *newpkt,FILE *outfile){
int ret = 0;
// 送原始数据到编码器进行编码
ret = avcodec_send_frame(enc_ctx, frame);
if (ret<0) {
printf("");
}
// 从编码器获取编码好的数据
if (ret>=0) {
ret = avcodec_receive_packet(enc_ctx, newpkt);
// 如果编码器数据不足时,返回EAGAIN,或者到数据尾时返回AVERROE_EOF
if (ret==AVERROR(EAGAIN)||ret ==AVERROR_EOF) {
return;
}else{
printf("");
exit(1);
}
fwrite(newpkt->data, 1, newpkt->size, outfile);
av_packet_unref(newpkt);
}
}
注意:
1、编码器中有未吐出的数据,需要再次调用encoder(AVCodecContext *enc_ctx,NULL,
AVPacket *newpkt,FILE *outfile)编码函数,frame传NULL。
2、对于输入的编码器函数的参数frame,我们需要设置frame->pts,int base = 0 frame->pts=base++;这样我们的视频才会按照顺序播放,否则会花屏。
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功
查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我在使用Ruby1.9.2p290更改文本文件的编码时遇到问题。我收到错误消息invalidbytesequenceinUTF-8(ArgumentError)。问题(我认为)在于字符集似乎是未知的。如果我执行以下操作,则从命令行:$filetest.txt我得到:Non-ISOextended-ASCIIEnglishtext,withCRLFlineterminators或者,或者,如果我这样做:$file-itest.txt我得到:test.txt:text/plain;charset=unknown但是,如果我这样做,在Ruby中:data=File.open("test.tx