성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
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)를 이용한 resampling_audio.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)를 이용한 qsvdec.c 예제 포팅 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12975'>https://www.sysnet.pe.kr/2/0/12975</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/resampling_audio_8c-example.html'>resampling_audio.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; namespace resampling_audio { internal unsafe class Program { static int Main(string[] args) { FFmpegBinariesHelper.RegisterFFmpegBinaries(); long src_ch_layout = ffmpeg.AV_CH_LAYOUT_STEREO; long dst_ch_layout = ffmpeg.AV_CH_LAYOUT_SURROUND; int src_rate = 48000, dst_rate = 44100; byte** src_data = null; byte** dst_data = null; int src_nb_channels = 0, dst_nb_channels = 0; int src_linesize, dst_linesize; int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples; AVSampleFormat src_sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_DBL, dst_sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S16; int dst_bufsize; string fmt = ""; SwrContext* swr_ctx; double t; int ret; string dirPath = Path.GetDirectoryName(typeof(Program).Assembly.Location) ?? ""; string dst_filename = Path.Combine(dirPath, "test.dat"); using FileStream dst_file = File.OpenWrite(dst_filename); swr_ctx = ffmpeg.swr_alloc(); if (swr_ctx == null) { Console.WriteLine("Could not allocate resampler context"); ret = ffmpeg.AVERROR(ffmpeg.ENOMEM); goto end; } ffmpeg.av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0); ffmpeg.av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0); ffmpeg.av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0); ffmpeg.av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0); ffmpeg.av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0); ffmpeg.av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0); if ((ret = ffmpeg.swr_init(swr_ctx)) < 0) { Console.WriteLine("Failed to initialize the resampling context"); goto end; } src_nb_channels = ffmpeg.av_get_channel_layout_nb_channels((ulong)src_ch_layout); ret = ffmpeg.av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels, src_nb_samples, src_sample_fmt, 0); if (ret < 0) { Console.WriteLine("Could not allocate source samples"); goto end; } max_dst_nb_samples = dst_nb_samples = (int)ffmpeg.av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AVRounding.AV_ROUND_UP); dst_nb_channels = ffmpeg.av_get_channel_layout_nb_channels((ulong)dst_ch_layout); ret = ffmpeg.av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_sample_fmt, 0); if (ret < 0) { Console.WriteLine("Could not allocate destination samples"); goto end; } t = 0; do { fill_samples((double*)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t); dst_nb_samples = (int)ffmpeg.av_rescale_rnd(ffmpeg.swr_get_delay(swr_ctx, src_rate) + src_nb_samples, dst_rate, src_rate, AVRounding.AV_ROUND_UP); if (dst_nb_samples > max_dst_nb_samples) { ffmpeg.av_freep(&dst_data[0]); ret = ffmpeg.av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_sample_fmt, 1); if (ret < 0) { break; } max_dst_nb_samples = dst_nb_samples; } ret = ffmpeg.swr_convert(swr_ctx, dst_data, dst_nb_samples, src_data, src_nb_samples); if (ret < 0) { Console.WriteLine("Error while converting"); goto end; } dst_bufsize = ffmpeg.av_samples_get_buffer_size(&dst_linesize, dst_nb_channels, ret, dst_sample_fmt, 1); if (dst_bufsize < 0) { Console.WriteLine("Could not get sample buffer size"); goto end; } Console.WriteLine($"t:{t} in:{src_nb_samples} out:{ret}"); dst_file.Write(new ReadOnlySpan<byte>(dst_data[0], dst_bufsize)); } while (t < 10); if ((ret = get_format_from_sample_fmt(out fmt, dst_sample_fmt)) < 0) { goto end; } Console.WriteLine($"Resampling succeeded. Play the output file with the command:\n ffplay -autoexit -f {fmt} -channel_layout {dst_ch_layout} -channels {dst_nb_channels} -ar {dst_rate} {dst_filename}"); end: if (src_data != null) { ffmpeg.av_freep(&src_data[0]); } ffmpeg.av_freep(&src_data); if (dst_data != null) { ffmpeg.av_freep(&dst_data[0]); } ffmpeg.av_freep(&dst_data); ffmpeg.swr_free(&swr_ctx); return 0; } static void fill_samples(double* dst, int nb_samples, int nb_channels, int sample_rate, double* t) { int i, j; double tincr = 1.0 / sample_rate; double* dstp = dst; const double c = 2 * Math.PI * 440.0; for (i = 0; i < nb_samples; i++) { *dstp = Math.Sin(c * *t); for (j = 1; j < nb_channels; j++) { dstp[j] = dstp[0]; } dstp += nb_channels; *t += tincr; } } static int get_format_from_sample_fmt(out string fmt, AVSampleFormat sample_fmt) { fmt = ""; foreach (var item in sample_fmt_entry.entries) { if (item.sample_fmt == sample_fmt) { fmt = (BitConverter.IsLittleEndian) ? item.fmt_le : item.fmt_be; return 0; } } return ffmpeg.AVERROR(ffmpeg.EINVAL); } } public class sample_fmt_entry { public AVSampleFormat sample_fmt; public string fmt_be = ""; public string fmt_le = ""; public static sample_fmt_entry[] entries = new sample_fmt_entry[] { new sample_fmt_entry { sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_U8, fmt_be = "u8", fmt_le = "u8" }, new sample_fmt_entry { sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S16, fmt_be = "s16be", fmt_le = "s16le" }, new sample_fmt_entry { sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S32, fmt_be = "s32be", fmt_le = "s32le" }, new sample_fmt_entry { sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_FLT, fmt_be = "f32be", fmt_le = "f32le" }, new sample_fmt_entry { sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_DBL, fmt_be = "f64be", fmt_le = "f64le" }, }; } } </pre> <br /> 실행하면, 실행 파일 위치에 test.dat 파일이 생성되고, ffplay를 이용한 재생 방법이 출력됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > t:0.021333333333333492 in:1024 out:925 t:0.042666666666666124 in:1024 out:941 t:0.06399999999999711 in:1024 out:940 ...[생략]... t:9.941333333343279 in:1024 out:941 t:9.96266666667732 in:1024 out:941 t:9.984000000011362 in:1024 out:940 t:10.005333333345403 in:1024 out:941 Resampling succeeded. Play the output file with the command: ffplay -autoexit -f s16le -channel_layout 7 -channels 3 -ar 44100 E:\...[생략]...\test.dat </pre> <br /> 예제 코드가 아주 간결해서 더 설명할 것이 없군요. ^^<br /> <br /> (<a target='tab' href='https://github.com/stjeong/ffmpeg_autogen_cs/tree/master/resampling_audio'>이 글의 소스 코드는 github에 올려</a>져 있습니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2082
(왼쪽의 숫자를 입력해야 합니다.)