ffmpeg condec ctx gop H.264多参考帧及 h264规格 ffmpeg-解码 gop 段任意一帧

ffmpeg-解码 gop 段任意一帧

https://blog.csdn.net/u012780655/article/details/109573471

 

FFmpeg的GOP(I帧)对齐问题

https://blog.csdn.net/LvGreat/article/details/103540007

在之前的编码中,已经通过-g 48明确指定了GOP长度(48帧,即2s),具体命令为

H264多参考帧个数考虑

https://blog.csdn.net/haima1998/article/details/50754087

H.264多参考帧

https://blog.csdn.net/icekings/article/details/24538861?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328680.24463.16162376321043669&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

 

 

使用ffmpeg转换视频时,设置参考帧-refs 8 为什么转换完的视频参考帧是4~?

https://zhidao.baidu.com/question/241610096900491124.html

-b 1200 应该改成-b 1200k
少了单位,于是报码率小。

 

https://zhidao.baidu.com/question/550993826.html

,在这里首先要阐明所谓的AVC其实就是H.264标准,是由ITU-T和ISO/IEC组成的联合视频组(JVT,Joint Video Team)一起开发的,ITU-T给这个标准命名为H.264(以前叫做H.26L),而ISO/IEC称它为MPEG-4 高级视频编码(Advanced Video Coding,AVC),它定位于覆盖整个视频应用领域,包括:低码率的无线应用、标准清晰度和高清晰度的电视广播应用、Internet上的视频流应用,传输高清晰度的DVD视频以及应用于数码相机的高质量视频应用等等。
AVC的规格分为三等,从低到高分别为:Baseline、Main、High。
Baseline(最低Profile)级别支持I/P 帧,只支持无交错(Progressive)和CAVLC,一般用于低阶或需要额外容错的应用,比如视频通话、手机视频等;
Main(主要Profile)级别提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),同样提供对于CAVLC 和CABAC 的支持,用于主流消费类电子产品规格如低解码(相对而言)的mp4、便携的视频播放器、PSP和Ipod等;
High(高端Profile,也叫FRExt)级别在Main的基础上增加了8x8 内部预测、自定义量化、无损视频编码和更多的YUV 格式(如4:4:4)用于广播及视频碟片存储(蓝光影片),高清电视的应用。 AVC 的规格主要是针对兼容性的,不同的规格能在相同级别上的平台应用。
至于Baseline@L x.x、Main@L x.x、High@L x.x形式则是在不同级别下的码流级别,数值越大码流就越大,更耗费资源。所以就码流而言High@L3.0<High@L4.0<High@L5.1。

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 FFmpeg 的 C++ 接口来实现 RGB 转 H.264 的多线程编码。下面是一个简单的示例代码,它将一系列 RGB 图像转换为 H.264 视频: ```cpp #include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <vector> #include <sstream> extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> } using namespace std; // 定义互斥量和条件变量,用于多线程同步 mutex mtx; condition_variable cv; // 定义全局变量,用于存储编码后的视频数据 vector<uint8_t> video_buffer; // 定义编码器上下文和对象 AVCodecContext *encoder_ctx = NULL; AVFrame *frame = NULL; // 定义编码器线程 void encode_thread() { AVPacket pkt; int ret; while (true) { unique_lock<mutex> lock(mtx); cv.wait(lock, [] { return !video_buffer.empty(); }); // 从全局变量中取出一帧 RGB 图像 vector<uint8_t> rgb_image = video_buffer.back(); video_buffer.pop_back(); // 把 RGB 图像转换为编码器所需的格式 av_image_fill_arrays(frame->data, frame->linesize, rgb_image.data(), encoder_ctx->pix_fmt, encoder_ctx->width, encoder_ctx->height, 1); // 发送图像数据到编码器 ret = avcodec_send_frame(encoder_ctx, frame); if (ret < 0) { cerr << "Error sending a frame to the encoder: " << av_err2str(ret) << endl; continue; } // 接收编码后的数据包 while (ret >= 0) { ret = avcodec_receive_packet(encoder_ctx, &pkt); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break; else if (ret < 0) { cerr << "Error encoding a frame: " << av_err2str(ret) << endl; continue; } // 把编码后的数据包存储到全局变量中 video_buffer.insert(video_buffer.begin(), pkt.data, pkt.data + pkt.size); av_packet_unref(&pkt); } } } int main() { // 初始化 FFmpeg 库 av_register_all(); avformat_network_init(); // 打开编码器并设置编码参数 AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { cerr << "Codec not found" << endl; return -1; } encoder_ctx = avcodec_alloc_context3(codec); if (!encoder_ctx) { cerr << "Could not allocate video codec context" << endl; return -1; } encoder_ctx->bit_rate = 400000; encoder_ctx->width = 640; encoder_ctx->height = 480; encoder_ctx->time_base = {1, 25}; encoder_ctx->gop_size = 10; encoder_ctx->max_b_frames = 1; encoder_ctx->pix_fmt = AV_PIX_FMT_YUV420P; if (avcodec_open2(encoder_ctx, codec, NULL) < 0) { cerr << "Could not open codec" << endl; return -1; } // 创建对象并分配内存 frame = av_frame_alloc(); if (!frame) { cerr << "Could not allocate video frame" << endl; return -1; } frame->format = encoder_ctx->pix_fmt; frame->width = encoder_ctx->width; frame->height = encoder_ctx->height; if (av_frame_get_buffer(frame, 0) < 0) { cerr << "Could not allocate the video frame data" << endl; return -1; } // 创建编码器线程 thread t(encode_thread); // 读入 RGB 图像并发送到编码器线程进行编码 for (int i = 1; i <= 100; i++) { stringstream ss; ss << "rgb" << i << ".raw"; FILE *f = fopen(ss.str().c_str(), "rb"); if (!f) { cerr << "Could not open file: " << ss.str() << endl; return -1; } int size = encoder_ctx->width * encoder_ctx->height * 3; vector<uint8_t> rgb_image(size); fread(rgb_image.data(), 1, size, f); fclose(f); { lock_guard<mutex> lock(mtx); video_buffer.push_back(rgb_image); } cv.notify_one(); } // 等待编码器线程退出 t.join(); // 释放资源 avcodec_free_context(&encoder_ctx); av_frame_free(&frame); return 0; } ``` 在这个示例代码中,我们使用了一个互斥量和一个条件变量来实现多线程同步。编码器线程等待条件变量的通知,然后从全局变量中取出一帧 RGB 图像,把它转换为编码器所需的格式,并发送到编码器进行编码。编码器线程把编码后的数据包存储到全局变量中,然后再次等待条件变量的通知。主线程读入一系列 RGB 图像,并把它们存储到全局变量中,然后通过条件变量通知编码器线程进行编码。最后,主线程等待编码器线程退出,并释放资源。 注意,这个示例代码中只使用了一个编码器线程。如果你想进一步提高编码速度,可以使用多个编码器线程,并且把 RGB 图像分割成多块,让每个编码器线程处理一块图像。你也可以使用 OpenMP 或其他线程库来实现多线程编码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值