Advertisement
hamidi2

Untitled

Mar 12th, 2019
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.21 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using System.Diagnostics;
  7. using System.Drawing;
  8. using System.Drawing.Imaging;
  9. using System.IO;
  10. using FFmpeg.AutoGen;
  11.  
  12. namespace player.cs.console
  13. {
  14.     class Program
  15.     {
  16.         static void Main(string[] args)
  17.         {
  18.             play(args);
  19.         }
  20.  
  21.         enum FrameType
  22.         {
  23.             FRAME_TYPE_HEADER,
  24.             FRAME_TYPE_STREAM,
  25.             FRAME_TYPE_METADATA,
  26.             FRAME_TYPE_NOFRAME,
  27.         };
  28.  
  29.         [StructLayout(LayoutKind.Sequential, Pack = 1)]
  30.         unsafe struct RecordFrame
  31.         {
  32.             public Int64 timestamp;
  33.             public Int32 frameType;
  34.             public Int32 frameSize;
  35.             public Int16 motionLevel;
  36.             public Int32 flags;
  37.             private fixed byte extraData[20];
  38.         };
  39.  
  40.         [StructLayout(LayoutKind.Sequential, Pack = 1)]
  41.         struct RecordHeader
  42.         {
  43.             public Int16 width;
  44.             public Int16 height;
  45.             public Int32 pixelFormat;
  46.             public Int32 codecId;
  47.             public Int32 timebaseNum;
  48.             public Int32 timebaseDen;
  49.         };
  50.  
  51.         private static unsafe AVCodec* _pCodec;
  52.         private static unsafe AVBufferRef* hw_device_ctx;
  53.         private static AVPixelFormat hw_pix_fmt;
  54.  
  55.         static unsafe int hw_play(byte* buf, int pos, int len, Int64 firstTimestamp)
  56.         {
  57.             FFmpegInvoke.AVHWDeviceType type = FFmpegInvoke.av_hwdevice_find_type_by_name("dxva2");
  58.             Debug.Assert(type != FFmpegInvoke.AVHWDeviceType.AV_HWDEVICE_TYPE_NONE);
  59.             AVCodecID codecId = AVCodecID.AV_CODEC_ID_H264;
  60.             _pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
  61.             Debug.Assert(_pCodec != null);
  62.             for (int i = 0; ; i++)
  63.             {
  64.                 FFmpegInvoke.AVCodecHWConfig* config = FFmpegInvoke.avcodec_get_hw_config(_pCodec, i);
  65.                 Debug.Assert(config != null);
  66.                 if ((config->methods & (int)FFmpegInvoke.CodecHWConfig.AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
  67.                     config->device_type == type)
  68.                 {
  69.                     hw_pix_fmt = config->pix_fmt;
  70.                     break;
  71.                 }
  72.             }
  73.             AVCodecContext* _pCodecContext = FFmpegInvoke.avcodec_alloc_context3(_pCodec);
  74.             Debug.Assert(_pCodecContext != null);
  75.             //_pCodecContext->get_format = get_hw_format;
  76.             fixed (AVBufferRef** pDeviceCtx = &hw_device_ctx)
  77.                 Debug.Assert(FFmpegInvoke.av_hwdevice_ctx_create(pDeviceCtx, type, null, null, 0) == 0);
  78.             _pCodecContext->hw_device_ctx = FFmpegInvoke.av_buffer_ref(hw_device_ctx);
  79.             Debug.Assert(FFmpegInvoke.avcodec_open2(_pCodecContext, _pCodec, null) == 0);
  80.             _pCodecContext->codec_id = codecId;
  81.             _pCodecContext->time_base.num = 1;
  82.             _pCodecContext->time_base.den = 1000;
  83.             if ((_pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) != 0)
  84.                 _pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;
  85.             _pCodecContext->width = 1280;
  86.             _pCodecContext->height = 720;
  87.             _pCodecContext->pix_fmt = (AVPixelFormat)0;
  88.             AVFrame* frame = FFmpegInvoke.av_frame_alloc();
  89.             Debug.Assert(frame != null);
  90.             RecordFrame* rf;
  91.             AVPacket packet;
  92.             FFmpegInvoke.av_init_packet(&packet);
  93.             AVFrame* _pDecodedFrame = FFmpegInvoke.av_frame_alloc();
  94.             while (true)
  95.             {
  96.                 while (pos != len)
  97.                 {
  98.                     rf = (RecordFrame*)(buf + pos);
  99.                     pos += sizeof(RecordFrame);
  100.                     Debug.Assert(rf->frameType == (int)FrameType.FRAME_TYPE_STREAM);
  101.                     packet.data = buf;
  102.                     packet.size = rf->frameSize;
  103.                     Debug.Assert(packet.size > 0);
  104.                     packet.flags = rf->flags;
  105.                     packet.dts = packet.pts = rf->timestamp - firstTimestamp;
  106.                     packet.stream_index = 0;
  107.  
  108.                     var err = FFmpegInvoke.avcodec_send_packet(_pCodecContext, &packet);
  109.                     Debug.Assert(err == 0);
  110.                     Debug.Assert(FFmpegInvoke.avcodec_receive_frame(_pCodecContext, _pDecodedFrame) == 0);
  111.  
  112.                     //int gotPicture = 0;
  113.                     //int size = FFmpegInvoke.avcodec_decode_video2(_pCodecContext, _pDecodedFrame, &gotPicture, &packet);
  114.                     //Debug.Assert(size == packet.size);
  115.  
  116.                     pos += packet.size;
  117.                 }
  118.                 pos = sizeof(RecordFrame) + sizeof(RecordHeader);
  119.             }
  120.             FFmpegInvoke.av_frame_free(&frame);
  121.         }
  122.  
  123.         static unsafe int sw_play(byte* buf, int pos, int len, Int64 firstTimestamp)
  124.         {
  125.             AVCodecID codecId = AVCodecID.AV_CODEC_ID_H264;
  126.             _pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
  127.             Debug.Assert(_pCodec != null);
  128.             AVCodecContext* _pCodecContext = FFmpegInvoke.avcodec_alloc_context3(_pCodec);
  129.             Debug.Assert(_pCodecContext != null);
  130.             Debug.Assert(FFmpegInvoke.avcodec_open2(_pCodecContext, _pCodec, null) == 0);
  131.             _pCodecContext->codec_id = codecId;
  132.             _pCodecContext->time_base.num = 1;
  133.             _pCodecContext->time_base.den = 1000;
  134.             if ((_pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) != 0)
  135.                 _pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;
  136.             _pCodecContext->width = 1280;
  137.             _pCodecContext->height = 720;
  138.             _pCodecContext->pix_fmt = AVPixelFormat.AV_PIX_FMT_NONE;
  139.             _pCodecContext->sw_pix_fmt = AVPixelFormat.AV_PIX_FMT_NONE;
  140.             _pCodecContext->frame_bits = 1;
  141.             AVFrame* frame = FFmpegInvoke.av_frame_alloc();
  142.             Debug.Assert(frame != null);
  143.             RecordFrame* rf;
  144.             AVPacket packet;
  145.             FFmpegInvoke.av_init_packet(&packet);
  146.             AVFrame* _pDecodedFrame = FFmpegInvoke.av_frame_alloc();
  147.             while (true)
  148.             {
  149.                 while (pos != len)
  150.                 {
  151.                     rf = (RecordFrame*)(buf + pos);
  152.                     pos += sizeof(RecordFrame);
  153.                     Debug.Assert(rf->frameType == (int)FrameType.FRAME_TYPE_STREAM);
  154.                     packet.data = buf;
  155.                     packet.size = rf->frameSize;
  156.                     Debug.Assert(packet.size > 0);
  157.                     packet.flags = rf->flags;
  158.                     packet.dts = packet.pts = rf->timestamp - firstTimestamp;
  159.                     packet.stream_index = 0;
  160.  
  161.                     //var err = FFmpegInvoke.avcodec_send_packet(_pCodecContext, &packet);
  162.                     //Debug.Assert(err == 0);
  163.                     //Debug.Assert(FFmpegInvoke.avcodec_receive_frame(_pCodecContext, _pDecodedFrame) == 0);
  164.  
  165.                     int gotPicture = 0;
  166.                     int size = FFmpegInvoke.avcodec_decode_video2(_pCodecContext, _pDecodedFrame, &gotPicture, &packet);
  167.                     Debug.Assert(size == packet.size);                  var _frameBitmap = new Bitmap(1280, 720, _pDecodedFrame->linesize[0], PixelFormat.Format32bppPArgb, new IntPtr(_pDecodedFrame->data_0));
  168.                     _frameBitmap.Save("first-frame.jpg", ImageFormat.Jpeg);
  169.                     Console.ReadKey();
  170.                     return 0;
  171.  
  172.                     pos += packet.size;
  173.                 }
  174.                 pos = sizeof(RecordFrame) + sizeof(RecordHeader);
  175.             }
  176.             FFmpegInvoke.av_frame_free(&frame);
  177.         }
  178.  
  179.         static unsafe int play(string[] args)
  180.         {
  181.             var fileContent = File.ReadAllBytes("video_files/7711.brf");
  182.             RecordFrame* pRecordFrame;
  183.             RecordHeader* pRecordHeader;
  184.             var pos = 0;
  185.             fixed (byte* buf = fileContent)
  186.             {
  187.                 pRecordFrame = (RecordFrame*)&buf[pos];
  188.                 pos += sizeof(RecordFrame);
  189.                 Debug.Assert(pRecordFrame->frameType == (int)FrameType.FRAME_TYPE_HEADER);
  190.                 Debug.Assert(pRecordFrame->frameSize == sizeof(RecordHeader));
  191.                 pRecordHeader = (RecordHeader*)&buf[pos];
  192.                 Debug.Assert(pRecordHeader->width == 1280);
  193.                 Debug.Assert(pRecordHeader->height == 720);
  194.                 Debug.Assert(pRecordHeader->codecId == 28);
  195.                 Debug.Assert(pRecordHeader->pixelFormat == 0);
  196.                 Debug.Assert(pRecordHeader->timebaseNum == 1);
  197.                 Debug.Assert(pRecordHeader->timebaseDen == 1000);
  198.                 pos += sizeof(RecordHeader);
  199.                 if (args.Length > 1 && args[1] == "hw")
  200.                     hw_play(buf, pos, fileContent.Length, pRecordFrame->timestamp);
  201.                 else
  202.                     sw_play(buf, pos, fileContent.Length, pRecordFrame->timestamp);
  203.             }
  204.             return 0;
  205.         }
  206.     }
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement