FFmpeg에서 DASH 용 키 프레임을 수정하는 올바른 방법은 무엇입니까?


38

DASH 재생을 위해 스트림을 컨디셔닝 할 때 임의의 액세스 포인트는 모든 스트림에서 정확히 동일한 소스 스트림 시간이어야합니다. 이를 수행하는 일반적인 방법은 고정 프레임 속도와 고정 GOP 길이 (즉, N 프레임마다 키 프레임)를 강제하는 것입니다.

FFmpeg에서는 고정 프레임 속도가 쉽습니다 (-r NUMBER).

그러나 고정 키 프레임 위치 (GOP 길이)의 경우 세 가지 방법이 있습니다. FFmpeg 문서는 이에 대해 애매 모호합니다.

방법 1 : libx264의 인수로 혼란

-c:v libx264 -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE:scenecut=-1

장면 컷이 발생할 때 키 프레임 "카운터"가 다시 시작되는지 확실하지 않기 때문에 장면 컷을 해제해야하는지에 대한 논쟁이있는 것 같습니다.

방법 2 : 고정 GOP 크기 설정 :

-g GOP_LEN_IN_FRAMES

불행히도 FFMPEG 문서를 전달할 때만 문서화되므로이 인수의 효과는 명확하지 않습니다.

방법 3 : N 초마다 키 프레임 삽입 ( 아마도? ) :

-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)

됩니다 명시 적으로 문서화. 그러나 모든 키 프레임 후에 "시간 카운터"가 다시 시작되는지 여부는 여전히 명확하지 않습니다. 예를 들어, 예상되는 5 초 GOP scenecut에서 libx264에 의해 3 초 동안 키 프레임이 주입 된 경우 다음 키 프레임이 5 초 후에 또는 2 초 후에 발생합니까?

실제로, FFmpeg 문서는이 -g옵션 과 옵션을 구별 하지만, 위의 두 옵션이 어떻게 조금 다른지 (정확하게 -g는 고정 된 프레임 속도를 요구할 것입니다) 말하지 않습니다 .

어느 것이 맞는지?

-force_key_frames고정 프레임 레이트가 필요하지 않기 때문에 더 우수 할 것 같습니다 . 그러나이를 위해서는

  • H.264의 GOP 사양을 준수합니다 (있는 경우 ).
  • libx264 scenecut키 프레임에 관계없이 고정 케이던스에 키 프레임이 있음을 보증합니다 .

-g-rffmpeg다른 코덱 인수로 여러 번 실행 하면 각 해상도에서 동일한 순간 프레임 속도를 제공 한다는 보장이 없으므로 고정 프레임 속도 ( )를 적용하지 않으면 작동하지 않는 것으로 보입니다 . 고정 프레임 속도는 압축 성능을 저하시킬 수 있습니다 (DASH 시나리오에서는 중요합니다!).

마지막으로, 방법은 해킹처럼 보인다 . 나는 이것이 정답이 아닌 희망에 반대하기를 바랍니다.keyint

참고 문헌 :

-force_key_frames방법을 사용하는 예

keyint방법을 사용하는 예

FFmpeg 고급 비디오 옵션 섹션

답변:


27

TL; DR

다음을 권장합니다.

  • libx264: (및 선택적으로 추가 )-g X -keyint_min X-force_key_frames "expr:gte(t,n_forced*N)"
  • libx265: -x265-params "keyint=X:min-keyint=X"
  • libvpx-vp9: -g X

여기서 X간격은 프레임 단위이며 N간격은 초입니다. 예를 들어 30fps 비디오의 2 초 간격으로 X= 60 및 N= 2입니다.

다른 프레임 유형에 대한 참고 사항

이 주제를 올바르게 설명하려면 먼저 두 가지 유형의 I- 프레임 / 키 프레임을 정의해야합니다.

  • IDR (Instantaneous Decoder Refresh) 프레임 : IDR 프레임 이전의 프레임에 액세스하지 않고도 다음 프레임을 독립적으로 디코딩 할 수 있습니다.
  • 비 IDR 프레임 : 디코딩이 작동하려면 이전 IDR 프레임이 필요합니다. 비 IDR 프레임은 GOP (픽처 그룹) 도중 장면 컷에 사용할 수 있습니다.

스트리밍에 권장되는 것은 무엇입니까?

스트리밍 사례의 경우 :

  • 비디오를 동일한 길이의 세그먼트로 분할 할 수 있도록 모든 IDR 프레임이 일정한 위치 (예 : 2, 4, 6,… 초)에 있는지 확인하십시오.
  • 코딩 효율 / 품질을 향상시키기 위해 장면 컷 감지를 활성화 이는 I- 프레임이 IDR 프레임 사이에 배치 될 수 있도록하는 것을 의미합니다. 장면 컷 감지를 비활성화 한 상태로 작업 할 수는 있지만 여전히 많은 가이드의 일부입니다. 그러나 필요하지는 않습니다.

매개 변수는 무엇을합니까?

인코더를 구성하려면 키 프레임 매개 변수의 기능을 이해해야합니다. 나는 몇 가지 테스트를했고, 세 인코더를 들어, 다음을 발견 libx264, libx265그리고 libvpx-vp9는 FFmpeg에서 :

  • libx264:

    • -g 키 프레임 간격을 설정합니다.
    • -keyint_min 최소 키 프레임 간격을 설정합니다.
    • -x264-params "keyint=x:min-keyint=y"와 동일합니다 -g x -keyint_min y.
    • 참고 : 둘 다 동일한 값으로 설정 하면 코드 에서 볼 수 있듯이 최소값이 내부적으로 최대 간격의 절반 에 1을 더한 값으로 설정됩니다 x264.

      h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
      
  • libx265:

    • -g 구현되지 않았습니다.
    • -x265-params "keyint=x:min-keyint=y" 공장.
  • libvpx-vp9:

    • -g 키 프레임 간격을 설정합니다.
    • -keyint_min 최소 키 프레임 간격을 설정합니다
    • 참고 : FFmpeg의 작동 방식으로 -keyint_min와 동일한 경우에만 인코더로 전달됩니다 -g. libvpxenc.cFFmpeg 의 코드에서 다음 을 찾을 수 있습니다.

      if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
          enccfg.kf_min_dist = avctx->keyint_min;
      if (avctx->gop_size >= 0)
          enccfg.kf_max_dist = avctx->gop_size;
      

      libvpx대한 다른 값 설정을 확실히 지원하므로 버그 (또는 기능이 부족합니까?) 일 수 kf_min_dist있습니다.

사용해야합니까 -force_key_frames?

-force_key_frames옵션은 주어진 간격 (표현)으로 키 프레임을 강제로 삽입합니다. 이것은 모든 인코더에서 작동하지만 속도 제어 메커니즘을 망칠 수 있습니다. 특히 VP9의 경우 심각한 품질 변동이 발견되었으므로이 경우에는 사용하지 않는 것이 좋습니다.


고맙습니다! 이것은 좋은 피드백입니다. 내가 가진 한 가지 질문은 어떻게 멋진 테이블을 생성했는지입니다. 나는 완전히 그런 것을 사용할 수 있습니다.
Mark Gerolimatos

(당신을 직접 쓸 수있는 방법이없는 것 같습니다)이 ITU-T 토론에서 스레드로 연결되는 링크를 알려주시겠습니까? 감사!
마크 Gerolimatos

2
방금 Excel에서 세 번의 실행 결과를 붙여 ffprobe -i input.mp4 -select_streams v -show_frames -of csv -show_entries frame=pict_type넣은 다음 셀을 채색했습니다. 공개 토론이 두렵지 않지만 그때 내가 찾은 링크 중 일부를 파낼 수 있는지 볼 수 있습니다.
slhck

-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)양식으로 실험을 다시 시도해 주 시겠습니까? 방금 시도해 보았고 스트림에 여분의 I 프레임이있는 동안 DID가 내 규칙을 준수하는 것으로 나타났습니다. 주석에 마크 업을 사용할 수 없으므로 PERL 프로그램은 "답변"으로 따릅니다.
마크 Gerolimatos

흥미 롭군 나는 그것이 효과가 있다는 것을 알면 별도의 "실제"답변의 가치가 있다고 생각합니다. (스택 교환 사이트는이 토론 스타일의 회신에 실제로 좋지 않습니다.) 마지막으로 확인 -force_key_frames했을 때 제대로 작동하지 않아 다시 시도하지 않았습니다. 그것은 1 년 전이었습니다. 아마도 그것은 버그였습니다. 곧 다시 시도하겠습니다.
slhck

12

여기에 50 센트가 있습니다.

방법 1 :

libx264의 인수로 혼란

-c : v libx264 -x264opts keyint = GOPSIZE : min-keyint = GOPSIZE : scenecut = -1

원하는 간격으로 만 iframe을 생성하십시오.

예 1 :

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-x264opts "keyint=48:min-keyint=48:no-scenecut" \
-c:a copy \
-y test_keyint_48.mp4

다음과 같이 iframe을 생성하십시오.

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
961         40
1009        42
1057        44
1105        46
1153        48
1201        50
1249        52
1297        54
1345        56
1393        58

방법 2가 감가 상각됩니다. 생략되었습니다.

방법 3 :

N 초마다 키 프레임 삽입 (MAYBE) :

-force_key_frames expr : gte (t, n_forced * GOP_LEN_IN_SECONDS)

실시 예 2

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-force_key_frames "expr:gte(t,n_forced*2)"
-c:a copy \
-y test_fkf_2.mp4

약간 다른 방식으로 iframe을 생성하십시오.

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
519         21.58333333
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
931         38.75
941         39.16666667
961         40
1008        42
1056        44
1104        46
1152        48
1200        50
1248        52
1296        54
1305        54.375
1344        56
1367        56.95833333
1392        58
1430        59.58333333
1440        60
1475        61.45833333
1488        62
1536        64
1544        64.33333333
1584        66
1591        66.29166667
1632        68
1680        70
1728        72
1765        73.54166667
1776        74
1811        75.45833333
1824        75.95833333
1853        77.16666667
1872        77.95833333
1896        78.95833333
1920        79.95833333
1939        80.75
1968        81.95833333

보시다시피 2 초마다 iframe을 배치하고 장면 컷 (플로팅 부분이있는 초)에 iframe을 배치하므로 비디오 스트림 복잡성에 중요합니다.

생성 된 파일 크기는 거의 같습니다. 방법 3 에서 더 많은 키 프레임을 사용하더라도 표준 x264 라이브러리 알고리즘보다 적은 파일을 생성 한다는 것은 매우 이상합니다 .

HLS 스트림에 대해 여러 비트 전송률 파일을 생성하려면 방법 3을 선택하십시오. 그것은 청크 사이에 2 초로 완벽하게 정렬되어 있으며, 모든 청크의 시작 부분에 iframe이 있으며 복잡한 장면에 추가 iframe이있어 오래된 장치가 있고 x264 하이 프로파일을 재생할 수없는 사용자에게 더 나은 경험을 제공합니다.

그것이 누군가를 돕기를 바랍니다.


환상적인, 50 센트 감사합니다!
BrunoFenzl

7

따라서 대답은 다음과 같습니다.

  • 방법 1은 작동하는 것으로 확인되었지만 libx264고유하며의 유용한 scenecut옵션 을 제거하는 비용이 듭니다 libx264.
  • 방법 3은 2015 년 4 월 FFMPEG 버전에서 작동하지만 FFMPEG 설명서가 옵션의 효과에 대해 명확하지 않기 때문에이 게시물의 맨 아래에 포함 된 스크립트를 사용하여 결과를 확인해야합니다. 작동하면 두 가지 옵션 중 우수합니다.
  • 방법 2를 사용하지 마십시오 -g. 더 이상 사용되지 않는 것으로 보입니다. 작동하지 않거나 설명서에 명시 적으로 정의되어 있지 않거나 도움말에서 찾을 수 없으며 코드에서 사용되지도 않습니다. 코드 검사에 따르면이 -g옵션은 MPEG-2 스트림 (PAL 및 NTSC를 참조하는 코드 스탠자도 있음)을위한 것입니다.

또한:

  • 삽입 광고 I 프레임 (키 프레임)이 허용되므로 방법 3으로 생성 된 파일은 방법 1보다 약간 클 수 있습니다.
  • 방법 3에서 지정된 시간 또는 그 이후 에 다음 프레임 슬롯에 I 프레임을 배치하더라도 두 경우 모두 "-r"플래그를 명시 적으로 설정해야 합니다. "-r"플래그를 설정하지 않으면 가변 프레임 속도로 소스 파일을 사용할 수 있습니다. 호환되지 않는 DASH 전환이 발생할 수 있습니다.
  • FFMPEG 문서의 경고에도 불구하고 방법 3은 다른 방법 보다 효율적이지 않습니다 . 실제로 테스트에 따르면 방법 1보다 약간 더 효율적일 수 있습니다.

-force_key_frames옵션 스크립트

다음은 slhck의 ffprobe 제안 출력을 기반으로 I- 프레임 케이던스를 확인하는 데 사용한 짧은 PERL 프로그램입니다. 이 -force_key_frames방법이 작동 하는지 확인하고 scenecut프레임 을 허용한다는 추가 이점이 있습니다. 나는 FFMPEG가 어떻게이 작업을 수행하는지, 또는 내 스트림이 잘 조절되어 있기 때문에 어떻게 든 운이 있는지 전혀 모른다.

필자의 경우 예상되는 GOP 크기는 6 초 또는 180 프레임으로 30fps로 인코딩되었습니다. 이 프로그램에 대한 gopsize 인수로 180을 사용하여 180의 각 배수에서 I 프레임을 확인했지만 181 (또는 180의 배수가 아닌 다른 숫자)로 설정하면 불평했습니다.

#!/usr/bin/perl
use strict;
my $gopsize = shift(@ARGV);
my $file = shift(@ARGV);
print "GOPSIZE = $gopsize\n";
my $linenum = 0;
my $expected = 0;
open my $pipe, "ffprobe -i $file -select_streams v -show_frames -of csv -show_entries frame=pict_type |"
        or die "Blah";
while (<$pipe>) {
  if ($linenum > $expected) {
    # Won't catch all the misses. But even one is good enough to fail.
    print "Missed IFrame at $expected\n";
    $expected = (int($linenum/$gopsize) + 1)*$gopsize;
  }
  if (m/,I\s*$/) {
    if ($linenum < $expected) {
      # Don't care term, just an extra I frame. Snore.
      #print "Free IFrame at $linenum\n";
    } else {
      #print "IFrame HIT at $expected\n";
      $expected += $gopsize;
    }
  }
  $linenum += 1;
}

참고 사항 :이 사이트는 Q & A 사이트이며 실제로는 게시물이 시간순으로 정렬되는 토론 포럼이 아니므 로 모든 정보를 하나의 답변 에 넣는 것이 가장 좋습니다 . 따라서 솔루션을 찾는 사람들은 하나의 게시물 만 읽고 보지 않아야합니다. 누가 언제 무엇을 게시했는지 :) 나는 당신의 답변을 병합하고 이것에 대해 +1을주었습니다. 이후 크로스 게시가 허용되지 않습니다 , 당신은 비디오 사이트에서 질문을 삭제 건의 할 것입니다. 사람들은 여기서 답변을 찾을 수 있습니다.
slhck

1
방금 하나 더 생각했습니다 (실제로 FFmpeg 메일 링리스트에서 제기되었습니다). 를 사용 force_key_frames하면 x264 비트 할당 알고리즘이 엉망이되므로 고정 된 키 프레임 간격을 설정하는 것보다 품질이 떨어질 수 있습니다.
slhck

