@@ -243,12 +243,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);
@@ -268,6 +273,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);
@@ -284,6 +290,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);
@@ -295,6 +327,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
return length_size;
fail:
+ ff_h2645_packet_uninit(&pkt);
av_freep(&new_extradata);
return ret;
}
@@ -302,7 +335,6 @@ fail:
static int hevc_mp4toannexb_init(AVBSFContext *ctx)
{
HEVCBSFContext *s = ctx->priv_data;
- H2645Packet pkt;
int ret;
if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH ||
@@ -310,44 +342,14 @@ static int hevc_mp4toannexb_init(AVBSFContext *ctx)
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 (int 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;
+ return 0;
}
static void ps_uninit(ParamSets *ps)
From: Andriy Gelman <andriy.gelman@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(-)