diff options
author | Tim Walker <tdskywalker@gmail.com> | 2014-03-03 18:53:42 +0400 |
---|---|---|
committer | Vittorio Giovara <vittorio.giovara@gmail.com> | 2014-03-09 21:09:40 +0400 |
commit | b6c61fb83e876d404ac3b0b3657ebfcafdcd1926 (patch) | |
tree | 834651d24d895171ad86398106ac3f3d51937671 /libavformat/hevc.c | |
parent | 20b40a597cdd4969cf1147d7c7efee2b6232524b (diff) |
movenc: enable Annex B to MP4 conversion for HEVC tracks.
Diffstat (limited to 'libavformat/hevc.c')
-rw-r--r-- | libavformat/hevc.c | 101 |
1 files changed, 101 insertions, 0 deletions
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) { |