이런 세상에. FFMPEG를 사용해야하는 또 하나의 이유는이 문제를 해결하기 위해 코덱에 고유하지 않은 방법을 제공하는데, 이는 "해당 코덱에 가장 좋은 일을 할 것"이라는 주장입니다. 나는
FFMPEG

@ slhck : 자세한 내용을 알려주시겠습니까? 2015 년 5 월 메일 링리스트 아카이브를 살펴 봤지만 찾을 수 없습니다. 결론은 "방법 3"을 잊고 "방법 1"을 고수하는 것입니다.
schieferstapel

3
@MarkGerolimatos :에 대해 -g"작동하지 않거나 코드에 사용 된 것으로 보이지 않습니다."라고 말합니다. 확인하고 입력 내용 g이 저장되고 avctx->gop_sizelibx264가 사용합니다 x4->params.i_keyint_max = avctx->gop_size;. 이 생성 된 테스트 파일을 조사 할 때 ffmpeg -i a-test-file.mp4 -g 37 -t 15 gtest.mp4정확히 키 프레임을 얻습니다 0,37,74,111,148,185,222,259,296,333,370. 장면 변경이 트리거되면 GOP가 짧아 질 -sc_threshold수 있으며 x264에 의해 포착 될 수 있습니다.
Gyan

4

내 인터넷 검색에서 원하는 방식으로 DASH 인코딩을 세그먼트 화하는 방법을 찾으려는 정보를 찾으려고 노력 하면서이 토론을 꽤 많이 끌어 들였으므로 여기에 정보를 추가하고 싶었습니다. 내가 찾은 정보가 완전히 정확하지 않았습니다.

먼저 몇 가지 오해를 제거하십시오.

  1. 모든 I- 프레임이 같은 것은 아닙니다. 큰 "I"프레임과 작은 "i"프레임이 있습니다. 또는 올바른 용어, IDR I- 프레임 및 비 IDR I- 프레임을 사용하십시오. IDR I- 프레임 ( "키 프레임"이라고도 함)은 새로운 GOP를 생성합니다. 비 IDR 프레임은 그렇지 않습니다. 장면 변경이있는 GOP 내부에 있으면 편리합니다.

  2. -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE← 이것은 당신이 생각하는 것을하지 않습니다. 알아내는 데 시간이 조금 걸렸습니다. min-keyint코드에 제한 이 있음이 밝혀졌습니다 . 보다 클 수 없습니다 (keyint / 2) + 1. 따라서이 두 변수에 동일한 값을 할당 min-keyint하면 인코딩시 값 이 반으로 줄어 듭니다.

장면 컷은 정말 빠릅니다. 특히 빠른 컷이 빠른 비디오에서 특히 그렇습니다. 멋지고 선명하게 유지하므로 사용하지 않으려 고하지만 동시에 사용 가능한 한 고정 GOP 크기를 얻을 수 없었습니다. 장면 컷을 활성화하고 싶지만 IDR이 아닌 I- 프레임 만 사용하도록했습니다. 그러나 작동하지 않았습니다. 오해 # 2에 대해 (많은 독서에서) 알아낼 때까지.

keyint원하는 GOP 크기를 두 배로 설정해야한다는 것이 밝혀졌습니다 . 즉 min-keyint, 내부 코드를 반으로 자르지 않고 원하는 GOP 크기로 설정할 수 있습니다. 이로 인해 장면 ID를 감지하여 GOP 크기 내에서 IDR I- 프레임을 사용하지 못합니다. 마지막 IDR I- 프레임 이후의 프레임 수는 항상보다 작습니다 min-keyinit.

마지막으로 force_key_frame옵션을 설정하면 double 크기가 무시 keyint됩니다. 그래서 여기에 효과가 있습니다.

2 초 단위로 세그먼트를 선호하므로 GOPSIZE = Framerate * 2

