From b6c61fb83e876d404ac3b0b3657ebfcafdcd1926 Mon Sep 17 00:00:00 2001 From: Tim Walker Date: Mon, 3 Mar 2014 14:53:42 +0000 Subject: movenc: enable Annex B to MP4 conversion for HEVC tracks. --- libavformat/hevc.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'libavformat/hevc.c') diff --git a/libavformat/hevc.c b/libavformat/hevc.c index ab4eb10a8b..2c1b4c492d 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -1014,6 +1014,107 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) return 0; } +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; + + 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; + + switch (type) { + case NAL_VPS: + case NAL_SPS: + case NAL_PPS: + num_ps++; + break; + default: + ret += 4 + len; + avio_wb32(pb, len); + avio_write(pb, buf, len); + break; + } + + buf += len; + } + +end: + free(start); + if (ps_count) + *ps_count = num_ps; + return ret; +} + +int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, + int *size, int filter_ps, int *ps_count) +{ + AVIOContext *pb; + int num_ps = 0, ret = 0; + uint8_t *buf, *end, *start = NULL; + + if (!filter_ps) { + ret = ff_avc_parse_nal_units_buf(buf_in, buf_out, size); + goto end; + } + + ret = avio_open_dyn_buf(&pb); + if (ret < 0) + goto end; + + ret = ff_avc_parse_nal_units_buf(buf_in, &start, size); + if (ret < 0) + goto end; + + 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; + + switch (type) { + case NAL_VPS: + case NAL_SPS: + case NAL_PPS: + num_ps++; + break; + default: + avio_wb32(pb, len); + avio_write(pb, buf, len); + break; + } + + buf += len; + } + + *size = avio_close_dyn_buf(pb, buf_out); + +end: + free(start); + if (ps_count) + *ps_count = num_ps; + return ret; +} + int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness) { -- cgit v1.2.3