Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

(시리즈 글이 24개 있습니다.)
.NET Framework: 1129. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 인코딩 예제(encode_video.c)
; https://www.sysnet.pe.kr/2/0/12898

.NET Framework: 1134. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 디코딩 예제(decode_video.c)
; https://www.sysnet.pe.kr/2/0/12924

.NET Framework: 1135. C# - ffmpeg(FFmpeg.AutoGen)로 하드웨어 가속기를 이용한 비디오 디코딩 예제(hw_decode.c)
; https://www.sysnet.pe.kr/2/0/12932

.NET Framework: 1136. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 MP2 오디오 파일 디코딩 예제(decode_audio.c)
; https://www.sysnet.pe.kr/2/0/12933

.NET Framework: 1137. ffmpeg의 파일 해시 예제(ffhash.c)를 C#으로 포팅
; https://www.sysnet.pe.kr/2/0/12935

.NET Framework: 1138. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 멀티미디어 파일의 메타데이터를 보여주는 예제(metadata.c)
; https://www.sysnet.pe.kr/2/0/12936

.NET Framework: 1139. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 오디오(mp2) 인코딩하는 예제(encode_audio.c)
; https://www.sysnet.pe.kr/2/0/12937

.NET Framework: 1147. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 오디오 필터링 예제(filtering_audio.c)
; https://www.sysnet.pe.kr/2/0/12951

.NET Framework: 1148. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 오디오 필터 예제(filter_audio.c)
; https://www.sysnet.pe.kr/2/0/12952

.NET Framework: 1150. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 디코딩 예제(decode_video.c) - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/12959

개발 환경 구성: 637. ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 디코딩 예제(decode_video.c) - 세 번째 이야기
; https://www.sysnet.pe.kr/2/0/12960

.NET Framework: 1151. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 프레임의 크기 및 포맷 변경 예제(scaling_video.c)
; https://www.sysnet.pe.kr/2/0/12961

.NET Framework: 1153. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 avio_reading.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12964

.NET Framework: 1157. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 muxing.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12971

.NET Framework: 1159. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 qsvdec.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12975

.NET Framework: 1161. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 resampling_audio.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12978

.NET Framework: 1166. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 filtering_video.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12984

.NET Framework: 1169. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 demuxing_decoding.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12987

.NET Framework: 1170. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 transcode_aac.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/12991

.NET Framework: 1178. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 http_multiclient.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/13002

.NET Framework: 1180. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 remuxing.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/13006

.NET Framework: 1188. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 transcoding.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/13023

.NET Framework: 1190. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 vaapi_encode.c, vaapi_transcode.c 예제 포팅
; https://www.sysnet.pe.kr/2/0/13025

.NET Framework: 1191. C 언어로 작성된 FFmpeg Examples의 C# 포팅 전체 소스 코드
; https://www.sysnet.pe.kr/2/0/13026




C# - ffmpeg(FFmpeg.AutoGen)를 이용한 avio_reading.c 예제 포팅

지난 예제에 이어,

C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 프레임의 크기 및 포맷 변경 예제(scaling_video.c)
; https://www.sysnet.pe.kr/2/0/12961

이번에는 ffmpeg 예제 중 "avio_reading.c" 파일을 FFmpeg.AutoGen으로 포팅하겠습니다.

using FFmpeg.AutoGen;
using FFmpeg.AutoGen.Example;
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;

namespace FFmpegApp1
{
    internal unsafe class Program
    {
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
        static extern void MoveMemory(IntPtr dest, IntPtr src, int size);

