
x264 이전 버전의 버그로 인해 h.264 비디오 스트림은 다음 세 가지 속성을 갖습니다.
- x264 빌드 150 이하로 인코딩됨
- 4:4:4 크로마 서브샘플링 사용
- 비트스트림에는 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"을 사용하는 것입니다.