FreeRDP
h264_ffmpeg.c
1 
21 #include <freerdp/config.h>
22 
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>
28 
29 #include "h264.h"
30 
31 #ifdef WITH_VAAPI
32 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 9, 0)
33 #include <libavutil/hwcontext.h>
34 #else
35 #pragma warning You have asked for VA - API decoding, \
36  but your version of libavutil is too old !Disabling.
37 #undef WITH_VAAPI
38 #endif
39 #endif
40 
41 /* Fallback support for older libavcodec versions */
42 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
43 #define AV_CODEC_ID_H264 CODEC_ID_H264
44 #endif
45 
46 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 34, 2)
47 #define AV_CODEC_FLAG_LOOP_FILTER CODEC_FLAG_LOOP_FILTER
48 #define AV_CODEC_CAP_TRUNCATED CODEC_CAP_TRUNCATED
49 #define AV_CODEC_FLAG_TRUNCATED CODEC_FLAG_TRUNCATED
50 #endif
51 
52 #if LIBAVUTIL_VERSION_MAJOR < 52
53 #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
54 #endif
55 
56 /* Ubuntu 14.04 ships without the functions provided by avutil,
57  * so define error to string methods here. */
58 #if !defined(av_err2str)
59 static inline char* error_string(char* errbuf, size_t errbuf_size, int errnum)
60 {
61  av_strerror(errnum, errbuf, errbuf_size);
62  return errbuf;
63 }
64 
65 #define av_err2str(errnum) error_string((char[64]){ 0 }, 64, errnum)
66 #endif
67 
68 #ifdef WITH_VAAPI
69 #define VAAPI_DEVICE "/dev/dri/renderD128"
70 #endif
71 
72 typedef struct
73 {
74  const AVCodec* codecDecoder;
75  AVCodecContext* codecDecoderContext;
76  const AVCodec* codecEncoder;
77  AVCodecContext* codecEncoderContext;
78  AVCodecParserContext* codecParser;
79  AVFrame* videoFrame;
80 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
81  AVPacket bufferpacket;
82 #endif
83  AVPacket* packet;
84 #ifdef WITH_VAAPI
85  AVBufferRef* hwctx;
86  AVFrame* hwVideoFrame;
87  enum AVPixelFormat hw_pix_fmt;
88 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100)
89  AVBufferRef* hw_frames_ctx;
90 #endif
91 #endif
92 } H264_CONTEXT_LIBAVCODEC;
93 
94 static void libavcodec_destroy_encoder(H264_CONTEXT* WINPR_RESTRICT h264)
95 {
96  H264_CONTEXT_LIBAVCODEC* sys = NULL;
97 
98  if (!h264 || !h264->subsystem)
99  return;
100 
101  sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
102 
103  if (sys->codecEncoderContext)
104  {
105  avcodec_close(sys->codecEncoderContext);
106 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
107  avcodec_free_context(&sys->codecEncoderContext);
108 #else
109  av_free(sys->codecEncoderContext);
110 #endif
111  }
112 
113  sys->codecEncoder = NULL;
114  sys->codecEncoderContext = NULL;
115 }
116 
117 static BOOL libavcodec_create_encoder(H264_CONTEXT* WINPR_RESTRICT h264)
118 {
119  BOOL recreate = FALSE;
120  H264_CONTEXT_LIBAVCODEC* sys = NULL;
121 
122  if (!h264 || !h264->subsystem)
123  return FALSE;
124 
125  if ((h264->width > INT_MAX) || (h264->height > INT_MAX))
126  return FALSE;
127 
128  sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
129  if (!sys)
130  return FALSE;
131  recreate = !sys->codecEncoder || !sys->codecEncoderContext;
132 
133  if (sys->codecEncoderContext)
134  {
135  if ((sys->codecEncoderContext->width != (int)h264->width) ||
136  (sys->codecEncoderContext->height != (int)h264->height))
137  recreate = TRUE;
138  }
139 
140  if (!recreate)
141  return TRUE;
142 
143  libavcodec_destroy_encoder(h264);
144  sys->codecEncoder = avcodec_find_encoder(AV_CODEC_ID_H264);
145 
146  if (!sys->codecEncoder)
147  goto EXCEPTION;
148 
149  sys->codecEncoderContext = avcodec_alloc_context3(sys->codecEncoder);
150 
151  if (!sys->codecEncoderContext)
152  goto EXCEPTION;
153 
154  switch (h264->RateControlMode)
155  {
156  case H264_RATECONTROL_VBR:
157  sys->codecEncoderContext->bit_rate = h264->BitRate;
158  break;
159 
160  case H264_RATECONTROL_CQP:
161  /* TODO: sys->codecEncoderContext-> = h264->QP; */
162  break;
163 
164  default:
165  break;
166  }
167 
168  sys->codecEncoderContext->width = (int)MIN(INT32_MAX, h264->width);
169  sys->codecEncoderContext->height = (int)MIN(INT32_MAX, h264->height);
170  sys->codecEncoderContext->delay = 0;
171 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 13, 100)
172  sys->codecEncoderContext->framerate = (AVRational){ h264->FrameRate, 1 };
173 #endif
174  sys->codecEncoderContext->time_base = (AVRational){ 1, h264->FrameRate };
175  av_opt_set(sys->codecEncoderContext, "preset", "medium", AV_OPT_SEARCH_CHILDREN);
176  av_opt_set(sys->codecEncoderContext, "tune", "zerolatency", AV_OPT_SEARCH_CHILDREN);
177  sys->codecEncoderContext->flags |= AV_CODEC_FLAG_LOOP_FILTER;
178  sys->codecEncoderContext->pix_fmt = AV_PIX_FMT_YUV420P;
179 
180  if (avcodec_open2(sys->codecEncoderContext, sys->codecEncoder, NULL) < 0)
181  goto EXCEPTION;
182 
183  return TRUE;
184 EXCEPTION:
185  libavcodec_destroy_encoder(h264);
186  return FALSE;
187 }
188 
189 static int libavcodec_decompress(H264_CONTEXT* WINPR_RESTRICT h264,
190  const BYTE* WINPR_RESTRICT pSrcData, UINT32 SrcSize)
191 {
192  union
193  {
194  const BYTE* cpv;
195  BYTE* pv;
196  } cnv;
197  int rc = -1;
198  int status = 0;
199  int gotFrame = 0;
200  AVPacket* packet = NULL;
201 
202  WINPR_ASSERT(h264);
203  WINPR_ASSERT(pSrcData || (SrcSize == 0));
204 
205  H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
206  BYTE** pYUVData = h264->pYUVData;
207  UINT32* iStride = h264->iStride;
208 
209  WINPR_ASSERT(sys);
210 
211 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
212  packet = &sys->bufferpacket;
213  WINPR_ASSERT(packet);
214  av_init_packet(packet);
215 #else
216  packet = av_packet_alloc();
217 #endif
218  if (!packet)
219  {
220  WLog_Print(h264->log, WLOG_ERROR, "Failed to allocate AVPacket");
221  goto fail;
222  }
223 
224  cnv.cpv = pSrcData;
225  packet->data = cnv.pv;
226  packet->size = (int)MIN(SrcSize, INT32_MAX);
227 
228  WINPR_ASSERT(sys->codecDecoderContext);
229  /* avcodec_decode_video2 is deprecated with libavcodec 57.48.101 */
230 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
231  status = avcodec_send_packet(sys->codecDecoderContext, packet);
232 
233  if (status < 0)
234  {
235  WLog_Print(h264->log, WLOG_ERROR, "Failed to decode video frame (status=%d)", status);
236  goto fail;
237  }
238 
239  sys->videoFrame->format = AV_PIX_FMT_YUV420P;
240 
241  do
242  {
243 #ifdef WITH_VAAPI
244  status = avcodec_receive_frame(sys->codecDecoderContext,
245  sys->hwctx ? sys->hwVideoFrame : sys->videoFrame);
246 #else
247  status = avcodec_receive_frame(sys->codecDecoderContext, sys->videoFrame);
248 #endif
249  } while (status == AVERROR(EAGAIN));
250 
251  gotFrame = (status == 0);
252 #else
253 #ifdef WITH_VAAPI
254  status =
255  avcodec_decode_video2(sys->codecDecoderContext,
256  sys->hwctx ? sys->hwVideoFrame : sys->videoFrame, &gotFrame, packet);
257 #else
258  status = avcodec_decode_video2(sys->codecDecoderContext, sys->videoFrame, &gotFrame, packet);
259 #endif
260 #endif
261  if (status < 0)
262  {
263  WLog_Print(h264->log, WLOG_ERROR, "Failed to decode video frame (status=%d)", status);
264  goto fail;
265  }
266 
267 #ifdef WITH_VAAPI
268 
269  if (sys->hwctx)
270  {
271  if (sys->hwVideoFrame->format == sys->hw_pix_fmt)
272  {
273  sys->videoFrame->width = sys->hwVideoFrame->width;
274  sys->videoFrame->height = sys->hwVideoFrame->height;
275  status = av_hwframe_transfer_data(sys->videoFrame, sys->hwVideoFrame, 0);
276  }
277  else
278  {
279  status = av_frame_copy(sys->videoFrame, sys->hwVideoFrame);
280  }
281  }
282 
283  gotFrame = (status == 0);
284 
285  if (status < 0)
286  {
287  WLog_Print(h264->log, WLOG_ERROR, "Failed to transfer video frame (status=%d) (%s)", status,
288  av_err2str(status));
289  goto fail;
290  }
291 
292 #endif
293 #if 0
294  WLog_Print(h264->log, WLOG_INFO,
295  "libavcodec_decompress: frame decoded (status=%d, gotFrame=%d, width=%d, height=%d, Y=[%p,%d], U=[%p,%d], V=[%p,%d])",
296  status, gotFrame, sys->videoFrame->width, sys->videoFrame->height,
297  (void*) sys->videoFrame->data[0], sys->videoFrame->linesize[0],
298  (void*) sys->videoFrame->data[1], sys->videoFrame->linesize[1],
299  (void*) sys->videoFrame->data[2], sys->videoFrame->linesize[2]);
300 #endif
301 
302  if (gotFrame)
303  {
304  WINPR_ASSERT(sys->videoFrame);
305 
306  pYUVData[0] = sys->videoFrame->data[0];
307  pYUVData[1] = sys->videoFrame->data[1];
308  pYUVData[2] = sys->videoFrame->data[2];
309  iStride[0] = (UINT32)MAX(0, sys->videoFrame->linesize[0]);
310  iStride[1] = (UINT32)MAX(0, sys->videoFrame->linesize[1]);
311  iStride[2] = (UINT32)MAX(0, sys->videoFrame->linesize[2]);
312 
313  rc = 1;
314  }
315  else
316  rc = -2;
317 
318 fail:
319 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
320  av_packet_unref(packet);
321 #else
322  av_packet_free(&packet);
323 #endif
324 
325  return rc;
326 }
327 
328 static int libavcodec_compress(H264_CONTEXT* WINPR_RESTRICT h264,
329  const BYTE** WINPR_RESTRICT pSrcYuv,
330  const UINT32* WINPR_RESTRICT pStride,
331  BYTE** WINPR_RESTRICT ppDstData, UINT32* WINPR_RESTRICT pDstSize)
332 {
333  union
334  {
335  const BYTE* cpv;
336  uint8_t* pv;
337  } cnv;
338  int rc = -1;
339  int status = 0;
340  int gotFrame = 0;
341 
342  WINPR_ASSERT(h264);
343 
344  H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
345  WINPR_ASSERT(sys);
346 
347  if (!libavcodec_create_encoder(h264))
348  return -1;
349 
350 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
351  sys->packet = &sys->bufferpacket;
352  av_packet_unref(sys->packet);
353  av_init_packet(sys->packet);
354 #else
355  av_packet_free(&sys->packet);
356  sys->packet = av_packet_alloc();
357 #endif
358  if (!sys->packet)
359  {
360  WLog_Print(h264->log, WLOG_ERROR, "Failed to allocate AVPacket");
361  goto fail;
362  }
363 
364  WINPR_ASSERT(sys->packet);
365  sys->packet->data = NULL;
366  sys->packet->size = 0;
367 
368  WINPR_ASSERT(sys->videoFrame);
369  WINPR_ASSERT(sys->codecEncoderContext);
370  sys->videoFrame->format = sys->codecEncoderContext->pix_fmt;
371  sys->videoFrame->width = sys->codecEncoderContext->width;
372  sys->videoFrame->height = sys->codecEncoderContext->height;
373 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 48, 100)
374  sys->videoFrame->colorspace = AVCOL_SPC_BT709;
375 #endif
376 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 92, 100)
377  sys->videoFrame->chroma_location = AVCHROMA_LOC_LEFT;
378 #endif
379  cnv.cpv = pSrcYuv[0];
380  sys->videoFrame->data[0] = cnv.pv;
381 
382  cnv.cpv = pSrcYuv[1];
383  sys->videoFrame->data[1] = cnv.pv;
384 
385  cnv.cpv = pSrcYuv[2];
386  sys->videoFrame->data[2] = cnv.pv;
387 
388  sys->videoFrame->linesize[0] = (int)pStride[0];
389  sys->videoFrame->linesize[1] = (int)pStride[1];
390  sys->videoFrame->linesize[2] = (int)pStride[2];
391  sys->videoFrame->pts++;
392  /* avcodec_encode_video2 is deprecated with libavcodec 57.48.101 */
393 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
394  status = avcodec_send_frame(sys->codecEncoderContext, sys->videoFrame);
395 
396  if (status < 0)
397  {
398  WLog_Print(h264->log, WLOG_ERROR, "Failed to encode video frame (%s [%d])",
399  av_err2str(status), status);
400  goto fail;
401  }
402 
403  status = avcodec_receive_packet(sys->codecEncoderContext, sys->packet);
404 
405  if (status < 0)
406  {
407  WLog_Print(h264->log, WLOG_ERROR, "Failed to encode video frame (%s [%d])",
408  av_err2str(status), status);
409  goto fail;
410  }
411 
412  gotFrame = (status == 0);
413 #elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
414 
415  do
416  {
417  status = avcodec_encode_video2(sys->codecEncoderContext, sys->packet, sys->videoFrame,
418  &gotFrame);
419  } while ((status >= 0) && (gotFrame == 0));
420 
421 #else
422  sys->packet->size =
423  avpicture_get_size(sys->codecDecoderContext->pix_fmt, sys->codecDecoderContext->width,
424  sys->codecDecoderContext->height);
425  sys->packet->data = av_malloc(sys->packet->size);
426 
427  if (!sys->packet->data)
428  status = -1;
429  else
430  {
431  status = avcodec_encode_video(sys->codecDecoderContext, sys->packet->data,
432  sys->packet->size, sys->videoFrame);
433  }
434 
435 #endif
436 
437  if (status < 0)
438  {
439  WLog_Print(h264->log, WLOG_ERROR, "Failed to encode video frame (%s [%d])",
440  av_err2str(status), status);
441  goto fail;
442  }
443 
444  WINPR_ASSERT(sys->packet);
445  *ppDstData = sys->packet->data;
446  *pDstSize = (UINT32)MAX(0, sys->packet->size);
447 
448  if (!gotFrame)
449  {
450  WLog_Print(h264->log, WLOG_ERROR, "Did not get frame! (%s [%d])", av_err2str(status),
451  status);
452  rc = -2;
453  }
454  else
455  rc = 1;
456 fail:
457  return rc;
458 }
459 
460 static void libavcodec_uninit(H264_CONTEXT* h264)
461 {
462  WINPR_ASSERT(h264);
463 
464  H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
465 
466  if (!sys)
467  return;
468 
469  if (sys->packet)
470  {
471 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 133, 100)
472  av_packet_unref(sys->packet);
473 #else
474  av_packet_free(&sys->packet);
475 #endif
476  }
477 
478  if (sys->videoFrame)
479  {
480 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
481  av_frame_free(&sys->videoFrame);
482 #else
483  av_free(sys->videoFrame);
484 #endif
485  }
486 
487 #ifdef WITH_VAAPI
488 
489  if (sys->hwVideoFrame)
490  {
491 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
492  av_frame_free(&sys->hwVideoFrame);
493 #else
494  av_free(sys->hwVideoFrame);
495 #endif
496  }
497 
498  if (sys->hwctx)
499  av_buffer_unref(&sys->hwctx);
500 
501 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100)
502 
503  if (sys->hw_frames_ctx)
504  av_buffer_unref(&sys->hw_frames_ctx);
505 
506 #endif
507 #endif
508 
509  if (sys->codecParser)
510  av_parser_close(sys->codecParser);
511 
512  if (sys->codecDecoderContext)
513  {
514  avcodec_close(sys->codecDecoderContext);
515 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
516  avcodec_free_context(&sys->codecDecoderContext);
517 #else
518  av_free(sys->codecDecoderContext);
519 #endif
520  }
521 
522  libavcodec_destroy_encoder(h264);
523  free(sys);
524  h264->pSystemData = NULL;
525 }
526 
527 #ifdef WITH_VAAPI
528 static enum AVPixelFormat libavcodec_get_format(struct AVCodecContext* ctx,
529  const enum AVPixelFormat* fmts)
530 {
531  WINPR_ASSERT(ctx);
532 
533  H264_CONTEXT* h264 = (H264_CONTEXT*)ctx->opaque;
534  WINPR_ASSERT(h264);
535 
536  H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*)h264->pSystemData;
537  WINPR_ASSERT(sys);
538 
539  for (const enum AVPixelFormat* p = fmts; *p != AV_PIX_FMT_NONE; p++)
540  {
541  if (*p == sys->hw_pix_fmt)
542  {
543 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 80, 100)
544  sys->hw_frames_ctx = av_hwframe_ctx_alloc(sys->hwctx);
545 
546  if (!sys->hw_frames_ctx)
547  {
548  return AV_PIX_FMT_NONE;
549  }
550 
551  sys->codecDecoderContext->pix_fmt = *p;
552  AVHWFramesContext* frames = (AVHWFramesContext*)sys->hw_frames_ctx->data;
553  frames->format = *p;
554  frames->height = sys->codecDecoderContext->coded_height;
555  frames->width = sys->codecDecoderContext->coded_width;
556  frames->sw_format =
557  (sys->codecDecoderContext->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ? AV_PIX_FMT_P010
558  : AV_PIX_FMT_NV12);
559  frames->initial_pool_size = 20;
560 
561  if (sys->codecDecoderContext->active_thread_type & FF_THREAD_FRAME)
562  frames->initial_pool_size += sys->codecDecoderContext->thread_count;
563 
564  int err = av_hwframe_ctx_init(sys->hw_frames_ctx);
565 
566  if (err < 0)
567  {
568  WLog_Print(h264->log, WLOG_ERROR, "Could not init hwframes context: %s",
569  av_err2str(err));
570  return AV_PIX_FMT_NONE;
571  }
572 
573  sys->codecDecoderContext->hw_frames_ctx = av_buffer_ref(sys->hw_frames_ctx);
574 #endif
575  return *p;
576  }
577  }
578 
579  return AV_PIX_FMT_NONE;
580 }
581 #endif
582 
583 static BOOL libavcodec_init(H264_CONTEXT* h264)
584 {
585  H264_CONTEXT_LIBAVCODEC* sys = NULL;
586 
587  WINPR_ASSERT(h264);
588  sys = (H264_CONTEXT_LIBAVCODEC*)calloc(1, sizeof(H264_CONTEXT_LIBAVCODEC));
589 
590  if (!sys)
591  {
592  goto EXCEPTION;
593  }
594 
595  h264->pSystemData = (void*)sys;
596 
597 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
598  avcodec_register_all();
599 #endif
600 
601  if (!h264->Compressor)
602  {
603  sys->codecDecoder = avcodec_find_decoder(AV_CODEC_ID_H264);
604 
605  if (!sys->codecDecoder)
606  {
607  WLog_Print(h264->log, WLOG_ERROR, "Failed to find libav H.264 codec");
608  goto EXCEPTION;
609  }
610 
611  sys->codecDecoderContext = avcodec_alloc_context3(sys->codecDecoder);
612 
613  if (!sys->codecDecoderContext)
614  {
615  WLog_Print(h264->log, WLOG_ERROR, "Failed to allocate libav codec context");
616  goto EXCEPTION;
617  }
618 
619 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
620  if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
621  {
622  sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
623  }
624 #endif
625 
626 #ifdef WITH_VAAPI
627 
628  if (!sys->hwctx)
629  {
630  int ret =
631  av_hwdevice_ctx_create(&sys->hwctx, AV_HWDEVICE_TYPE_VAAPI, VAAPI_DEVICE, NULL, 0);
632 
633  if (ret < 0)
634  {
635  WLog_Print(h264->log, WLOG_ERROR,
636  "Could not initialize hardware decoder, falling back to software: %s",
637  av_err2str(ret));
638  sys->hwctx = NULL;
639  goto fail_hwdevice_create;
640  }
641  }
642  WLog_Print(h264->log, WLOG_INFO, "Using VAAPI for accelerated H264 decoding");
643 
644  sys->codecDecoderContext->get_format = libavcodec_get_format;
645  sys->hw_pix_fmt = AV_PIX_FMT_VAAPI;
646 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 80, 100)
647  sys->codecDecoderContext->hw_device_ctx = av_buffer_ref(sys->hwctx);
648 #endif
649  sys->codecDecoderContext->opaque = (void*)h264;
650  fail_hwdevice_create:
651 #endif
652 
653  if (avcodec_open2(sys->codecDecoderContext, sys->codecDecoder, NULL) < 0)
654  {
655  WLog_Print(h264->log, WLOG_ERROR, "Failed to open libav codec");
656  goto EXCEPTION;
657  }
658 
659  sys->codecParser = av_parser_init(AV_CODEC_ID_H264);
660 
661  if (!sys->codecParser)
662  {
663  WLog_Print(h264->log, WLOG_ERROR, "Failed to initialize libav parser");
664  goto EXCEPTION;
665  }
666  }
667 
668 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102)
669  sys->videoFrame = av_frame_alloc();
670 #ifdef WITH_VAAPI
671  sys->hwVideoFrame = av_frame_alloc();
672 #endif
673 #else
674  sys->videoFrame = avcodec_alloc_frame();
675 #endif
676 
677  if (!sys->videoFrame)
678  {
679  WLog_Print(h264->log, WLOG_ERROR, "Failed to allocate libav frame");
680  goto EXCEPTION;
681  }
682 
683 #ifdef WITH_VAAPI
684 
685  if (!sys->hwVideoFrame)
686  {
687  WLog_Print(h264->log, WLOG_ERROR, "Failed to allocate libav hw frame");
688  goto EXCEPTION;
689  }
690 
691 #endif
692  sys->videoFrame->pts = 0;
693  return TRUE;
694 EXCEPTION:
695  libavcodec_uninit(h264);
696  return FALSE;
697 }
698 
699 const H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec = { "libavcodec", libavcodec_init,
700  libavcodec_uninit, libavcodec_decompress,
701  libavcodec_compress };