        static unsafe int Main(string[] args)
        {
            FFmpegBinariesHelper.RegisterFFmpegBinaries();

#if DEBUG
            Console.WriteLine("Current directory: " + Environment.CurrentDirectory);
            Console.WriteLine("Running in {0}-bit mode.", Environment.Is64BitProcess ? "64" : "32");
            Console.WriteLine($"FFmpeg version info: {ffmpeg.av_version_info()}");
#endif
            Console.WriteLine();

            AVFormatContext* fmt_ctx = null;
            AVIOContext* avio_ctx = null;

            byte* buffer = null;
            byte* avio_ctx_buffer = null;
            ulong buffer_size;
            ulong avio_ctx_buffer_size = 4096;
            
            int ret = 0;
            buffer_data bd = new buffer_data();

            string input_filename = @"D:\media_sample\test.mkv";
            ret = ffmpeg.av_file_map(input_filename, &buffer, &buffer_size, 0, null);
            if (ret < 0)
            {
                return ret;
            }

            bd.ptr = buffer;
            bd.size = (int)buffer_size;

            do
            {
                fmt_ctx = ffmpeg.avformat_alloc_context();
                if (fmt_ctx == null)
                {
                    ret = ffmpeg.AVERROR(ffmpeg.ENOMEM);
                    break;
                }

                avio_ctx_buffer = (byte*)ffmpeg.av_malloc(avio_ctx_buffer_size);
                if (avio_ctx_buffer == null)
                {
                    ret = ffmpeg.AVERROR(ffmpeg.ENOMEM);
                    break;
                }

                avio_ctx = ffmpeg.avio_alloc_context(avio_ctx_buffer, (int)avio_ctx_buffer_size, 0, &bd, 
                    (avio_alloc_context_read_packet_func)read_packet, null, null);
                if (avio_ctx == null)
                {
                    ret = ffmpeg.AVERROR(ffmpeg.ENOMEM);
                    break;
                }

                fmt_ctx->pb = avio_ctx;

                ret = ffmpeg.avformat_open_input(&fmt_ctx, null, null, null);
                if (ret < 0)
                {
                    Console.WriteLine("Could not open input");
                    break;
                }

                ret = ffmpeg.avformat_find_stream_info(fmt_ctx, null);
                if (ret < 0)
                {
                    Console.WriteLine("Could not find stream information");
                    break;
                }

                ffmpeg.av_dump_format(fmt_ctx, 0, input_filename, 0);

            } while (false);

            if (fmt_ctx != null)
            {
                ffmpeg.avformat_close_input(&fmt_ctx);
            }

            if (avio_ctx != null)
            {
                ffmpeg.av_freep(&avio_ctx->buffer);
                ffmpeg.avio_context_free(&avio_ctx);
            }

            ffmpeg.av_file_unmap(buffer, buffer_size);

            return ret;
        }

        static unsafe int read_packet(void *opaque, byte* buf, int buf_size)
        {
            buffer_data* bd = (buffer_data*)opaque;
            buf_size = (int)Math.Min(buf_size, bd->size);

            if (buf_size == 0)
            {
                return ffmpeg.AVERROR_EOF;
            }

            Console.WriteLine($"ptr:{new IntPtr(bd->ptr):x} size:{bd->size}");

            MoveMemory(new IntPtr(buf), new IntPtr(bd->ptr), buf_size);
            bd->ptr += buf_size;
            bd->size -= buf_size;

            return buf_size;
        }
    }

    public unsafe struct buffer_data
    {
        public byte* ptr;
        public int size;
    }
}

이런 식의 제어가 언제 필요한지는 모르겠지만, 일단 실행하면 avformat_find_stream_info 등의 함수를 실행하는 중에 read_packet 메서드가 콜백이 되어 다음과 같은 출력이 나옵니다.

ptr:1b27a880000 size:75337278
ptr:1b27a881000 size:75333182
ptr:1b27a88acff size:75292991
ptr:1b27a88bcff size:75288895
ptr:1b27a8907bb size:75269763
ptr:1b27a8917bb size:75265667

그리고 av_dump_format의 호출에 대한 출력은 예제의 특성과는 별 상관이 없습니다.

