Re: [FFmpeg-devel] [PATCH v10 4/4] avcodec/h264: create user data unregistered SEI side data for H.264
On Wed, Jun 10, 2020 at 10:57:00AM +0200, Marton Balint wrote: > > > On Wed, 10 Jun 2020, lance.lmw...@gmail.com wrote: > > > From: Limin Wang > > > > Signed-off-by: Limin Wang > > --- > > libavcodec/h264_sei.c | 30 +-- > > libavcodec/h264_sei.h | 2 + > > libavcodec/h264_slice.c | 14 > > tests/ref/fate/mov-zombie | 195 > > ++ > > 4 files changed, 171 insertions(+), 70 deletions(-) > > > > diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c > > index 870dd90..0d96fcb 100644 > > --- a/libavcodec/h264_sei.c > > +++ b/libavcodec/h264_sei.c > > @@ -24,6 +24,7 @@ > > * H.264 / AVC / MPEG-4 part10 SEI decoding. > > * @author Michael Niedermayer > > */ > > +#include > > > > #include "avcodec.h" > > #include "get_bits.h" > > @@ -52,6 +53,10 @@ void ff_h264_sei_uninit(H264SEIContext *h) > > h->afd.present = 0; > > > > av_buffer_unref(&h->a53_caption.buf_ref); > > +for (int i = 0; i < h->unregistered.nb_buf_ref; i++) > > +av_buffer_unref(&h->unregistered.buf_ref[i]); > > +h->unregistered.nb_buf_ref = 0; > > +av_freep(&h->unregistered.buf_ref); > > } > > > > int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS > > *sps, > > @@ -255,30 +260,45 @@ static int decode_registered_user_data(H264SEIContext > > *h, GetBitContext *gb, > > return 0; > > } > > > > +static int string_is_print(const uint8_t *str) > > +{ > > +while (isprint(*str)) str++; > > +return !*str; > > +} > > + > > static int decode_unregistered_user_data(H264SEIUnregistered *h, > > GetBitContext *gb, > > void *logctx, int size) > > { > > uint8_t *user_data; > > int e, build, i; > > +AVBufferRef *buf_ref, **tmp; > > > > -if (size < 16 || size >= INT_MAX - 1) > > +if (size < 16) > > return AVERROR_INVALIDDATA; > > > > -user_data = av_malloc(size + 1); > > -if (!user_data) > > +tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, > > sizeof(*h->buf_ref)); > > +if (!tmp) > > return AVERROR(ENOMEM); > > +h->buf_ref = tmp; > > + > > +buf_ref = av_buffer_alloc(size); > > +if (!buf_ref) > > +return AVERROR(ENOMEM); > > +user_data = buf_ref->data; > > > > for (i = 0; i < size; i++) > > user_data[i] = get_bits(gb, 8); > > +h->buf_ref[h->nb_buf_ref++] = buf_ref; > > + > > +if (!string_is_print(user_data + 16)) > > +return 0; > > This check is overkill, alloc size+1 buffer instead, so you can leave the > code as is. This way you don't even need ctype here. OK, will use size+1 although it's have one extra byte if user data is not string. I haven't got such condition yet. > > Thanks, > Marton > > > > > -user_data[i] = 0; > > e = sscanf(user_data + 16, "x264 - core %d", &build); > > if (e == 1 && build > 0) > > h->x264_build = build; > > if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core ", > > 16)) > > h->x264_build = 67; > > > > -av_free(user_data); > > return 0; > > } > > > > diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h > > index f07a505..4fdcf4e 100644 > > --- a/libavcodec/h264_sei.h > > +++ b/libavcodec/h264_sei.h > > @@ -126,6 +126,8 @@ typedef struct H264SEIA53Caption { > > > > typedef struct H264SEIUnregistered { > > int x264_build; > > +AVBufferRef **buf_ref; > > +int nb_buf_ref; > > } H264SEIUnregistered; > > > > typedef struct H264SEIRecoveryPoint { > > diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c > > index 7139537..47f3917 100644 > > --- a/libavcodec/h264_slice.c > > +++ b/libavcodec/h264_slice.c > > @@ -1289,6 +1289,20 @@ static int h264_export_frame_props(H264Context *h) > > h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; > > } > > > > +for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { > > +H264SEIUnregistered *unreg = &h->sei.unregistered; > > + > > +if (unreg->buf_ref[i]) { > > +AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, > > +AV_FRAME_DATA_SEI_UNREGISTERED, > > +unreg->buf_ref[i]); > > +if (!sd) > > +av_buffer_unref(&unreg->buf_ref[i]); > > +unreg->buf_ref[i] = NULL; > > +} > > +} > > +h->sei.unregistered.nb_buf_ref = 0; > > + > > if (h->sei.picture_timing.timecode_cnt > 0) { > > uint32_t tc = 0; > > uint32_t *tc_sd; > > diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie > > index 445f921..1a6625b 100644 > > --- a/tests/ref/fate/mov-zombie > > +++ b/tests/ref/fate/mov-zombie > > @@ -1,133 +1,198 @@ > > packet|codec_type=video|stream_index=0|pts=0|pts_time=0.00|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ > > pac
Re: [FFmpeg-devel] [PATCH v10 4/4] avcodec/h264: create user data unregistered SEI side data for H.264
On Wed, 10 Jun 2020, lance.lmw...@gmail.com wrote: From: Limin Wang Signed-off-by: Limin Wang --- libavcodec/h264_sei.c | 30 +-- libavcodec/h264_sei.h | 2 + libavcodec/h264_slice.c | 14 tests/ref/fate/mov-zombie | 195 ++ 4 files changed, 171 insertions(+), 70 deletions(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 870dd90..0d96fcb 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -24,6 +24,7 @@ * H.264 / AVC / MPEG-4 part10 SEI decoding. * @author Michael Niedermayer */ +#include #include "avcodec.h" #include "get_bits.h" @@ -52,6 +53,10 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->afd.present = 0; av_buffer_unref(&h->a53_caption.buf_ref); +for (int i = 0; i < h->unregistered.nb_buf_ref; i++) +av_buffer_unref(&h->unregistered.buf_ref[i]); +h->unregistered.nb_buf_ref = 0; +av_freep(&h->unregistered.buf_ref); } int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, @@ -255,30 +260,45 @@ static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, return 0; } +static int string_is_print(const uint8_t *str) +{ +while (isprint(*str)) str++; +return !*str; +} + static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb, void *logctx, int size) { uint8_t *user_data; int e, build, i; +AVBufferRef *buf_ref, **tmp; -if (size < 16 || size >= INT_MAX - 1) +if (size < 16) return AVERROR_INVALIDDATA; -user_data = av_malloc(size + 1); -if (!user_data) +tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); +if (!tmp) return AVERROR(ENOMEM); +h->buf_ref = tmp; + +buf_ref = av_buffer_alloc(size); +if (!buf_ref) +return AVERROR(ENOMEM); +user_data = buf_ref->data; for (i = 0; i < size; i++) user_data[i] = get_bits(gb, 8); +h->buf_ref[h->nb_buf_ref++] = buf_ref; + +if (!string_is_print(user_data + 16)) +return 0; This check is overkill, alloc size+1 buffer instead, so you can leave the code as is. This way you don't even need ctype here. Thanks, Marton -user_data[i] = 0; e = sscanf(user_data + 16, "x264 - core %d", &build); if (e == 1 && build > 0) h->x264_build = build; if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core ", 16)) h->x264_build = 67; -av_free(user_data); return 0; } diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index f07a505..4fdcf4e 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -126,6 +126,8 @@ typedef struct H264SEIA53Caption { typedef struct H264SEIUnregistered { int x264_build; +AVBufferRef **buf_ref; +int nb_buf_ref; } H264SEIUnregistered; typedef struct H264SEIRecoveryPoint { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 7139537..47f3917 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1289,6 +1289,20 @@ static int h264_export_frame_props(H264Context *h) h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } +for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { +H264SEIUnregistered *unreg = &h->sei.unregistered; + +if (unreg->buf_ref[i]) { +AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, +AV_FRAME_DATA_SEI_UNREGISTERED, +unreg->buf_ref[i]); +if (!sd) +av_buffer_unref(&unreg->buf_ref[i]); +unreg->buf_ref[i] = NULL; +} +} +h->sei.unregistered.nb_buf_ref = 0; + if (h->sei.picture_timing.timecode_cnt > 0) { uint32_t tc = 0; uint32_t *tc_sd; diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie index 445f921..1a6625b 100644 --- a/tests/ref/fate/mov-zombie +++ b/tests/ref/fate/mov-zombie @@ -1,133 +1,198 @@ packet|codec_type=video|stream_index=0|pts=0|pts_time=0.00|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1077|pos=15442|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.00|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.00|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=tople
[FFmpeg-devel] [PATCH v10 4/4] avcodec/h264: create user data unregistered SEI side data for H.264
From: Limin Wang Signed-off-by: Limin Wang --- libavcodec/h264_sei.c | 30 +-- libavcodec/h264_sei.h | 2 + libavcodec/h264_slice.c | 14 tests/ref/fate/mov-zombie | 195 ++ 4 files changed, 171 insertions(+), 70 deletions(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 870dd90..0d96fcb 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -24,6 +24,7 @@ * H.264 / AVC / MPEG-4 part10 SEI decoding. * @author Michael Niedermayer */ +#include #include "avcodec.h" #include "get_bits.h" @@ -52,6 +53,10 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->afd.present = 0; av_buffer_unref(&h->a53_caption.buf_ref); +for (int i = 0; i < h->unregistered.nb_buf_ref; i++) +av_buffer_unref(&h->unregistered.buf_ref[i]); +h->unregistered.nb_buf_ref = 0; +av_freep(&h->unregistered.buf_ref); } int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, @@ -255,30 +260,45 @@ static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, return 0; } +static int string_is_print(const uint8_t *str) +{ +while (isprint(*str)) str++; +return !*str; +} + static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb, void *logctx, int size) { uint8_t *user_data; int e, build, i; +AVBufferRef *buf_ref, **tmp; -if (size < 16 || size >= INT_MAX - 1) +if (size < 16) return AVERROR_INVALIDDATA; -user_data = av_malloc(size + 1); -if (!user_data) +tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); +if (!tmp) return AVERROR(ENOMEM); +h->buf_ref = tmp; + +buf_ref = av_buffer_alloc(size); +if (!buf_ref) +return AVERROR(ENOMEM); +user_data = buf_ref->data; for (i = 0; i < size; i++) user_data[i] = get_bits(gb, 8); +h->buf_ref[h->nb_buf_ref++] = buf_ref; + +if (!string_is_print(user_data + 16)) +return 0; -user_data[i] = 0; e = sscanf(user_data + 16, "x264 - core %d", &build); if (e == 1 && build > 0) h->x264_build = build; if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core ", 16)) h->x264_build = 67; -av_free(user_data); return 0; } diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index f07a505..4fdcf4e 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -126,6 +126,8 @@ typedef struct H264SEIA53Caption { typedef struct H264SEIUnregistered { int x264_build; +AVBufferRef **buf_ref; +int nb_buf_ref; } H264SEIUnregistered; typedef struct H264SEIRecoveryPoint { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 7139537..47f3917 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1289,6 +1289,20 @@ static int h264_export_frame_props(H264Context *h) h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } +for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { +H264SEIUnregistered *unreg = &h->sei.unregistered; + +if (unreg->buf_ref[i]) { +AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, +AV_FRAME_DATA_SEI_UNREGISTERED, +unreg->buf_ref[i]); +if (!sd) +av_buffer_unref(&unreg->buf_ref[i]); +unreg->buf_ref[i] = NULL; +} +} +h->sei.unregistered.nb_buf_ref = 0; + if (h->sei.picture_timing.timecode_cnt > 0) { uint32_t tc = 0; uint32_t *tc_sd; diff --git a/tests/ref/fate/mov-zombie b/tests/ref/fate/mov-zombie index 445f921..1a6625b 100644 --- a/tests/ref/fate/mov-zombie +++ b/tests/ref/fate/mov-zombie @@ -1,133 +1,198 @@ packet|codec_type=video|stream_index=0|pts=0|pts_time=0.00|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1077|pos=15442|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.00|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.00|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.00|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|b