This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM5728:AM5728 Linux ducatih264enc GStreamer 插件内存泄漏

Guru**** 2556920 points
Other Parts Discussed in Thread: AM5728

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/620539/linux-am5728-am5728-linux-ducatih264enc-gstreamer-plugin-memory-leak

器件型号:AM5728

工具/软件:Linux

您好、专家

我的客户报告 说、他们在 AM5728 EVM 的 PDK 03.03.00.04上发现了 ducatih264enc GStreamer 插件内存泄漏库、可以检查一下吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    他们是通过 videnc2test 还是仅通过 gstreamer 观察到这种泄漏?
    他们是否仅在使用 ducatih264enc 时才观察到这一点?
    他们是在执行流水线、还是在应用中观察到这一点?

    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的回应。
    客户仅使用 gstreamer 流水线,如果没有 ducatih264enc 插件,他们就找不到内存泄漏。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、专家

     当我与 应用程序一起使用时、会发生内存泄漏。

    v4l2表示 cap 数据,v4l2 -> appsrc -> ducatih264enc (ti 表示编码)->文件链接 {这种方法是内存泄漏}

     v4l2->appsrc ->文件链接{这种方法不会发现内存泄漏}

    /*
     *
     * compile command  arm-linux-gnueabihf-gcc app-camera.c -o app `pkg-config --cflags --libs gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0`
     *
    */
    #include <linux/videodev2.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    #include <gst/gst.h>
    #include <gst/app/gstappsrc.h>
    #define waylandsink
    #define v4l2src
    typedefstruct_App App;
    struct_App
    {
        GstElement *pipeline;
        GstElement *appsrc;
        GstElement *encode;
        GstElement *parse;
         GstElement *sink;
        GstElement *decode;
        GstBus *bus;
        GstMessage *msg;
        GMainLoop *loop;
        guint bus_watch_id;
    };
    App s_app;
    intret, idx, fd;
    #define NBUF 3
    #define FRAME_SIZE 152064 //352*288*1.5
    intwidth = 352, height = 288;
    void*buffer_addr[NBUF];
    intsize[NBUF];
    staticvoid
    feed_data (GstElement * appsrc, guint size, App * app)
    {
        printf("feed-data....\n");
        structv4l2_buffer buf;
        /* Dequeue one buffer */
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        if(-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
            perror("Queue Buffer");
            returnFALSE;
        }
        idx = buf.index;
        GstBuffer *buffer;
        GstFlowReturn ret;
        buffer = gst_buffer_new_allocate(NULL,FRAME_SIZE,NULL);
        GstMapInfo info;
        gst_buffer_map(buffer,&info,GST_MAP_WRITE);
        unsigned char* buff = info.data;
        memcpy(buff,buffer_addr[idx],FRAME_SIZE);
        gst_buffer_unmap(buffer,&info);
        g_signal_emit_by_name(app->appsrc,"push-buffer",buffer,&ret);
        printf("ret:%d\n",ret);
        if(ret != GST_FLOW_OK) {
            /* some error, stop sending data */
            printf("push error...\n");
            returnFALSE;
        }
        gst_buffer_unref(buffer);
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = idx;
        if(-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
            perror("Queue Buffer");
            returnFALSE;
        }
        returnTRUE;
    }
    intxioctl(intfd, intrequest, void*arg)
    {
        intr;
        dor = ioctl (fd, request, arg);
        while(-1 == r && EINTR == errno);
        returnr;
    }
    intinit_device(intfd) {
        unsigned inti;
        structv4l2_capability caps;
        structv4l2_format fmt;
        structv4l2_requestbuffers req;
        structv4l2_buffer buf;
        /* Check for capture device */
        memset(&caps, 0, sizeof(caps));
        if(-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps)) {
            perror("Setting Pixel Format");
            return1;
        }
        printf("Driver: %s\ncaps: %8x", caps.driver, caps.capabilities);
        if(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
            printf("Not a capture device");
            return1;
        }
        /* Set capture format to UYVY */
        memset(&fmt, 0, sizeof(fmt));
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width = width;
        fmt.fmt.pix.height = height;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
        //  fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
        fmt.fmt.pix.field = V4L2_FIELD_NONE;
        if(-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) {
            perror("Setting Pixel Format");
            return1;
        }
        printf("Selected Camera Mode:\n""  Width: %d\n""  Height: %d\n""  Field: %d",
            fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.field);
        printf("  PixFmt = %c%c%c%c\n",
               fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,
               (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) &0xFF);
        /* Currently driver supports only mmap buffers
         * Request memory mapped buffers */
        memset(&req, 0, sizeof(req));
        req.count = NBUF;
        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory = V4L2_MEMORY_MMAP;
        if(-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
            perror("Requesting Buffer");
            return1;
        }
        printf("Total buffer num %d\n", req.count);
        for(i = 0; i < req.count; i++) {
            memset(&buf, 0, sizeof(buf));
            buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buf.memory = V4L2_MEMORY_MMAP;
            buf.index = i;
            if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) {
                perror("Querying Buffer");
                return1;
            }
            /* Memory map all the buffers and save the addresses */
            buffer_addr[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
                                 MAP_SHARED, fd, buf.m.offset);
            //buffer_addr[i]=(void*)malloc(FRAME_SIZE);
            size[i] = buf.length;
            printf("Address %p, size %d, image size: %d \n", buffer_addr[i], buf.length, buf.bytesused);
            /* Queue the buffer for capture */
            memset(&buf, 0, sizeof(buf));
            buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buf.memory = V4L2_MEMORY_MMAP;
            buf.index = i;
            if(-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
                perror("Queue Buffer");
                return1;
            }
            printf("12345\r\n");
        }
        if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type)) {
            perror("Start Capture");
            return1;
        }
        return0;
    }
    voidrelease_device(intfd)
    {
        inttype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        xioctl(fd, VIDIOC_STREAMOFF, &type);
        close(fd);
    }
    gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
    {
        GMainLoop *loop = (GMainLoop *) data;
        switch(GST_MESSAGE_TYPE (msg))
        {
        caseGST_MESSAGE_EOS:
            fprintf(stderr, "End of stream\n");
            g_main_loop_quit(loop);
            break;
        caseGST_MESSAGE_ERROR:
        {
            gchar *debug;
            GError *error;
            gst_message_parse_error(msg, &error, &debug);
            g_free(debug);
            g_printerr("Error: %s\n", error->message);
            g_error_free(error);
            g_main_loop_quit(loop);
            break;
        }
        default:
            break;
        }
        returnTRUE;
    }
    intmain(intargc, char**argv)
    {
        App *app = &s_app;
        printf("==========\n");
        chardevnode[100] = "/dev/video1";
        fd = open(devnode, O_RDWR);
        if(fd == -1) {
            perror("Opening video device");
            return1;
        }
        ret = init_device(fd);
        if(0 != ret) {
            printf("Exiting");
            returnret;
        }
        gst_init(NULL,NULL);
        app->pipeline = gst_pipeline_new("encodepipeline");
        g_assert(app->pipeline);
        app->appsrc = gst_element_factory_make("appsrc","srcElement");
        g_assert(app->appsrc);
        app->encode = gst_element_factory_make("ducatih264enc","encodeElement");
        g_assert(app->encode);
        app->parse = gst_element_factory_make("h264parse","parseElement");
        g_assert(app->parse);
        app->decode = gst_element_factory_make("ducatih264dec","decodeElement");
        g_assert(app->decode);
        app->sink = gst_element_factory_make("filesink","sinkElement");
        g_assert(app->sink);
        printf("element creat success\n");
        GstCaps *capsappsrc2H264enc;
        capsappsrc2H264enc = gst_caps_new_simple("video/x-raw",
                                                 "format",G_TYPE_STRING, "NV12",
                                                 "width", G_TYPE_INT, 352,
                                                 "height",G_TYPE_INT, 288,
                                                 "framerate", GST_TYPE_FRACTION, 30, 1,
                                                 NULL);
    //    g_object_set(G_OBJECT (app->sink), "sync", FALSE,
    //                 NULL);
        gst_app_src_set_caps(GST_APP_SRC(app->appsrc), capsappsrc2H264enc);
        g_object_set(app->sink,"location","/mnt/camera.yuv",NULL);
        app->loop = g_main_loop_new(NULL,FALSE);
        app->bus = gst_pipeline_get_bus(GST_PIPELINE(app->pipeline));
        app->bus_watch_id = gst_bus_add_watch(app->bus,bus_call,app->loop);
        gst_object_unref(app->bus);
        gst_bin_add_many(GST_BIN(app->pipeline), app->appsrc,app->sink,NULL);
        gboolean bLinkOk;
        bLinkOk= gst_element_link(app->appsrc,app->sink);
        if(!bLinkOk){
            g_warning("Failed to link many 1\n");
            return-5;
        }
        g_signal_connect(app->appsrc, "need-data", G_CALLBACK(feed_data), app);
        gst_element_set_state (app->pipeline, GST_STATE_PLAYING);
        printf("run....1\n");
        g_main_loop_run(app->loop);
        printf("run....2\n");
        app->msg = gst_bus_timed_pop_filtered (app->bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
        if(app->msg != NULL)
            gst_message_unref (app->msg);
        gst_object_unref (app->bus);
        gst_element_set_state (app->pipeline, GST_STATE_NULL);
        gst_object_unref (app->pipeline);
        gst_object_unref(app->appsrc);
        gst_object_unref(app->sink);
        printf("close...\n");
        return0;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    因此、仅在应用中观察到内存泄漏?
    它是在使用 fakesink 时还是仅在使用文件链接时观察到相同的应用程序?
    我将查看该应用。
    还有一个问题、您是通过 v4l2src 捕获的、使用 appsrc 元素而不是 v4l2src 元素的原因是什么?

    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    实际上,我看到在应用程序中有编码->解码。
    您是否可以移除解码器件或您已经完成此测试?
    我对所有这些问题都很抱歉、但我想了解使用案例。

    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    抱歉、gs-launch-1.0 -v -e v4l2src device=/dev/video1 io-mode=2! 'video/x-raw、format=(string) NV12、width=(int) 352、height=(int) 288、framerate=(fraction) 30/1、bitrate=(int) 30'! ducatih264enc! filesink location=test.h264也是内存泄漏
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是,删除解码元件也会导致内存泄漏
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您是否也通过 videnc2test 观察它?

    BR
    玛格丽塔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    什么是 videnc2test?  

    当我使用它时、我需要 足够大的文件进行编码? 环路对其进行编码?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们将在9月中旬左右尝试深入探讨这一内存泄漏问题、并回顾我们的调查结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    此问题是否未通过 ducatimpeg4enc 重现?

    请告诉我您收集了哪些内存统计数据来缩小问题的根源所在 ducatih264enc。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尚未使用 ducatimpeg4enc、有关 ducatih264enc、您可以查看此页面 e2e.ti.com/.../2287603

    我只使用 TOP 命令来检测内存泄漏。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Abayyy、

    已修复编码器内存泄漏问题、此处提供补丁-  

    您可以使用 Arago Build 来重建插件-

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Manisha、

    谢谢、但我不知道如何仅使用 ti-processor-sdk-linux-am57xx-evm-03.03.00.04 SDK 构建 ducatih264enc 插件? 可以帮帮我吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [引用用户="abayyyyyyyy"]谢谢、但我不知道如何仅使用 ti-processor-sdk-linux-am57xx-evm-03.03.00.04 SDK 构建 ducatih264enc 插件?

    该问题并非仅针对 ducatih264enc。


    这是 PSDK 版本03.03.00.04的用户指南
    processors.wiki.ti.com/index.php

    请按照指南中的步骤操作。
    这是构建 Ducati 插件的最后一步:
    MACHINE=am57xx-EVM bitbake gstreamer1.0-plugins-Ducati

    您可以在 gstducatividenc.c 文件中手动应用修补程序。
    请查看指南中的强制重新编译章节。
    新的 libgstducati.so 文件应为 cp 到 rootfs//usr/lib/gstreamer-1.0。

    希望这对您有所帮助。

    BR
    玛格丽塔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、Margarita
    在中国、互联网的使用非常慢且经常断开连接、您能给我提供一个编译的互联网吗? 我的 SDK 为03.03.00.04。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    不幸的是、我身边没有3.03.00.04。

    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Margarita、

    您的 duchati 插件补丁可使用哪个版本的 PDK? 我认为.so 文件 不依赖于 PDK 版本。

    感谢您的大力支持!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Margarita、
    由于客户需要时间重新编译 GStreamer 插件.so 文件、您能否直接发送.so 文件及补丁以进行客户快速验证? 非常感谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    检查附件:

    e2e.ti.com/.../libgstducati.zip

    BR
    玛格丽塔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。


    非常感谢您帮助解决内存泄漏问题

    e2e.ti.com/.../2291680

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Margarita、

    我们使用的是 AM57XX 的"3.2.0.5" SDK 版本、并面临"ducatih264enC"中的内存泄漏。
    通过使用附带的"libgstducati.so"、我们发现问题已解决。
    我们已使用 Yocto 构建并自定义更改来编译"libducati.so"、是否可以获取此".so"的源代码、以便我们可以避免整个 Yocto 构建设置。

    此致、
    Nirav
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Nirav、您好!
    git.ti.com/.../7205d7cb75944e816622d5daca88804819ff16d3
    是此修复所需的更改。 这是一行更改。

    您可以从 git://git.ti.com/glsdk/gst-plugin-ducati.git 克隆整个存储库

    Ramprasad
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Margarita、

    客户在您提供的.so 文件中找不到 H264enc 插件中的内存泄漏问题、感谢您的支持!

    您是否也可以检查 ducatih264dec 插件、客户报告此插件中也存在内存泄漏问题、谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我将进行检查。
    观察到 gstreamer 流水线不是应用程序的问题、对吧?



    BR
    玛格丽塔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我们能够重现此问题。

    BR
    玛格丽塔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Margarita:

    客户的测试方案如下:

    gst-launch-1.0 -v -e v4l2src device=/dev/video1 io-mode=2! 'video/x-raw、format=(string) NV12、width=(int) 800、height=(int) 600、framerate=(fraction) 30/1、bitrate=(int) 30'! ducatih264enc! h264parse! ducatih264dec! landwaysink 同步=错误

     

    那么、您可以重现此问题吗? 是否可以在解决内存泄漏问题后提供更新的插件? 谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    是否可以尝试用 avdec 替换 ducatih264dec 并运行测试1小时? 您是否观察到侧面的 MEM 泄漏问题?
    注意:请确保应用.so 编码器内存泄漏修复。

    我们在我们的一侧尝试了该流水线:
    gst-launch-1.0 -e videotestsrc! 'video/x-raw、format=(string) NV12、width=(int) 1280、height=(int) 720、framerate=(fraction) 30/1'! ducatih264enc! 排队! h264parse! avdec h264! 视频转换! Kmsink 和
    但在我们一侧、即使使用 avdec _h264也会观察到泄漏。

    我们还尝试了该流水线:
    gst-launch-1.0 -e videotestsrc! 'video/x-raw、format=(string) NV12、width=(int) 1280、height=(int) 720、framerate=(fraction) 30/1'! ducatih264enc! 排队! h264parse! 'video/x-h264、stream-format=byte-stream'! h264parse! ducatih264dec! Kmsink 和

    我们正在尝试缩小泄漏范围。



    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jian:

    我在您的流水线中再现了该问题。  我分析了 ducatiDecoder 源代码,发现每帧有一个小内存泄漏,但修复此泄漏后,仍然观察到顶部命令中的 Mem%增加。

    我已附上修改后的 libgstducati.so 用于您的测试。 您能确认该行为吗?

    另一个观察结果是、如果管线中的 kmsink 被 fakesink 替换、则没有记忆泄漏。

    kmsink 或 waylandsink 出现问题。

    e2e.ti.com/.../6012.libgstducati.zip

    RAM

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 RAM、

    非常感谢您的支持和辛勤工作!

    因此、您已经修复了 ducatiDecoder 插件中的内存泄漏问题、还分析了 kmsink 或 landsink 中的代码?

    我将根据您的指导与客户合作进行测试、谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Jian:

    我们对 kmsink 和 waylandsink 进行了初步分析、看不到这些插件的内存泄漏。

    我们期待客户在使用内存泄漏修复插件后提供反馈。 如果更多的问题是开源插件、而 TI 不提供这些插件、恐怕我们无法为它们提供更多帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Manisha、

    感谢您的支持! 在中国国庆节之后、我将与客户合作进行验证!