[FFmpeg-devel] [PATCH v2] avcodec/h264_sei: Add acces to truncated SEI data
Antonin Gouzer
antonin.gouzer at gmail.com
Sat Jun 8 16:21:45 EEST 2019
---
Some codecs editors had miss interpreted the H264 standart and
have coded a wrong size in the SEI data.
size = SEI size + 1.
The SEI data is detected as "truncated"
Ex: https://drive.google.com/file/d/1cNtLwnfPnyJnYqE7OYhU3SCoLRtuXIUM/view?usp=sharing
Command:
ffprobe -print_format xml -show_frames -read_intervals %+0.04 truncated.h264
This (simple) patch add the possibility to read this false truncated SEI data with the default stric_std_compliance or less.
The error remain logged in both cases.
V2: Modifiy the patch for only the off by one values
Thanks in advance !
---
libavcodec/h264_sei.c | 24 +++++++++++++++---------
libavcodec/h264_sei.h | 2 +-
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index d4eb9c0dab..7871cf87ed 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -402,7 +402,7 @@ static int decode_alternative_transfer(H264SEIAlternativeTransfer *h,
}
int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
- const H264ParamSets *ps, void *logctx)
+ const H264ParamSets *ps, AVCodecContext *avctx)
{
int master_ret = 0;
@@ -425,27 +425,33 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
} while (get_bits(gb, 8) == 255);
if (size > get_bits_left(gb) / 8) {
- av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n",
+
+ if (size == get_bits_left(gb) / 8 + 1 && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL){
+ av_log(avctx, AV_LOG_WARNING, "SEI type %d size %d truncated at %d\n",
type, 8*size, get_bits_left(gb));
- return AVERROR_INVALIDDATA;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d, data will not be read\n",
+ type, 8*size, get_bits_left(gb));
+ return AVERROR_INVALIDDATA;
+ }
}
next = get_bits_count(gb) + 8 * size;
switch (type) {
case H264_SEI_TYPE_PIC_TIMING: // Picture timing SEI
- ret = decode_picture_timing(&h->picture_timing, gb, ps, logctx);
+ ret = decode_picture_timing(&h->picture_timing, gb, ps, avctx);
break;
case H264_SEI_TYPE_USER_DATA_REGISTERED:
- ret = decode_registered_user_data(h, gb, logctx, size);
+ ret = decode_registered_user_data(h, gb, avctx, size);
break;
case H264_SEI_TYPE_USER_DATA_UNREGISTERED:
- ret = decode_unregistered_user_data(&h->unregistered, gb, logctx, size);
+ ret = decode_unregistered_user_data(&h->unregistered, gb, avctx, size);
break;
case H264_SEI_TYPE_RECOVERY_POINT:
- ret = decode_recovery_point(&h->recovery_point, gb, logctx);
+ ret = decode_recovery_point(&h->recovery_point, gb, avctx);
break;
case H264_SEI_TYPE_BUFFERING_PERIOD:
- ret = decode_buffering_period(&h->buffering_period, gb, ps, logctx);
+ ret = decode_buffering_period(&h->buffering_period, gb, ps, avctx);
break;
case H264_SEI_TYPE_FRAME_PACKING:
ret = decode_frame_packing_arrangement(&h->frame_packing, gb);
@@ -460,7 +466,7 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
ret = decode_alternative_transfer(&h->alternative_transfer, gb);
break;
default:
- av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);
+ av_log(avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);
}
if (ret < 0 && ret != AVERROR_PS_NOT_FOUND)
return ret;
diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h
index a75c3aa175..32f3d67096 100644
--- a/libavcodec/h264_sei.h
+++ b/libavcodec/h264_sei.h
@@ -190,7 +190,7 @@ typedef struct H264SEIContext {
struct H264ParamSets;
int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb,
- const struct H264ParamSets *ps, void *logctx);
+ const struct H264ParamSets *ps, AVCodecContext *avctx);
/**
* Reset SEI values at the beginning of the frame.
--
2.11.0
More information about the ffmpeg-devel
mailing list