FFmpeg 101 (2024)
(blogs.igalia.com)- 오디오와 비디오를 인코딩·디코딩·트랜스코딩하고 스트리밍할 수 있는 FFmpeg 프레임워크의 구조와 사용법을 다룸
- ffmpeg, ffplay, ffprobe 등 명령줄 도구와 libavcodec, libavformat, libavfilter 등 핵심 라이브러리의 역할을 구체적으로 설명
- AVFormatContext, AVCodecContext, AVPacket, AVFrame을 중심으로 한 스트림 분석과 디코딩 절차를 단계별로 구현
- meson/ninja 빌드 시스템을 이용해 예제 코드를 자동으로 다운로드·컴파일하고, 샘플 미디어 파일을 분석해 결과를 출력
- FFmpeg의 내부 동작 원리와 디코딩 파이프라인 이해를 위한 실습형 입문 자료로 활용 가능
FFmpeg 패키지 구성
- FFmpeg은 다양한 오디오·비디오 포맷을 인코딩, 디코딩, 트랜스코딩하고 네트워크를 통해 스트리밍할 수 있는 도구와 라이브러리 모음으로 구성됨
-
FFmpeg 도구
- ffmpeg: 명령줄 기반 멀티미디어 포맷 변환 도구
- ffplay: SDL과 FFmpeg 라이브러리를 기반으로 한 간단한 미디어 플레이어
- ffprobe: 멀티미디어 스트림을 분석하는 도구
-
FFmpeg 라이브러리
- libavformat: 입출력 및 muxing/demuxing 기능 제공
- libavcodec: 인코딩/디코딩 기능 제공
- libavfilter: 그래프 기반 필터를 통한 원시 미디어 처리
- libavdevice: 입력/출력 장치 지원
- libavutil: 공통 멀티미디어 유틸리티 제공
- libswresample: 오디오 리샘플링, 샘플 포맷 변환, 오디오 믹싱 지원
- libswscale: 색상 변환 및 이미지 스케일링 기능
- libpostproc: 비디오 후처리(디블로킹, 노이즈 필터 등) 기능
FFmpeg 간단 플레이어
- 기본적인 FFmpeg 사용 방식은 멀티미디어 스트림을 demux하여 오디오와 비디오 스트림으로 분리하고, 이를 raw 오디오/비디오 데이터로 디코딩하는 과정
-
주요 구조체
- AVFormatContext: 스트림의 동기화, 메타데이터, muxing을 관리하는 상위 구조체
- AVStream: 연속적인 오디오 또는 비디오 스트림
- AVCodec: 데이터 인코딩 및 디코딩 방식 정의
- AVPacket: 스트림 내 인코딩된 데이터
- AVFrame: 디코딩된 원시 비디오 프레임 또는 오디오 샘플
-
스트림 분석 및 demux 과정
-
avformat_alloc_context()로 AVFormatContext 메모리 할당 -
avformat_open_input()으로 멀티미디어 파일 열기 -
avformat_find_stream_info()로 파일 내 스트림 정보 분석 - 각 스트림의 시간 기반(time base), 프레임레이트, 시작 시간, 길이, 타입, FourCC 코드를 출력
-
avformat_close_input()으로 파일 닫기 및 메모리 해제
-
-
코덱 탐색 및 초기화
-
avcodec_find_decoder()로 AVStream의 코덱 ID에 맞는 디코더 탐색 - 비디오 스트림의 경우 해상도(width, height), 오디오 스트림의 경우 채널 수와 샘플레이트 출력
-
avcodec_alloc_context3()로 AVCodecContext 생성 -
avcodec_parameters_to_context()로 스트림의 코덱 파라미터를 디코더 컨텍스트에 적용 -
avcodec_open2()로 디코더 열기
-
-
패킷 읽기 및 디코딩
-
AVPacket과AVFrame구조체를 각각 인코딩된 패킷과 디코딩된 프레임 저장용으로 할당 -
av_read_frame()으로 입력 파일에서 패킷을 순차적으로 읽음 - 패킷의 stream_index를 통해 어떤 스트림에서 왔는지 식별
- 선택된 비디오 스트림(
first_video_stream_index)의 패킷만 디코더로 전송 -
avcodec_send_packet()으로 패킷을 디코더에 전달 -
avcodec_receive_frame()으로 디코딩된 프레임을 반복적으로 수신 - 각 프레임의 번호, 타입(I/P/B), 포맷, PTS, 키프레임 여부 출력
-
av_packet_unref()으로 패킷 메모리 재활용 - 모든 처리가 끝나면
av_packet_free(),av_frame_free(),avcodec_free_context(),avformat_close_input()으로 메모리 해제
-
-
실행 및 결과 예시
- 예제 코드는 GitHub 저장소에서 제공
-
meson과 ninja를 이용해 빌드 가능 (
pip3 install meson ninja) -
meson setup build실행 시 FFmpeg 자동 다운로드 및 설정 -
ninja -C build로 빌드 후./build/ffmpeg-101 sample.mp4로 실행 - 실행 결과는 파일 포맷, 스트림 정보(비디오/오디오), 코덱, 해상도, 샘플레이트, 각 패킷의 PTS 및 디코딩된 프레임 정보 출력
-
출력 예시 요약
- 비디오 스트림: H.264 (avc1), 해상도 206x80, 프레임레이트 30fps
- 오디오 스트림: AAC (mp4a), 2채널, 44.1kHz
- 각 패킷의 PTS와 프레임 타입(I/P) 이 순차적으로 표시되며, 디코딩 과정이 콘솔에 출력됨
빌드 및 실행 환경
- 필요 도구: Python, pip, meson, ninja
-
설치 명령:
pip3 install meson ninja -
빌드 절차
- 예제 압축 파일을
ffmpeg-101폴더에 추출 -
meson setup build실행 -
ninja -C build로 빌드 -
./build/ffmpeg-101 sample.mp4로 실행 - FFmpeg이 시스템에 설치되어 있지 않으면 자동으로 다운로드 및 구성됨
- 예제 압축 파일을
Hacker News 의견들
-
FFmpeg과 libav의 내부 동작을 깊이 이해하고 싶은 사람에게 Leandro Moreira의 튜토리얼을 강력히 추천함
개인적으로 지금까지 본 것 중 가장 완전하고 명확한 설명임
FFmpeg-libav 튜토리얼 링크- 이 튜토리얼이 정말 도움이 됨. 고마움
- 원문에 있던 명령어들은 별로 흥미롭지 않았는데, 이 튜토리얼은 훨씬 실용적으로 보임
-
벌써 ffmpeg 101이라니 놀라움. ffmpeg 8이 나온 게 어제 같은 느낌임
- 잠자는 사이에 에이전트가 코드 푸시, 승인, 릴리스까지 다 해버린 결과 같음
-
또 다른 가이드를 공유함
HN의 관련 가이드 링크 -
FFmpeg, 정말 사랑하는 도구임
-
훌륭한 ffmpeg 입문 자료였음. 감사함
-
ffmpeg은 진정한 슈퍼파워임
나는 여러 영상 조각을 하나의 재생 가능한 형태로 조립할 때 항상 사용함