Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using FFmpeg.AutoGen;
- namespace player.cs.console
- {
- class Program
- {
- static void Main(string[] args)
- {
- play(args);
- }
- enum FrameType
- {
- FRAME_TYPE_HEADER,
- FRAME_TYPE_STREAM,
- FRAME_TYPE_METADATA,
- FRAME_TYPE_NOFRAME,
- };
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- unsafe struct RecordFrame
- {
- public Int64 timestamp;
- public Int32 frameType;
- public Int32 frameSize;
- public Int16 motionLevel;
- public Int32 flags;
- private fixed byte extraData[20];
- };
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- struct RecordHeader
- {
- public Int16 width;
- public Int16 height;
- public Int32 pixelFormat;
- public Int32 codecId;
- public Int32 timebaseNum;
- public Int32 timebaseDen;
- };
- private static unsafe AVCodec* _pCodec;
- private static unsafe AVBufferRef* hw_device_ctx;
- private static AVPixelFormat hw_pix_fmt;
- static unsafe int hw_play(byte* buf, int pos, int len, Int64 firstTimestamp)
- {
- FFmpegInvoke.AVHWDeviceType type = FFmpegInvoke.av_hwdevice_find_type_by_name("dxva2");
- Debug.Assert(type != FFmpegInvoke.AVHWDeviceType.AV_HWDEVICE_TYPE_NONE);
- AVCodecID codecId = AVCodecID.AV_CODEC_ID_H264;
- _pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
- Debug.Assert(_pCodec != null);
- for (int i = 0; ; i++)
- {
- FFmpegInvoke.AVCodecHWConfig* config = FFmpegInvoke.avcodec_get_hw_config(_pCodec, i);
- Debug.Assert(config != null);
- if ((config->methods & (int)FFmpegInvoke.CodecHWConfig.AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
- config->device_type == type)
- {
- hw_pix_fmt = config->pix_fmt;
- break;
- }
- }
- AVCodecContext* _pCodecContext = FFmpegInvoke.avcodec_alloc_context3(_pCodec);
- Debug.Assert(_pCodecContext != null);
- //_pCodecContext->get_format = get_hw_format;
- fixed (AVBufferRef** pDeviceCtx = &hw_device_ctx)
- Debug.Assert(FFmpegInvoke.av_hwdevice_ctx_create(pDeviceCtx, type, null, null, 0) == 0);
- _pCodecContext->hw_device_ctx = FFmpegInvoke.av_buffer_ref(hw_device_ctx);
- Debug.Assert(FFmpegInvoke.avcodec_open2(_pCodecContext, _pCodec, null) == 0);
- _pCodecContext->codec_id = codecId;
- _pCodecContext->time_base.num = 1;
- _pCodecContext->time_base.den = 1000;
- if ((_pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) != 0)
- _pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;
- _pCodecContext->width = 1280;
- _pCodecContext->height = 720;
- _pCodecContext->pix_fmt = (AVPixelFormat)0;
- AVFrame* frame = FFmpegInvoke.av_frame_alloc();
- Debug.Assert(frame != null);
- RecordFrame* rf;
- AVPacket packet;
- FFmpegInvoke.av_init_packet(&packet);
- AVFrame* _pDecodedFrame = FFmpegInvoke.av_frame_alloc();
- while (true)
- {
- while (pos != len)
- {
- rf = (RecordFrame*)(buf + pos);
- pos += sizeof(RecordFrame);
- Debug.Assert(rf->frameType == (int)FrameType.FRAME_TYPE_STREAM);
- packet.data = buf;
- packet.size = rf->frameSize;
- Debug.Assert(packet.size > 0);
- packet.flags = rf->flags;
- packet.dts = packet.pts = rf->timestamp - firstTimestamp;
- packet.stream_index = 0;
- var err = FFmpegInvoke.avcodec_send_packet(_pCodecContext, &packet);
- Debug.Assert(err == 0);
- Debug.Assert(FFmpegInvoke.avcodec_receive_frame(_pCodecContext, _pDecodedFrame) == 0);
- //int gotPicture = 0;
- //int size = FFmpegInvoke.avcodec_decode_video2(_pCodecContext, _pDecodedFrame, &gotPicture, &packet);
- //Debug.Assert(size == packet.size);
- pos += packet.size;
- }
- pos = sizeof(RecordFrame) + sizeof(RecordHeader);
- }
- FFmpegInvoke.av_frame_free(&frame);
- }
- static unsafe int sw_play(byte* buf, int pos, int len, Int64 firstTimestamp)
- {
- AVCodecID codecId = AVCodecID.AV_CODEC_ID_H264;
- _pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
- Debug.Assert(_pCodec != null);
- AVCodecContext* _pCodecContext = FFmpegInvoke.avcodec_alloc_context3(_pCodec);
- Debug.Assert(_pCodecContext != null);
- Debug.Assert(FFmpegInvoke.avcodec_open2(_pCodecContext, _pCodec, null) == 0);
- _pCodecContext->codec_id = codecId;
- _pCodecContext->time_base.num = 1;
- _pCodecContext->time_base.den = 1000;
- if ((_pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) != 0)
- _pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;
- _pCodecContext->width = 1280;
- _pCodecContext->height = 720;
- _pCodecContext->pix_fmt = AVPixelFormat.AV_PIX_FMT_NONE;
- _pCodecContext->sw_pix_fmt = AVPixelFormat.AV_PIX_FMT_NONE;
- _pCodecContext->frame_bits = 1;
- AVFrame* frame = FFmpegInvoke.av_frame_alloc();
- Debug.Assert(frame != null);
- RecordFrame* rf;
- AVPacket packet;
- FFmpegInvoke.av_init_packet(&packet);
- AVFrame* _pDecodedFrame = FFmpegInvoke.av_frame_alloc();
- while (true)
- {
- while (pos != len)
- {
- rf = (RecordFrame*)(buf + pos);
- pos += sizeof(RecordFrame);
- Debug.Assert(rf->frameType == (int)FrameType.FRAME_TYPE_STREAM);
- packet.data = buf;
- packet.size = rf->frameSize;
- Debug.Assert(packet.size > 0);
- packet.flags = rf->flags;
- packet.dts = packet.pts = rf->timestamp - firstTimestamp;
- packet.stream_index = 0;
- //var err = FFmpegInvoke.avcodec_send_packet(_pCodecContext, &packet);
- //Debug.Assert(err == 0);
- //Debug.Assert(FFmpegInvoke.avcodec_receive_frame(_pCodecContext, _pDecodedFrame) == 0);
- int gotPicture = 0;
- int size = FFmpegInvoke.avcodec_decode_video2(_pCodecContext, _pDecodedFrame, &gotPicture, &packet);
- Debug.Assert(size == packet.size); var _frameBitmap = new Bitmap(1280, 720, _pDecodedFrame->linesize[0], PixelFormat.Format32bppPArgb, new IntPtr(_pDecodedFrame->data_0));
- _frameBitmap.Save("first-frame.jpg", ImageFormat.Jpeg);
- Console.ReadKey();
- return 0;
- pos += packet.size;
- }
- pos = sizeof(RecordFrame) + sizeof(RecordHeader);
- }
- FFmpegInvoke.av_frame_free(&frame);
- }
- static unsafe int play(string[] args)
- {
- var fileContent = File.ReadAllBytes("video_files/7711.brf");
- RecordFrame* pRecordFrame;
- RecordHeader* pRecordHeader;
- var pos = 0;
- fixed (byte* buf = fileContent)
- {
- pRecordFrame = (RecordFrame*)&buf[pos];
- pos += sizeof(RecordFrame);
- Debug.Assert(pRecordFrame->frameType == (int)FrameType.FRAME_TYPE_HEADER);
- Debug.Assert(pRecordFrame->frameSize == sizeof(RecordHeader));
- pRecordHeader = (RecordHeader*)&buf[pos];
- Debug.Assert(pRecordHeader->width == 1280);
- Debug.Assert(pRecordHeader->height == 720);
- Debug.Assert(pRecordHeader->codecId == 28);
- Debug.Assert(pRecordHeader->pixelFormat == 0);
- Debug.Assert(pRecordHeader->timebaseNum == 1);
- Debug.Assert(pRecordHeader->timebaseDen == 1000);
- pos += sizeof(RecordHeader);
- if (args.Length > 1 && args[1] == "hw")
- hw_play(buf, pos, fileContent.Length, pRecordFrame->timestamp);
- else
- sw_play(buf, pos, fileContent.Length, pRecordFrame->timestamp);
- }
- return 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement