int display::initFrameBuffer(int in_width, int in_height)
{
avfilter_register_all();
buffersrc = avfilter_get_by_name("buffer");
buffersink = avfilter_get_by_name("buffersink");
frame_buffer_in = new unsigned char[MAX_FRAME_BUFFER_SIZE];
memset(frame_buffer_in, 0, MAX_FRAME_BUFFER_SIZE);
frame_buffer_out = new unsigned char[MAX_FRAME_BUFFER_SIZE];
memset(frame_buffer_out, 0, MAX_FRAME_BUFFER_SIZE);
frame_in = av_frame_alloc();
av_image_fill_arrays(frame_in->data, frame_in->linesize, frame_buffer_in,
AV_PIX_FMT_YUV420P, in_width, in_height, 1);
frame_in->width = in_width;
frame_in->height = in_height;
frame_in->format = AV_PIX_FMT_YUV420P;
frame_out = av_frame_alloc();
av_image_fill_arrays(frame_out->data, frame_out->linesize, frame_buffer_out,
AV_PIX_FMT_YUV420P, in_width, in_height, 1);
return 0;
}
int display::initFace(int in_width, int in_height, FaceStructInfo *pUser, int nCount)
{
char filter_descr_user[1024 * 10] = { 0 };
InfoStruct usrInfoStr;
char info[128];
std::string strTemp = parseSex(pUser[0].usrSex);
_snprintf_s(info, sizeof(info), "性别:%s", strTemp.c_str());
usrInfoStr.usrSex = MutilToUTF8(info, sizeof(info));
strTemp = parseAge(pUser[0].userAge);
_snprintf_s(info, sizeof(info), "年龄:%s", strTemp.c_str());
usrInfoStr.userAge = MutilToUTF8(info, sizeof(info));
strTemp = parseBrow(pUser[0].userBrow);
_snprintf_s(info, sizeof(info), "表情:%s", strTemp.c_str());
usrInfoStr.userBrow = MutilToUTF8(info, sizeof(info));
strTemp = parseHairstyle(pUser[0].userHairstyle);
_snprintf_s(info, sizeof(info), "发型:%s", strTemp.c_str());
usrInfoStr.userHairstyle = MutilToUTF8(info, sizeof(info));
strTemp = parseGlasses(pUser[0].userGlasses);
_snprintf_s(info, sizeof(info), "眼镜:%s", strTemp.c_str());
usrInfoStr.userGlasses = MutilToUTF8(info, sizeof(info));
strTemp = parseHat(pUser[0].userHat);
_snprintf_s(info, sizeof(info), "帽子:%s", strTemp.c_str());
usrInfoStr.userHat = MutilToUTF8(info, sizeof(info));
strTemp = parseMask(pUser[0].userMask);
_snprintf_s(info, sizeof(info), "口罩:%s", strTemp.c_str());
usrInfoStr.userMask = MutilToUTF8(info, sizeof(info));
strTemp = parseRace(pUser[0].userRace);
_snprintf_s(info, sizeof(info), "人种:%s", strTemp.c_str());
usrInfoStr.userRace = MutilToUTF8(info, sizeof(info));
int nX = pUser->face_x + pUser->face_w + 10;
int nY = pUser->face_y;
_snprintf_s(filter_descr_user, sizeof(filter_descr_user), "drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s",
m_strFontPath.c_str(), nX, nY, usrInfoStr.usrSex.c_str(),
m_strFontPath.c_str(), nX, nY + 30, usrInfoStr.userAge.c_str(),
m_strFontPath.c_str(), nX, nY + 60, usrInfoStr.userBrow.c_str(),
m_strFontPath.c_str(), nX, nY + 90, usrInfoStr.userHairstyle.c_str(),
m_strFontPath.c_str(), nX, nY + 120, usrInfoStr.userGlasses.c_str(),
m_strFontPath.c_str(), nX, nY + 150, usrInfoStr.userHat.c_str(),
m_strFontPath.c_str(), nX, nY + 180, usrInfoStr.userMask.c_str(),
m_strFontPath.c_str(), nX, nY + 210, usrInfoStr.userRace.c_str());
char filter_descr_point[1024 * 10] = { 0 };
_snprintf_s(filter_descr_point, sizeof(filter_descr_point), "drawbox=x=%d:y=%d:w=%d:h=%d:color=red@1", pUser[0].face_x, pUser[0].face_y, pUser[0].face_w, pUser[0].face_h);
for (int i = 1; i < nCount; i++)
{
strTemp = parseSex(pUser[i].usrSex);
_snprintf_s(info, sizeof(info), "性别:%s", strTemp.c_str());
usrInfoStr.usrSex = MutilToUTF8(info, sizeof(info));
strTemp = parseAge(pUser[i].userAge);
_snprintf_s(info, sizeof(info), "年龄:%s", strTemp.c_str());
usrInfoStr.userAge = MutilToUTF8(info, sizeof(info));
strTemp = parseBrow(pUser[i].userBrow);
_snprintf_s(info, sizeof(info), "表情:%s", strTemp.c_str());
usrInfoStr.userBrow = MutilToUTF8(info, sizeof(info));
strTemp = parseHairstyle(pUser[i].userHairstyle);
_snprintf_s(info, sizeof(info), "发型:%s", strTemp.c_str());
usrInfoStr.userHairstyle = MutilToUTF8(info, sizeof(info));
strTemp = parseGlasses(pUser[i].userGlasses);
_snprintf_s(info, sizeof(info), "眼镜:%s", strTemp.c_str());
usrInfoStr.userGlasses = MutilToUTF8(info, sizeof(info));
strTemp = parseHat(pUser[i].userHat);
_snprintf_s(info, sizeof(info) - 1, "帽子:%s", strTemp.c_str());
usrInfoStr.userHat = MutilToUTF8(info, sizeof(info));
strTemp = parseMask(pUser[i].userMask);
_snprintf_s(info, sizeof(info), "口罩:%s", strTemp.c_str());
usrInfoStr.userMask = MutilToUTF8(info, sizeof(info));
strTemp = parseRace(pUser[i].userRace);
_snprintf_s(info, sizeof(info), "人种:%s", strTemp.c_str());
usrInfoStr.userRace = MutilToUTF8(info, sizeof(info));
nX = pUser[i].face_x + pUser[i].face_w + 10;
nY = pUser[i].face_y;
_snprintf_s(filter_descr_user, sizeof(filter_descr_user), "%s, drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626@1:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s,
drawtext=fontfile='%sDroidSans.ttf':fontsize=17:x=%d:fontcolor=0xCD2626:y=%d:text=%s",
filter_descr_user,
m_strFontPath.c_str(), nX, nY, usrInfoStr.usrSex.c_str(),
m_strFontPath.c_str(), nX, nY + 30, usrInfoStr.userAge.c_str(),
m_strFontPath.c_str(), nX, nY + 60, usrInfoStr.userBrow.c_str(),
m_strFontPath.c_str(), nX, nY + 90, usrInfoStr.userHairstyle.c_str(),
m_strFontPath.c_str(), nX, nY + 120, usrInfoStr.userGlasses.c_str(),
m_strFontPath.c_str(), nX, nY + 150, usrInfoStr.userHat.c_str(),
m_strFontPath.c_str(), nX, nY + 180, usrInfoStr.userMask.c_str(),
m_strFontPath.c_str(), nX, nY + 210, usrInfoStr.userRace.c_str());
_snprintf_s(filter_descr_point, sizeof(filter_descr_point), "%s, drawbox=x=%d:y=%d:w=%d:h=%d:color=red@1", filter_descr_point, pUser[i].face_x, pUser[i].face_y, pUser[i].face_w, pUser[i].face_h);
}
char filter_descr[2048 * 10] = { 0 };
_snprintf_s(filter_descr, sizeof(filter_descr), "%s, %s", filter_descr_user, filter_descr_point);
char args[512] = { 0 };
int ret = -1;
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
AVBufferSinkParams *buffersink_params;
if (filter_graph)
{
avfilter_graph_free(&filter_graph);
filter_graph = NULL;
}
filter_graph = avfilter_graph_alloc();
/* buffer video source: the decoded frames from the decoder will be inserted here. */
_snprintf_s(args, sizeof(args) - 1,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
in_width, in_height, AV_PIX_FMT_YUV420P,
1, 25, 1, 1);
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
printf("Cannot create buffer source
");
return ret;
}
/* buffer video sink: to terminate the filter chain. */
buffersink_params = av_buffersink_params_alloc();
buffersink_params->pixel_fmts = pix_fmts;
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
NULL, buffersink_params, filter_graph);
av_free(buffersink_params);
if (ret < 0) {
printf("Cannot create buffer sink
");
return ret;
}
/* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
return ret;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
int display::uinitFace()
{
if (frame_in)
{
av_frame_free(&frame_in);
frame_in = nullptr;
}
if (frame_out)
{
av_frame_free(&frame_out);
frame_out = nullptr;
}
if (filter_graph)
{
avfilter_graph_free(&filter_graph);
filter_graph = nullptr;
}
if (frame_buffer_in)
{
delete[] frame_buffer_in;
frame_buffer_in = nullptr;
}
if (frame_buffer_out)
{
delete[] frame_buffer_out;
frame_buffer_out = nullptr;
}
return 0;
}
int display::showFace(const char * pBuf, long nInSize, int width, int height, unsigned char *outFrame, long& nOutSize)
{
memcpy_s(frame_buffer_in, MAX_FRAME_BUFFER_SIZE, pBuf, nInSize);
//input Y,U,V
frame_in->data[0] = frame_buffer_in;
frame_in->data[1] = frame_buffer_in + width * height;
frame_in->data[2] = frame_buffer_in + width * height * 5 / 4;
if (av_buffersrc_add_frame(buffersrc_ctx, frame_in) < 0) {
printf("Error while add frame.
");
return 0;
}
/* pull filtered pictures from the filtergraph */
int ret = av_buffersink_get_frame(buffersink_ctx, frame_out);
if (ret < 0)
return 0;
//output Y,U,V
if (frame_out->format != AV_PIX_FMT_YUV420P) {
return 0;
}
nOutSize = frame_out->width * frame_out->height * 3 >> 1;
if (nOutSize > MAX_FRAME_BUFFER_SIZE)
{
return 0;
}
if (frame_out->format == AV_PIX_FMT_YUV420P) //如果是yuv420p的
{
// for (int i = 0; i < frame_out->height; i++)
// {
// memcpy(outFrame + frame_out->width*i,
// frame_out->data[0] + frame_out->linesize[0] * i,
// frame_out->width);
// }
// for (int j = 0; j < frame_out->height / 2; j++)
// {
// memcpy(outFrame + frame_out->width*frame_out->height + frame_out->width / 2 * j,
// frame_out->data[1] + frame_out->linesize[1] * j,
// frame_out->width / 2);
// }
// for (int k = 0; k < frame_out->height / 2; k++)
// {
// memcpy(outFrame + frame_out->width*frame_out->height + frame_out->width / 2 * frame_out->height / 2 + frame_out->width / 2 * k,
// frame_out->data[2] + frame_out->linesize[2] * k,
// frame_out->width / 2);
// }
avpicture_layout((AVPicture*)frame_out, AV_PIX_FMT_YUV420P, frame_out->width, frame_out->height, outFrame, nOutSize);
}
//int nRet = avpicture_layout((AVPicture*)frame_out, AV_PIX_FMT_YUV420P, frame_out->width, frame_out->height, outFrame, nOutSize);
av_frame_unref(frame_out);
return 0;
}