#include "EncoderH264.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "ShareHeader.h"
CEnCoderH264::CEnCoderH264(const char *_fpath)
: m_pts(0)
, m_pCodecCtx(0)
, m_pSwsContext(0)
, m_pFrame(0)
, m_pPacket(0)
, m_src_pix_fmt(AV_PIX_FMT_BGR24)
{
m_filePath = _fpath;
m_OutFile.close();
m_OutFile.clear();
m_OutFile.open(_fpath, std::ios::out | std::ios::trunc | std::ios::binary);
}
CEnCoderH264::~CEnCoderH264()
{
uninit();
}
void CEnCoderH264::init(const ENCODEINFO *_p)
{
const ENCODEINFO *_info = (_p == 0) ? &ENCODEINFO() : _p;
//find h264 encoder.
AVCodec *pEnCode = avcodec_find_encoder(AV_CODEC_ID_H264);
RETURN_H264(pEnCode == 0, "Encoder initialize fail.\n");
//get a AVCodecContext.
m_pCodecCtx = avcodec_alloc_context3(pEnCode);
RETURN_H264(m_pCodecCtx == 0, "alloc AVCodecContext fail.\n");
m_pCodecCtx->bit_rate = _info->bitRate;
m_pCodecCtx->width = _info->width;
m_pCodecCtx->height = _info->height;
m_pCodecCtx->time_base.den = 25;//fps.
m_pCodecCtx->time_base.num = 1;
m_pCodecCtx->framerate.den = 1;
m_pCodecCtx->framerate.num = 25;
//The fewer I frames are inserted into every 25 frames, the smaller the video is.
m_pCodecCtx->gop_size = 25;
/**
* How many B frames are allowed between two non-B frames.
* 0 indicates that B frame is not applicable.
* B the more frames, the smaller the picture.
* note:
* It'seems that B frame is not suitable for live broadcast.
*/
m_pCodecCtx->max_b_frames = 0;
m_pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
//Set Option[just for AV_CODEC_ID_H264].
//Set encoder to non-delay format.
//av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0);
//Set the encoder delay to solve the previous dozens of frames without data.
av_opt_set(m_pCodecCtx->priv_data, "tune", "zerolatency", 0);
//open encoder.
RETURN_H264(avcodec_open2(m_pCodecCtx, pEnCode, NULL) < 0, "open encoder fail.\n");
//get a swscontext according to the image format.
switch (_info->format)
{
case ENCODEINFO::FMT_BGR24: m_src_pix_fmt = AV_PIX_FMT_BGR24; break;
case ENCODEINFO::FMT_RGB24: m_src_pix_fmt = AV_PIX_FMT_RGB24; break;
//case ENCODEINFO::FMT_RGBA: m_src_pix_fmt = AV_PIX_FMT_RGBA; break;
default:break;
}
m_pSwsContext = sws_getContext(
m_pCodecCtx->width, m_pCodecCtx->height, m_src_pix_fmt,
m_pCodecCtx->width, m_pCodecCtx->height, AV_PIX_FMT_YUV420P,
SWS_POINT, NULL, NULL, NULL);
RETURN_H264(m_pSwsContext == 0, "create swscontext fail.\n");
//alloc a frame to deal with data.
m_pFrame = av_frame_alloc();
RETURN_H264(m_pFrame == 0, "alloc a frame fail.\n");
m_pFrame->format = m_pCodecCtx->pix_fmt;
m_pFrame->width = m_pCodecCtx->width;
m_pFrame->height = m_pCodecCtx->height;
RETURN_H264(av_frame_get_buffer(m_pFrame, /*32*/0) !=0, "frame get buffer fail.\n");
//alloc a packet to deal with data.
m_pPacket = av_packet_alloc();
m_pts = 0;
}
void CEnCoderH264::addPicture(uint8_t *_data, uint32_t _linestride)
{
RETURN_H264(m_pFrame == 0 || m_pSwsContext == 0 || _data == 0 || _linestride <= 0 || m_pCodecCtx == 0, "paramter is unvalid.\n");
//make sure the frame data is writable.
RETURN_H264(av_frame_make_writable(m_pFrame)<0, "is not writable");
int _StrideLen = _linestride;
sws_scale(m_pSwsContext, &_data, &_StrideLen, 0, m_pCodecCtx->height, m_pFrame->data, m_pFrame->linesize);
m_pFrame->pts = m_pts++;
//encode the image.
Encode();
}
void CEnCoderH264::addPicture(const char *_fpath)
{
RETURN_H264(m_src_pix_fmt != AV_PIX_FMT_BGR24, "format of picture data is not meet the requirements.\n");
//read file data with opencv.
RETURN_H264(_access(_fpath, 0) == -1, "file does not exist.\n");
cv::Mat _img = cv::imread(_fpath);
//to encode.
size_t _imgstep = _img.step;
size_t _imgsize = _img.rows*_img.step;
uint8_t *_imgdata = (uint8_t *)malloc(sizeof(uint8_t) * _imgsize);
memcpy(_imgdata, _img.data, _imgsize);
addPicture(_imgdata, (uint32_t)_imgstep);
//release.
_img.release();
free(_imgdata);
}
void CEnCoderH264::Encode()
{
RETURN_H264(m_pCodecCtx == 0 || m_pPacket == 0, "Encode fail,paramters is null.\n");
RETURN_H264(avcodec_send_frame(m_pCodecCtx, m_pFrame) < 0, "send frame fail.\n");
//frame to packet is encode.
int _ret = avcodec_receive_packet(m_pCodecCtx, m_pPacket);
RETURN_H264(_ret == AVERROR(EAGAIN) || _ret == AVERROR_EOF || _ret < 0, "receive packet fail.\n");
fflush(stdout);
//write to h264 file.
if (m_OutFile.is_open())
{
m_OutFile.write((char *)m_pPacket->data, m_pPacket->size);
}
av_packet_unref(m_pPacket);
}
void CEnCoderH264::uninit()
{
//flush the encoder.
av_frame_free(&m_pFrame);
m_pFrame = 0;
Encode();
//add sequence end code to have a real MPEG file.
if (m_OutFile.is_open())
{
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
m_OutFile.write((char *)endcode, sizeof(endcode));
m_OutFile.close();
}
avcodec_free_context(&m_pCodecCtx);
av_packet_free(&m_pPacket);
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
使用ffmpeg将多张图片生成H264裸流并获取帧图片 (369个子文件)
EncodeH264.cpp 5KB
Decoder.cpp 5KB
NaluH264.cpp 4KB
main.cpp 2KB
DecoderH264.cpp 2KB
opencv_world300d.dll 49.59MB
avcodec-58.dll 45.02MB
avfilter-7.dll 6.68MB
avformat-58.dll 5.83MB
avdevice-58.dll 2.32MB
avutil-56.dll 639KB
swscale-5.dll 525KB
swresample-3.dll 368KB
postproc-55.dll 124KB
ffmpeg.exe 292KB
MakeH264.exe 198KB
ffprobe.exe 166KB
ffplay.exe 149KB
MakeVideo.vcxproj.filters 2KB
avcodec.h 207KB
core_c.h 127KB
avformat.h 115KB
types_c.h 59KB
imgproc_c.h 51KB
avfilter.h 41KB
kmeans_index.h 36KB
opt.h 35KB
pixfmt.h 32KB
avio.h 31KB
frame.h 28KB
dist.h 27KB
hierarchical_clustering_index.h 25KB
mem.h 23KB
hwcontext.h 22KB
defs.h 22KB
swresample.h 21KB
autotuned_index.h 20KB
kdtree_single_index.h 20KB
calib3d_c.h 20KB
kdtree_index.h 19KB
videoio_c.h 18KB
intreadwrite.h 18KB
lsh_table.h 18KB
avdevice.h 17KB
types_c.h 17KB
common.h 16KB
pixdesc.h 15KB
lsh_index.h 15KB
result_set.h 15KB
avstring.h 14KB
swscale.h 12KB
imgutils.h 11KB
tracking_c.h 11KB
log.h 11KB
index_testing.h 11KB
buffer.h 10KB
highgui_c.h 10KB
samplefmt.h 10KB
channel_layout.h 9KB
avutil.h 9KB
cvdef.h 9KB
hash.h 8KB
dict.h 8KB
any.h 8KB
spherical.h 8KB
mathematics.h 8KB
bprint.h 8KB
parseutils.h 7KB
hdf5.h 7KB
encryption_info.h 7KB
buffersrc.h 6KB
buffersink.h 6KB
hwcontext_d3d11va.h 6KB
allocator.h 6KB
xvmc.h 6KB
nn_index.h 6KB
composite_index.h 6KB
objdetect_c.h 6KB
all_indices.h 6KB
audio_fifo.h 6KB
fifo.h 6KB
rational.h 6KB
vdpau.h 6KB
saving.h 6KB
simplex_downhill.h 6KB
cpu.h 6KB
error.h 5KB
tree.h 5KB
cap_ios.h 5KB
timecode.h 5KB
eval.h 5KB
stereo3d.h 5KB
imgcodecs_c.h 5KB
version.h 5KB
defines.h 5KB
attributes.h 5KB
hwcontext_drm.h 5KB
version.h 5KB
dynamic_bitset.h 4KB
heap.h 4KB
共 369 条
- 1
- 2
- 3
- 4
资源评论
- 西部秋虫2018-10-31非常好的学习资料。
- johnyu352018-12-26非常好的学习资料
- ermzdy22020-06-12好用,请问有没有什么办法提高编码效率?我编码 1920X1080 比特率4M 的mpeg2格式视频,只能达到18帧每秒,平均一帧得花五十多毫秒
xiaoyong79639981
- 粉丝: 1
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功