zoukankan      html  css  js  c++  java
  • 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
    ");
    		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;
    }
  • 相关阅读:
    每天一个命令
    2017-2-21
    egrep []+ 和awk总结
    ifconfig eth0 取行取列
    stat /etc/hosts 取行取列644
    压缩解压缩
    目录
    公告
    To do list
    CSP 2019 游记
  • 原文地址:https://www.cnblogs.com/SunkingYang/p/11049138.html
Copyright © 2011-2022 走看看