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;
}

发布了2672 篇原创文章 · 获赞 973 · 访问量 527万+

猜你喜欢

转载自blog.csdn.net/jacke121/article/details/104349022