二、ffmpeg 将YUV编码为.h264
1.下载安装ffmpeg
./configure --enable-libx264 --enable-gpl --enable-shared
make
make install
2.用安装好的ffmpeg用命令将YUV编码为.h264
ffmpeg -s 480x272 -i ds_480x272.yuv -r 25 -vcodec libx264 ds2.h264
yuv文件:
https://github.com/leixiaohua1020/simplest_ffmpeg_video_encoder/blob/master/ds_480x272.yuv
3.用C语言代码调用ffmpeg接口将YUV编码为.h264
编译命令:编译之前,执行下ldconfig命令,把libx264库更新到系统库路径;
gcc simplest_ffmpeg_video_encoder_pure.cpp -g -o sffmpegencoder -I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil
代码如下
simplest_ffmpeg_video_encoder_pure.cpp
-
/* -
* Simplest FFmpeg Video Encoder Pure -
* -
* Lei Xiaohua -
* leixiaohua1020@126.com -
* Communication University of China / Digital TV Technology -
* http://blog.csdn.net/leixiaohua1020 -
* -
* This software encode YUV420P data to video bitstream -
* (Such as H.264, H.265, VP8, MPEG2 etc). -
* It only uses libavcodec to encode video (without libavformat) -
* It's the simplest video encoding software based on FFmpeg. -
* Suitable for beginner of FFmpeg -
* -
* -
* modify: openswc -
* build: -
* gcc simplest_ffmpeg_video_encoder_pure.cpp -g -o sffmpegencoder -I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil -
* before use sffmpegencoder: you need to excute the following command: su root; ldconfig; -
* or there is an error: -
* ./sffmpegencoder: error while loading shared libraries: libavcodec.so.57: cannot open shared object file: No such file or directory -
*/ -
#include <stdio.h> -
#define __STDC_CONSTANT_MACROS -
#ifdef _WIN32 -
//Windows -
extern "C" -
{ -
#include "libavutil/opt.h" -
#include "libavcodec/avcodec.h" -
#include "libavutil/imgutils.h" -
}; -
#else -
//Linux... -
#ifdef __cplusplus -
extern "C" -
{ -
#endif -
#include <libavutil/opt.h> -
#include <libavcodec/avcodec.h> -
#include <libavutil/imgutils.h> -
#ifdef __cplusplus -
}; -
#endif -
#endif -
//test different codec -
#define TEST_H264 1 -
#define TEST_HEVC 0 -
int main(int argc, char* argv[]) -
{ -
AVCodec *pCodec; -
AVCodecContext *pCodecCtx= NULL; -
int i, ret, got_output; -
FILE *fp_in; -
FILE *fp_out; -
AVFrame *pFrame; -
AVPacket pkt; -
int y_size; -
int framecnt=0; -
char filename_in[]="../ds_480x272.yuv"; -
#if TEST_HEVC -
AVCodecID codec_id=AV_CODEC_ID_HEVC; -
char filename_out[]="ds.hevc"; -
#else -
AVCodecID codec_id=AV_CODEC_ID_H264; -
char filename_out[]="ds.h264"; -
#endif -
int in_w=480,in_h=272; -
int framenum=100; -
avcodec_register_all(); -
pCodec = avcodec_find_encoder(codec_id); -
if (!pCodec) { -
printf("Codec not foundn"); -
return -1; -
} -
pCodecCtx = avcodec_alloc_context3(pCodec); -
if (!pCodecCtx) { -
printf("Could not allocate video codec contextn"); -
return -1; -
} -
pCodecCtx->bit_rate = 400000; -
pCodecCtx->width = in_w; -
pCodecCtx->height = in_h; -
pCodecCtx->time_base.num=1; -
pCodecCtx->time_base.den=25; -
pCodecCtx->gop_size = 10; -
pCodecCtx->max_b_frames = 1; -
pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; -
if (codec_id == AV_CODEC_ID_H264) -
av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0); -
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { -
printf("Could not open codecn"); -
return -1; -
} -
pFrame = av_frame_alloc(); -
if (!pFrame) { -
printf("Could not allocate video framen"); -
return -1; -
} -
pFrame->format = pCodecCtx->pix_fmt; -
pFrame->width = pCodecCtx->width; -
pFrame->height = pCodecCtx->height; -
ret = av_image_alloc(pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height, -
pCodecCtx->pix_fmt, 16); -
if (ret < 0) { -
printf("Could not allocate raw picture buffern"); -
return -1; -
} -
//Input raw data -
fp_in = fopen(filename_in, "rb"); -
if (!fp_in) { -
printf("Could not open %sn", filename_in); -
return -1; -
} -
//Output bitstream -
fp_out = fopen(filename_out, "wb"); -
if (!fp_out) { -
printf("Could not open %sn", filename_out); -
return -1; -
} -
y_size = pCodecCtx->width * pCodecCtx->height; -
//Encode -
for (i = 0; i < framenum; i++) { -
av_init_packet(&pkt); -
pkt.data = NULL; // packet data will be allocated by the encoder -
pkt.size = 0; -
//Read raw YUV data -
if (fread(pFrame->data[0],1,y_size,fp_in)<= 0|| // Y -
fread(pFrame->data[1],1,y_size/4,fp_in)<= 0|| // U -
fread(pFrame->data[2],1,y_size/4,fp_in)<= 0){ // V -
return -1; -
}else if(feof(fp_in)){ -
break; -
} -
pFrame->pts = i; -
/* encode the image */ -
ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output); -
if (ret < 0) { -
printf("Error encoding framen"); -
return -1; -
} -
if (got_output) { -
printf("Succeed to encode frame: %5dtsize:%5dn",framecnt,pkt.size); -
framecnt++; -
fwrite(pkt.data, 1, pkt.size, fp_out); -
av_free_packet(&pkt); -
} -
} -
//Flush Encoder -
for (got_output = 1; got_output; i++) { -
ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output); -
if (ret < 0) { -
printf("Error encoding framen"); -
return -1; -
} -
if (got_output) { -
printf("Flush Encoder: Succeed to encode 1 frame!tsize:%5dn",pkt.size); -
fwrite(pkt.data, 1, pkt.size, fp_out); -
av_free_packet(&pkt); -
} -
} -
fclose(fp_out); -
avcodec_close(pCodecCtx); -
av_free(pCodecCtx); -
av_freep(&pFrame->data[0]); -
av_frame_free(&pFrame); -
return 0; -
}
最后
以上就是结实蜻蜓最近收集整理的关于用x264和ffmpeg将YUV编码为.h264(2)的全部内容,更多相关用x264和ffmpeg将YUV编码为内容请搜索靠谱客的其他文章。
发表评论 取消回复