When creating H.264 or HEVC extradata from annex B extradata or when transforming annex B into HEVC while also filtering parameter sets away, the whole input has first been transformed into mp4-style H.264/HEVC in order to simplify parsing at the next step. By using ff_avc_parse_nalu, one can avoid these intermediate steps (which involved (re)allocations).
Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavformat/avc.c | 28 ++++++++----------------- libavformat/hevc.c | 52 +++++++++++++--------------------------------- 2 files changed, 23 insertions(+), 57 deletions(-) diff --git a/libavformat/avc.c b/libavformat/avc.c index d089051034..98462940ad 100644 --- a/libavformat/avc.c +++ b/libavformat/avc.c @@ -147,7 +147,7 @@ int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size) int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) { AVIOContext *sps_pb = NULL, *pps_pb = NULL, *sps_ext_pb = NULL; - uint8_t *buf, *end, *start; + const uint8_t *nal, *nal_end, *end; uint8_t *sps, *pps, *sps_ext; uint32_t sps_size = 0, pps_size = 0, sps_ext_size = 0; int ret, nb_sps = 0, nb_pps = 0, nb_sps_ext = 0; @@ -162,12 +162,6 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) return 0; } - ret = ff_avc_parse_nal_units_buf(data, &buf, &len); - if (ret < 0) - return ret; - start = buf; - end = buf + len; - ret = avio_open_dyn_buf(&sps_pb); if (ret < 0) goto fail; @@ -179,12 +173,11 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) goto fail; /* look for sps and pps */ - while (end - buf > 4) { - uint32_t size; - uint8_t nal_type; - size = FFMIN(AV_RB32(buf), end - buf - 4); - buf += 4; - nal_type = buf[0] & 0x1f; + nal_end = NULL; + end = data + len; + while (nal = ff_avc_parse_nalu(&data, &nal_end, end)) { + uint32_t size = nal_end - nal; + uint8_t nal_type = nal[0] & 0x1f; if (nal_type == 7) { /* SPS */ nb_sps++; @@ -193,7 +186,7 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) goto fail; } avio_wb16(sps_pb, size); - avio_write(sps_pb, buf, size); + avio_write(sps_pb, nal, size); } else if (nal_type == 8) { /* PPS */ nb_pps++; if (size > UINT16_MAX || nb_pps >= H264_MAX_PPS_COUNT) { @@ -201,7 +194,7 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) goto fail; } avio_wb16(pps_pb, size); - avio_write(pps_pb, buf, size); + avio_write(pps_pb, nal, size); } else if (nal_type == 13) { /* SPS_EXT */ nb_sps_ext++; if (size > UINT16_MAX || nb_sps_ext >= 256) { @@ -209,10 +202,8 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) goto fail; } avio_wb16(sps_ext_pb, size); - avio_write(sps_ext_pb, buf, size); + avio_write(sps_ext_pb, nal, size); } - - buf += size; } sps_size = avio_get_dyn_buf(sps_pb, &sps); pps_size = avio_get_dyn_buf(pps_pb, &pps); @@ -252,7 +243,6 @@ fail: ffio_free_dyn_buf(&sps_pb); ffio_free_dyn_buf(&pps_pb); ffio_free_dyn_buf(&sps_ext_pb); - av_free(start); return ret; } diff --git a/libavformat/hevc.c b/libavformat/hevc.c index 94eb3a9cb1..095988b7df 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -35,7 +35,7 @@ typedef struct HVCCNALUnitArray { uint8_t NAL_unit_type; uint16_t numNalus; uint16_t *nalUnitLength; - uint8_t **nalUnit; + const uint8_t **nalUnit; } HVCCNALUnitArray; typedef struct HEVCDecoderConfigurationRecord { @@ -657,7 +657,7 @@ static void nal_unit_parse_header(GetBitContext *gb, uint8_t *nal_type) skip_bits(gb, 9); } -static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, +static int hvcc_array_add_nal_unit(const uint8_t *nal_buf, uint32_t nal_size, uint8_t nal_type, int ps_array_completeness, HEVCDecoderConfigurationRecord *hvcc) { @@ -710,7 +710,7 @@ static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, return 0; } -static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, +static int hvcc_add_nal_unit(const uint8_t *nal_buf, uint32_t nal_size, int ps_array_completeness, HEVCDecoderConfigurationRecord *hvcc) { @@ -1000,26 +1000,16 @@ int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count) { int num_ps = 0, ret = 0; - uint8_t *buf, *end, *start = NULL; + const uint8_t *nal, *nal_end = NULL, *end = buf_in + size; if (!filter_ps) { ret = ff_avc_parse_nal_units(pb, buf_in, size); goto end; } - ret = ff_avc_parse_nal_units_buf(buf_in, &start, &size); - if (ret < 0) - goto end; - - ret = 0; - buf = start; - end = start + size; - - while (end - buf > 4) { - uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); - uint8_t type = (buf[4] >> 1) & 0x3f; - - buf += 4; + while (nal = ff_avc_parse_nalu(&buf_in, &nal_end, end)) { + uint32_t len = nal_end - nal; + uint8_t type = (nal[0] >> 1) & 0x3f; switch (type) { case HEVC_NAL_VPS: @@ -1030,15 +1020,12 @@ int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, default: ret += 4 + len; avio_wb32(pb, len); - avio_write(pb, buf, len); + avio_write(pb, nal, len); break; } - - buf += len; } end: - av_free(start); if (ps_count) *ps_count = num_ps; return ret; @@ -1069,7 +1056,7 @@ int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness) { HEVCDecoderConfigurationRecord hvcc; - uint8_t *buf, *end, *start; + const uint8_t *nal, *nal_end = NULL, *end; int ret; if (size < 6) { @@ -1084,20 +1071,12 @@ int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, return AVERROR_INVALIDDATA; } - ret = ff_avc_parse_nal_units_buf(data, &start, &size); - if (ret < 0) - return ret; - hvcc_init(&hvcc); - buf = start; - end = start + size; - - while (end - buf > 4) { - uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); - uint8_t type = (buf[4] >> 1) & 0x3f; - - buf += 4; + end = data + size; + while (nal = ff_avc_parse_nalu(&data, &nal_end, end)) { + uint32_t len = nal_end - nal; + uint8_t type = (nal[0] >> 1) & 0x3f; switch (type) { case HEVC_NAL_VPS: @@ -1105,21 +1084,18 @@ int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, case HEVC_NAL_PPS: case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: - ret = hvcc_add_nal_unit(buf, len, ps_array_completeness, &hvcc); + ret = hvcc_add_nal_unit(nal, len, ps_array_completeness, &hvcc); if (ret < 0) goto end; break; default: break; } - - buf += len; } ret = hvcc_write(pb, &hvcc); end: hvcc_close(&hvcc); - av_free(start); return ret; } -- 2.20.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".