ffmpeg <other_options> -force_key_frames "expr:eq(mod(n,<GOPSIZE>),0)" -x264opts rc-lookahead=<GOPSIZE>:keyint=<GOPSIZE * 2>:min-keyint=<GOPSIZE> <other_options>

ffprobe를 사용하여 확인할 수 있습니다.

ffprobe <SRC_FLE> -select_streams v -show_frames -of csv -show_entries frame=coded_picture_number,key_frame,pict_type > frames.csv

생성 된 CSV 파일에서 각 줄은 다음을 알려줍니다. frame, [is_an_IDR_?], [frame_type], [frame_number]:

frame,1,I,60  <-- frame 60, is I frame, 1 means is an IDR I-frame (aka KeyFrame)
frame,0,I,71  <-- frame 71, is I frame, 0 means not an IDR I_frame

결과적으로 고정 된 GOPSIZE간격으로 IDR I- 프레임 만 볼 수 있고 다른 모든 I 프레임은 장면 컷 감지에 필요한 비 IDR I- 프레임입니다.


환상적이었다! 알도는 매우 반 직관적이었습니다. 노력을 기울여 주셔서 감사합니다. 그리고 요약하자면, "I-frames"와 "i-frames"에 대한 정의가 개념적인 것 (즉, libx264에서 명시 적으로 구성 할 수 없음)이고 "max * 2"가 적용한 방식이라고 가정합니다.
Mark Gerolimatos

그렇습니다. 사람들이 IDR과 비 IDR I- 프레임을 구별하기 위해 "I"와 "i"를 사용하는 것을 보았지만 개념적이었습니다. 그리고 그렇습니다 .keyinit를 원하는 gop 크기 * 2로 설정하면 gop 내부의 모든 I 프레임이 비 IDR I- 프레임이되도록합니다. 그런 다음 ffmpeg -force-key-frames는 x264opts의 key-init를 재정의합니다. 기본적으로 x264 코드를 사용하여 min-keyinit 및 keyinit를 동일한 값으로 설정할 수있는 경우 원하는 결과를 얻는 방법은 실제로 거꾸로입니다.
Reuben

... 장면 컷 감지 기능을 켜고 고정 된 GOP 크기를 얻을 수 있습니다.
Reuben

멋진 작업에 다시 한번 감사드립니다! "거꾸로"효과를 줄 필요가있는 것 같습니다
Mark Gerolimatos

여기 rc-lookahead가 필요합니까? mbtree 및 VBV에는 영향을 주지만 i-frame 생성에는 영향을 줍니까?
Alexander Svetkin

0

이 구문은 항상 작동하지 않는 것 같습니다. VOD 컨텐츠와 라이브 컨텐츠 (파일 덤프)에 대해 많은 테스트를 거쳤으며 때로는 scenecut이 작동하지 않고 iframe 사이에서 트리거되는 경우가 있습니다.

i50-> p50 업 컨버전, 2 초 이동 / 세그먼트, 시작시 IDR, 필요한 경우 iframe 간 구문

ffmpeg.exe -loglevel verbose -i avc_50i.ts -pix_fmt yuv420p -filter_complex yadif=1,scale=1920:1080 -vcodec libx264 -preset fast -x264-params "rc-lookahead=100:keyint=200:min-keyint=100:hrd=1:vbv_maxrate=12000:vbv_bufsize=12000:no-open-gop=1" -r 50 -crf 22 -force_key_frames "expr:eq(mod(n,100),0)" -codec:a aac -b:a 128k -y target.ts

0

Twitch는 이에 관한 게시물을 가지고 있습니다. 그들은 여러 가지 이유로 자신의 프로그램을 사용하기로 결정했다고 설명합니다. 그중 하나는 ffmpeg를 사용하면 다른 스레드에서 다른 x264 인스턴스를 실행할 수 없지만 대신 다음 출력으로 이동하기 전에 지정된 모든 스레드를 한 출력의 한 프레임에 할당합니다.

