[FFmpeg-devel] [PATCH v5 3/3] hevc_mp4toannexb: Parse extradata directly from HVCC format
Andriy Gelman
andriy.gelman at gmail.com
Thu Sep 26 21:10:01 EEST 2019
From: Andriy Gelman <andriy.gelman at gmail.com>
Since the original extradata is in HVCC format, there is no need to
segment the output extradata into nal units.
---
libavcodec/hevc_mp4toannexb_bsf.c | 66 ++++++++++++++++---------------
1 file changed, 34 insertions(+), 32 deletions(-)
diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c
index 90a4d17d25..78176290d8 100644
--- a/libavcodec/hevc_mp4toannexb_bsf.c
+++ b/libavcodec/hevc_mp4toannexb_bsf.c
@@ -228,12 +228,17 @@ static int update_paramset(AVBSFContext *ctx, H2645NAL *nal)
static int hevc_extradata_to_annexb(AVBSFContext *ctx)
{
+ HEVCBSFContext *s = ctx->priv_data;
GetByteContext gb;
int length_size, num_arrays, i, j;
int ret = 0;
uint8_t *new_extradata = NULL;
size_t new_extradata_size = 0;
+ size_t start, end;
+
+ H2645Packet pkt;
+ memset(&pkt, 0, sizeof(H2645Packet)); /*in case goto fail is called before pkt is initialized*/
bytestream2_init(&gb, ctx->par_in->extradata, ctx->par_in->extradata_size);
@@ -253,6 +258,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
goto fail;
}
+ start = bytestream2_tell(&gb);
for (j = 0; j < cnt; j++) {
int nalu_len = bytestream2_get_be16(&gb);
@@ -269,6 +275,32 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
new_extradata_size += 4 + nalu_len;
memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
+ end = bytestream2_tell(&gb);
+
+ /*split extradata into nalu packets*/
+ ret = ff_h2645_packet_split(&pkt, ctx->par_in->extradata + start,
+ end - start, ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 0);
+ if (ret < 0)
+ goto fail;
+
+ /*parse the segmented nals*/
+ for (j = 0; j < pkt.nb_nals; j++) {
+ H2645NAL *nal = &pkt.nals[j];
+
+ if (IS_PARAMSET(nal)) {
+ ret = update_paramset(ctx, nal);
+ if (ret < 0)
+ goto fail;
+ continue;
+ }
+
+ if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) {
+ ret = append_sei_annexb(&s->ps.sei, nal);
+ if (ret < 0)
+ goto fail;
+ }
+ }
+ ff_h2645_packet_uninit(&pkt);
}
av_freep(&ctx->par_out->extradata);
@@ -280,6 +312,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
return length_size;
fail:
+ ff_h2645_packet_uninit(&pkt);
av_freep(&new_extradata);
return ret;
}
@@ -287,51 +320,20 @@ fail:
static int hevc_mp4toannexb_init(AVBSFContext *ctx)
{
HEVCBSFContext *s = ctx->priv_data;
- H2645Packet pkt;
- int i, ret;
+ int ret = 0;
if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH ||
AV_RB24(ctx->par_in->extradata) == 1 ||
AV_RB32(ctx->par_in->extradata) == 1) {
av_log(ctx, AV_LOG_VERBOSE,
"The input looks like it is Annex B already\n");
- return 0;
} else {
ret = hevc_extradata_to_annexb(ctx);
if (ret < 0)
return ret;
s->length_size = ret;
s->extradata_parsed = 1;
-
- memset(&pkt, 0, sizeof(H2645Packet));
- ret = ff_h2645_packet_split(&pkt, ctx->par_out->extradata, ctx->par_out->extradata_size,
- ctx, 0, 0, AV_CODEC_ID_HEVC, 1, 0);
- if (ret < 0)
- goto done;
-
- for (i = 0; i < pkt.nb_nals; ++i) {
- H2645NAL *nal = &pkt.nals[i];
-
- /*current segmentation algorithm includes next 0x00 from next nal unit*/
- if (nal->raw_data[nal->raw_size - 1] == 0x00)
- nal->raw_size--;
-
- if (IS_PARAMSET(nal)) {
- ret = update_paramset(ctx, nal);
- if (ret < 0)
- goto done;
- continue;
- }
-
- if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) {
- ret = append_sei_annexb(&s->ps.sei, nal);
- if (ret < 0)
- goto done;
- }
- }
}
-done:
- ff_h2645_packet_uninit(&pkt);
return ret;
}
--
2.23.0
More information about the ffmpeg-devel
mailing list