18#include <freerdp/codec/av2.h>
19#include <freerdp/primitives.h>
20#include <freerdp/log.h>
21#include <freerdp/codec/region.h>
23#define TAG FREERDP_TAG("codec.av2")
25#if defined(WITH_LIBAVM)
28#include <avm/avm_decoder.h>
29#include <avm/avm_image.h>
35#if defined(WITH_LIBAVM) && defined(WITH_LIBAVM_ENCODER)
36#define AV2_ENCODER_LIBAVM
37#include <avm/avm_encoder.h>
43#if defined(WITH_DAV2D) && !defined(WITH_LIBAVM)
44#define AV2_DECODER_DAV2D
45#include <dav2d/dav2d.h>
48#if defined(WITH_LIBAVM) || defined(WITH_DAV2D)
50#if defined(WITH_LIBYUV)
55#define AV2_PROFILE_MAIN_420_10_IP0 0
56#define AV2_PROFILE_MAIN_444_10_IP1 4
59#if defined(WITH_LIBAVM) && !defined(AVM_USAGE_REALTIME)
60#define AVM_USAGE_REALTIME AVM_USAGE_GOOD_QUALITY
75struct S_FREERDP_AV2_CONTEXT
80#if defined(WITH_LIBAVM)
82#if defined(AV2_ENCODER_LIBAVM)
83 avm_codec_enc_cfg_t ecfg;
84 avm_codec_pts_t framecount;
85 avm_enc_frame_flags_t eflags;
87 avm_codec_flags_t flags;
88 avm_codec_iface_t* iface;
91#if defined(WITH_LIBAVM)
92 avm_codec_dec_cfg_t dcfg;
94#if defined(AV2_DECODER_DAV2D)
103#if defined(WITH_LIBAVM)
104static void av2_avm_destroy(FREERDP_AV2_CONTEXT* av2)
106 const avm_codec_err_t rc = avm_codec_destroy(&av2->ctx);
107 if (rc != AVM_CODEC_OK)
108 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_destroy: %s", avm_codec_err_to_string(rc));
112#if defined(AV2_ENCODER_LIBAVM)
115static BOOL allocate_h264_metablock(UINT32 QP,
RECTANGLE_16* rectangles,
119 if (!meta || (QP > UINT8_MAX))
125 meta->regionRects = rectangles;
129 if (count > UINT32_MAX)
134 if (!meta->quantQualityVals || !meta->regionRects)
136 meta->numRegionRects = (UINT32)count;
137 for (
size_t x = 0; x < count; x++)
144 cur->qualityVal = 100 - (QP & 0x3F);
150static BOOL av2_avm_control(FREERDP_AV2_CONTEXT* av2,
int id,
const char* name,
int value)
152 const avm_codec_err_t rc = avm_codec_control(&av2->ctx,
id, value);
153 if (rc != AVM_CODEC_OK)
155 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_control(%s, %d): %s", name, value,
156 avm_codec_err_to_string(rc));
163BOOL freerdp_av2_context_set_option(FREERDP_AV2_CONTEXT* av2, FREERDP_AV2_CONTEXT_OPTION option,
166#if defined(AV2_ENCODER_LIBAVM)
169 case FREERDP_AV2_CONTEXT_OPTION_PROFILE:
174 WLog_Print(av2->log, WLOG_WARN,
175 "Unknown FREERDP_AV2_CONTEXT_OPTION_PROFILE value %" PRIu32, value);
179 av2->profile = value;
180 av2->ecfg.g_profile =
181 (value == 1) ? AV2_PROFILE_MAIN_444_10_IP1 : AV2_PROFILE_MAIN_420_10_IP0;
184 case FREERDP_AV2_CONTEXT_OPTION_RATECONTROL:
189 case FREERDP_AV2_VBR:
190 av2->ecfg.rc_end_usage = AVM_VBR;
192 case FREERDP_AV2_CBR:
193 av2->ecfg.rc_end_usage = AVM_CBR;
196 av2->ecfg.rc_end_usage = AVM_CQ;
199 av2->ecfg.rc_end_usage = AVM_Q;
202 WLog_Print(av2->log, WLOG_WARN,
203 "Unknown FREERDP_AV2_CONTEXT_OPTION_RATECONTROL value [0x%08" PRIx32
209 case FREERDP_AV2_CONTEXT_OPTION_BITRATE:
212 av2->ecfg.rc_target_bitrate = value;
214 case FREERDP_AV2_CONTEXT_OPTION_USAGETYPE:
217 av2->ecfg.g_usage = value;
220 WLog_Print(av2->log, WLOG_ERROR,
"Unknown FREERDP_AV2_CONTEXT_OPTION[0x%08" PRIx32
"]",
224 return freerdp_av2_context_reset(av2, av2->ecfg.g_w, av2->ecfg.g_h);
226 WLog_Print(av2->log, WLOG_WARN,
227 "AV2 encoder requires libavm with its encoder, recompile with '-DWITH_AVM=ON'");
228 WINPR_UNUSED(option);
234UINT32 freerdp_av2_context_get_option(FREERDP_AV2_CONTEXT* av2, FREERDP_AV2_CONTEXT_OPTION option)
236#if defined(AV2_ENCODER_LIBAVM)
239 case FREERDP_AV2_CONTEXT_OPTION_PROFILE:
243 case FREERDP_AV2_CONTEXT_OPTION_RATECONTROL:
246 switch (av2->ecfg.rc_end_usage)
249 return FREERDP_AV2_VBR;
251 return FREERDP_AV2_CBR;
253 return FREERDP_AV2_CQ;
256 return FREERDP_AV2_Q;
258 case FREERDP_AV2_CONTEXT_OPTION_BITRATE:
261 return av2->ecfg.rc_target_bitrate;
262 case FREERDP_AV2_CONTEXT_OPTION_USAGETYPE:
265 return av2->ecfg.g_usage;
267 WLog_Print(av2->log, WLOG_ERROR,
"Unknown FREERDP_AV2_CONTEXT_OPTION[0x%08" PRIx32
"]",
273 WINPR_UNUSED(option);
278INT32 freerdp_av2_compress(FREERDP_AV2_CONTEXT* av2,
const BYTE* pSrcData, DWORD SrcFormat,
279 UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight,
280 const RECTANGLE_16* regionRect, BYTE** ppDstData, UINT32* pDstSize,
283 *ppDstData =
nullptr;
288 WLog_Print(av2->log, WLOG_ERROR,
"av2->encoder: %d", av2->encoder);
292#if defined(AV2_ENCODER_LIBAVM)
296 WLog_Print(av2->log, WLOG_ERROR,
"primitives_get(): nullptr");
300 if (av2->yuvWidth != nSrcWidth)
302 WLog_Print(av2->log, WLOG_ERROR,
"av2->yuvWidth[%" PRIu32
"] != nSrcWidth[%" PRIu32
"]",
303 av2->yuvWidth, nSrcWidth);
307 if (av2->yuvHeight != nSrcHeight)
309 WLog_Print(av2->log, WLOG_ERROR,
"av2->yuvHeight[%" PRIu32
"] != nSrcHeight[%" PRIu32
"]",
310 av2->yuvHeight, nSrcHeight);
314 const prim_size_t roi = { .width = nSrcWidth, .height = nSrcHeight };
316 avm_image_t buffer = WINPR_C_ARRAY_INIT;
318 avm_image_t* img = &buffer;
320#if defined(WITH_LIBYUV)
324 if ((SrcFormat == PIXEL_FORMAT_BGRA32) || (SrcFormat == PIXEL_FORMAT_BGRX32))
326 switch (av2->profile)
329 img->fmt = AVM_IMG_FMT_I420;
330 img->x_chroma_shift = 1;
331 img->y_chroma_shift = 1;
332 rec = ARGBToI420(pSrcData, nSrcStep, av2->yuvdata[0], av2->yuvStride[0],
333 av2->yuvdata[1], av2->yuvStride[1], av2->yuvdata[2],
334 WINPR_ASSERTING_INT_CAST(
int, av2->yuvStride[2]),
335 WINPR_ASSERTING_INT_CAST(
int, roi.width),
336 WINPR_ASSERTING_INT_CAST(
int, roi.height));
339 img->fmt = AVM_IMG_FMT_I444;
340 rec = ARGBToI444(pSrcData, nSrcStep, av2->yuvdata[0], av2->yuvStride[0],
341 av2->yuvdata[1], av2->yuvStride[1], av2->yuvdata[2],
342 WINPR_ASSERTING_INT_CAST(
int, av2->yuvStride[2]),
343 WINPR_ASSERTING_INT_CAST(
int, roi.width),
344 WINPR_ASSERTING_INT_CAST(
int, roi.height));
347 WLog_Print(av2->log, WLOG_ERROR,
"Unsupported AV2 profile %" PRIu32, av2->profile);
354 switch (av2->profile)
357 img->fmt = AVM_IMG_FMT_I420;
358 img->x_chroma_shift = 1;
359 img->y_chroma_shift = 1;
360 rec = primitives->RGBToYUV420_8u_P3AC4R(pSrcData, SrcFormat, nSrcStep, av2->yuvdata,
361 av2->yuvStride, &roi);
364 img->fmt = AVM_IMG_FMT_I444;
365 rec = primitives->
RGBToI444_8u(pSrcData, SrcFormat, nSrcStep, av2->yuvdata,
366 av2->yuvStride, &roi);
369 WLog_Print(av2->log, WLOG_ERROR,
"Unsupported AV2 profile %" PRIu32, av2->profile);
375 WLog_Print(av2->log, WLOG_ERROR,
"RGB to YUV conversion failed: %d", rec);
379 img->d_w = img->r_w = img->w = roi.width;
380 img->d_h = img->r_h = img->h = roi.height;
381 img->stride[0] = WINPR_ASSERTING_INT_CAST(
int, av2->yuvStride[0]);
382 img->stride[1] = WINPR_ASSERTING_INT_CAST(
int, av2->yuvStride[1]);
383 img->stride[2] = WINPR_ASSERTING_INT_CAST(
int, av2->yuvStride[2]);
384 img->planes[0] = av2->yuvdata[0];
385 img->planes[1] = av2->yuvdata[1];
386 img->planes[2] = av2->yuvdata[2];
388 const avm_codec_err_t rc = avm_codec_encode(&av2->ctx, img, ++av2->framecount, 1, av2->eflags);
391 if (rc != AVM_CODEC_OK)
393 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_encode: %s", avm_codec_err_to_string(rc));
397 avm_codec_iter_t iter =
nullptr;
398 const avm_codec_cx_pkt_t* pkt =
nullptr;
399 while ((pkt = avm_codec_get_cx_data(&av2->ctx, &iter)) !=
nullptr)
401 if (pkt->kind != AVM_CODEC_CX_FRAME_PKT)
404 *ppDstData = pkt->data.frame.buf;
405 *pDstSize = WINPR_ASSERTING_INT_CAST(UINT32, pkt->data.frame.sz);
413 rect->right = WINPR_ASSERTING_INT_CAST(UINT16, nSrcWidth);
414 rect->bottom = WINPR_ASSERTING_INT_CAST(UINT16, nSrcHeight);
416 return allocate_h264_metablock(10, rect, meta, 1);
418 WLog_Print(av2->log, WLOG_ERROR,
419 "AV2 encoder requires libavm with its encoder, recompile with '-DWITH_AVM=ON'");
420 WINPR_UNUSED(pSrcData);
421 WINPR_UNUSED(SrcFormat);
422 WINPR_UNUSED(nSrcStep);
423 WINPR_UNUSED(nSrcWidth);
424 WINPR_UNUSED(nSrcHeight);
425 WINPR_UNUSED(regionRect);
431static BOOL isRectValid(UINT32 width, UINT32 height,
const RECTANGLE_16* rect)
434 if (rect->left > width)
436 if (rect->right > width)
438 if (rect->left >= rect->right)
440 if (rect->top > height)
442 if (rect->bottom > height)
444 if (rect->top >= rect->bottom)
449static BOOL areRectsValid(wLog* log, UINT32 width, UINT32 height,
const RECTANGLE_16* rects,
452 WINPR_ASSERT(rects || (count == 0));
453 for (
size_t x = 0; x < count; x++)
456 if (!isRectValid(width, height, rect))
458 char buffer[64] = WINPR_C_ARRAY_INIT;
459 WLog_Print(log, WLOG_WARN,
460 "Rectangle %" PRIuz
" %s outside of bounding frame %" PRIu32
"x%" PRIu32, x,
461 rectangle_to_string(rect, buffer,
sizeof(buffer)), width, height);
472static BOOL av2_planes_to_8bit(FREERDP_AV2_CONTEXT* av2, av2_planes* planes)
475 WINPR_ASSERT(planes);
478 return (planes->bpc == 8);
479 if ((planes->bpc < 8) || (planes->bpc > 16))
481 WLog_Print(av2->log, WLOG_ERROR,
"AV2 picture bpc %" PRIu32
" not supported", planes->bpc);
485 if ((planes->width > av2->yuvWidth) || (planes->height > av2->yuvHeight))
487 WLog_Print(av2->log, WLOG_ERROR,
488 "AV2 picture %" PRIu32
"x%" PRIu32
" larger than the surface %" PRIu32
490 planes->width, planes->height, av2->yuvWidth, av2->yuvHeight);
494 const UINT32 shift = planes->bpc - 8;
495 for (
size_t p = 0; p < 3; p++)
497 const UINT32 w = ((p == 0) || planes->i444) ? planes->width : (planes->width + 1) / 2;
498 const UINT32 h = ((p == 0) || planes->i444) ? planes->height : (planes->height + 1) / 2;
499 for (UINT32 y = 0; y < h; y++)
501 const UINT16* src = WINPR_PACKED_ALIGN_CAST(
502 const UINT16*, &planes->data[p][1ull * y * planes->stride[p]]);
503 BYTE* dst = &av2->yuvdata[p][1ull * y * av2->yuvStride[p]];
504 for (UINT32 x = 0; x < w; x++)
506 const UINT32 v = src[x] >> shift;
507 dst[x] = (BYTE)MIN(v, UINT8_MAX);
510 planes->data[p] = av2->yuvdata[p];
511 planes->stride[p] = av2->yuvStride[p];
514 planes->highbd = FALSE;
519static INT32 av2_convert(FREERDP_AV2_CONTEXT* av2, av2_planes* planes, BYTE* pDstData,
520 DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
523 if (!av2_planes_to_8bit(av2, planes))
525 WLog_Print(av2->log, WLOG_ERROR,
"AV2 picture with %" PRIu32
" bit samples not supported",
533 const UINT32 nWidth = (planes->width < nDstWidth) ? planes->width : nDstWidth;
534 const UINT32 nHeight = (planes->height < nDstHeight) ? planes->height : nDstHeight;
535 const prim_size_t roi = { .width = nWidth, .height = nHeight };
537 if (!areRectsValid(av2->log, roi.width, roi.height, regionRects, numRegionRect))
541#if defined(WITH_LIBYUV)
545 if ((DstFormat == PIXEL_FORMAT_BGRA32) || (DstFormat == PIXEL_FORMAT_BGRX32))
547 const int stride0 = WINPR_ASSERTING_INT_CAST(
int, planes->stride[0]);
548 const int stride1 = WINPR_ASSERTING_INT_CAST(
int, planes->stride[1]);
549 const int stride2 = WINPR_ASSERTING_INT_CAST(
int, planes->stride[2]);
550 const int iWidth = WINPR_ASSERTING_INT_CAST(
int, nWidth);
551 const int iHeight = WINPR_ASSERTING_INT_CAST(
int, nHeight);
552 const int iDstStep = WINPR_ASSERTING_INT_CAST(
int, nDstStep);
555 rec = J444ToARGB(planes->data[0], stride0, planes->data[1], stride1, planes->data[2],
556 stride2, pDstData, iDstStep, iWidth, iHeight);
558 rec = J420ToARGB(planes->data[0], stride0, planes->data[1], stride1, planes->data[2],
559 stride2, pDstData, iDstStep, iWidth, iHeight);
567 WLog_Print(av2->log, WLOG_ERROR,
"primitives_get(): nullptr");
572 rec = primitives->
I444ToRGB_8u(planes->data, planes->stride, pDstData, nDstStep,
575 rec = primitives->YUV420ToRGB_8u_P3AC4R(planes->data, planes->stride, pDstData,
576 nDstStep, DstFormat, &roi);
580 WLog_Print(av2->log, WLOG_ERROR,
"YUV to RGB conversion failed: %d", rec);
586#if defined(AV2_DECODER_DAV2D)
587static void av2_dav2d_data_free(WINPR_ATTR_UNUSED
const uint8_t* buf,
588 WINPR_ATTR_UNUSED
void* cookie)
594static INT32 av2_dav2d_drain_one(FREERDP_AV2_CONTEXT* av2, BYTE* pDstData, DWORD DstFormat,
595 UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
598 Dav2dPicture pic = WINPR_C_ARRAY_INIT;
599 const int prc = dav2d_get_picture(av2->dav2d, &pic);
600 if (prc == DAV2D_ERR(EAGAIN))
604 WLog_Print(av2->log, WLOG_WARN,
"dav2d_get_picture: %d", prc);
609 switch (pic.p.layout)
611 case DAV2D_PIXEL_LAYOUT_I420:
612 case DAV2D_PIXEL_LAYOUT_I444:
614 av2_planes planes = { .data = { pic.data[0], pic.data[1], pic.data[2] },
615 .stride = { (UINT32)pic.stride[0], (UINT32)pic.stride[1],
616 (UINT32)pic.stride[1] },
617 .width = (UINT32)pic.p.w,
618 .height = (UINT32)pic.p.h,
619 .bpc = (UINT32)pic.p.bpc,
620 .highbd = (pic.p.bpc > 8),
621 .i444 = (pic.p.layout == DAV2D_PIXEL_LAYOUT_I444) };
622 rc = av2_convert(av2, &planes, pDstData, DstFormat, nDstStep, nDstWidth, nDstHeight,
623 regionRects, numRegionRect);
627 WLog_Print(av2->log, WLOG_ERROR,
"dav2d picture layout %u not supported", pic.p.layout);
630 dav2d_picture_unref(&pic);
631 return (rc == TRUE) ? TRUE : rc;
635INT32 freerdp_av2_decompress(FREERDP_AV2_CONTEXT* av2,
const BYTE* pSrcData, UINT32 SrcSize,
636 BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth,
638 UINT32 numRegionRect)
643 WLog_Print(av2->log, WLOG_ERROR,
"av2->encoder: %d", av2->encoder);
647 if (!areRectsValid(av2->log, nDstWidth, nDstHeight, regionRects, numRegionRect))
650#if defined(AV2_DECODER_DAV2D)
651 Dav2dData data = WINPR_C_ARRAY_INIT;
652 const int wrc = dav2d_data_wrap(&data, pSrcData, SrcSize, av2_dav2d_data_free,
nullptr);
655 WLog_Print(av2->log, WLOG_WARN,
"dav2d_data_wrap: %d", wrc);
661 const int src = dav2d_send_data(av2->dav2d, &data);
662 if ((src < 0) && (src != DAV2D_ERR(EAGAIN)))
664 WLog_Print(av2->log, WLOG_WARN,
"dav2d_send_data: %d", src);
665 dav2d_data_unref(&data);
669 const INT32 rc = av2_dav2d_drain_one(av2, pDstData, DstFormat, nDstStep, nDstWidth,
670 nDstHeight, regionRects, numRegionRect);
671 if ((rc != TRUE) && (rc != FALSE))
673 dav2d_data_unref(&data);
681 const INT32 rc = av2_dav2d_drain_one(av2, pDstData, DstFormat, nDstStep, nDstWidth,
682 nDstHeight, regionRects, numRegionRect);
690#elif defined(WITH_LIBAVM)
691 const avm_codec_err_t rc = avm_codec_decode(&av2->ctx, pSrcData, SrcSize,
nullptr);
692 if (rc != AVM_CODEC_OK)
694 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_decode: %s", avm_codec_err_to_string(rc));
698 avm_image_t* img =
nullptr;
699 avm_codec_iter_t iter =
nullptr;
700 while ((img = avm_codec_get_frame(&av2->ctx, &iter)) !=
nullptr)
702 const avm_img_fmt_t fmt = img->fmt & ~AVM_IMG_FMT_HIGHBITDEPTH;
703 if ((fmt != AVM_IMG_FMT_I420) && (fmt != AVM_IMG_FMT_I444))
705 WLog_Print(av2->log, WLOG_ERROR,
"img->fmt %d not supported", img->fmt);
710 av2_planes planes = { .data = { img->planes[0], img->planes[1], img->planes[2] },
711 .stride = { (UINT32)img->stride[0], (UINT32)img->stride[1],
712 (UINT32)img->stride[2] },
715 .bpc = img->bit_depth,
716 .highbd = (img->fmt & AVM_IMG_FMT_HIGHBITDEPTH) != 0,
717 .i444 = (fmt == AVM_IMG_FMT_I444) };
719 const INT32 crc = av2_convert(av2, &planes, pDstData, DstFormat, nDstStep, nDstWidth,
720 nDstHeight, regionRects, numRegionRect);
729BOOL freerdp_av2_context_reset(FREERDP_AV2_CONTEXT* av2, UINT32 width, UINT32 height)
733#if defined(AV2_ENCODER_LIBAVM)
734 av2->ecfg.g_w = width;
735 av2->ecfg.g_h = height;
737 if (av2->initialized)
739 const avm_codec_err_t rc = avm_codec_destroy(&av2->ctx);
740 av2->initialized =
false;
741 if (rc != AVM_CODEC_OK)
743 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_destroy: %s",
744 avm_codec_err_to_string(rc));
749 const avm_codec_err_t rc =
750 avm_codec_enc_init(&av2->ctx, av2->iface, &av2->ecfg, av2->flags);
751 if (rc != AVM_CODEC_OK)
753 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_enc_init: %s", avm_codec_err_to_string(rc));
756 av2->initialized =
true;
759 const int cpuUsed = (av2->ecfg.g_usage == AVM_USAGE_REALTIME) ? 9 : 6;
760 if (!av2_avm_control(av2, AVME_SET_CPUUSED,
"AVME_SET_CPUUSED", cpuUsed) ||
761 !av2_avm_control(av2, AV2E_SET_TUNE_CONTENT,
"AV2E_SET_TUNE_CONTENT",
762 AVM_CONTENT_SCREEN) ||
763 !av2_avm_control(av2, AV2E_SET_ROW_MT,
"AV2E_SET_ROW_MT", 1))
767 av2->eflags = AVM_EFLAG_FORCE_KF;
769 WLog_Print(av2->log, WLOG_ERROR,
770 "AV2 encoder requires libavm with its encoder, recompile with '-DWITH_AVM=ON'");
776#if defined(AV2_DECODER_DAV2D)
777 if (av2->initialized)
779 dav2d_close(&av2->dav2d);
780 av2->initialized =
false;
783 Dav2dSettings settings = WINPR_C_ARRAY_INIT;
784 dav2d_default_settings(&settings);
787 settings.n_threads = 1;
788 settings.max_frame_delay = 1;
790 const int rc = dav2d_open(&av2->dav2d, &settings);
793 WLog_Print(av2->log, WLOG_WARN,
"dav2d_open: %d", rc);
796 av2->initialized =
true;
797#elif defined(WITH_LIBAVM)
798 if (av2->initialized)
800 av2_avm_destroy(av2);
801 av2->initialized =
false;
805 av2->dcfg.h = height;
806 const avm_codec_err_t rc =
807 avm_codec_dec_init(&av2->ctx, av2->iface, &av2->dcfg, av2->flags);
808 if (rc != AVM_CODEC_OK)
810 WLog_Print(av2->log, WLOG_WARN,
"avm_codec_dec_init: %s", avm_codec_err_to_string(rc));
813 av2->initialized =
true;
815 WLog_Print(av2->log, WLOG_WARN,
816 "This build does not support AV2 decoding. Recompile with '-DWITH_DAV2D=ON' "
817 "or '-DWITH_AVM=ON'");
822 av2->yuvWidth = width;
823 av2->yuvStride[0] = width;
825 const size_t pad = av2->yuvStride[0] % 16;
827 av2->yuvStride[0] += 16 - pad;
828 av2->yuvStride[1] = av2->yuvStride[0];
829 av2->yuvStride[2] = av2->yuvStride[0];
831 av2->yuvHeight = height;
832 winpr_aligned_free(av2->yuvdata[0]);
833 winpr_aligned_free(av2->yuvdata[1]);
834 winpr_aligned_free(av2->yuvdata[2]);
835 av2->yuvdata[0] = winpr_aligned_malloc(1ull * av2->yuvStride[0] * av2->yuvHeight, 64);
836 av2->yuvdata[1] = winpr_aligned_malloc(1ull * av2->yuvStride[1] * av2->yuvHeight, 64);
837 av2->yuvdata[2] = winpr_aligned_malloc(1ull * av2->yuvStride[2] * av2->yuvHeight, 64);
838 return (av2->yuvdata[0] !=
nullptr) && (av2->yuvdata[1] !=
nullptr) &&
839 (av2->yuvdata[2] !=
nullptr);
842void freerdp_av2_context_free(FREERDP_AV2_CONTEXT* av2)
847 if (av2->initialized)
851#if defined(WITH_LIBAVM)
852 av2_avm_destroy(av2);
857#if defined(AV2_DECODER_DAV2D)
858 dav2d_close(&av2->dav2d);
859#elif defined(WITH_LIBAVM)
860 av2_avm_destroy(av2);
864 winpr_aligned_free(av2->yuvdata[0]);
865 winpr_aligned_free(av2->yuvdata[1]);
866 winpr_aligned_free(av2->yuvdata[2]);
870FREERDP_AV2_CONTEXT* freerdp_av2_context_new(BOOL Compressor)
872 FREERDP_AV2_CONTEXT* ctx = calloc(1,
sizeof(FREERDP_AV2_CONTEXT));
875 ctx->encoder = Compressor;
876 ctx->log = WLog_Get(TAG);
882#if defined(AV2_ENCODER_LIBAVM)
883 ctx->iface = avm_codec_av2_cx();
886 WLog_Print(ctx->log, WLOG_ERROR,
"avm_codec_av2_cx() nullptr");
890 const avm_codec_err_t rc =
891 avm_codec_enc_config_default(ctx->iface, &ctx->ecfg, AVM_USAGE_REALTIME);
892 if (rc != AVM_CODEC_OK)
894 WLog_Print(ctx->log, WLOG_ERROR,
"avm_codec_enc_config_default() %s",
895 avm_codec_err_to_string(rc));
899 ctx->ecfg.g_lag_in_frames = 0;
900 ctx->ecfg.kf_mode = AVM_KF_DISABLED;
901 ctx->ecfg.g_profile = AV2_PROFILE_MAIN_420_10_IP0;
902 ctx->ecfg.g_bit_depth = AVM_BITS_8;
903 ctx->ecfg.g_input_bit_depth = 8;
905 WLog_Print(ctx->log, WLOG_ERROR,
906 "AV2 encoder requires libavm with its encoder, recompile with '-DWITH_AVM=ON'");
910#if defined(WITH_LIBAVM)
913 ctx->iface = avm_codec_av2_dx();
916 WLog_Print(ctx->log, WLOG_ERROR,
"avm_codec_av2_dx() nullptr");
925 freerdp_av2_context_free(ctx);
930struct S_FREERDP_AV2_CONTEXT
936BOOL freerdp_av2_context_set_option(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2,
937 WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT_OPTION option,
938 WINPR_ATTR_UNUSED UINT32 value)
943UINT32 freerdp_av2_context_get_option(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2,
944 WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT_OPTION option)
949INT32 freerdp_av2_compress(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2,
950 WINPR_ATTR_UNUSED
const BYTE* pSrcData,
951 WINPR_ATTR_UNUSED DWORD SrcFormat, WINPR_ATTR_UNUSED UINT32 nSrcStep,
952 WINPR_ATTR_UNUSED UINT32 nSrcWidth, WINPR_ATTR_UNUSED UINT32 nSrcHeight,
954 WINPR_ATTR_UNUSED BYTE** ppDstData, WINPR_ATTR_UNUSED UINT32* pDstSize,
958 WLog_Print(av2->log, WLOG_ERROR,
959 "This build does not support AV2 codec. Recompile with '-DWITH_AVM=ON' or "
960 "'-DWITH_DAV2D=ON'");
964INT32 freerdp_av2_decompress(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2,
965 WINPR_ATTR_UNUSED
const BYTE* pSrcData,
966 WINPR_ATTR_UNUSED UINT32 SrcSize, WINPR_ATTR_UNUSED BYTE* pDstData,
967 WINPR_ATTR_UNUSED DWORD DstFormat, WINPR_ATTR_UNUSED UINT32 nDstStep,
968 WINPR_ATTR_UNUSED UINT32 nDstWidth,
969 WINPR_ATTR_UNUSED UINT32 nDstHeight,
971 WINPR_ATTR_UNUSED UINT32 numRegionRect)
974 WLog_Print(av2->log, WLOG_ERROR,
975 "This build does not support AV2 codec. Recompile with '-DWITH_AVM=ON' or "
976 "'-DWITH_DAV2D=ON'");
980BOOL freerdp_av2_context_reset(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2,
981 WINPR_ATTR_UNUSED UINT32 width, WINPR_ATTR_UNUSED UINT32 height)
984 WLog_Print(av2->log, WLOG_WARN,
985 "This build does not support AV2 codec. Recompile with '-DWITH_AVM=ON' or "
986 "'-DWITH_DAV2D=ON'");
990void freerdp_av2_context_free(WINPR_ATTR_UNUSED FREERDP_AV2_CONTEXT* av2)
995FREERDP_AV2_CONTEXT* freerdp_av2_context_new(BOOL Compressor)
997 FREERDP_AV2_CONTEXT* ctx = calloc(1,
sizeof(FREERDP_AV2_CONTEXT));
1000 ctx->Compressor = Compressor;
1001 ctx->log = WLog_Get(TAG);
WINPR_ATTR_NODISCARD fn_RGBToYUV444_8u_P3AC4R_t RGBToI444_8u
WINPR_ATTR_NODISCARD fn_YUV444ToRGB_8u_P3AC4R_t I444ToRGB_8u
Convert a plain YUV444 picture (e.g. decoded AV1) to RGB. Unlike YUV444ToRGB_8u_P3AC4R this does not ...