실시간 스트리밍을하지 않으면 더 고급스러워집니다. '올바른'방법은 -g로 지정된 GOP 크기만으로 한 해상도에서 인코딩 한 다음 같은 위치에서 키 프레임을 강제하는 다른 해상도를 인코딩하는 것입니다.

그렇게하려면 ffprobe를 사용하여 키 프레임 시간을 얻은 다음 셸 스크립트 또는 실제 프로그래밍 언어를 사용하여 ffmpeg 명령으로 변환 할 수 있습니다.

그러나 대부분의 콘텐츠의 경우 5 초마다 하나의 키 프레임과 5 초마다 2 개의 키 프레임을 갖는 것 (하나는 강제 및 하나는 장면 컷에서) 사이에 차이가 거의 없습니다. 이것은 평균 I- 프레임 크기와 P- 프레임 및 B- 프레임의 크기에 관한 것입니다. 일반적인 설정으로 x264를 사용하는 경우 (이에 영향을 미치는 모든 조치는 x264를 사용하여 쉬운 콘텐츠에서 비트 전송률을 사용하지 못하게하는 나쁜 방법으로 -qmin을 설정하는 것입니다. 모든 프레임 유형을 동일한 값으로 제한합니다) 생각합니다) I- 프레임 평균 크기 46kB, P- 프레임 24kB, B- 프레임 17kB (P- 프레임의 절반) 및 30fps에서 1 초마다 추가 I- 프레임과 같은 결과를 얻습니다. 파일 크기가 3 % 만 증가합니다. h264와 h263의 차이는 3 % 감소로 구성 될 수 있지만 단일 항목은 그다지 중요하지 않습니다.

다른 유형의 컨텐츠에서는 프레임 크기가 다릅니다. 공평하게 말하면 이것은 공간적 복잡성이 아니라 시간적 복잡성에 관한 것이므로 콘텐츠와 하드 콘텐츠가 쉬운 것은 아닙니다. 그러나 일반적으로 스트리밍 비디오 사이트에는 비트 전송률 제한이 있으며 비교적 큰 I- 프레임이있는 콘텐츠는 추가 된 키 프레임 수에 관계없이 고품질로 인코딩되는 쉬운 콘텐츠입니다. 낭비이지만이 폐기물은 일반적으로 눈에 띄지 않습니다. 가장 낭비되는 사례는 아마도 노래와 함께 제공되는 정적 이미지 일 뿐이고 각 키 프레임이 정확히 동일한 비디오 일 것입니다.

확실하지 않은 한 가지는 강제 키 프레임이 -maxrate 및 -bufsize로 설정된 속도 제한 기와 상호 작용하는 방식입니다. YouTube에서도 최근에도 일관된 품질을 제공하기 위해 버퍼 설정을 올바르게 구성하는 데 문제가 있다고 생각합니다. 일부 사이트에서 볼 수 있듯이 평균 비트 전송률 설정을 사용하는 경우 (16 진수 편집기로 헤더 / mov atom에서 x264의 옵션을 검사 할 수 있기 때문에) 버퍼 모델은 문제가되지 않지만 사용자 생성 콘텐츠를 제공하는 평균 비트 전송률은 사용자가 동영상 끝에 검은 색 화면을 추가하도록 권장합니다.

Ffmpeg의 -g 옵션 또는 사용하는 다른 인코더 옵션은 인코더 별 옵션에 매핑됩니다. 따라서 '-x264-params keyint = GOPSIZE'는 '-g GOPSIZE'와 같습니다.

장면 감지를 사용할 때의 한 가지 문제는 어떤 이유로 든 특정 숫자 근처의 키 프레임을 선호하는 경우입니다. 5 초마다 키 프레임을 지정하고 장면 감지를 사용하고 4.5에서 장면이 변경되면 감지해야하지만 다음 키 프레임은 9.5입니다. 시간이 계속 이렇게 높아지면 40, 45, 50, 55 대신 42.5, 47.5, 52.5 등의 키 프레임으로 끝날 수 있습니다. 반대로 5.5에서 장면이 변경되면 5.5가됩니다. 5와 5.5의 키 프레임은 다른 키 프레임에 비해 너무 빠릅니다. Ffmpeg에서는 "다음 30 프레임 내에 장면이 변경되지 않으면 여기에서 키 프레임을 작성하십시오"를 지정할 수 없습니다. C를 이해하는 사람은 그 옵션을 추가 할 수 있습니다.

