주 메뉴 열기

wwiki β

바뀜

FFmpeg 개발

4,088 바이트 추가됨, 2020년 5월 31일 (일) 00:24
모듈
I/O and Muxing/Demuxing Library.
=== 설명 ===
다양한 미디어 컨테이너 형식을 처리하기 위한 라이브러리입니다. 데이터에 액세스하기 위한 여러 프로토콜(예: 파일, tcp, http 및 기타)을 지원하는 I/O모듈이 있습니다. lavf를 사용하기 전에 av_register_all()을 호출하여 컴파일된 모든 muxer, 디먹서 및 프로토콜을 등록해야 합니다. libavformat의 네트워크 기능을 사용하려면 avformat_network_init()를 호출해야 합니다.
이 기능은 구형 GnuTLS 또는 OpenSSL 라이브러리의 스레드 안전 문제를 해결하기 위해서만 존재합니다. 최신(4.0이상)버전에서 사용할 필요가 없다. 구형 OpenSSL등을 사용하는 경우에 스레드를 사용하기 전에 호출해라.
 
==== 디먹싱 ====
디먹서는 미디어 파일을 읽고 패킷(chunks of data)으로 분리한다.
 
패킷은 하나의 기본 스트림에 속하는 하나 개 이상의 인코딩 된 프레임을 포함한다. lavf API에서는 파일을 열기 위해서 avformat_open_input()함수를 호출한 후, 단일패킷을 읽기 위해서 av_read_frame()함수를 호출한 후, 마지막으로 avformat_close_input()을 호출해서 정리한다.
 
===== 미디어 파일 열기 =====
파일을 열기 위해서는 avformat_open_input()함수에 파일의 url만은 전달해야 한다. 다음 코드처럼.<syntaxhighlight lang="c">
const char *url = "file:in.mp3";
AVFormatContext *s = NULL;
int ret = avformat_open_input(&s, url, NULL, NULL);
if (ret < 0)
abort();
</syntaxhighlight>위 코드는 AVFormatContext를 할당하고, 파일을 열어(포맷을 자동인식) 미디어파일 헤더를 읽고, 정보를 s에 내보낸다. 어떤 포맷은 헤더를 가지고 있지 않거나 충분한 정보를 저장하고 있지 않으므로, 놓친 정보를 찾기 위해서 avformat_find_stream_info() 함수를 호출해서 몇 프레임을 디코드를 시도해 보아라.
 
몇몇 경우에 avformat_alloc_context()를 호출해서 AVFormatContext를 미리 할당하고 avformat_open_input()에 전달하기 전에 조정하는 것이 좋습니다. lavf 내부 I/O layer대신에 입력 데이터를 읽기 위해서 custom function을 호출하려는 경우이다. 그렇게 하려면 avio_alloc_context()로 AVIOContext를 생성하고, 읽기콜백에 그것을 전달하세요. 그리고 AVFormatContext의 pb필드를 새로 생성한 AVIOContext로 설정해라.
 
파일포맷은 avformat_open_input()이 리턴할 때까지 알 수 없으므로, 미리 할당된 context에 private options을 디먹서에 설정하는 것은 불가능하다. 대신에 avformat_open_input()함수에 AVDictionary를 전달해서 가능하다.<syntaxhighlight lang="c">
AVDictionary *options = NULL;
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "pixel_format", "rgb24", 0);
if (avformat_open_input(&s, url, NULL, &options) < 0)
abort();
av_dict_free(&options);
</syntaxhighlight>이 코드는 private options인 'video_size', 'pixel_format'을 디먹서에게 전달한다. rowvideo 디먹서의 경우에 필요하다. 그렇지 않으면 원시 비디오 데이터를 어떻게 해석할지 알 수 없다. 만약 원시 비디오와 다르다고 판명되면, 디먹서에 의해 인식되지 않으므로 적용되지 않을 것이다. 인식되지 않은 그런 옵션은 options dictionary에 반환된다.(인식된 옵션들은 사용된다.) 다음처럼 인식되지 않은 옵션들은 원하는 대로 처리할 수도 있다. <syntaxhighlight lang="c">
AVDictionaryEntry *e;
if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key);
abort();
}
</syntaxhighlight>파일 읽기가 끝난 후에 avformat_close_input()을 호출해야 한다. 파일과 관련된 모든 것들을 해제한다.
 
===== 열린 파일에서 읽기 =====
열린 AVFormatContext에서 데이터를 읽는 것은 av_read_frame()를 반복적으로 호출하면 된다. 호출할 때마다 인코딩된 데이터인 하나의 AVStream을 포함한 AVPacket(AVPacket.stream_index번호로 식별된다.)을 리턴한다. 데이터를 디코딩하려면 패킷을 libavcodec의 디코딩 함수인 avcodec_send_packet()이나 avcodec_decode_subtitle2()에 직접 전달할 수 있다.
 
AVPacket.pts, AVPacket.dts, AVPacket.duration은 타이밍정보가 설정된다. 만약 스트림이 제공하지 않는다면 pts와 dts가 AV_NOPTS_VALUE이거나 duration은 0이다. 타이밍 정보는 AVStream.time_base단위로 표시됩니다. 즉, 시간단위를 곱하여 초로 변환한다.
 
반환된 패킷에 AVPacket.buf가 설정되어 있으면 패킷이 동적으로 할당되므로 사용자가 이를 무한정 유지할 수 있다. 그렇지 않으면 AVPacket.buf는 NULL이다.
== 외부링크 ==
편집
2,431