B-프레임은 화면을 만들 때 이전 프레임과 이후 프레임을 모두 사용할 수 있는 비디오 프레임입니다. 여기서 B는 양방향(bidirectional)을 의미합니다. B-프레임은 다른 프레임 유형보다 더 많은 압축률을 제공하여 비디오 용량을 줄이는 데 도움이 됩니다.
비디오 파일의 메타데이터에는 Has B Frames 또는 has_b_frames라는 필드가 있을 수 있습니다. 이름만 보면 예/아니요로 답하는 항목 같지만 실제 값은 숫자입니다. 이 숫자는 디코더가 올바른 순서로 비디오를 표시하기 위해 메모리에 동시에 보관해야 하는 프레임 개수를 나타냅니다.
B-프레임은 I-프레임 및 P-프레임과 어떻게 다른가요?
비디오 압축은 일반적으로 프레임끼리 비교하고 서로의 차이만 기록하는 방식으로 동작합니다. MPEG-2 비디오는 다음 3가지 프레임 유형을 정의합니다.
- I-프레임: 다른 프레임을 참조하지 않고 인코딩되므로, 여기서부터 디코딩을 시작할 수 있습니다.
- P-프레임: 이전 I-프레임 또는 P-프레임을 사용할 수 있습니다.
- B-프레임: 이전과 이후의 I-프레임 또는 P-프레임을 모두 사용할 수 있습니다.
B-프레임은 시간상으로 나중에 오는 프레임에 의존할 수 있으므로, 그 나중 프레임을 먼저 저장해 두어야 합니다. 따라서 저장되는 순서는 화면에 표시되는 순서와 달라집니다. 전형적인 MPEG-2 시퀀스는 다음과 같습니다.
- 표시 순서:
B1 B2 I3 B4 B5 P6 B7 B8 P9 B10 B11 P12 - 저장 순서:
I3 B1 B2 P6 B4 B5 P9 B7 B8 P12 B10 B11
값이 어떻게 표시되는지
Has B Frames 값은 정수입니다. FFmpeg는 이 값을 디코더의 프레임 재정렬 버퍼 크기로 설명합니다. MPEG-2 비디오의 경우 FFmpeg는 두 가지 값을 사용합니다.
0: I-프레임과 P-프레임만 사용하는 저지연 비디오1: I-프레임, P-프레임, B-프레임을 모두 사용하는 비디오
H.264 및 HEVC 인코더는 일부 B-프레임을 다른 프레임의 참조용으로 유지할 수도 있습니다. FFmpeg의 H.264 테스트 파일은 이 설정에 따라 값이 어떻게 달라지는지 보여 줍니다. 파일 이름에는 인코더 설정이 표시됩니다.
- 연속 B-프레임 최대 3개, 참조용으로 유지하는 B-프레임 없음:
1 - 연속 B-프레임 최대 3개, 일부를 참조용으로 유지:
2 - 연속 B-프레임 최대 4개, 일부를 참조용으로 유지:
2
따라서 이 값은 B-프레임 개수를 나타내는 것이 아닙니다. ffprobe 프로그램은 각 프레임의 유형을 pict_type 값으로 표시합니다. I, P, B 중 하나입니다. NB Frames 필드는 전체 프레임 수만 제공하며, 프레임 유형은 알려 주지 않습니다.
값이 어디에서 오는지
이 필드 이름은 FFmpeg에서 왔으며, FFmpeg의 ffprobe 프로그램은 비디오 스트림에 대해 has_b_frames 값을 출력합니다. H.264 스트림은 자체 헤더에 이 숫자를 포함할 수 있습니다. 헤더에 숫자가 없으면, FFmpeg가 프레임과 해당 시간 정보를 기준으로 값을 계산합니다.
비디오가 B-프레임을 사용할지는 인코더 설정에 따라 결정됩니다. FFmpeg와 Microsoft H.264 인코더에서는 설정값을 0으로 두면 B-프레임이 사용되지 않습니다.
어떤 파일에 포함되어 있는지
이 필드는 비디오 스트림에만 존재합니다. MP4, MOV, MKV, WebM, AVI 파일의 비디오 스트림에서 이 필드를 확인할 수 있습니다. 프레임이 재정렬된 MOV 파일은 각 프레임에 대해 디코딩 시점과 표시 시점 사이의 시간을 기록한 테이블도 함께 저장합니다.
B-프레임 사용 가능 여부는 코덱에 따라 달라집니다. MPEG-2 비디오와 H.264 Main 프로필은 B-프레임을 사용할 수 있지만, H.264 Baseline 프로필은 사용할 수 없습니다. WebM 파일에 사용되는 VP8 코덱에는 B-프레임이 없습니다. VP8 프레임은 이후 프레임을 기반으로 예측되지 않기 때문입니다.
왜 중요한지
B-프레임은 비디오 용량을 줄이는 데 도움이 되지만, 지연을 증가시킵니다. 인코더는 프레임을 저장하기 전에 순서를 재정렬해야 하며, 이 지연은 연속된 B-프레임의 개수에 따라 달라집니다.
프레임이 재정렬된 비디오는 각 프레임마다 디코딩해야 하는 시점과 화면에 표시해야 하는 시점이라는 두 가지 시간이 존재합니다. FFmpeg는 스트림의 time base를 기준으로 이 두 시점을 타임스탬프로 제공합니다.