가변 프레임 속도 비디오의 경우 Twitch와 같은 라이브 스트리밍이 아닌 경우 영구적으로 일정한 프레임 속도로 변환하지 않고 장면 변경을 사용할 수 있어야합니다. ffmpeg에서 'select'필터를 사용하고 표현식에서 'scene'상수를 사용하면 디버그 출력 (-v 디버그 또는 인코딩 중에 '+'를 여러 번 누름)이 장면 변경 번호를 표시합니다. 이것은 아마도 x264가 사용하는 숫자와 다르고 유용하지는 않지만 여전히 유용 할 수 있습니다.

따라서이 절차는 아마도 키 프레임 변경만을위한 테스트 비디오를 수행하는 것이지만 2- 패스를 사용하는 경우 속도 제어 데이터에 사용될 수 있습니다. 일정한 프레임 속도 비디오로 변환 (생성 된 데이터는 서로 다른 해상도 및 설정에 대한 모든 유용한에 있는지 확실하지. 매크로 블록 트리 데이터는되지 않습니다)하지만 볼 이 버그를 당신이 이제까지 결정하는 경우 프레임 속도를 절반으로 할 때 출력을 망가에 대해 다른 목적으로 fps 필터를 사용합니다. 원하는 키 프레임 및 GOP 설정으로 x264를 통해 실행하십시오.

그런 다음이 키 프레임 시간을 원래 가변 프레임 속도 비디오와 함께 사용하십시오.

프레임간에 20 초 간격으로 완전히 미친 사용자 생성 콘텐츠를 허용하는 경우 가변 프레임 속도 인코딩의 경우 출력을 분할하고 fps 필터를 사용하고 어떻게 든 select 필터를 사용할 수 있습니다. ffmpeg 옵션이 작동하는 경우 테스트 비디오를 입력으로 사용하고 키 프레임 만 디코딩하거나 선택 필터를 사용하여 키 프레임을 선택할 수 있습니다. 그런 다음 올바른 크기로 조정하고 (이 경우 scale2ref 필터도 있음) 원본 비디오를 오버레이하십시오. 그런 다음 인터리브 필터를 사용하여 이러한 예정된 강제 키 프레임을 원본 비디오와 결합하십시오. 인터리브 필터로 방지 할 수없는 0.001 초 간격의 두 프레임이 발생하는 경우 다른 선택 필터를 사용하여이 문제를 직접 해결하십시오. 인터리브 필터에 대한 프레임 버퍼 한계를 다루는 것이 주요 문제가 될 수 있습니다. 이것들은 모두 작동 할 수 있습니다 : 어떤 종류의 필터를 사용하여 밀도가 높은 스트림을 버퍼링하십시오 (오 필터)? 입력 파일을 여러 번 참조하여 파일이 두 번 이상 디코딩되고 프레임을 저장할 필요가 없습니다. 정확히 키 프레임 시간에 내가 한 적이없는 'streamselect'필터를 사용하십시오. 기본 동작을 변경하거나 프레임을 삭제하는 대신 버퍼에서 가장 오래된 프레임을 출력하는 옵션을 추가하여 인터리브 필터를 개선하십시오. 정확히 키 프레임의 시간에 내가 한 적이 없습니다. 기본 동작을 변경하거나 프레임을 삭제하는 대신 버퍼에서 가장 오래된 프레임을 출력하는 옵션을 추가하여 인터리브 필터를 개선하십시오. 정확히 키 프레임의 시간에 내가 한 적이 없습니다. 기본 동작을 변경하거나 프레임을 삭제하는 대신 버퍼에서 가장 오래된 프레임을 출력하는 옵션을 추가하여 인터리브 필터를 개선하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.