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)
1065정성태6/13/201137262개발 환경 구성: 125. Firebird - 유니코드 기본 문자셋 지정
1064정성태6/11/201131726웹: 22. Visual Studio 2010에서 CSS 3 인텔리센스(intellisense) 지원하는 방법 [1]
1063정성태6/10/201133488웹: 21. Sysnet 웹 사이트의 CSS 2.1 변환 기록 [1]
1062정성태6/9/201133657웹: 20. Sysnet 웹 사이트의 HTML5 변환 기록 [1]
1061정성태6/8/201131940오류 유형: 125. 인터넷 익스플로러 - 개발자 도구에서 정지점(BP: Breakpoint) 설정이 안 되는 경우 [1]
1060정성태6/8/201128625VC++: 51. PHP 모듈의 F5 디버깅
1059정성태6/6/201133838VC++: 50. PHP 모듈 - php_mysql 빌드하는 방법파일 다운로드1
1058정성태6/5/201137453개발 환경 구성: 124. .NET 개발자가 처음 해보는 PHP + MySQL 연동 [2]
1057정성태6/4/201134936VC++: 49. 소스 코드로부터 php5apache2_2.dll 생성하는 방법파일 다운로드1
1056정성태6/2/201133189VC++: 48. 윈도우에서 Apache Module - Content Handler 컴파일파일 다운로드1
1055정성태6/1/201130359오류 유형: 124. MVC 프로젝트의 Site.Master 관련 오류 정리
1054정성태5/31/201133919.NET Framework: 220. ASP.NET MVC Web Site 프로젝트 - 단위 테스트 작성파일 다운로드1
1053정성태5/31/201136757VC++: 47. Apache Module에 대한 'F5 디버그 (Start with debugging)' [2]
1052정성태5/30/201134279.NET Framework: 219. ASP.NET MVC Web Site 프로젝트 구성하기파일 다운로드1
1051정성태5/28/201142802VC++: 46. 윈도우에서 Apache Module 컴파일 (VC++)파일 다운로드1
1050정성태5/28/201128881오류 유형: 123. Firebird - Exception of type 'FirebirdSql.Data.Common.IscException' was thrown.
1049정성태5/28/201134640.NET Framework: 218. WCF REST 서비스 - 웹 브라우저 측 Ajax 호출 캐시 [1]
1048정성태5/27/201136469개발 환경 구성: 123. Apache 소스를 윈도우 환경에서 빌드하기
1047정성태5/27/201130191.NET Framework: 217. Firebird ALinq Provider - 날짜 필드에 대한 낙관적 동시성 쿼리 오류
1046정성태5/26/201135079.NET Framework: 216. 라이선스까지도 뛰어넘는 .NET Profiler [5]
1045정성태5/24/201135959.NET Framework: 215. 닷넷 System.ComponentModel.LicenseManager를 이용한 라이선스 적용 [1]파일 다운로드1
1044정성태5/24/201136752오류 유형: 122. zlib 빌드 오류 - inflate.obj : error LNK2001: unresolved external symbol _inflate_fast
1043정성태5/24/201136542.NET Framework: 214. 무료 Linq Provider - DbLinq를 이용한 Firebird 접근파일 다운로드1
1042정성태5/23/201142137개발 환경 구성: 122. PHP 소스를 윈도우 환경에서 빌드하기
1041정성태5/22/201133112.NET Framework: 213. Linq To SQL - ALinq Provider를 이용하여 Firebird 사용파일 다운로드1
1040정성태5/21/201143594개발 환경 구성: 121. .NET 개발자가 처음 설치해 본 Apache + PHP [2]
... 151  152  153  154  155  156  157  158  159  160  161  162  [163]  164  165  ...