성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - ffmpeg(FFmpeg.AutoGen)를 이용한 avio_reading.c 예제 포팅</h1> <p> 지난 예제에 이어,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 프레임의 크기 및 포맷 변경 예제(scaling_video.c) ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12961'>https://www.sysnet.pe.kr/2/0/12961</a> </pre> <br /> 이번에는 <a target='tab' href='https://ffmpeg.org/doxygen/trunk/examples.html'>ffmpeg 예제</a> 중 "<a target='tab' href='https://ffmpeg.org/doxygen/trunk/avio_reading_8c-example.html'>avio_reading.c</a>" 파일을 FFmpeg.AutoGen으로 포팅하겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 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; } } </pre> <br /> 이런 식의 제어가 언제 필요한지는 모르겠지만, 일단 실행하면 avformat_find_stream_info 등의 함수를 실행하는 중에 read_packet 메서드가 콜백이 되어 다음과 같은 출력이 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ptr:1b27a880000 size:75337278 ptr:1b27a881000 size:75333182 ptr:1b27a88acff size:75292991 ptr:1b27a88bcff size:75288895 ptr:1b27a8907bb size:75269763 ptr:1b27a8917bb size:75265667 </pre> <br /> 그리고 av_dump_format의 호출에 대한 출력은 예제의 특성과는 별 상관이 없습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 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 </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1902&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> (<a target='tab' href='https://github.com/stjeong/ffmpeg_autogen_cs/tree/master/avio_reading'>이 글의 소스 코드는 github에 올려</a>져 있습니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2843
(왼쪽의 숫자를 입력해야 합니다.)