FFmpegContext.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using FFmpeg.AutoGen;
  2. using System;
  3. namespace Ryujinx.Graphics.Nvdec.H264
  4. {
  5. unsafe class FFmpegContext : IDisposable
  6. {
  7. private readonly AVCodec* _codec;
  8. private AVPacket* _packet;
  9. private AVCodecContext* _context;
  10. public FFmpegContext()
  11. {
  12. _codec = ffmpeg.avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
  13. _context = ffmpeg.avcodec_alloc_context3(_codec);
  14. ffmpeg.avcodec_open2(_context, _codec, null);
  15. _packet = ffmpeg.av_packet_alloc();
  16. }
  17. public int DecodeFrame(Surface output, ReadOnlySpan<byte> bitstream)
  18. {
  19. // Ensure the packet is clean before proceeding
  20. ffmpeg.av_packet_unref(_packet);
  21. fixed (byte* ptr = bitstream)
  22. {
  23. _packet->data = ptr;
  24. _packet->size = bitstream.Length;
  25. int rc = ffmpeg.avcodec_send_packet(_context, _packet);
  26. if (rc != 0)
  27. {
  28. return rc;
  29. }
  30. }
  31. return ffmpeg.avcodec_receive_frame(_context, output.Frame);
  32. }
  33. public void Dispose()
  34. {
  35. fixed (AVPacket** ppPacket = &_packet)
  36. {
  37. ffmpeg.av_packet_free(ppPacket);
  38. }
  39. ffmpeg.avcodec_close(_context);
  40. fixed (AVCodecContext** ppContext = &_context)
  41. {
  42. ffmpeg.avcodec_free_context(ppContext);
  43. }
  44. }
  45. }
  46. }