-
-
Save rcombs/318dbc4a324a13473a79 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c | |
index ae96ee9..dfbd643 100644 | |
--- a/libavcodec/h264_mp4toannexb_bsf.c | |
+++ b/libavcodec/h264_mp4toannexb_bsf.c | |
@@ -63,56 +63,83 @@ static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, | |
return 0; | |
} | |
+#define NAL_SPS 33 | |
+#define NAL_PPS 34 | |
+ | |
static int h264_extradata_to_annexb(H264BSFContext *ctx, AVCodecContext *avctx, const int padding) | |
{ | |
- uint16_t unit_size; | |
+ int hevc = 1; | |
+ uint16_t unit_size, unit_nb; | |
uint64_t total_size = 0; | |
- uint8_t *out = NULL, unit_nb, sps_done = 0, | |
- sps_seen = 0, pps_seen = 0; | |
- const uint8_t *extradata = avctx->extradata + 4; | |
+ uint8_t *out = NULL, sps_done = 0, | |
+ sps_seen = 0, pps_seen = 0, set_nb; | |
+ const uint8_t *extradata = avctx->extradata + (hevc ? 21 : 4); | |
static const uint8_t nalu_header[4] = { 0, 0, 0, 1 }; | |
int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size | |
ctx->sps_offset = ctx->pps_offset = -1; | |
- /* retrieve sps and pps unit(s) */ | |
- unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ | |
- if (!unit_nb) { | |
- goto pps; | |
- } else { | |
- ctx->sps_offset = 0; | |
- sps_seen = 1; | |
- } | |
- | |
- while (unit_nb--) { | |
- int err; | |
+ set_nb = hevc ? *extradata++ : 1; | |
- unit_size = AV_RB16(extradata); | |
- total_size += unit_size + 4; | |
- if (total_size > INT_MAX - padding) { | |
- av_log(avctx, AV_LOG_ERROR, | |
- "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n"); | |
- av_free(out); | |
- return AVERROR(EINVAL); | |
- } | |
- if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) { | |
- av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, " | |
- "corrupted stream or invalid MP4/AVCC bitstream\n"); | |
- av_free(out); | |
- return AVERROR(EINVAL); | |
- } | |
- if ((err = av_reallocp(&out, total_size + padding)) < 0) | |
- return err; | |
- memcpy(out + total_size - unit_size - 4, nalu_header, 4); | |
- memcpy(out + total_size - unit_size, extradata + 2, unit_size); | |
- extradata += 2 + unit_size; | |
-pps: | |
- if (!unit_nb && !sps_done++) { | |
- unit_nb = *extradata++; /* number of pps unit(s) */ | |
- if (unit_nb) { | |
- ctx->pps_offset = (extradata - 1) - (avctx->extradata + 4); | |
+ while (set_nb--) { | |
+ int type = hevc ? *extradata++ & 0x3f : 0; | |
+ /* retrieve sps and pps unit(s) */ | |
+ if (hevc) { | |
+ unit_nb = AV_RB16(extradata); | |
+ extradata += 2; | |
+ if (type == NAL_SPS) { | |
+ ctx->sps_offset = total_size; | |
+ sps_seen = 1; | |
+ } else if (type == NAL_PPS) { | |
+ ctx->pps_offset = total_size; | |
pps_seen = 1; | |
} | |
+ } else { | |
+ unit_nb = *extradata++ & 0x1f; /* number of units */ | |
+ if (!unit_nb) { | |
+ type = NAL_PPS; | |
+ goto pps; | |
+ } else { | |
+ type = NAL_SPS; | |
+ ctx->sps_offset = 0; | |
+ sps_seen = 1; | |
+ } | |
+ } | |
+ | |
+ while (unit_nb--) { | |
+ int err; | |
+ | |
+ unit_size = AV_RB16(extradata); | |
+ if (type == NAL_SPS || type == NAL_PPS || !hevc) { | |
+ if (!hevc) | |
+ ctx->sps_offset = total_size; | |
+ total_size += unit_size + 4; | |
+ if (total_size > INT_MAX - padding) { | |
+ av_log(avctx, AV_LOG_ERROR, | |
+ "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n"); | |
+ av_free(out); | |
+ return AVERROR(EINVAL); | |
+ } | |
+ if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) { | |
+ av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, " | |
+ "corrupted stream or invalid MP4/AVCC bitstream\n"); | |
+ av_free(out); | |
+ return AVERROR(EINVAL); | |
+ } | |
+ if ((err = av_reallocp(&out, total_size + padding)) < 0) | |
+ return err; | |
+ memcpy(out + total_size - unit_size - 4, nalu_header, 4); | |
+ memcpy(out + total_size - unit_size, extradata + 2, unit_size); | |
+ } | |
+ extradata += 2 + unit_size; | |
+ pps: | |
+ if (!hevc && !unit_nb && !sps_done++) { | |
+ unit_nb = *extradata++; /* number of pps unit(s) */ | |
+ if (unit_nb) { | |
+ ctx->pps_offset = (extradata - 1) - (avctx->extradata + 4); | |
+ pps_seen = 1; | |
+ } | |
+ } | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment