はじめに
表題の通り、PythonのOpenCVを使って動画からフレームを読み込んだ時でデコード中にエラーが発生しました。
調査しても解決したというような内容がないので、とりあえず私が対処した方法を共有しようか思い、投稿してみました。
「私、同じようなことが起きてこんな対処したよ」なんてことがある人が入ればコメントを残して頂けると幸いです。
エラー内容
環境
- Ubuntu 20.04
- Python 3.8
実行したソースコード
以下のソースコードは解析のため最低限まで減らしたソースコード。この状態でも発生する
import cv2
cap = cv2.VideoCapture('動画パス')
whlie cap.isOpened():
ret, frame = cap.read()
if not ret:
break
エラー文
missing picture in access unit with size104922
Invalid NAL unit size (-1378577636 > 104918)
Error splitting the input into NAL units.
cabac decode of qscale diff failed at 20 128
error while decoding MB 20 128, bytestream 15066
読み込んだ動画
- MP4の4K動画
事象
3万フレームの動画を1枚ずつ読み込み、500フレームのデコード中にエラーが発生し、cap.read() の戻り値retが Falseとなり終了する。
発生している事象は以下のイメージでデコードが発生するとcap.read()を実行しても次のフレームに移動しないような仕様になっているようで終了する。。
そのため、処理するフレームが残っている場合は読み込むフレームをセットする処理を追加する。
以下のようなイメージの仕様になる想定。
対策
今回困ったことに残りの2万5500フレームが読み込まれずに終わることが問題。その対策が以下の通り。
import cv2
cap = cv2.VideoCapture('動画パス')
for i in range(cap.get(cv2.CAP_FROP_FRAME_COUNT)):
ret, frame = cap.read()
if not ret:
if cap.get(cv2.CAP_PROP_POS_FRAMES) < cap.get(cv2.CAP_PROP_FRAME_COUNT):
cap.set(cv2.CAP_PROP_POS_FRAMES, i)
continue
break
上記のように書き込むことで、途中で終わることがなくすべてのフレームを読み込むことができる。
簡単な話ではあるものの、読み込みができないと次のフレームに移動しないこと知らないと対策も思いつけないこともあるので解析は大切ですね。
この対処法ではデコード中のエラーがなぜ発生しているかが分からないことも問題点は残っているので要調査ではあります。