Input #0, matroska,webm, from 'D:\media_sample\test.mkv':
  Metadata:
    COMPATIBLE_BRANDS: iso6avc1mp41
    MAJOR_BRAND     : dash
    MINOR_VERSION   : 0
    ENCODER         : Lavf58.45.100
  Duration: 00:03:07.98, start: -0.007000, bitrate: N/A
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
    Metadata:
      HANDLER_NAME    : ISO Media file produced by Google Inc.
      DURATION        : 00:03:07.954000000
  Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
    Metadata:
      DURATION        : 00:03:07.981000000

(첨부 파일은 이 글의 예제 코드를 포함합니다.)
(이 글의 소스 코드는 github에 올려져 있습니다.)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 2/24/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  154  155  156  157  158  159  160  161  162  163  164  [165]  ...
NoWriterDateCnt.TitleFile(s)
919정성태8/30/201040757DDK: 1. Visual Studio 2010 - Device Driver 제작- Hello World 예제 [3]파일 다운로드1
918정성태8/28/201026920개발 환경 구성: 87. Hyper-V의 네트워크 유형 (3)
917정성태8/26/201021903개발 환경 구성: 86. "Routing and Remote Access"의 "Routing" 기능 활성화 방법
916정성태8/25/201021137개발 환경 구성: 85. 가상 네트워크에 LAN 어댑터 보이거나 감추는 방법
915정성태8/24/201039265개발 환경 구성: 84. Hyper-V의 네트워크 유형 (2)
913정성태8/22/201028384오류 유형: 104. Hyper-V 관리자 - VM 생성 오류 (VHD 생성 오류)
912정성태8/20/201030312.NET Framework: 183. 구조체 포인터 인자에 대한 P/Invoke 정의파일 다운로드1
911정성태8/19/201027164오류 유형: 103. System.Reflection.TargetException파일 다운로드1
910정성태8/19/201037981개발 환경 구성: 83. Hyper-V의 네트워크 유형 (1)
909정성태8/18/201033343오류 유형: 102. System.MissingMethodException
908정성태8/17/201024374개발 환경 구성: 82. Windows Virtual PC의 네트워크 유형 (3)
907정성태8/14/201021912개발 환경 구성: 81. Windows Virtual PC의 네트워크 유형 (2)
906정성태8/13/201030792개발 환경 구성: 80. Windows Virtual PC의 네트워크 유형 (1)
905정성태8/8/201032938Team Foundation Server: 39. 배치 파일로 팀 빌드 구성 [2]파일 다운로드1
904정성태8/8/201035709오류 유형: 101. SignTool Error: No certificates were found that met all the given criteria. [2]
903정성태8/6/201032569Team Foundation Server: 38. TFS 소스 코드 관리 기능 (4) - Branch
902정성태8/5/201024912Team Foundation Server: 37. TFS 2010의 소스 서버 수작업 구성
901정성태8/4/201024206Team Foundation Server: 36. TFS 소스 코드 관리 기능 (3) - Label
900정성태8/3/201026888Team Foundation Server: 35. TFS 소스 코드 관리 기능 (2) - Shelveset
899정성태8/2/201028926Team Foundation Server: 34. TFS 소스 코드 관리 기능 (1) - Changeset
898정성태7/31/201028453.NET Framework: 182. WCF의 InactivityTimeout [1]파일 다운로드1
897정성태7/26/201129671.NET Framework: 181. AssemblyVersion, AssemblyFileVersion, AssemblyInformationalVersion [4]
896정성태7/25/201036464.NET Framework: 180. C# Singleton 인스턴스 생성 [2]
895정성태7/25/201020324VS.NET IDE: 68. Visual Studio 2010 - .NET 1.1 원격 디버깅
894정성태7/25/201026237오류 유형: 100. Could not find the Database Engine startup handle. [1]
893정성태7/25/201027387오류 유형: 99. .NET 4.0 설치된 윈도우 7에서 SQL Server 2008 R2 설치 오류
... 151  152  153  154  155  156  157  158  159  160  161  162  163  164  [165]  ...