怎么建设网站上传音乐,wordpress项目下载文件,简单大气的网站模板,网站建设属不属于无形资产文章目录 基本概念流程api核心代码 基本概念
YUV格式#xff1a;是一种颜色编码方式#xff0c;YUV分别为三个分量#xff1a;‘Y’是明亮度#xff0c;也就是灰度值#xff1b;‘U’和‘V’是色度 YUV格式的分类#xff1a;
planar的YUV格式#xff1a;先存储planar的… 文章目录 基本概念流程api核心代码 基本概念
YUV格式是一种颜色编码方式YUV分别为三个分量‘Y’是明亮度也就是灰度值‘U’和‘V’是色度 YUV格式的分类
planar的YUV格式先存储planar的Y像素点在依次存储U和V像素点packed的YUV格式交叉存储YUV像素点
YUV流的采样方式
YUV4:4:4表示一个Y分量对应一组UV分量。YUV4:2:2表示两个Y分量共用一组UV分量。YUV4:2:0表示四个Y分量共用一组UV分量。
流程 api int av_frame_get_buffer(AVFrame *frame, int align); 为⾳频或视频数据分配新的buffer使用完成后需要将引用计数-1 int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt,int align) 按照指定的宽、高、像素格式来分配图像内存第一个参数为Frame的数据 int av_frame_make_writable(AVFrame *frame) 检查AVFrame-data是否可写 int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align) 计算1帧数据的大小参数为像素格式、图像宽、图像⾼字节对齐方式 av_image_fill_arrays: 存储⼀帧像素数据存储到AVFrame对应的data buffer
核心代码
#include stdio.h
#include stdlib.h
#include string.h#include libavcodec/avcodec.h
#include libavutil/time.h
#include libavutil/opt.h
#include libavutil/imgutils.hint64_t get_time()
{return av_gettime_relative() / 1000; // 换算成毫秒
}
static int encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,FILE *outfile)
{int ret;/* send the frame to the encoder */ret avcodec_send_frame(enc_ctx, frame);if (ret 0){return -1;}while (ret 0){ret avcodec_receive_packet(enc_ctx, pkt);if (ret AVERROR(EAGAIN) || ret AVERROR_EOF) {return 0;} else if (ret 0) {return -1;}fwrite(pkt-data, 1, pkt-size, outfile);}return 0;
}int main(int argc, char **argv)
{char *in_yuv_file NULL;char *out_h264_file NULL;FILE *infile NULL;FILE *outfile NULL;const char *codec_name NULL;const AVCodec *codec NULL;AVCodecContext *codec_ctx NULL;AVFrame *frame NULL;AVPacket *pkt NULL;int ret 0;in_yuv_file argv[1]; // 输入YUV文件out_h264_file argv[2];codec_name argv[3];/* 查找指定的编码器 */codec avcodec_find_encoder_by_name(codec_name);if (!codec) {fprintf(stderr, Codec %s not found\n, codec_name);exit(1);}codec_ctx avcodec_alloc_context3(codec);if (!codec_ctx) {fprintf(stderr, Could not allocate video codec context\n);exit(1);}/* 设置分辨率*/codec_ctx-width 1280;codec_ctx-height 720;/* 设置time base */codec_ctx-time_base (AVRational){1, 25};codec_ctx-framerate (AVRational){25, 1};/* 设置I帧间隔* 如果frame-pict_type设置为AV_PICTURE_TYPE_I, 则忽略gop_size的设置一直当做I帧进行编码*/codec_ctx-gop_size 25; // I帧间隔codec_ctx-max_b_frames 2; // 如果不想包含B帧则设置为0codec_ctx-pix_fmt AV_PIX_FMT_YUV420P;//if (codec-id AV_CODEC_ID_H264) {// 相关的参数可以参考libx264.c的 AVOption optionsav_opt_set(codec_ctx-priv_data, preset, medium, 0);av_opt_set(codec_ctx-priv_data, profile, main, 0);av_opt_set(codec_ctx-priv_data, tune,zerolatency,0);}/** 设置编码器参数*//* 设置bitrate */codec_ctx-bit_rate 3000000;/* 将codec_ctx和codec进行绑定 */avcodec_open2(codec_ctx, codec, NULL);// 打开输入和输出文件infile fopen(in_yuv_file, rb);outfile fopen(out_h264_file, wb);// 分配pkt和framepkt av_packet_alloc();frame av_frame_alloc();// 为frame分配bufferframe-format codec_ctx-pix_fmt;frame-width codec_ctx-width;frame-height codec_ctx-height;ret av_frame_get_buffer(frame, 0);// 计算出每一帧的数据 像素格式 * 宽 * 高// 1382400int frame_bytes av_image_get_buffer_size(frame-format, frame-width,frame-height, 1);uint8_t *yuv_buf (uint8_t *)malloc(frame_bytes);// 作用int64_t begin_time get_time();int64_t end_time begin_time;int64_t all_begin_time get_time();int64_t all_end_time all_begin_time;int64_t pts 0;printf(start enode\n);for (;;) {memset(yuv_buf, 0, frame_bytes);size_t read_bytes fread(yuv_buf, 1, frame_bytes, infile);ret av_frame_make_writable(frame);int need_size av_image_fill_arrays(frame-data, frame-linesize, yuv_buf,frame-format,frame-width, frame-height, 1);pts 40;// 设置pts 计算frame-pts pts; // 使用采样率作为pts的单位具体换算成秒 pts*1/采样率begin_time get_time();encode(codec_ctx, frame, pkt, outfile);end_time get_time();printf(encode time:%lldms\n, end_time - begin_time);}/* 冲刷编码器 */encode(codec_ctx, NULL, pkt, outfile);all_end_time get_time();printf(all encode time:%lldms\n, all_end_time - all_begin_time);// 关闭文件fclose(infile);fclose(outfile);// 释放内存if(yuv_buf) {free(yuv_buf);}av_frame_free(frame);av_packet_free(pkt);avcodec_free_context(codec_ctx);printf(main finish, please enter Enter and exit\n);getchar();return 0;
}