#include "ScreenRecorder.h"
using namespace std;
/* initialize the resources*/
ScreenRecorder::ScreenRecorder()
{
av_register_all();
avcodec_register_all();
avdevice_register_all();
cout << "\nall required functions are registered successfully";
}
/* uninitialize the resources */
ScreenRecorder::~ScreenRecorder()
{
avformat_close_input(&pAVFormatContext);
if (!pAVFormatContext)
{
cout << "\nfile closed sucessfully";
}
else
{
cout << "\nunable to close the file";
exit(1);
}
avformat_free_context(pAVFormatContext);
if (!pAVFormatContext)
{
cout << "\navformat free successfully";
}
else
{
cout << "\nunable to free avformat context";
exit(1);
}
}
/* function to capture and store data in frames by allocating required memory and auto deallocating the memory. */
int ScreenRecorder::CaptureVideoFrames()
{
int flag;
int frameFinished;//when you decode a single packet, you still don't have information enough to have a frame [depending on the type of codec, some of them //you do], when you decode a GROUP of packets that represents a frame, then you have a picture! that's why frameFinished will let //you know you decoded enough to have a frame.
int frame_index = 0;
value = 0;
pAVPacket = (AVPacket *)av_malloc(sizeof(AVPacket));
av_init_packet(pAVPacket);
pAVFrame = av_frame_alloc();
if (!pAVFrame)
{
cout << "\nunable to release the avframe resources";
exit(1);
}
outFrame = av_frame_alloc();//Allocate an AVFrame and set its fields to default values.
if (!outFrame)
{
cout << "\nunable to release the avframe resources for outframe";
exit(1);
}
int video_outbuf_size;
int nbytes = av_image_get_buffer_size(outAVCodecContext->pix_fmt, outAVCodecContext->width, outAVCodecContext->height, 32);
uint8_t *video_outbuf = (uint8_t*)av_malloc(nbytes);
if (video_outbuf == NULL)
{
cout << "\nunable to allocate memory";
exit(1);
}
// Setup the data pointers and linesizes based on the specified image parameters and the provided array.
value = av_image_fill_arrays(outFrame->data, outFrame->linesize, video_outbuf, AV_PIX_FMT_YUV420P, outAVCodecContext->width, outAVCodecContext->height, 1); // returns : the size in bytes required for src
if (value < 0)
{
cout << "\nerror in filling image array";
}
SwsContext* swsCtx_;
// Allocate and return swsContext.
// a pointer to an allocated context, or NULL in case of error
// Deprecated : Use sws_getCachedContext() instead.
swsCtx_ = sws_getContext(pAVCodecContext->width,
pAVCodecContext->height,
pAVCodecContext->pix_fmt,
outAVCodecContext->width,
outAVCodecContext->height,
outAVCodecContext->pix_fmt,
SWS_BICUBIC, NULL, NULL, NULL);
int ii = 0;
int no_frames = 100;
cout << "\nenter No. of frames to capture : ";
cin >> no_frames;
AVPacket outPacket;
int j = 0;
int got_picture;
while (av_read_frame(pAVFormatContext, pAVPacket) >= 0)
{
if (ii++ == no_frames)break;
if (pAVPacket->stream_index == VideoStreamIndx)
{
value = avcodec_decode_video2(pAVCodecContext, pAVFrame, &frameFinished, pAVPacket);
if (value < 0)
{
cout << "unable to decode video";
}
if (frameFinished)// Frame successfully decoded :)
{
sws_scale(swsCtx_, pAVFrame->data, pAVFrame->linesize, 0, pAVCodecContext->height, outFrame->data, outFrame->linesize);
av_init_packet(&outPacket);
outPacket.data = NULL; // packet data will be allocated by the encoder
outPacket.size = 0;
avcodec_encode_video2(outAVCodecContext, &outPacket, outFrame, &got_picture);
if (got_picture)
{
if (outPacket.pts != AV_NOPTS_VALUE)
outPacket.pts = av_rescale_q(outPacket.pts, video_st->codec->time_base, video_st->time_base);
if (outPacket.dts != AV_NOPTS_VALUE)
outPacket.dts = av_rescale_q(outPacket.dts, video_st->codec->time_base, video_st->time_base);
printf("Write frame %3d (size= %2d)\n", j++, outPacket.size / 1000);
if (av_write_frame(outAVFormatContext, &outPacket) != 0)
{
cout << "\nerror in writing video frame";
}
av_packet_unref(&outPacket);
} // got_picture
av_packet_unref(&outPacket);
} // frameFinished
}
}// End of while-loop
value = av_write_trailer(outAVFormatContext);
if (value < 0)
{
cout << "\nerror in writing av trailer";
exit(1);
}
//THIS WAS ADDED LATER
av_free(video_outbuf);
}
/* establishing the connection between camera or screen through its respective folder */
int ScreenRecorder::openCamera()
{
value = 0;
options = NULL;
pAVFormatContext = NULL;
//Henry
pAVFormatContext = avformat_alloc_context();//Allocate an AVFormatContext.
/*
X11 video input device.
To enable this input device during configuration you need libxcb installed on your system. It will be automatically detected during configuration.
This device allows one to capture a region of an X11 display.
refer : https://www.ffmpeg.org/ffmpeg-devices.html#x11grab
*/
/* current below is for screen recording. to connect with camera use v4l2 as a input parameter for av_find_input_format */
pAVInputFormat = av_find_input_format("x11grab");
value = avformat_open_input(&pAVFormatContext, ":0.0+10,250", pAVInputFormat, NULL);
if (value != 0)
{
cout << "\nerror in opening input device";
//Henry
//exit(1);
}
/* set frame per second */
value = av_dict_set(&options, "framerate", "30", 0);
if (value < 0)
{
cout << "\nerror in setting dictionary value";
exit(1);
}
value = av_dict_set(&options, "preset", "medium", 0);
if (value < 0)
{
cout << "\nerror in setting preset values";
exit(1);
}
// value = avformat_find_stream_info(pAVFormatContext,NULL);
if (value < 0)
{
cout << "\nunable to find the stream information";
exit(1);
}
VideoStreamIndx = -1;
/* find the first video stream index . Also there is an API available to do the below operations */
for (int i = 0; i < pAVFormatContext->nb_streams; i++) // find video stream posistion/index.
{
if (pAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
VideoStreamIndx = i;
break;
}
}
if (VideoStreamIndx == -1)
{
cout << "\nunable to find the video stream index. (-1)";
exit(1);
}
// assign pAVFormatContext to VideoStreamIndx
pAVCodecContext = pAVFormatContext->streams[VideoStreamIndx]->codec;
pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id);
if (pAVCodec == NULL)
{
cout << "\nunable to find the decoder";
exit(1);
}
value = avcodec_open2(pAVCodecContext, pAVCodec, NULL);//Initialize the AVCodecContext to use the given AVCodec.
if (value < 0)
{
cout << "\nunable to open the av codec";
exit(1);
}
}
/* initialize the video output file and its properties */
int ScreenRecorder::init_outputfile()
{
outAVFormatContext = NULL;
value = 0;
output_file = "../media/output.mp4";
avformat_alloc_output_context2(&outAVFormatContext, NULL, NULL, output_file);
if (!outAVFormatContext)
{
cout << "\nerror in allocating av format output context";
exit(1);
}
/* Returns the output format in the list of registered output formats which best matches the provided parameters, or returns NULL if there is no match. */
output_format = av_guess_format(NULL, output_file, NULL);
if (!output_format)
{
cout << "\nerror in guessing the video format. try with correct format";
exit(1);
}
video_st = avformat_new_stream(outAVFormatContext, NULL);
if (!video_st)
{
cout << "\nerror in creating a av format new stream";
exit(1);
}
outAVCodecContext = avcodec_alloc_context3(outAVCodec);
if (!outAVCodecContext)
{
cout << "\nerror in allocating the codec contexts";
exit(1);
}
/* set property of the video file */
outAVCodecContext = video
没有合适的资源?快使用搜索试试~ 我知道了~
ffmpeg录制视频(需要安装x11grab)--C++编程
共36个文件
dll:8个
tlog:6个
exe:4个
5星 · 超过95%的资源 需积分: 50 39 下载量 142 浏览量
2018-05-22
14:31:30
上传
评论 1
收藏 21MB ZIP 举报
温馨提示
录制电脑屏幕操作,基于ffmpeg库使用C++程序开发的。电脑上需要安装x11grab。
资源推荐
资源详情
资源评论
收起资源包目录
ScreenRecorder.zip (36个子文件)
ScreenRecorder
Debug
ffprobe.exe 160KB
ScreenRecorder.exe 77KB
swscale-5.dll 502KB
avcodec-58.dll 29.68MB
ScreenRecorder.pdb 995KB
ScreenRecorder.ilk 651KB
avfilter-7.dll 6.46MB
avdevice-58.dll 1.25MB
avformat-58.dll 5.62MB
swresample-3.dll 316KB
avutil-56.dll 654KB
postproc-55.dll 114KB
ffplay.exe 146KB
ffmpeg.exe 293KB
ScreenRecorder.sln 988B
ScreenRecorder.sdf 9.19MB
ScreenRecorder.v12.suo 27KB
ScreenRecorder
ScreenRecorder.cpp 10KB
Debug
ScreenRecorder.tlog
cl.command.1.tlog 1KB
CL.read.1.tlog 33KB
link.read.1.tlog 3KB
link.write.1.tlog 562B
CL.write.1.tlog 1KB
link.command.1.tlog 1KB
ScreenRecorder.lastbuildstate 159B
vc120.pdb 412KB
ScreenRecorder.obj 168KB
main.obj 151KB
vc120.idb 499KB
ScreenRecorder.Build.CppClean.log 908B
ScreenRecorder.log 5KB
main.cpp 642B
ScreenRecorder.h 2KB
ScreenRecorder.vcxproj.user 165B
ScreenRecorder.vcxproj 4KB
ScreenRecorder.vcxproj.filters 1KB
共 36 条
- 1
资源评论
- JianZhang_Sdocker2020-02-23opencv是哪个版本?
heartgoingon
- 粉丝: 1
- 资源: 15
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功