简单了解
先简单了解一下ffmpge使用 代码的大致流程 过后详细学习
看了两个代码 一个是h264转MP4 一个是yuv转jpeg h264和yuv是一种视频编码格式 一个是压缩格式 我理解一个是米饭一个是饭碗 我先简单理解了几个重要的api和结构体 大致的流程
视频
首先比较重要的结构体
AVFormatContext *inputFmtCtx = NULL, *outputFmtCtx = NULL;
AVPacket packet;
AVFormatContext 视频结构体 储存帧率啊,文件名啊等等
AVPacket packet; 帧信息
首先打开视频文件获取流信息
// 打开输入文件
if (avformat_open_input(&inputFmtCtx, “input.h264”, NULL, NULL) < 0) {
fprintf(stderr, “无法打开输入文件\n”);
return -1;
}
// 检索输入文件的流信息
if (avformat_find_stream_info(inputFmtCtx, NULL) < 0) {
fprintf(stderr, “无法找到流信息\n”);
return -1;
}
// 找到视频流的索引
for (int i = 0; i < inputFmtCtx->nb_streams; i++) {
if (inputFmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
break;
}
}
if (videoStreamIndex == -1) {
fprintf(stderr, “找不到视频流\n”);
return -1;
}
其中:avformat_open_input自动根据后缀来分配 然后创建avi个i视频 把流塞进去 分几步 线创建上下文 然后打开文件 然后文件头写流 写文尾
图片
图片片和视频的区别就在于操作一个帧 你需要设置编码器参数 首先 // 设置编码器参数
jpegContext->pix_fmt = AV_PIX_FMT_YUVJ420P; // JPEG 通常使用 YUVJ420P
jpegContext->height = 480; // 设置你的帧高度
jpegContext->width = 640; // 设置你的帧宽度
jpegContext->time_base = (AVRational){1, 25};设置你想要格式的编码器参数 然后创建一个帧 frame = av_frame_alloc();
frame->format = jpegContext->pix_fmt;
frame->width = jpegContext->width;
frame->height = jpegContext->height;
// 为帧分配内存
av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, frame->format, 32);
// 填充你的帧数据
// 这里需要你自己填充 YUV 数据到 frame->data 中
// 假设 yPlane, uPlane, vPlane 是包含 Y, U, V 数据的缓冲区
// 并且这些数据的大小和格式已经与 frame 的宽度和高度匹配
uint8_t *yPlane; // Y 分量数据
uint8_t *uPlane; // U 分量数据
uint8_t *vPlane; // V 分量数据
int yPlaneSize = frame->width * frame->height; // Y 分量的大小
int uvPlaneSize = (frame->width / 2) * (frame->height / 2); // U 和 V 分量的大小
// 假设这些数据已经准备好了
// 这里只是示例,实际应用中需要根据数据来源进行调整
// 将 Y, U, V 数据复制到 frame 的数据缓冲区
memcpy(frame->data[0], yPlane, yPlaneSize);
memcpy(frame->data[1], uPlane, uvPlaneSize);
memcpy(frame->data[2], vPlane, uvPlaneSize);
然后直接先把创建的帧frame发送到编码 然后保存到 AVPacket pkt
// 发送帧到编码器
ret = avcodec_send_frame(jpegContext, frame);
if (ret < 0) {
fprintf(stderr, “发送帧到编码器失败\n”);
return -1;
}
// 接收编码后的数据
ret = avcodec_receive_packet(jpegContext, &pkt);
if (ret < 0) {
fprintf(stderr, “编码错误\n”);
return -1;
} 保存即可
以上只是简单的看了一下流程具体还要之后把这个系统的学习完毕
yuv转化
很好奇yuv内部的排列 这里做了两个实验 把拆成四等分 就是为了知道yuv是怎么排布的 结论就是一张图片 y均匀的在图像的各处 422 是y后又1/4的u 1/4的v 二nv12是y后u而后v