From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from galahad.ideasonboard.com ([185.26.127.97]:35891 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751842AbeDFUCZ (ORCPT ); Fri, 6 Apr 2018 16:02:25 -0400 From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, Kieran Bingham Subject: [PATCH v2.1 09/15] v4l: vsp1: Move DRM pipeline output setup code to a function Date: Fri, 6 Apr 2018 23:00:55 +0300 Message-Id: <20180406200055.12280-1-laurent.pinchart+renesas@ideasonboard.com> In-Reply-To: <20180405091840.30728-10-laurent.pinchart+renesas@ideasonboard.com> References: <20180405091840.30728-10-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org List-ID: In order to make the vsp1_du_setup_lif() easier to read, and for symmetry with the DRM pipeline input setup, move the pipeline output setup code to a separate function. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham -- Changes since v2: - Moved vsp1_du_pipeline_setup_input() rename to earlier patch Changes since v1: - Rename vsp1_du_pipeline_setup_input() to vsp1_du_pipeline_setup_inputs() - Initialize format local variable to 0 in vsp1_du_pipeline_setup_output() --- drivers/media/platform/vsp1/vsp1_drm.c | 106 +++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 4a628bbf7e47..a7cccc9b05ef 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -276,6 +276,65 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1, return 0; } +/* Setup the output side of the pipeline (WPF and LIF). */ +static int vsp1_du_pipeline_setup_output(struct vsp1_device *vsp1, + struct vsp1_pipeline *pipe) +{ + struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe); + struct v4l2_subdev_format format = { 0, }; + int ret; + + format.which = V4L2_SUBDEV_FORMAT_ACTIVE; + format.pad = RWPF_PAD_SINK; + format.format.width = drm_pipe->width; + format.format.height = drm_pipe->height; + format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; + format.format.field = V4L2_FIELD_NONE; + + ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF%u sink\n", + __func__, format.format.width, format.format.height, + format.format.code, pipe->output->entity.index); + + format.pad = RWPF_PAD_SOURCE; + ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF%u source\n", + __func__, format.format.width, format.format.height, + format.format.code, pipe->output->entity.index); + + format.pad = LIF_PAD_SINK; + ret = v4l2_subdev_call(&pipe->lif->subdev, pad, set_fmt, NULL, + &format); + if (ret < 0) + return ret; + + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF%u sink\n", + __func__, format.format.width, format.format.height, + format.format.code, pipe->lif->index); + + /* + * Verify that the format at the output of the pipeline matches the + * requested frame size and media bus code. + */ + if (format.format.width != drm_pipe->width || + format.format.height != drm_pipe->height || + format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) { + dev_dbg(vsp1->dev, "%s: format mismatch on LIF%u\n", __func__, + pipe->lif->index); + return -EPIPE; + } + + return 0; +} + /* Configure all entities in the pipeline. */ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe) { @@ -356,7 +415,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, struct vsp1_drm_pipeline *drm_pipe; struct vsp1_pipeline *pipe; struct vsp1_bru *bru; - struct v4l2_subdev_format format; unsigned long flags; unsigned int i; int ret; @@ -417,54 +475,10 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, if (ret < 0) return ret; - memset(&format, 0, sizeof(format)); - format.which = V4L2_SUBDEV_FORMAT_ACTIVE; - format.pad = RWPF_PAD_SINK; - format.format.width = cfg->width; - format.format.height = cfg->height; - format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; - format.format.field = V4L2_FIELD_NONE; - - ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL, - &format); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF%u sink\n", - __func__, format.format.width, format.format.height, - format.format.code, pipe->output->entity.index); - - format.pad = RWPF_PAD_SOURCE; - ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL, - &format); - if (ret < 0) - return ret; - - dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF%u source\n", - __func__, format.format.width, format.format.height, - format.format.code, pipe->output->entity.index); - - format.pad = LIF_PAD_SINK; - ret = v4l2_subdev_call(&pipe->lif->subdev, pad, set_fmt, NULL, - &format); + ret = vsp1_du_pipeline_setup_output(vsp1, pipe); if (ret < 0) return ret; - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF%u sink\n", - __func__, format.format.width, format.format.height, - format.format.code, pipe_index); - - /* - * Verify that the format at the output of the pipeline matches the - * requested frame size and media bus code. - */ - if (format.format.width != cfg->width || - format.format.height != cfg->height || - format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) { - dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__); - return -EPIPE; - } - /* Enable the VSP1. */ ret = vsp1_device_get(vsp1); if (ret < 0) -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: [PATCH v2.1 09/15] v4l: vsp1: Move DRM pipeline output setup code to a function Date: Fri, 6 Apr 2018 23:00:55 +0300 Message-ID: <20180406200055.12280-1-laurent.pinchart+renesas@ideasonboard.com> References: <20180405091840.30728-10-laurent.pinchart+renesas@ideasonboard.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [185.26.127.97]) by gabe.freedesktop.org (Postfix) with ESMTPS id 61F676EAAD for ; Fri, 6 Apr 2018 20:02:25 +0000 (UTC) In-Reply-To: <20180405091840.30728-10-laurent.pinchart+renesas@ideasonboard.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Kieran Bingham , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SW4gb3JkZXIgdG8gbWFrZSB0aGUgdnNwMV9kdV9zZXR1cF9saWYoKSBlYXNpZXIgdG8gcmVhZCwg YW5kIGZvcgpzeW1tZXRyeSB3aXRoIHRoZSBEUk0gcGlwZWxpbmUgaW5wdXQgc2V0dXAsIG1vdmUg dGhlIHBpcGVsaW5lIG91dHB1dApzZXR1cCBjb2RlIHRvIGEgc2VwYXJhdGUgZnVuY3Rpb24uCgpT aWduZWQtb2ZmLWJ5OiBMYXVyZW50IFBpbmNoYXJ0IDxsYXVyZW50LnBpbmNoYXJ0K3JlbmVzYXNA aWRlYXNvbmJvYXJkLmNvbT4KUmV2aWV3ZWQtYnk6IEtpZXJhbiBCaW5naGFtIDxraWVyYW4uYmlu Z2hhbStyZW5lc2FzQGlkZWFzb25ib2FyZC5jb20+Ci0tCkNoYW5nZXMgc2luY2UgdjI6CgotIE1v dmVkIHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfaW5wdXQoKSByZW5hbWUgdG8gZWFybGllciBwYXRj aAoKQ2hhbmdlcyBzaW5jZSB2MToKCi0gUmVuYW1lIHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfaW5w dXQoKSB0bwogIHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfaW5wdXRzKCkKLSBJbml0aWFsaXplIGZv cm1hdCBsb2NhbCB2YXJpYWJsZSB0byAwIGluCiAgdnNwMV9kdV9waXBlbGluZV9zZXR1cF9vdXRw dXQoKQotLS0KIGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdnNwMS92c3AxX2RybS5jIHwgMTA2ICsr KysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLQogMSBmaWxlIGNoYW5nZWQsIDYwIGluc2Vy dGlvbnMoKyksIDQ2IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxh dGZvcm0vdnNwMS92c3AxX2RybS5jIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92c3AxL3ZzcDFf ZHJtLmMKaW5kZXggNGE2MjhiYmY3ZTQ3Li5hN2NjY2M5YjA1ZWYgMTAwNjQ0Ci0tLSBhL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vdnNwMS92c3AxX2RybS5jCisrKyBiL2RyaXZlcnMvbWVkaWEvcGxh dGZvcm0vdnNwMS92c3AxX2RybS5jCkBAIC0yNzYsNiArMjc2LDY1IEBAIHN0YXRpYyBpbnQgdnNw MV9kdV9waXBlbGluZV9zZXR1cF9pbnB1dHMoc3RydWN0IHZzcDFfZGV2aWNlICp2c3AxLAogCXJl dHVybiAwOwogfQogCisvKiBTZXR1cCB0aGUgb3V0cHV0IHNpZGUgb2YgdGhlIHBpcGVsaW5lIChX UEYgYW5kIExJRikuICovCitzdGF0aWMgaW50IHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfb3V0cHV0 KHN0cnVjdCB2c3AxX2RldmljZSAqdnNwMSwKKwkJCQkJIHN0cnVjdCB2c3AxX3BpcGVsaW5lICpw aXBlKQoreworCXN0cnVjdCB2c3AxX2RybV9waXBlbGluZSAqZHJtX3BpcGUgPSB0b192c3AxX2Ry bV9waXBlbGluZShwaXBlKTsKKwlzdHJ1Y3QgdjRsMl9zdWJkZXZfZm9ybWF0IGZvcm1hdCA9IHsg MCwgfTsKKwlpbnQgcmV0OworCisJZm9ybWF0LndoaWNoID0gVjRMMl9TVUJERVZfRk9STUFUX0FD VElWRTsKKwlmb3JtYXQucGFkID0gUldQRl9QQURfU0lOSzsKKwlmb3JtYXQuZm9ybWF0LndpZHRo ID0gZHJtX3BpcGUtPndpZHRoOworCWZvcm1hdC5mb3JtYXQuaGVpZ2h0ID0gZHJtX3BpcGUtPmhl aWdodDsKKwlmb3JtYXQuZm9ybWF0LmNvZGUgPSBNRURJQV9CVVNfRk1UX0FSR0I4ODg4XzFYMzI7 CisJZm9ybWF0LmZvcm1hdC5maWVsZCA9IFY0TDJfRklFTERfTk9ORTsKKworCXJldCA9IHY0bDJf c3ViZGV2X2NhbGwoJnBpcGUtPm91dHB1dC0+ZW50aXR5LnN1YmRldiwgcGFkLCBzZXRfZm10LCBO VUxMLAorCQkJICAgICAgICZmb3JtYXQpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0Owor CisJZGV2X2RiZyh2c3AxLT5kZXYsICIlczogc2V0IGZvcm1hdCAldXgldSAoJXgpIG9uIFdQRiV1 IHNpbmtcbiIsCisJCV9fZnVuY19fLCBmb3JtYXQuZm9ybWF0LndpZHRoLCBmb3JtYXQuZm9ybWF0 LmhlaWdodCwKKwkJZm9ybWF0LmZvcm1hdC5jb2RlLCBwaXBlLT5vdXRwdXQtPmVudGl0eS5pbmRl eCk7CisKKwlmb3JtYXQucGFkID0gUldQRl9QQURfU09VUkNFOworCXJldCA9IHY0bDJfc3ViZGV2 X2NhbGwoJnBpcGUtPm91dHB1dC0+ZW50aXR5LnN1YmRldiwgcGFkLCBnZXRfZm10LCBOVUxMLAor CQkJICAgICAgICZmb3JtYXQpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0OworCisJZGV2 X2RiZyh2c3AxLT5kZXYsICIlczogZ290IGZvcm1hdCAldXgldSAoJXgpIG9uIFdQRiV1IHNvdXJj ZVxuIiwKKwkJX19mdW5jX18sIGZvcm1hdC5mb3JtYXQud2lkdGgsIGZvcm1hdC5mb3JtYXQuaGVp Z2h0LAorCQlmb3JtYXQuZm9ybWF0LmNvZGUsIHBpcGUtPm91dHB1dC0+ZW50aXR5LmluZGV4KTsK KworCWZvcm1hdC5wYWQgPSBMSUZfUEFEX1NJTks7CisJcmV0ID0gdjRsMl9zdWJkZXZfY2FsbCgm cGlwZS0+bGlmLT5zdWJkZXYsIHBhZCwgc2V0X2ZtdCwgTlVMTCwKKwkJCSAgICAgICAmZm9ybWF0 KTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJldDsKKworCWRldl9kYmcodnNwMS0+ZGV2LCAi JXM6IHNldCBmb3JtYXQgJXV4JXUgKCV4KSBvbiBMSUYldSBzaW5rXG4iLAorCQlfX2Z1bmNfXywg Zm9ybWF0LmZvcm1hdC53aWR0aCwgZm9ybWF0LmZvcm1hdC5oZWlnaHQsCisJCWZvcm1hdC5mb3Jt YXQuY29kZSwgcGlwZS0+bGlmLT5pbmRleCk7CisKKwkvKgorCSAqIFZlcmlmeSB0aGF0IHRoZSBm b3JtYXQgYXQgdGhlIG91dHB1dCBvZiB0aGUgcGlwZWxpbmUgbWF0Y2hlcyB0aGUKKwkgKiByZXF1 ZXN0ZWQgZnJhbWUgc2l6ZSBhbmQgbWVkaWEgYnVzIGNvZGUuCisJICovCisJaWYgKGZvcm1hdC5m b3JtYXQud2lkdGggIT0gZHJtX3BpcGUtPndpZHRoIHx8CisJICAgIGZvcm1hdC5mb3JtYXQuaGVp Z2h0ICE9IGRybV9waXBlLT5oZWlnaHQgfHwKKwkgICAgZm9ybWF0LmZvcm1hdC5jb2RlICE9IE1F RElBX0JVU19GTVRfQVJHQjg4ODhfMVgzMikgeworCQlkZXZfZGJnKHZzcDEtPmRldiwgIiVzOiBm b3JtYXQgbWlzbWF0Y2ggb24gTElGJXVcbiIsIF9fZnVuY19fLAorCQkJcGlwZS0+bGlmLT5pbmRl eCk7CisJCXJldHVybiAtRVBJUEU7CisJfQorCisJcmV0dXJuIDA7Cit9CisKIC8qIENvbmZpZ3Vy ZSBhbGwgZW50aXRpZXMgaW4gdGhlIHBpcGVsaW5lLiAqLwogc3RhdGljIHZvaWQgdnNwMV9kdV9w aXBlbGluZV9jb25maWd1cmUoc3RydWN0IHZzcDFfcGlwZWxpbmUgKnBpcGUpCiB7CkBAIC0zNTYs NyArNDE1LDYgQEAgaW50IHZzcDFfZHVfc2V0dXBfbGlmKHN0cnVjdCBkZXZpY2UgKmRldiwgdW5z aWduZWQgaW50IHBpcGVfaW5kZXgsCiAJc3RydWN0IHZzcDFfZHJtX3BpcGVsaW5lICpkcm1fcGlw ZTsKIAlzdHJ1Y3QgdnNwMV9waXBlbGluZSAqcGlwZTsKIAlzdHJ1Y3QgdnNwMV9icnUgKmJydTsK LQlzdHJ1Y3QgdjRsMl9zdWJkZXZfZm9ybWF0IGZvcm1hdDsKIAl1bnNpZ25lZCBsb25nIGZsYWdz OwogCXVuc2lnbmVkIGludCBpOwogCWludCByZXQ7CkBAIC00MTcsNTQgKzQ3NSwxMCBAQCBpbnQg dnNwMV9kdV9zZXR1cF9saWYoc3RydWN0IGRldmljZSAqZGV2LCB1bnNpZ25lZCBpbnQgcGlwZV9p bmRleCwKIAlpZiAocmV0IDwgMCkKIAkJcmV0dXJuIHJldDsKIAotCW1lbXNldCgmZm9ybWF0LCAw LCBzaXplb2YoZm9ybWF0KSk7Ci0JZm9ybWF0LndoaWNoID0gVjRMMl9TVUJERVZfRk9STUFUX0FD VElWRTsKLQlmb3JtYXQucGFkID0gUldQRl9QQURfU0lOSzsKLQlmb3JtYXQuZm9ybWF0LndpZHRo ID0gY2ZnLT53aWR0aDsKLQlmb3JtYXQuZm9ybWF0LmhlaWdodCA9IGNmZy0+aGVpZ2h0OwotCWZv cm1hdC5mb3JtYXQuY29kZSA9IE1FRElBX0JVU19GTVRfQVJHQjg4ODhfMVgzMjsKLQlmb3JtYXQu Zm9ybWF0LmZpZWxkID0gVjRMMl9GSUVMRF9OT05FOwotCi0JcmV0ID0gdjRsMl9zdWJkZXZfY2Fs bCgmcGlwZS0+b3V0cHV0LT5lbnRpdHkuc3ViZGV2LCBwYWQsIHNldF9mbXQsIE5VTEwsCi0JCQkg ICAgICAgJmZvcm1hdCk7Ci0JaWYgKHJldCA8IDApCi0JCXJldHVybiByZXQ7Ci0KLQlkZXZfZGJn KHZzcDEtPmRldiwgIiVzOiBzZXQgZm9ybWF0ICV1eCV1ICgleCkgb24gV1BGJXUgc2lua1xuIiwK LQkJX19mdW5jX18sIGZvcm1hdC5mb3JtYXQud2lkdGgsIGZvcm1hdC5mb3JtYXQuaGVpZ2h0LAot CQlmb3JtYXQuZm9ybWF0LmNvZGUsIHBpcGUtPm91dHB1dC0+ZW50aXR5LmluZGV4KTsKLQotCWZv cm1hdC5wYWQgPSBSV1BGX1BBRF9TT1VSQ0U7Ci0JcmV0ID0gdjRsMl9zdWJkZXZfY2FsbCgmcGlw ZS0+b3V0cHV0LT5lbnRpdHkuc3ViZGV2LCBwYWQsIGdldF9mbXQsIE5VTEwsCi0JCQkgICAgICAg JmZvcm1hdCk7Ci0JaWYgKHJldCA8IDApCi0JCXJldHVybiByZXQ7Ci0KLQlkZXZfZGJnKHZzcDEt PmRldiwgIiVzOiBnb3QgZm9ybWF0ICV1eCV1ICgleCkgb24gV1BGJXUgc291cmNlXG4iLAotCQlf X2Z1bmNfXywgZm9ybWF0LmZvcm1hdC53aWR0aCwgZm9ybWF0LmZvcm1hdC5oZWlnaHQsCi0JCWZv cm1hdC5mb3JtYXQuY29kZSwgcGlwZS0+b3V0cHV0LT5lbnRpdHkuaW5kZXgpOwotCi0JZm9ybWF0 LnBhZCA9IExJRl9QQURfU0lOSzsKLQlyZXQgPSB2NGwyX3N1YmRldl9jYWxsKCZwaXBlLT5saWYt PnN1YmRldiwgcGFkLCBzZXRfZm10LCBOVUxMLAotCQkJICAgICAgICZmb3JtYXQpOworCXJldCA9 IHZzcDFfZHVfcGlwZWxpbmVfc2V0dXBfb3V0cHV0KHZzcDEsIHBpcGUpOwogCWlmIChyZXQgPCAw KQogCQlyZXR1cm4gcmV0OwogCi0JZGV2X2RiZyh2c3AxLT5kZXYsICIlczogc2V0IGZvcm1hdCAl dXgldSAoJXgpIG9uIExJRiV1IHNpbmtcbiIsCi0JCV9fZnVuY19fLCBmb3JtYXQuZm9ybWF0Lndp ZHRoLCBmb3JtYXQuZm9ybWF0LmhlaWdodCwKLQkJZm9ybWF0LmZvcm1hdC5jb2RlLCBwaXBlX2lu ZGV4KTsKLQotCS8qCi0JICogVmVyaWZ5IHRoYXQgdGhlIGZvcm1hdCBhdCB0aGUgb3V0cHV0IG9m IHRoZSBwaXBlbGluZSBtYXRjaGVzIHRoZQotCSAqIHJlcXVlc3RlZCBmcmFtZSBzaXplIGFuZCBt ZWRpYSBidXMgY29kZS4KLQkgKi8KLQlpZiAoZm9ybWF0LmZvcm1hdC53aWR0aCAhPSBjZmctPndp ZHRoIHx8Ci0JICAgIGZvcm1hdC5mb3JtYXQuaGVpZ2h0ICE9IGNmZy0+aGVpZ2h0IHx8Ci0JICAg IGZvcm1hdC5mb3JtYXQuY29kZSAhPSBNRURJQV9CVVNfRk1UX0FSR0I4ODg4XzFYMzIpIHsKLQkJ ZGV2X2RiZyh2c3AxLT5kZXYsICIlczogZm9ybWF0IG1pc21hdGNoXG4iLCBfX2Z1bmNfXyk7Ci0J CXJldHVybiAtRVBJUEU7Ci0JfQotCiAJLyogRW5hYmxlIHRoZSBWU1AxLiAqLwogCXJldCA9IHZz cDFfZGV2aWNlX2dldCh2c3AxKTsKIAlpZiAocmV0IDwgMCkKLS0gClJlZ2FyZHMsCgpMYXVyZW50 IFBpbmNoYXJ0CgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcK aHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK