21#include <freerdp/codec/av1.h>
22#include <freerdp/primitives.h>
23#include <freerdp/log.h>
24#include <freerdp/codec/region.h>
26#define TAG FREERDP_TAG("codec.av1")
28#if defined(WITH_LIBAOM)
31#include <aom/aom_decoder.h>
32#include <aom/aom_encoder.h>
34#include <aom/aom_image.h>
39#if defined(WITH_DAV1D)
40#include <dav1d/dav1d.h>
43#if defined(WITH_AV1_WEBCODECS)
44#include "av1_webcodecs.h"
47#if defined(WITH_LIBAOM) || defined(WITH_DAV1D)
49#if defined(WITH_LIBYUV)
53struct S_FREERDP_AV1_CONTEXT
58#if defined(WITH_LIBAOM)
60 aom_codec_enc_cfg_t ecfg;
61 aom_codec_pts_t framecount;
62 aom_enc_frame_flags_t eflags;
63 aom_codec_flags_t flags;
64 aom_codec_iface_t* iface;
66#if defined(WITH_LIBAOM) && !defined(WITH_DAV1D)
67 aom_codec_dec_cfg_t dcfg;
69#if defined(WITH_DAV1D)
72#if defined(WITH_AV1_WEBCODECS)
81#if defined(WITH_LIBAOM)
82static void av1_aom_destroy(FREERDP_AV1_CONTEXT* av1)
84 const aom_codec_err_t rc = aom_codec_destroy(&av1->ctx);
85 if (rc != AOM_CODEC_OK)
86 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_destroy: %s", aom_codec_err_to_string(rc));
90static BOOL allocate_h264_metablock(UINT32 QP,
RECTANGLE_16* rectangles,
94 if (!meta || (QP > UINT8_MAX))
100 meta->regionRects = rectangles;
104 if (count > UINT32_MAX)
109 if (!meta->quantQualityVals || !meta->regionRects)
111 meta->numRegionRects = (UINT32)count;
112 for (
size_t x = 0; x < count; x++)
119 cur->qualityVal = 100 - (QP & 0x3F);
125BOOL freerdp_av1_context_set_option(FREERDP_AV1_CONTEXT* av1, FREERDP_AV1_CONTEXT_OPTION option,
128#if defined(WITH_LIBAOM)
131 case FREERDP_AV1_CONTEXT_OPTION_PROFILE:
135 av1->ecfg.g_profile = value;
138 case FREERDP_AV1_CONTEXT_OPTION_RATECONTROL:
143 case FREERDP_AV1_VBR:
144 case FREERDP_AV1_CBR:
149 WLog_Print(av1->log, WLOG_WARN,
150 "Unknown FREERDP_AV1_CONTEXT_OPTION_RATECONTROL value [0x%08" PRIx32
155 av1->ecfg.rc_end_usage = value;
157 case FREERDP_AV1_CONTEXT_OPTION_BITRATE:
160 av1->ecfg.rc_target_bitrate = value;
162 case FREERDP_AV1_CONTEXT_OPTION_USAGETYPE:
165 av1->ecfg.g_usage = value;
168 WLog_Print(av1->log, WLOG_ERROR,
"Unknown FREERDP_AV1_CONTEXT_OPTION[0x%08" PRIx32
"]",
172 return freerdp_av1_context_reset(av1, av1->ecfg.g_w, av1->ecfg.g_h);
174 WLog_Print(av1->log, WLOG_WARN,
"AV1 encoder requires libaom, recompile with '-DWITH_AOM=ON'");
175 WINPR_UNUSED(option);
181UINT32 freerdp_av1_context_get_option(FREERDP_AV1_CONTEXT* av1, FREERDP_AV1_CONTEXT_OPTION option)
183#if defined(WITH_LIBAOM)
186 case FREERDP_AV1_CONTEXT_OPTION_PROFILE:
189 return av1->ecfg.g_profile;
190 case FREERDP_AV1_CONTEXT_OPTION_RATECONTROL:
193 return av1->ecfg.rc_end_usage;
194 case FREERDP_AV1_CONTEXT_OPTION_BITRATE:
197 return av1->ecfg.rc_target_bitrate;
198 case FREERDP_AV1_CONTEXT_OPTION_USAGETYPE:
201 return av1->ecfg.g_usage;
203 WLog_Print(av1->log, WLOG_ERROR,
"Unknown FREERDP_AV1_CONTEXT_OPTION[0x%08" PRIx32
"]",
208 WINPR_UNUSED(option);
213INT32 freerdp_av1_compress(FREERDP_AV1_CONTEXT* av1,
const BYTE* pSrcData, DWORD SrcFormat,
214 UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight,
215 const RECTANGLE_16* regionRect, BYTE** ppDstData, UINT32* pDstSize,
218 *ppDstData =
nullptr;
223 WLog_Print(av1->log, WLOG_ERROR,
"av1->encoder: %d", av1->encoder);
227#if defined(WITH_LIBAOM)
231 WLog_Print(av1->log, WLOG_ERROR,
"primitives_get(): nullptr");
235 if (av1->yuvWidth != nSrcWidth)
237 WLog_Print(av1->log, WLOG_ERROR,
"av1->yuvWidth[%" PRIu32
"] != nSrcWidth[%" PRIu32
"]",
238 av1->yuvWidth, nSrcWidth);
242 if (av1->yuvHeight != nSrcHeight)
244 WLog_Print(av1->log, WLOG_ERROR,
"av1->yuvHeight[%" PRIu32
"] != nSrcHeight[%" PRIu32
"]",
245 av1->yuvHeight, nSrcHeight);
249 const prim_size_t roi = { .width = nSrcWidth, .height = nSrcHeight };
251 aom_image_t buffer = WINPR_C_ARRAY_INIT;
253 aom_image_t* img = &buffer;
255#if defined(WITH_LIBYUV)
259 if ((SrcFormat == PIXEL_FORMAT_BGRA32) || (SrcFormat == PIXEL_FORMAT_BGRX32))
261 switch (av1->ecfg.g_profile)
264 img->fmt = AOM_IMG_FMT_I420;
265 img->x_chroma_shift = 1;
266 img->y_chroma_shift = 1;
267 rec = ARGBToI420(pSrcData, nSrcStep, av1->yuvdata[0], av1->yuvStride[0],
268 av1->yuvdata[1], av1->yuvStride[1], av1->yuvdata[2],
269 WINPR_ASSERTING_INT_CAST(
int, av1->yuvStride[2]),
270 WINPR_ASSERTING_INT_CAST(
int, roi.width),
271 WINPR_ASSERTING_INT_CAST(
int, roi.height));
274 img->fmt = AOM_IMG_FMT_I444;
275 rec = ARGBToI444(pSrcData, nSrcStep, av1->yuvdata[0], av1->yuvStride[0],
276 av1->yuvdata[1], av1->yuvStride[1], av1->yuvdata[2],
277 WINPR_ASSERTING_INT_CAST(
int, av1->yuvStride[2]),
278 WINPR_ASSERTING_INT_CAST(
int, roi.width),
279 WINPR_ASSERTING_INT_CAST(
int, roi.height));
282 WLog_Print(av1->log, WLOG_ERROR,
"Unsupoorted AV1 profile %" PRIu32,
283 av1->ecfg.g_profile);
290 switch (av1->ecfg.g_profile)
293 img->fmt = AOM_IMG_FMT_I420;
294 img->x_chroma_shift = 1;
295 img->y_chroma_shift = 1;
296 rec = primitives->RGBToYUV420_8u_P3AC4R(pSrcData, SrcFormat, nSrcStep, av1->yuvdata,
297 av1->yuvStride, &roi);
300 img->fmt = AOM_IMG_FMT_I444;
301 rec = primitives->
RGBToI444_8u(pSrcData, SrcFormat, nSrcStep, av1->yuvdata,
302 av1->yuvStride, &roi);
305 WLog_Print(av1->log, WLOG_ERROR,
"Unsupoorted AV1 profile %" PRIu32,
306 av1->ecfg.g_profile);
312 WLog_Print(av1->log, WLOG_ERROR,
"RGB to YUV conversion failed: %d", rec);
316 img->d_w = img->r_w = img->w = roi.width;
317 img->d_h = img->r_h = img->h = roi.height;
318 img->stride[0] = WINPR_ASSERTING_INT_CAST(
int, av1->yuvStride[0]);
319 img->stride[1] = WINPR_ASSERTING_INT_CAST(
int, av1->yuvStride[1]);
320 img->stride[2] = WINPR_ASSERTING_INT_CAST(
int, av1->yuvStride[2]);
321 img->planes[0] = av1->yuvdata[0];
322 img->planes[1] = av1->yuvdata[1];
323 img->planes[2] = av1->yuvdata[2];
325 const aom_codec_err_t rc = aom_codec_encode(&av1->ctx, img, ++av1->framecount, 1, av1->eflags);
328 if (rc != AOM_CODEC_OK)
330 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_encode: %s", aom_codec_err_to_string(rc));
334 aom_codec_iter_t iter =
nullptr;
335 const aom_codec_cx_pkt_t* pkt =
nullptr;
336 while ((pkt = aom_codec_get_cx_data(&av1->ctx, &iter)) !=
nullptr)
338 if (pkt->kind != AOM_CODEC_CX_FRAME_PKT)
341 *ppDstData = pkt->data.frame.buf;
342 *pDstSize = pkt->data.frame.sz;
350 rect->right = nSrcWidth;
351 rect->bottom = nSrcHeight;
353 return allocate_h264_metablock(10, rect, meta, 1);
355 WLog_Print(av1->log, WLOG_ERROR,
"AV1 encoder requires libaom, recompile with '-DWITH_AOM=ON'");
356 WINPR_UNUSED(pSrcData);
357 WINPR_UNUSED(SrcFormat);
358 WINPR_UNUSED(nSrcStep);
359 WINPR_UNUSED(nSrcWidth);
360 WINPR_UNUSED(nSrcHeight);
361 WINPR_UNUSED(regionRect);
367static BOOL isRectValid(UINT32 width, UINT32 height,
const RECTANGLE_16* rect)
370 if (rect->left > width)
372 if (rect->right > width)
374 if (rect->left >= rect->right)
376 if (rect->top > height)
378 if (rect->bottom > height)
380 if (rect->top >= rect->bottom)
385static BOOL areRectsValid(wLog* log, UINT32 width, UINT32 height,
const RECTANGLE_16* rects,
388 WINPR_ASSERT(rects || (count == 0));
389 for (
size_t x = 0; x < count; x++)
392 if (!isRectValid(width, height, rect))
394 char buffer[64] = WINPR_C_ARRAY_INIT;
395 WLog_Print(log, WLOG_WARN,
396 "Rectangle %" PRIuz
" %s outside of bounding frame %" PRIu32
"x%" PRIu32, x,
397 rectangle_to_string(rect, buffer,
sizeof(buffer)), width, height);
404#if defined(WITH_DAV1D)
405static void av1_dav1d_data_free(WINPR_ATTR_UNUSED
const uint8_t* buf,
406 WINPR_ATTR_UNUSED
void* cookie)
411static INT32 av1_dav1d_convert(FREERDP_AV1_CONTEXT* av1,
const Dav1dPicture* pic, BYTE* pDstData,
412 DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth,
414 UINT32 numRegionRect)
418 WLog_Print(av1->log, WLOG_ERROR,
"dav1d picture bpc %d not supported", pic->p.bpc);
425 const UINT32 dw = (UINT32)pic->p.w;
426 const UINT32 dh = (UINT32)pic->p.h;
427 const UINT32 nWidth = (dw < nDstWidth) ? dw : nDstWidth;
428 const UINT32 nHeight = (dh < nDstHeight) ? dh : nDstHeight;
429 const prim_size_t roi = { .width = nWidth, .height = nHeight };
431 if (!areRectsValid(av1->log, roi.width, roi.height, regionRects, numRegionRect))
434 const UINT32 strides[] = { (UINT32)pic->stride[0], (UINT32)pic->stride[1],
435 (UINT32)pic->stride[1] };
438#if defined(WITH_LIBYUV)
442 if ((DstFormat == PIXEL_FORMAT_BGRA32) || (DstFormat == PIXEL_FORMAT_BGRX32))
444 const uint8_t* y = pic->data[0];
445 const uint8_t* u = pic->data[1];
446 const uint8_t* v = pic->data[2];
448 const int stride0 = WINPR_ASSERTING_INT_CAST(
int, strides[0]);
449 const int stride1 = WINPR_ASSERTING_INT_CAST(
int, strides[1]);
450 const int stride2 = WINPR_ASSERTING_INT_CAST(
int, strides[2]);
451 const int iWidth = WINPR_ASSERTING_INT_CAST(
int, nWidth);
452 const int iHeight = WINPR_ASSERTING_INT_CAST(
int, nHeight);
453 const int iDstStep = WINPR_ASSERTING_INT_CAST(
int, nDstStep);
455 switch (pic->p.layout)
457 case DAV1D_PIXEL_LAYOUT_I420:
458 rec = J420ToARGB(y, stride0, u, stride1, v, stride2, pDstData, iDstStep, iWidth,
461 case DAV1D_PIXEL_LAYOUT_I444:
462 rec = J444ToARGB(y, stride0, u, stride1, v, stride2, pDstData, iDstStep, iWidth,
466 WLog_Print(av1->log, WLOG_ERROR,
"dav1d picture layout %d not supported",
477 WLog_Print(av1->log, WLOG_ERROR,
"primitives_get(): nullptr");
481 const BYTE* pSrc[] = { pic->data[0], pic->data[1], pic->data[2] };
482 switch (pic->p.layout)
484 case DAV1D_PIXEL_LAYOUT_I420:
485 rec = primitives->YUV420ToRGB_8u_P3AC4R(pSrc, strides, pDstData, nDstStep,
488 case DAV1D_PIXEL_LAYOUT_I444:
489 rec = primitives->
I444ToRGB_8u(pSrc, strides, pDstData, nDstStep, DstFormat, &roi);
492 WLog_Print(av1->log, WLOG_ERROR,
"dav1d picture layout %d not supported",
499 WLog_Print(av1->log, WLOG_ERROR,
"RGB to YUV conversion failed: %d", rec);
506static INT32 av1_dav1d_drain_one(FREERDP_AV1_CONTEXT* av1, BYTE* pDstData, DWORD DstFormat,
507 UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
510 Dav1dPicture pic = WINPR_C_ARRAY_INIT;
511 const int prc = dav1d_get_picture(av1->dav1d, &pic);
512 if (prc == DAV1D_ERR(EAGAIN))
516 WLog_Print(av1->log, WLOG_WARN,
"dav1d_get_picture: %d", prc);
520 const INT32 rc = av1_dav1d_convert(av1, &pic, pDstData, DstFormat, nDstStep, nDstWidth,
521 nDstHeight, regionRects, numRegionRect);
522 dav1d_picture_unref(&pic);
523 return (rc == TRUE) ? TRUE : rc;
527INT32 freerdp_av1_decompress(FREERDP_AV1_CONTEXT* av1,
const BYTE* pSrcData, UINT32 SrcSize,
528 BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth,
530 UINT32 numRegionRect)
535 WLog_Print(av1->log, WLOG_ERROR,
"av1->encoder: %d", av1->encoder);
539 if (!areRectsValid(av1->log, nDstWidth, nDstHeight, regionRects, numRegionRect))
542#if defined(WITH_AV1_WEBCODECS)
543 if (av1->webcodecs > 0)
545 const INT32 wrc = av1_wc_decode(av1->webcodecs, pSrcData, SrcSize, pDstData, DstFormat,
546 nDstStep, nDstWidth, nDstHeight);
550 if (wrc == AV1_WC_UNSUPPORTED)
551 WLog_Print(av1->log, WLOG_DEBUG,
"surface format needs dav1d instead of WebCodecs");
553 WLog_Print(av1->log, WLOG_WARN,
554 "WebCodecs AV1 decode failed (%" PRId32
"), using dav1d", wrc);
555 av1_wc_close(av1->webcodecs);
560#if defined(WITH_DAV1D)
561 Dav1dData data = WINPR_C_ARRAY_INIT;
562 const int wrc = dav1d_data_wrap(&data, pSrcData, SrcSize, av1_dav1d_data_free,
nullptr);
565 WLog_Print(av1->log, WLOG_WARN,
"dav1d_data_wrap: %d", wrc);
571 const int src = dav1d_send_data(av1->dav1d, &data);
572 if ((src < 0) && (src != DAV1D_ERR(EAGAIN)))
574 WLog_Print(av1->log, WLOG_WARN,
"dav1d_send_data: %d", src);
575 dav1d_data_unref(&data);
579 const INT32 rc = av1_dav1d_drain_one(av1, pDstData, DstFormat, nDstStep, nDstWidth,
580 nDstHeight, regionRects, numRegionRect);
581 if ((rc != TRUE) && (rc != FALSE))
583 dav1d_data_unref(&data);
591 const INT32 rc = av1_dav1d_drain_one(av1, pDstData, DstFormat, nDstStep, nDstWidth,
592 nDstHeight, regionRects, numRegionRect);
600#elif defined(WITH_LIBAOM)
601 const aom_codec_err_t rc = aom_codec_decode(&av1->ctx, pSrcData, SrcSize,
nullptr);
602 if (rc != AOM_CODEC_OK)
604 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_decode: %s", aom_codec_err_to_string(rc));
608 aom_image_t* img =
nullptr;
609 aom_codec_iter_t iter =
nullptr;
610 while ((img = aom_codec_get_frame(&av1->ctx, &iter)) !=
nullptr)
615 const UINT32 nWidth = (img->d_w < nDstWidth) ? img->d_w : nDstWidth;
616 const UINT32 nHeight = (img->d_h < nDstHeight) ? img->d_h : nDstHeight;
617 const prim_size_t roi = { .width = nWidth, .height = nHeight };
619 if (!areRectsValid(av1->log, roi.width, roi.height, regionRects, numRegionRect))
623#if defined(WITH_LIBYUV)
627 if ((DstFormat == PIXEL_FORMAT_BGRA32) || (DstFormat == PIXEL_FORMAT_BGRX32))
631 case AOM_IMG_FMT_I420:
632 rec = J420ToARGB(img->planes[0], img->stride[0], img->planes[1], img->stride[1],
633 img->planes[2], img->stride[2], pDstData, nDstStep, nWidth,
636 case AOM_IMG_FMT_I444:
637 rec = J444ToARGB(img->planes[0], img->stride[0], img->planes[1], img->stride[1],
638 img->planes[2], img->stride[2], pDstData, nDstStep, nWidth,
642 WLog_Print(av1->log, WLOG_ERROR,
"img->fmt %d not supported", img->fmt);
649 const BYTE* pSrc[] = { img->planes[0], img->planes[1], img->planes[2] };
650 const UINT32 strides[] = { img->stride[0], img->stride[1], img->stride[2] };
655 WLog_Print(av1->log, WLOG_ERROR,
"primitives_get(): nullptr");
661 case AOM_IMG_FMT_I420:
662 rec = primitives->YUV420ToRGB_8u_P3AC4R(pSrc, strides, pDstData, nDstStep,
665 case AOM_IMG_FMT_I444:
666 rec = primitives->
I444ToRGB_8u(pSrc, strides, pDstData, nDstStep, DstFormat,
670 WLog_Print(av1->log, WLOG_ERROR,
"img->fmt %d not supported", img->fmt);
676 WLog_Print(av1->log, WLOG_ERROR,
"RGB to YUV conversion failed: %d", rec);
685BOOL freerdp_av1_context_reset(FREERDP_AV1_CONTEXT* av1, UINT32 width, UINT32 height)
689#if defined(WITH_LIBAOM)
690 av1->ecfg.g_w = width;
691 av1->ecfg.g_h = height;
693 if (av1->initialized)
695 const aom_codec_err_t rc = aom_codec_destroy(&av1->ctx);
696 av1->initialized =
false;
697 if (rc != AOM_CODEC_OK)
699 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_destroy: %s",
700 aom_codec_err_to_string(rc));
705 const aom_codec_err_t rc =
706 aom_codec_enc_init(&av1->ctx, av1->iface, &av1->ecfg, av1->flags);
707 if (rc != AOM_CODEC_OK)
709 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_enc_init: %s", aom_codec_err_to_string(rc));
715 av1->initialized =
true;
717 WLog_Print(av1->log, WLOG_ERROR,
718 "AV1 encoder requires libaom, recompile with '-DWITH_AOM=ON'");
724#if defined(WITH_AV1_WEBCODECS)
725 if (av1->webcodecs == 0)
727 av1->webcodecs = av1_wc_open();
728 WLog_Print(av1->log, WLOG_INFO,
"AV1 decoder: %s",
729 av1->webcodecs > 0 ?
"WebCodecs (browser), dav1d as fallback" :
"dav1d");
732#if defined(WITH_DAV1D)
733 if (av1->initialized)
735 dav1d_close(&av1->dav1d);
736 av1->initialized =
false;
739 Dav1dSettings settings = WINPR_C_ARRAY_INIT;
740 dav1d_default_settings(&settings);
743 settings.n_threads = 1;
744 settings.max_frame_delay = 1;
746 const int rc = dav1d_open(&av1->dav1d, &settings);
749 WLog_Print(av1->log, WLOG_WARN,
"dav1d_open: %d", rc);
752 av1->initialized =
true;
753#elif defined(WITH_LIBAOM)
755 av1->dcfg.h = height;
756 av1->dcfg.allow_lowbitdepth = 1;
757 const aom_codec_err_t rc =
758 aom_codec_dec_init(&av1->ctx, av1->iface, &av1->dcfg, av1->flags);
759 if (rc != AOM_CODEC_OK)
761 WLog_Print(av1->log, WLOG_WARN,
"aom_codec_dec_init: %s", aom_codec_err_to_string(rc));
764 av1->initialized =
true;
766 WLog_Print(av1->log, WLOG_WARN,
767 "This build does not support AV1 decoding. Recompile with '-DWITH_DAV1D=ON' "
768 "or '-DWITH_AOM=ON'");
773 av1->yuvWidth = width;
774 av1->yuvStride[0] = width;
776 const size_t pad = av1->yuvStride[0] % 16;
778 av1->yuvStride[0] += 16 - pad;
779 av1->yuvStride[0] *= 3;
780 av1->yuvStride[1] = width;
781 av1->yuvStride[2] = width;
783 av1->yuvHeight = height;
784 winpr_aligned_free(av1->yuvdata[0]);
785 winpr_aligned_free(av1->yuvdata[1]);
786 winpr_aligned_free(av1->yuvdata[2]);
787 av1->yuvdata[0] = winpr_aligned_malloc(1ull * av1->yuvStride[0] * av1->yuvHeight, 64);
788 av1->yuvdata[1] = winpr_aligned_malloc(1ull * av1->yuvStride[1] * av1->yuvHeight, 64);
789 av1->yuvdata[2] = winpr_aligned_malloc(1ull * av1->yuvStride[2] * av1->yuvHeight, 64);
790 return av1->yuvdata[0] !=
nullptr;
793void freerdp_av1_context_free(FREERDP_AV1_CONTEXT* av1)
798 if (av1->initialized)
802#if defined(WITH_LIBAOM)
803 av1_aom_destroy(av1);
808#if defined(WITH_DAV1D)
809 dav1d_close(&av1->dav1d);
810#elif defined(WITH_LIBAOM)
811 av1_aom_destroy(av1);
815#if defined(WITH_AV1_WEBCODECS)
816 av1_wc_close(av1->webcodecs);
818 winpr_aligned_free(av1->yuvdata[0]);
819 winpr_aligned_free(av1->yuvdata[1]);
820 winpr_aligned_free(av1->yuvdata[2]);
824FREERDP_AV1_CONTEXT* freerdp_av1_context_new(BOOL Compressor)
826 FREERDP_AV1_CONTEXT* ctx = calloc(1,
sizeof(FREERDP_AV1_CONTEXT));
829 ctx->encoder = Compressor;
830 ctx->log = WLog_Get(TAG);
836#if defined(WITH_LIBAOM)
837 ctx->iface = aom_codec_av1_cx();
840 WLog_Print(ctx->log, WLOG_ERROR,
"aom_codec_av1_cx() nullptr");
844 const aom_codec_err_t rc =
845 aom_codec_enc_config_default(ctx->iface, &ctx->ecfg, AOM_USAGE_REALTIME);
846 if (rc != AOM_CODEC_OK)
848 WLog_Print(ctx->log, WLOG_ERROR,
"aom_codec_enc_config_default() %s",
849 aom_codec_err_to_string(rc));
853 WLog_Print(ctx->log, WLOG_ERROR,
854 "AV1 encoder requires libaom, recompile with '-DWITH_AOM=ON'");
858#if defined(WITH_LIBAOM) && !defined(WITH_DAV1D)
861 ctx->iface = aom_codec_av1_dx();
864 WLog_Print(ctx->log, WLOG_ERROR,
"aom_codec_av1_dx() nullptr");
873 freerdp_av1_context_free(ctx);
878struct S_FREERDP_AV1_CONTEXT
884BOOL freerdp_av1_context_set_option(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1,
885 WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT_OPTION option,
886 WINPR_ATTR_UNUSED UINT32 value)
891UINT32 freerdp_av1_context_get_option(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1,
892 WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT_OPTION option)
897INT32 freerdp_av1_compress(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1,
898 WINPR_ATTR_UNUSED
const BYTE* pSrcData,
899 WINPR_ATTR_UNUSED DWORD SrcFormat, WINPR_ATTR_UNUSED UINT32 nSrcStep,
900 WINPR_ATTR_UNUSED UINT32 nSrcWidth, WINPR_ATTR_UNUSED UINT32 nSrcHeight,
902 WINPR_ATTR_UNUSED BYTE** ppDstData, WINPR_ATTR_UNUSED UINT32* pDstSize,
906 WLog_Print(av1->log, WLOG_ERROR,
907 "This build does not support AV1 codec. Recompile with '-DWITH_AOM=ON' or "
908 "'-DWITH_DAV1D=ON'");
912INT32 freerdp_av1_decompress(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1,
913 WINPR_ATTR_UNUSED
const BYTE* pSrcData,
914 WINPR_ATTR_UNUSED UINT32 SrcSize, WINPR_ATTR_UNUSED BYTE* pDstData,
915 WINPR_ATTR_UNUSED DWORD DstFormat, WINPR_ATTR_UNUSED UINT32 nDstStep,
916 WINPR_ATTR_UNUSED UINT32 nDstWidth,
917 WINPR_ATTR_UNUSED UINT32 nDstHeight,
919 WINPR_ATTR_UNUSED UINT32 numRegionRect)
922 WLog_Print(av1->log, WLOG_ERROR,
923 "This build does not support AV1 codec. Recompile with '-DWITH_AOM=ON' or "
924 "'-DWITH_DAV1D=ON'");
928BOOL freerdp_av1_context_reset(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1,
929 WINPR_ATTR_UNUSED UINT32 width, WINPR_ATTR_UNUSED UINT32 height)
932 WLog_Print(av1->log, WLOG_WARN,
933 "This build does not support AV1 codec. Recompile with '-DWITH_AOM=ON' or "
934 "'-DWITH_DAV1D=ON'");
938void freerdp_av1_context_free(WINPR_ATTR_UNUSED FREERDP_AV1_CONTEXT* av1)
943FREERDP_AV1_CONTEXT* freerdp_av1_context_new(BOOL Compressor)
945 FREERDP_AV1_CONTEXT* ctx = calloc(1,
sizeof(FREERDP_AV1_CONTEXT));
948 ctx->Compressor = Compressor;
949 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 ...