<div dir="ltr"># HG changeset patch<br># User Niranjan <<a href="mailto:niranjan@multicorewareinc.com">niranjan@multicorewareinc.com</a>><br># Date 1582622787 -19800<br>#      Tue Feb 25 14:56:27 2020 +0530<br># Node ID 2ec7d27dc576cd993fd0bfe4b116514e8f2ddc0c<br># Parent  1a47c3802fa38bdb4606e3d8203b73b4474d1ce6<br>Add: Auto AQ Mode<br><br>This patch does the following:<br>1. Automatically decides the AQ Mode for each frame, using its scene statistics,<br>such as luma intensity and edge density.<br>2. Add option "--auto-aq" to enable auto detection of AQ Mode per frame.<br><br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 doc/reST/cli.rst<br>--- a/doc/reST/cli.rst  Mon Feb 24 12:51:41 2020 +0530<br>+++ b/doc/reST/cli.rst  Tue Feb 25 14:56:27 2020 +0530<br>@@ -1721,6 +1721,12 @@<br>       5. Same as AQ mode 3, but uses edge density instead of auto-variance.<br>        i.e, AQ with bias towards dark scenes which have high edge density.<br> <br>+.. option:: --auto-aq --no-auto-aq<br>+<br>+      To enable and disable automatic AQ mode detection per frame.<br>+ This option adaptively sets the AQ mode for each frame between 2, 3, 4 and 5 based on the scene statistics.<br>+  Default: disabled.<br>+<br> .. option:: --aq-strength <float><br> <br>         Adjust the strength of the adaptive quantization offsets. Setting<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/CMakeLists.txt<br>--- a/source/CMakeLists.txt      Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/CMakeLists.txt     Tue Feb 25 14:56:27 2020 +0530<br>@@ -29,7 +29,7 @@<br> option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br> # X265_BUILD must be incremented each time the public API is changed<br>-set(X265_BUILD 189)<br>+set(X265_BUILD 190)<br> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in">x265.def.in</a>"<br>                "${PROJECT_BINARY_DIR}/x265.def")<br> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in">x265_config.h.in</a>"<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/common.h<br>--- a/source/common/common.h  Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/common.h    Tue Feb 25 14:56:27 2020 +0530<br>@@ -131,6 +131,7 @@<br> typedef int64_t  ssum2_t;<br> #define SHIFT_TO_BITPLANE 9<br> #define HISTOGRAM_BINS 1024<br>+#define BRIGHTNESS_THRESHOLD 120 // The threshold above which a pixel is bright<br> #else<br> typedef uint8_t  pixel;<br> typedef uint16_t sum_t;<br>@@ -139,6 +140,7 @@<br> typedef int32_t  ssum2_t; // Signed sum<br> #define SHIFT_TO_BITPLANE 7<br> #define HISTOGRAM_BINS 256<br>+#define BRIGHTNESS_THRESHOLD 30 // The threshold above which a pixel is bright<br> #endif // if HIGH_BIT_DEPTH<br> <br> #if X265_DEPTH < 10<br>@@ -163,6 +165,8 @@<br> #define MIN_QPSCALE     0.21249999999999999<br> #define MAX_MAX_QPSCALE 615.46574234477100<br> <br>+#define FRAME_BRIGHTNESS_THRESHOLD  50.0 // Min % of pixels in a frame, that are above BRIGHTNESS_THRESHOLD for it to be considered a bright frame<br>+#define FRAME_EDGE_THRESHOLD  10.0 // Min % of edge pixels in a frame, for it to be considered to have high edge density<br> <br> template<typename T><br> inline T x265_min(T a, T b) { return a < b ? a : b; }<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/frame.cpp<br>--- a/source/common/frame.cpp      Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/frame.cpp   Tue Feb 25 14:56:27 2020 +0530<br>@@ -63,6 +63,7 @@<br>     m_thetaPic = NULL;<br>     m_edgeBitPlane = NULL;<br>     m_edgeBitPic = NULL;<br>+    m_frameAq = X265_AQ_NONE;<br> }<br> <br> bool Frame::create(x265_param *param, float* quantOffsets)<br>@@ -103,7 +104,7 @@<br>         CHECKED_MALLOC_ZERO(m_classifyCount, uint32_t, size);<br>     }<br> <br>-    if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED || (param->rc.zonefileCount && param->rc.aqMode != 0))<br>+    if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED || param->rc.bAutoAq || (param->rc.zonefileCount && param->rc.aqMode != 0))<br>     {<br>         uint32_t numCuInWidth = (param->sourceWidth + param->maxCUSize - 1) / param->maxCUSize;<br>         uint32_t numCuInHeight = (param->sourceHeight + param->maxCUSize - 1) / param->maxCUSize;<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/frame.h<br>--- a/source/common/frame.h       Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/frame.h     Tue Feb 25 14:56:27 2020 +0530<br>@@ -141,6 +141,9 @@<br>     pixel*                 m_edgeBitPlane;<br>     pixel*                 m_edgeBitPic;<br> <br>+    /* AQ mode for each frame */<br>+    int                    m_frameAq;<br>+<br>     Frame();<br> <br>     bool create(x265_param *param, float* quantOffsets);<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/lowres.cpp<br>--- a/source/common/lowres.cpp    Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/lowres.cpp  Tue Feb 25 14:56:27 2020 +0530<br>@@ -190,6 +190,9 @@<br>         }<br>     }<br> <br>+    if (param->rc.bAutoAq)<br>+        lowresEdgePlane = X265_MALLOC(pixel, lumaStride * (lines + (origPic->m_lumaMarginY * 2)));<br>+<br>     return true;<br> <br> fail:<br>@@ -235,6 +238,7 @@<br>     X265_FREE(edgeInclined);<br>     X265_FREE(qpAqMotionOffset);<br>     X265_FREE(blockVariance);<br>+    X265_FREE(lowresEdgePlane);<br>     if (maxAQDepth > 0)<br>     {<br>         for (uint32_t d = 0; d < 4; d++)<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/lowres.h<br>--- a/source/common/lowres.h    Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/lowres.h    Tue Feb 25 14:56:27 2020 +0530<br>@@ -44,6 +44,9 @@<br>     pixel*   fpelLowerResPlane[3];<br>     pixel*   lowerResPlane[4];<br> <br>+    /* Edge Plane in Lowres */<br>+    pixel*   lowresEdgePlane;<br>+<br>     bool     isWeighted;<br>     bool     isLowres;<br>     bool     isHMELowres;<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/common/param.cpp<br>--- a/source/common/param.cpp        Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/common/param.cpp   Tue Feb 25 14:56:27 2020 +0530<br>@@ -286,6 +286,7 @@<br>     param->rc.bEnableConstVbv = 0;<br>     param->bResetZoneConfig = 1;<br>     param->reconfigWindowSize = 0;<br>+    param->rc.bAutoAq = 0;<br> <br>     /* Video Usability Information (VUI) */<br>     param->vui.aspectRatioIdc = 0;<br>@@ -1229,6 +1230,7 @@<br>         OPT("multi-pass-opt-analysis") p->analysisMultiPassRefine = atobool(value);<br>         OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion = atobool(value);<br>         OPT("aq-motion") p->bAQMotion = atobool(value);<br>+        OPT("auto-aq") p->rc.bAutoAq = atobool(value);<br>         OPT("dynamic-rd") p->dynamicRd = atof(value);<br>         OPT("analysis-reuse-level")<br>         {<br>@@ -1877,9 +1879,12 @@<br>              param->maxNumReferences, (param->limitReferences & X265_REF_LIMIT_CU) ? "on" : "off",<br>              (param->limitReferences & X265_REF_LIMIT_DEPTH) ? "on" : "off");<br> <br>-    if (param->rc.aqMode)<br>+    if (param->rc.aqMode && !param->rc.bAutoAq)<br>         x265_log(param, X265_LOG_INFO, "AQ: mode / str / qg-size / cu-tree  : %d / %0.1f / %d / %d\n", param->rc.aqMode,<br>                  param->rc.aqStrength, param->rc.qgSize, param->rc.cuTree);<br>+    else if (param->rc.bAutoAq)<br>+        x265_log(param, X265_LOG_INFO, "AQ: mode / str / qg-size / cu-tree  : auto / %0.1f / %d / %d\n", param->rc.aqStrength,<br>+                 param->rc.qgSize, param->rc.cuTree);<br> <br>     if (param->bLossless)<br>         x265_log(param, X265_LOG_INFO, "Rate Control                        : Lossless\n");<br>@@ -2187,6 +2192,7 @@<br>     s += sprintf(s, " hist-threshold=%.2f", p->edgeTransitionThreshold);<br>     BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");<br>     BOOL(p->bAQMotion, "aq-motion");<br>+    BOOL(p->rc.bAutoAq, "auto-aq");<br>     BOOL(p->bEmitHDR10SEI, "hdr10");<br>     BOOL(p->bHDR10Opt, "hdr10-opt");<br>     BOOL(p->bDhdr10opt, "dhdr10-opt");<br>@@ -2468,6 +2474,7 @@<br>     dst->rc.bEnableConstVbv = src->rc.bEnableConstVbv;<br>     dst->rc.hevcAq = src->rc.hevcAq;<br>     dst->rc.qpAdaptationRange = src->rc.qpAdaptationRange;<br>+    dst->rc.bAutoAq = src->rc.bAutoAq;<br> <br>     dst->vui.aspectRatioIdc = src->vui.aspectRatioIdc;<br>     dst->vui.sarWidth = src->vui.sarWidth;<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/encoder/slicetype.cpp<br>--- a/source/encoder/slicetype.cpp        Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/encoder/slicetype.cpp      Tue Feb 25 14:56:27 2020 +0530<br>@@ -473,9 +473,9 @@<br>     if (!(param->rc.bStatRead && param->rc.cuTree && IS_REFERENCED(curFrame)))<br>     {<br>         /* Calculate Qp offset for each 16x16 or 8x8 block in the frame */<br>-        if (param->rc.aqMode == X265_AQ_NONE || param->rc.aqStrength == 0)<br>+        if (curFrame->m_frameAq == X265_AQ_NONE || param->rc.aqStrength == 0)<br>         {<br>-            if (param->rc.aqMode && param->rc.aqStrength == 0)<br>+            if (curFrame->m_frameAq && param->rc.aqStrength == 0)<br>             {<br>                 if (quantOffsets)<br>                 {<br>@@ -516,18 +516,18 @@<br>                 double bias_strength = 0.f;<br>                 double strength = 0.f;<br> <br>-                if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)<br>+                if (curFrame->m_frameAq == X265_AQ_EDGE || curFrame->m_frameAq == X265_AQ_EDGE_BIASED)<br>                     edgeFilter(curFrame, param);<br> <br>-                if (param->rc.aqMode == X265_AQ_EDGE && !param->bHistBasedSceneCut && param->enableRecursionSkip >= EDGE_BASED_RSKIP)<br>+                if (curFrame->m_frameAq == X265_AQ_EDGE && !param->bHistBasedSceneCut && param->enableRecursionSkip >= EDGE_BASED_RSKIP)<br>                 {<br>                     pixel* src = curFrame->m_edgePic + curFrame->m_fencPic->m_lumaMarginY * curFrame->m_fencPic->m_stride + curFrame->m_fencPic->m_lumaMarginX;<br>                     primitives.planecopy_pp_shr(src, curFrame->m_fencPic->m_stride, curFrame->m_edgeBitPic,<br>                         curFrame->m_fencPic->m_stride, curFrame->m_fencPic->m_picWidth, curFrame->m_fencPic->m_picHeight, SHIFT_TO_BITPLANE);<br>                 }<br> <br>-                if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED ||<br>-                    param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)<br>+                if (curFrame->m_frameAq == X265_AQ_AUTO_VARIANCE || curFrame->m_frameAq == X265_AQ_AUTO_VARIANCE_BIASED ||<br>+                    curFrame->m_frameAq == X265_AQ_EDGE || curFrame->m_frameAq == X265_AQ_EDGE_BIASED)<br>                 {<br>                     double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));<br>                     for (int blockY = 0; blockY < maxRow; blockY += loopIncr)<br>@@ -536,7 +536,7 @@<br>                         {<br>                             uint32_t energy, edgeDensity, avgAngle;<br>                             energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);<br>-                            if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)<br>+                            if (curFrame->m_frameAq == X265_AQ_EDGE || curFrame->m_frameAq == X265_AQ_EDGE_BIASED)<br>                             {<br>                                 edgeDensity = edgeDensityCu(curFrame, avgAngle, blockX, blockY, param->rc.qgSize);<br>                                 if (edgeDensity)<br>@@ -576,17 +576,17 @@<br>                 {<br>                     for (int blockX = 0; blockX < maxCol; blockX += loopIncr)<br>                     {<br>-                        if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)<br>+                        if (curFrame->m_frameAq == X265_AQ_AUTO_VARIANCE_BIASED)<br>                         {<br>                             qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];<br>                             qp_adj = strength * (qp_adj - avg_adj) + bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj));<br>                         }<br>-                        else if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE)<br>+                        else if (curFrame->m_frameAq == X265_AQ_AUTO_VARIANCE)<br>                         {<br>                             qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];<br>                             qp_adj = strength * (qp_adj - avg_adj);<br>                         }<br>-                        else if (param->rc.aqMode == X265_AQ_EDGE)<br>+                        else if (curFrame->m_frameAq == X265_AQ_EDGE)<br>                         {<br>                             inclinedEdge = curFrame->m_lowres.edgeInclined[blockXY];<br>                             qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];<br>@@ -595,7 +595,7 @@<br>                             else<br>                                 qp_adj = strength * (qp_adj - avg_adj);<br>                         }<br>-                        else if (param->rc.aqMode == X265_AQ_EDGE_BIASED)<br>+                        else if (curFrame->m_frameAq == X265_AQ_EDGE_BIASED)<br>                         {<br>                             inclinedEdge = curFrame->m_lowres.edgeInclined[blockXY];<br>                             qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];<br>@@ -1387,6 +1387,44 @@<br>     }<br> }<br> <br>+double computeBrightnessIntensity(pixel *inPlane, int width, int height, intptr_t stride)<br>+{<br>+    pixel* rowStart = inPlane;<br>+    double count = 0;<br>+<br>+    for (int i = 0; i < height; i++)<br>+    {<br>+        for (int j = 0; j < width; j++)<br>+        {<br>+            if (rowStart[j] > BRIGHTNESS_THRESHOLD)<br>+                count++;<br>+        }<br>+        rowStart += stride;<br>+    }<br>+<br>+    /* Returns the brightness percentage of the input plane */<br>+    return (count / (width * height)) * 100;<br>+}<br>+<br>+double computeEdgeIntensity(pixel *inPlane, int width, int height, intptr_t stride)<br>+{<br>+    pixel* rowStart = inPlane;<br>+    double count = 0;<br>+<br>+    for (int i = 0; i < height; i++)<br>+    {<br>+        for (int j = 0; j < width; j++)<br>+        {<br>+            if (rowStart[j] > 0)<br>+                count++;<br>+        }<br>+        rowStart += stride;<br>+    }<br>+<br>+    /* Returns the edge percentage of the input plane */<br>+    return (count / (width * height)) * 100;<br>+}<br>+<br> void PreLookaheadGroup::processTasks(int workerThreadID)<br> {<br>     if (workerThreadID < 0)<br>@@ -1401,6 +1439,36 @@<br>         ProfileScopeEvent(prelookahead);<br>         m_lock.release();<br>         preFrame->m_lowres.init(preFrame->m_fencPic, preFrame->m_poc);<br>+<br>+        /* Auto AQ */<br>+        if (preFrame->m_param->rc.bAutoAq)<br>+        {<br>+            int heightL = preFrame->m_lowres.lines;<br>+            int widthL = preFrame->m_lowres.width;<br>+            pixel *lumaPlane = preFrame->m_lowres.fpelPlane[0];<br>+            intptr_t stride = preFrame->m_lowres.lumaStride;<br>+            double brightnessIntensity = 0, edgeIntensity = 0;<br>+<br>+            /* Edge plane computation */<br>+            memset(preFrame->m_lowres.lowresEdgePlane, 0, stride * (heightL + (preFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));<br>+            pixel* lowresEdgePic = preFrame->m_lowres.lowresEdgePlane + preFrame->m_fencPic->m_lumaMarginY * stride + preFrame->m_fencPic->m_lumaMarginX;<br>+            computeEdge(lowresEdgePic, lumaPlane, NULL, stride, heightL, widthL, false);<br>+<br>+            /*Frame edge percentage computation */<br>+            edgeIntensity = computeEdgeIntensity(lowresEdgePic, widthL, heightL, stride);<br>+<br>+            /* Frame Brightness percentage computation */<br>+            brightnessIntensity = computeBrightnessIntensity(lumaPlane, widthL, heightL, stride);<br>+<br>+            /* AQ mode switch */<br>+            if (edgeIntensity < FRAME_EDGE_THRESHOLD)<br>+                preFrame->m_frameAq = brightnessIntensity > FRAME_BRIGHTNESS_THRESHOLD? X265_AQ_AUTO_VARIANCE : X265_AQ_AUTO_VARIANCE_BIASED;<br>+            else<br>+                preFrame->m_frameAq = brightnessIntensity > FRAME_BRIGHTNESS_THRESHOLD? X265_AQ_EDGE : X265_AQ_EDGE_BIASED;<br>+        }<br>+        else<br>+            preFrame->m_frameAq = preFrame->m_param->rc.aqMode;<br>+<br>         if (m_lookahead.m_bAdaptiveQuant)<br>             tld.calcAdaptiveQuantFrame(preFrame, m_lookahead.m_param);<br>         tld.lowresIntraEstimate(preFrame->m_lowres, m_lookahead.m_param->rc.qgSize);<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/test/regression-tests.txt<br>--- a/source/test/regression-tests.txt       Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/test/regression-tests.txt  Tue Feb 25 14:56:27 2020 +0530<br>@@ -171,6 +171,7 @@<br> crowd_run_1080p50.yuv, --preset slow --ctu 32 --rskip 3 --rskip-edge-threshold 5 --hist-scenecut --hist-threshold 0.1<br> crowd_run_1080p50.yuv, --preset slower --ctu 16 --rskip 3 --rskip-edge-threshold 5 --hist-scenecut --hist-threshold 0.1 --aq-mode 4<br> sintel_trailer_2k_1920x1080_24.yuv, --preset medium --aq-mode 5<br>+ducks_take_off_420_720p50.y4m, --preset slow --auto-aq --aq-strength 1.5 --aq-motion<br>  <br> # Main12 intraCost overflow bug test<br> 720p50_parkrun_ter.y4m,--preset medium<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/x265.h<br>--- a/source/x265.h   Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/x265.h     Tue Feb 25 14:56:27 2020 +0530<br>@@ -1477,6 +1477,9 @@<br>         /* internally enable if tune grain is set */<br>         int      bEnableConstVbv;<br> <br>+        /* automatically switch AQ mode for each frame */<br>+        int      bAutoAq;<br>+<br>     } rc;<br> <br>     /*== Video Usability Information ==*/<br>diff -r 1a47c3802fa3 -r 2ec7d27dc576 source/x265cli.h<br>--- a/source/x265cli.h        Mon Feb 24 12:51:41 2020 +0530<br>+++ b/source/x265cli.h  Tue Feb 25 14:56:27 2020 +0530<br>@@ -172,6 +172,8 @@<br>     { "qp",             required_argument, NULL, 'q' },<br>     { "aq-mode",        required_argument, NULL, 0 },<br>     { "aq-strength",    required_argument, NULL, 0 },<br>+    { "auto-aq",              no_argument, NULL, 0 },<br>+    { "no-auto-aq",           no_argument, NULL, 0 },<br>     { "rc-grain",             no_argument, NULL, 0 },<br>     { "no-rc-grain",          no_argument, NULL, 0 },<br>     { "ipratio",        required_argument, NULL, 0 },<br>@@ -594,6 +596,7 @@<br>     H0("   --aq-strength <float>         Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);<br>     H0("   --qp-adaptation-range <float> Delta QP range by QP adaptation based on a psycho-visual model (1.0 to 6.0). Default %.2f\n", param->rc.qpAdaptationRange);<br>     H0("   --[no-]aq-motion              Block level QP adaptation based on the relative motion between the block and the frame. Default %s\n", OPT(param->bAQMotion));<br>+    H1("   --[no-]auto-aq                Automatically decides the AQ Mode for each frame, using its scene statistics, such as luma intensity and edge density. Default %s\n", OPT(param->rc.bAutoAq));<br>     H0("   --qg-size <int>               Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);<br>     H0("   --[no-]cutree                 Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));<br>     H0("   --[no-]rc-grain               Enable ratecontrol mode to handle grains specifically. turned on with tune grain. Default %s\n", OPT(param->rc.bEnableGrain));<br><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><font color="#0c343d" face="verdana, sans-serif">Thanks & Regards</font><div><font color="#0c343d" face="verdana, sans-serif"><b>Niranjan Kumar B</b></font></div><div><font size="1" color="#0c343d" face="verdana, sans-serif">Video Codec Engineer </font></div><div><font size="1" color="#0c343d" face="verdana, sans-serif">Media & AI Analytics</font></div><div><font face="trebuchet ms, sans-serif" color="#0c343d">+91 958 511 1449</font></div><div><a href="https://multicorewareinc.com/" style="color:rgb(17,85,204)" target="_blank"><img src="https://docs.google.com/uc?export=download&id=1kc3RJu9M8bnIf6Xa5rUw2d-eEVUsPBE5&revid=0B7tw9XJBmynaemR1VUpQUi9DVytRVW5SVkRwVTFjb1hBMUcwPQ"></a></div></div></div></div></div></div></div></div></div>