이전 버전의 x264로 인코딩된 비디오를 올바르게 수정합니다.

이전 버전의 x264로 인코딩된 비디오를 올바르게 수정합니다.

x264 이전 버전의 버그로 인해 h.264 비디오 스트림은 다음 세 가지 속성을 갖습니다.

  1. x264 빌드 150 이하로 인코딩됨
  2. 4:4:4 크로마 서브샘플링 사용
  3. 비트스트림에는 x264 버전 정보가 없습니다.

많은 비디오 플레이어에서는 제대로 재생되지 않습니다. 새 버전의 비디오 플레이어에는 mpv전용 옵션이 있습니다.

--vd-lavc-assume-old-x264

특히 이 문제를 해결하는 방법(참조:https://mpv.io/manual/master/).

FFmpeg 버그 추적기적절한 SEI.h264를 비디오 스트림에 추가하는 것이 좋습니다(x264 버전 정보가 포함된 것 같습니다). 나는 그러한 해킹에 의존하지 않는 것을 선호하므로 내 질문은 다음과 같습니다.처음에 x264의 새로운 (고정) 버전으로 인코딩된 것처럼 파일을 복구하는 "적절한" 방법(이상적으로는 ffmpeg 사용)이 있습니까??

분명히 나는 ​​(다소) 비디오를 남기고 싶습니다.품질그리고파일 크기. 재인코딩이 필요한 경우 이전 x264 구현의 버그 동작을 수정하는 것 외에는 아무것도 변경하지 않아야 합니다. (추가 정보:버그 보고서손상된 파일의 예를 제공합니다. 이전 x264의 버그는 아마도여기에 소개.)

답변1

이 질문을 게시해주셔서 감사합니다. 제가 겪고 있는 문제의 본질을 이해하는 데 도움이 되었습니다. 작동하는 것 같은 솔루션이 있습니다.

제 경우에는 Ubuntu 리포지토리의 ffmpeg를 사용하고 있습니다. 내 libx264 파일을 디코딩할 수 있는 마지막 버전은 2.8.6이었습니다. 2.8.14 또는 2.8.15로 업그레이드한 후 설명하신 디코딩 문제가 발생했습니다. 이전 동영상을 다시 인코딩하고 싶지 않고, ffmpeg가 원래 인코딩 중에 발생한 오류를 올바르게 식별하고 제대로 재생할 수 있도록 헤더를 수정하고 싶습니다.

그래서 우선 나는최신 버전의 ffmpeg v4를 포함하는 정적 바이너리를 다운로드했습니다.. ffmpeg4사용 중인 버전을 제어할 수 있도록 이 바이너리를 내 시스템에 연결했습니다 . 2.8 이후에 도입된 새로운 기능 중 일부가 필요합니다(정확히 언제인지는 확실하지 않음). 최신 버전의 ffmpeg가 이미 설치되어 있는 경우 해당 버전을 사용하고 아래 명령에서 ffmpeg4로 바꾸십시오.ffmpeg

이제 손상된 비디오에서 원시 비트스트림을 추출합니다(BROKEN.mkv라고 함).

ffmpeg4 -i BROKEN.mkv -vcodec copy -an -bsf:v h264_mp4toannexb raw.h264

h264_mp4toannexb 플래그가 필요한지 확실하지 않습니다.자동으로 삽입될 수도 있습니다이 형식의 경우.

이제 비트스트림을 새로운 mp4 컨테이너에 넣고,SEI 헤더에서 오래된 버그 x264 빌드에 대한 정보를 수정합니다..

ffmpeg4 -r 30 -i raw.h264 -avoid_negative_ts 1 -bsf:v h264_metadata='sei_user_data=dc45e9bde6d948b7962cd820d923eeef+x264 - core 150' -c copy FIXED.mp4

비트스트림에는 타임스탬프 정보가 포함되어 있지 않으므로 여기에서 수많은 경고를 받게 됩니다. 또한 프레임 속도를 수동으로 30fps( -r 30)로 설정해야 한다는 사실도 발견했습니다. 그렇지 않으면 25~30fps 사이의 가변 프레임 속도를 추측했기 때문입니다. 타임스탬프를 올바르게 추출하는 방법이나 타임스탬프를 새 컨테이너에 올바르게 다중화하는 방법을 모르겠습니다. 수정사항이 있으면 알려주세요! 많은 사람들이 추천 -fflags +genpts하지만 그렇지 않습니다.뭐든 할 것 같아나를 위한. 마지막 -avoid_negative_ts 1으로 첫 번째 프레임의 타임스탬프가 음수가 아니도록 추가했습니다 .

마지막으로 이것은 선택 사항입니다. 결과를 MKV 컨테이너에 넣으려면 다음을 수행할 수 있습니다.

ffmpeg4 -i FIXED.mp4 -c copy FIXED.mkv

먼저 MP4로 변환한 다음 MKV로 변환합니다.? MKV 컨테이너는 단순히 타임스탬프 없이 진행을 거부하는 것처럼 보이지만 MP4는 그렇게 하고 경고만 발행합니다. 그러면 경고 없이 MKV로 변환할 수 있습니다.

그래서 이 모든 작업을 마친 후 MP4 및 MKV 파일을 작업하게 되었습니다. 그런데 일부 프레임을 검사해보니 사소한 변화(~2레벨 정도의 휘도 변화)가 있습니다. 무손실이어야 했기 때문에 왜 이런 일이 발생했는지 이해할 수 없습니다. 이 작업을 더 효과적으로 수행할 수 있는 방법에 대한 제안 사항이 있으면 알려 주시기 바랍니다.

편집: MP4 컨테이너에서 내 타임스탬프 중 일부가 -0.066667s부터 시작하여 음수인 것으로 나타났습니다. MKV 컨테이너로 이동한 후 모든 음수 타임스탬프는 0이 되었습니다. -output_ts_offset 0.066667명령에 추가하면 이 문제가 해결되고 0에서 시작됩니다. 그래도 왜 -0.066667에서 시작했는지 이해할 수 없습니다.

편집 2: 음수 타임스탬프를 제거하는 더 좋은 방법은 mp4를 인코딩할 때 "-avoid_negative_ts 1"을 사용하는 것입니다.

관련 정보