21#include <freerdp/config.h>
23#include <winpr/wlog.h>
24#include <freerdp/log.h>
25#include <freerdp/codec/h264.h>
26#include <libavcodec/avcodec.h>
27#include <libavutil/opt.h>
31#ifdef WITH_VIDEOTOOLBOX
32#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 9, 0)
33#include <libavutil/hwcontext.h>
35#pragma warning You have asked for VideoToolbox decoding, \
36 but your version of libavutil is too old !Disabling.
37#undef WITH_VIDEOTOOLBOX
42#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 9, 0)
43#include <libavutil/hwcontext.h>
45#pragma warning You have asked for VA - API decoding, \
46 but your version of libavutil is too old !Disabling.
52#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
53#define AV_CODEC_ID_H264 CODEC_ID_H264
56#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 34, 2)
57#define AV_CODEC_FLAG_LOOP_FILTER CODEC_FLAG_LOOP_FILTER
58#define AV_CODEC_CAP_TRUNCATED CODEC_CAP_TRUNCATED
59#define AV_CODEC_FLAG_TRUNCATED CODEC_FLAG_TRUNCATED
62#if LIBAVUTIL_VERSION_MAJOR < 52
63#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
68#if !defined(av_err2str)
69static inline char* error_string(
char* errbuf,
size_t errbuf_size,
int errnum)
71 av_strerror(errnum, errbuf, errbuf_size);
75#define av_err2str(errnum) error_string((char[64])WINPR_C_ARRAY_INIT, 64, errnum)
78#if defined(WITH_VAAPI) || defined(WITH_VAAPI_H264_ENCODING)
79#define VAAPI_DEVICE "/dev/dri/renderD128"
84 const AVCodec* codecDecoder;
85 AVCodecContext* codecDecoderContext;
86 const AVCodec* codecEncoder;
87 AVCodecContext* codecEncoderContext;
88 AVCodecParserContext* codecParser;
90#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
91 AVPacket bufferpacket;
94#if defined(WITH_VAAPI) || defined(WITH_VAAPI_H264_ENCODING) || defined(WITH_VIDEOTOOLBOX)
96 AVFrame* hwVideoFrame;
97 enum AVPixelFormat hw_pix_fmt;
98#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100) || defined(WITH_VIDEOTOOLBOX)
99 AVBufferRef* hw_frames_ctx;
103} H264_CONTEXT_LIBAVCODEC;
105static void libavcodec_destroy_encoder_context(H264_CONTEXT* WINPR_RESTRICT h264)
107 H264_CONTEXT_LIBAVCODEC* sys =
nullptr;
109 if (!h264 || !h264->subsystem)
112 sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
114 if (sys->codecEncoderContext)
116#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
117 avcodec_free_context(&sys->codecEncoderContext);
119 avcodec_close(sys->codecEncoderContext);
120 av_free(sys->codecEncoderContext);
124 sys->codecEncoderContext =
nullptr;
127#ifdef WITH_VAAPI_H264_ENCODING
128static int set_hw_frames_ctx(H264_CONTEXT* WINPR_RESTRICT h264)
130 H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
131 AVBufferRef* hw_frames_ref =
nullptr;
132 AVHWFramesContext* frames_ctx =
nullptr;
135 if (!(hw_frames_ref = av_hwframe_ctx_alloc(sys->hwctx)))
137 WLog_Print(h264->log, WLOG_ERROR,
"Failed to create VAAPI frame context");
140 frames_ctx = (AVHWFramesContext*)(hw_frames_ref->data);
141 frames_ctx->format = AV_PIX_FMT_VAAPI;
142 frames_ctx->sw_format = AV_PIX_FMT_NV12;
143 frames_ctx->width = sys->codecEncoderContext->width;
144 frames_ctx->height = sys->codecEncoderContext->height;
145 frames_ctx->initial_pool_size = 20;
146 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0)
148 WLog_Print(h264->log, WLOG_ERROR,
149 "Failed to initialize VAAPI frame context."
152 av_buffer_unref(&hw_frames_ref);
155 sys->codecEncoderContext->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
156 if (!sys->codecEncoderContext->hw_frames_ctx)
157 err = AVERROR(ENOMEM);
159 av_buffer_unref(&hw_frames_ref);
164static BOOL libavcodec_create_encoder_context(H264_CONTEXT* WINPR_RESTRICT h264)
166 BOOL recreate = FALSE;
167 H264_CONTEXT_LIBAVCODEC* sys =
nullptr;
169 if (!h264 || !h264->subsystem)
172 if ((h264->width > INT_MAX) || (h264->height > INT_MAX))
175 sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
176 if (!sys || !sys->codecEncoder)
179 recreate = !sys->codecEncoderContext;
181 if (sys->codecEncoderContext)
183 if ((sys->codecEncoderContext->width != (
int)h264->width) ||
184 (sys->codecEncoderContext->height != (
int)h264->height))
191 libavcodec_destroy_encoder_context(h264);
193 sys->codecEncoderContext = avcodec_alloc_context3(sys->codecEncoder);
195 if (!sys->codecEncoderContext)
198 switch (h264->RateControlMode)
200 case H264_RATECONTROL_VBR:
201 sys->codecEncoderContext->bit_rate = h264->BitRate;
204 case H264_RATECONTROL_CQP:
205 if (av_opt_set_int(sys->codecEncoderContext,
"qp", h264->QP, AV_OPT_SEARCH_CHILDREN) <
208 WLog_Print(h264->log, WLOG_ERROR,
"av_opt_set_int failed");
216 sys->codecEncoderContext->width = (int)MIN(INT32_MAX, h264->width);
217 sys->codecEncoderContext->height = (int)MIN(INT32_MAX, h264->height);
218 sys->codecEncoderContext->delay = 0;
219#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 13, 100)
220 sys->codecEncoderContext->framerate =
221 (AVRational){ WINPR_ASSERTING_INT_CAST(
int, h264->FrameRate), 1 };
223 sys->codecEncoderContext->time_base =
224 (AVRational){ 1, WINPR_ASSERTING_INT_CAST(
int, h264->FrameRate) };
225 av_opt_set(sys->codecEncoderContext,
"tune",
"zerolatency", AV_OPT_SEARCH_CHILDREN);
227 sys->codecEncoderContext->flags |= AV_CODEC_FLAG_LOOP_FILTER;
229#ifdef WITH_VAAPI_H264_ENCODING
232 av_opt_set(sys->codecEncoderContext,
"preset",
"veryslow", AV_OPT_SEARCH_CHILDREN);
234 sys->codecEncoderContext->pix_fmt = AV_PIX_FMT_VAAPI;
236 if (set_hw_frames_ctx(h264) < 0)
242 av_opt_set(sys->codecEncoderContext,
"preset",
"medium", AV_OPT_SEARCH_CHILDREN);
243 sys->codecEncoderContext->pix_fmt = AV_PIX_FMT_YUV420P;
246 if (avcodec_open2(sys->codecEncoderContext, sys->codecEncoder,
nullptr) < 0)
251 libavcodec_destroy_encoder_context(h264);
255static int libavcodec_decompress(H264_CONTEXT* WINPR_RESTRICT h264,
256 const BYTE* WINPR_RESTRICT pSrcData, UINT32 SrcSize)
266 AVPacket* packet =
nullptr;
269 WINPR_ASSERT(pSrcData || (SrcSize == 0));
271 H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
272 BYTE** pYUVData = h264->pYUVData;
273 UINT32* iStride = h264->iStride;
277#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
278 packet = &sys->bufferpacket;
279 WINPR_ASSERT(packet);
280 av_init_packet(packet);
282 packet = av_packet_alloc();
286 WLog_Print(h264->log, WLOG_ERROR,
"Failed to allocate AVPacket");
291 packet->data = cnv.pv;
292 packet->size = (int)MIN(SrcSize, INT32_MAX);
294 WINPR_ASSERT(sys->codecDecoderContext);
296#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
297 status = avcodec_send_packet(sys->codecDecoderContext, packet);
301 WLog_Print(h264->log, WLOG_ERROR,
"Failed to decode video frame (status=%d)", status);
305 sys->videoFrame->format = AV_PIX_FMT_YUV420P;
307#if defined(WITH_VAAPI) || defined(WITH_VIDEOTOOLBOX)
308 status = avcodec_receive_frame(sys->codecDecoderContext,
309 sys->hwctx ? sys->hwVideoFrame : sys->videoFrame);
311 status = avcodec_receive_frame(sys->codecDecoderContext, sys->videoFrame);
313 if (status == AVERROR(EAGAIN))
319 gotFrame = (status == 0);
321#if defined(WITH_VAAPI) || defined(WITH_VIDEOTOOLBOX)
323 avcodec_decode_video2(sys->codecDecoderContext,
324 sys->hwctx ? sys->hwVideoFrame : sys->videoFrame, &gotFrame, packet);
326 status = avcodec_decode_video2(sys->codecDecoderContext, sys->videoFrame, &gotFrame, packet);
331 WLog_Print(h264->log, WLOG_ERROR,
"Failed to decode video frame (status=%d)", status);
335#if defined(WITH_VAAPI) || defined(WITH_VIDEOTOOLBOX)
339 if (sys->hwVideoFrame->format == sys->hw_pix_fmt)
341 sys->videoFrame->width = sys->hwVideoFrame->width;
342 sys->videoFrame->height = sys->hwVideoFrame->height;
343 status = av_hwframe_transfer_data(sys->videoFrame, sys->hwVideoFrame, 0);
347 status = av_frame_copy(sys->videoFrame, sys->hwVideoFrame);
351 gotFrame = (status == 0);
355 WLog_Print(h264->log, WLOG_ERROR,
"Failed to transfer video frame (status=%d) (%s)", status,
364 WINPR_ASSERT(sys->videoFrame);
366 pYUVData[0] = sys->videoFrame->data[0];
367 pYUVData[1] = sys->videoFrame->data[1];
368 pYUVData[2] = sys->videoFrame->data[2];
369 iStride[0] = (UINT32)MAX(0, sys->videoFrame->linesize[0]);
370 iStride[1] = (UINT32)MAX(0, sys->videoFrame->linesize[1]);
371 iStride[2] = (UINT32)MAX(0, sys->videoFrame->linesize[2]);
378#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
379 av_packet_unref(packet);
381 av_packet_free(&packet);
387static int libavcodec_compress(H264_CONTEXT* WINPR_RESTRICT h264,
388 const BYTE** WINPR_RESTRICT pSrcYuv,
389 const UINT32* WINPR_RESTRICT pStride,
390 BYTE** WINPR_RESTRICT ppDstData, UINT32* WINPR_RESTRICT pDstSize)
403 H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
406 if (!libavcodec_create_encoder_context(h264))
409#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
410 sys->packet = &sys->bufferpacket;
411 av_packet_unref(sys->packet);
412 av_init_packet(sys->packet);
414 av_packet_free(&sys->packet);
415 sys->packet = av_packet_alloc();
419 WLog_Print(h264->log, WLOG_ERROR,
"Failed to allocate AVPacket");
423 WINPR_ASSERT(sys->packet);
424 sys->packet->data =
nullptr;
425 sys->packet->size = 0;
427 WINPR_ASSERT(sys->videoFrame);
428 WINPR_ASSERT(sys->codecEncoderContext);
429 sys->videoFrame->format = AV_PIX_FMT_YUV420P;
430 sys->videoFrame->width = sys->codecEncoderContext->width;
431 sys->videoFrame->height = sys->codecEncoderContext->height;
432#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 48, 100)
433 sys->videoFrame->colorspace = AVCOL_SPC_BT709;
435#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 92, 100)
436 sys->videoFrame->chroma_location = AVCHROMA_LOC_LEFT;
438 cnv.cpv = pSrcYuv[0];
439 sys->videoFrame->data[0] = cnv.pv;
441 cnv.cpv = pSrcYuv[1];
442 sys->videoFrame->data[1] = cnv.pv;
444 cnv.cpv = pSrcYuv[2];
445 sys->videoFrame->data[2] = cnv.pv;
447 sys->videoFrame->linesize[0] = (int)pStride[0];
448 sys->videoFrame->linesize[1] = (int)pStride[1];
449 sys->videoFrame->linesize[2] = (int)pStride[2];
450 sys->videoFrame->pts++;
452#ifdef WITH_VAAPI_H264_ENCODING
455 av_frame_unref(sys->hwVideoFrame);
456 if ((status = av_hwframe_get_buffer(sys->codecEncoderContext->hw_frames_ctx,
457 sys->hwVideoFrame, 0)) < 0 ||
458 !sys->hwVideoFrame->hw_frames_ctx)
460 WLog_Print(h264->log, WLOG_ERROR,
"av_hwframe_get_buffer failed (%s [%d])",
461 av_err2str(status), status);
464 sys->videoFrame->format = AV_PIX_FMT_NV12;
465 if ((status = av_hwframe_transfer_data(sys->hwVideoFrame, sys->videoFrame, 0)) < 0)
467 WLog_Print(h264->log, WLOG_ERROR,
"av_hwframe_transfer_data failed (%s [%d])",
468 av_err2str(status), status);
475#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
476#ifdef WITH_VAAPI_H264_ENCODING
477 status = avcodec_send_frame(sys->codecEncoderContext,
478 sys->hwctx ? sys->hwVideoFrame : sys->videoFrame);
480 status = avcodec_send_frame(sys->codecEncoderContext, sys->videoFrame);
485 WLog_Print(h264->log, WLOG_ERROR,
"Failed to encode video frame (%s [%d])",
486 av_err2str(status), status);
490 status = avcodec_receive_packet(sys->codecEncoderContext, sys->packet);
494 WLog_Print(h264->log, WLOG_ERROR,
"Failed to encode video frame (%s [%d])",
495 av_err2str(status), status);
499 gotFrame = (status == 0);
500#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
504 status = avcodec_encode_video2(sys->codecEncoderContext, sys->packet, sys->videoFrame,
506 }
while ((status >= 0) && (gotFrame == 0));
510 avpicture_get_size(sys->codecDecoderContext->pix_fmt, sys->codecDecoderContext->width,
511 sys->codecDecoderContext->height);
512 sys->packet->data = av_malloc(sys->packet->size);
514 if (!sys->packet->data)
518 status = avcodec_encode_video(sys->codecDecoderContext, sys->packet->data,
519 sys->packet->size, sys->videoFrame);
526 WLog_Print(h264->log, WLOG_ERROR,
"Failed to encode video frame (%s [%d])",
527 av_err2str(status), status);
531 WINPR_ASSERT(sys->packet);
532 *ppDstData = sys->packet->data;
533 *pDstSize = (UINT32)MAX(0, sys->packet->size);
537 WLog_Print(h264->log, WLOG_ERROR,
"Did not get frame! (%s [%d])", av_err2str(status),
547static void libavcodec_uninit(H264_CONTEXT* h264)
551 H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
558#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
559 av_packet_unref(sys->packet);
561 av_packet_free(&sys->packet);
567#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
568 av_frame_free(&sys->videoFrame);
570 av_free(sys->videoFrame);
574#if defined(WITH_VAAPI) || defined(WITH_VAAPI_H264_ENCODING) || defined(WITH_VIDEOTOOLBOX)
575 if (sys->hwVideoFrame)
577#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
578 av_frame_free(&sys->hwVideoFrame);
580 av_free(sys->hwVideoFrame);
585 av_buffer_unref(&sys->hwctx);
587#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100) || defined(WITH_VIDEOTOOLBOX)
589 if (sys->hw_frames_ctx)
590 av_buffer_unref(&sys->hw_frames_ctx);
596 if (sys->codecParser)
597 av_parser_close(sys->codecParser);
599 if (sys->codecDecoderContext)
601#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
602 avcodec_free_context(&sys->codecDecoderContext);
604 avcodec_close(sys->codecDecoderContext);
605 av_free(sys->codecDecoderContext);
609 libavcodec_destroy_encoder_context(h264);
611 h264->pSystemData =
nullptr;
614#if defined(WITH_VAAPI) || defined(WITH_VIDEOTOOLBOX)
615static enum AVPixelFormat libavcodec_get_format(
struct AVCodecContext* ctx,
616 const enum AVPixelFormat* fmts)
620 H264_CONTEXT* h264 = (H264_CONTEXT*)ctx->opaque;
623 H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
626 for (
const enum AVPixelFormat* p = fmts; *p != AV_PIX_FMT_NONE; p++)
628 if (*p == sys->hw_pix_fmt)
630#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100) || defined(WITH_VIDEOTOOLBOX)
631 if (sys->hw_frames_ctx)
632 av_buffer_unref(&sys->hw_frames_ctx);
634 sys->hw_frames_ctx = av_hwframe_ctx_alloc(sys->hwctx);
636 if (!sys->hw_frames_ctx)
638 return AV_PIX_FMT_NONE;
641 sys->codecDecoderContext->pix_fmt = *p;
642 AVHWFramesContext* frames = (AVHWFramesContext*)sys->hw_frames_ctx->data;
644 frames->height = sys->codecDecoderContext->coded_height;
645 frames->width = sys->codecDecoderContext->coded_width;
646#ifdef WITH_VIDEOTOOLBOX
647 frames->sw_format = AV_PIX_FMT_YUV420P;
650 (sys->codecDecoderContext->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? AV_PIX_FMT_P010
653 frames->initial_pool_size = 20;
655 if (sys->codecDecoderContext->active_thread_type & FF_THREAD_FRAME)
656 frames->initial_pool_size += sys->codecDecoderContext->thread_count;
658 int err = av_hwframe_ctx_init(sys->hw_frames_ctx);
662 WLog_Print(h264->log, WLOG_ERROR,
"Could not init hwframes context: %s",
664 return AV_PIX_FMT_NONE;
667 sys->codecDecoderContext->hw_frames_ctx = av_buffer_ref(sys->hw_frames_ctx);
673 return AV_PIX_FMT_NONE;
677static BOOL libavcodec_init(H264_CONTEXT* h264)
679 H264_CONTEXT_LIBAVCODEC* sys =
nullptr;
682 sys = (H264_CONTEXT_LIBAVCODEC*)calloc(1,
sizeof(H264_CONTEXT_LIBAVCODEC));
689 h264->pSystemData = (
void*)sys;
691#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
692 avcodec_register_all();
695 if (!h264->Compressor)
697 sys->codecDecoder = avcodec_find_decoder(AV_CODEC_ID_H264);
699 if (!sys->codecDecoder)
701 WLog_Print(h264->log, WLOG_ERROR,
"Failed to find libav H.264 codec");
705 sys->codecDecoderContext = avcodec_alloc_context3(sys->codecDecoder);
707 if (!sys->codecDecoderContext)
709 WLog_Print(h264->log, WLOG_ERROR,
"Failed to allocate libav codec context");
713#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
714 if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
716 sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
724 int ret = av_hwdevice_ctx_create(&sys->hwctx, AV_HWDEVICE_TYPE_VAAPI, VAAPI_DEVICE,
729 WLog_Print(h264->log, WLOG_ERROR,
730 "Could not initialize hardware decoder, falling back to software: %s",
732 sys->hwctx =
nullptr;
733 goto fail_hwdevice_create;
736 WLog_Print(h264->log, WLOG_INFO,
"Using VAAPI for accelerated H264 decoding");
738 sys->codecDecoderContext->get_format = libavcodec_get_format;
739 sys->hw_pix_fmt = AV_PIX_FMT_VAAPI;
740#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 80, 100)
741 sys->codecDecoderContext->hw_device_ctx = av_buffer_ref(sys->hwctx);
743 sys->codecDecoderContext->opaque = (
void*)h264;
744 fail_hwdevice_create:
747#ifdef WITH_VIDEOTOOLBOX
751 int ret = av_hwdevice_ctx_create(&sys->hwctx, AV_HWDEVICE_TYPE_VIDEOTOOLBOX,
nullptr,
757 h264->log, WLOG_ERROR,
758 "Could not initialize VideoToolbox decoder, falling back to software: %s",
760 sys->hwctx =
nullptr;
764 WLog_Print(h264->log, WLOG_INFO,
"Using VideoToolbox for accelerated H264 decoding");
766 sys->codecDecoderContext->get_format = libavcodec_get_format;
767 sys->hw_pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX;
768 sys->codecDecoderContext->hw_device_ctx = av_buffer_ref(sys->hwctx);
769 sys->codecDecoderContext->opaque = (
void*)h264;
773 if (avcodec_open2(sys->codecDecoderContext, sys->codecDecoder,
nullptr) < 0)
775 WLog_Print(h264->log, WLOG_ERROR,
"Failed to open libav codec");
779 sys->codecParser = av_parser_init(AV_CODEC_ID_H264);
781 if (!sys->codecParser)
783 WLog_Print(h264->log, WLOG_ERROR,
"Failed to initialize libav parser");
789#ifdef WITH_VAAPI_H264_ENCODING
792 sys->codecEncoder = avcodec_find_encoder_by_name(
"h264_vaapi");
793 if (!sys->codecEncoder)
795 WLog_Print(h264->log, WLOG_ERROR,
"H264 VAAPI encoder not found");
797 else if (av_hwdevice_ctx_create(&sys->hwctx, AV_HWDEVICE_TYPE_VAAPI, VAAPI_DEVICE,
800 WLog_Print(h264->log, WLOG_ERROR,
"av_hwdevice_ctx_create failed");
801 sys->codecEncoder =
nullptr;
802 sys->hwctx =
nullptr;
806 WLog_Print(h264->log, WLOG_INFO,
"Using VAAPI for accelerated H264 encoding");
810 if (!sys->codecEncoder)
812 sys->codecEncoder = avcodec_find_encoder(AV_CODEC_ID_H264);
813 h264->hwAccel = FALSE;
816 if (!sys->codecEncoder)
818 WLog_Print(h264->log, WLOG_ERROR,
"Failed to initialize H264 encoder");
823#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
824 sys->videoFrame = av_frame_alloc();
825#if defined(WITH_VAAPI) || defined(WITH_VAAPI_H264_ENCODING) || defined(WITH_VIDEOTOOLBOX)
826 sys->hwVideoFrame = av_frame_alloc();
829 sys->videoFrame = avcodec_alloc_frame();
832 if (!sys->videoFrame)
834 WLog_Print(h264->log, WLOG_ERROR,
"Failed to allocate libav frame");
838#if defined(WITH_VAAPI) || defined(WITH_VAAPI_H264_ENCODING) || defined(WITH_VIDEOTOOLBOX)
839 if (!sys->hwVideoFrame)
841 WLog_Print(h264->log, WLOG_ERROR,
"Failed to allocate libav hw frame");
846 sys->videoFrame->pts = 0;
849 libavcodec_uninit(h264);
853const H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec = {
"libavcodec", libavcodec_init,
854 libavcodec_uninit, libavcodec_decompress,
855 libavcodec_compress };