H264解码之ffmpeg画矩形框和画字(滤镜)

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\n");
		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\n");
		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.\n");
		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;
}

 

posted @ 2018-07-23 16:02  SunkingYang  阅读(1143)  评论(0编辑  收藏  举报