p += 6;
for (i = 0; i < cnt; i++) {
nalsize = AV_RB16(p) + 2;
- if (p - avctx->extradata + nalsize > avctx->extradata_size)
+ if(nalsize > size - (p-buf))
return -1;
- if (decode_nal_units(h, p, nalsize) < 0) {
+ if (decode_nal_units(h, p, nalsize, 1) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Decoding sps %d from avcC failed\n", i);
return -1;
cnt = *(p++); // Number of pps
for (i = 0; i < cnt; i++) {
nalsize = AV_RB16(p) + 2;
- if (p - avctx->extradata + nalsize > avctx->extradata_size)
+ if(nalsize > size - (p-buf))
return -1;
- if (decode_nal_units(h, p, nalsize) < 0) {
+ if (decode_nal_units(h, p, nalsize, 1) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Decoding pps %d from avcC failed\n", i);
return -1;
p += nalsize;
}
// Now store right nal length size, that will be used to parse all other nals
- h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
+ h->nal_length_size = (buf[4] & 0x03) + 1;
} else {
h->is_avc = 0;
- if (decode_nal_units(h, buf, size) < 0)
- if (decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1) < 0)
++ if (decode_nal_units(h, buf, size, 1) < 0)
return -1;
}
- return 0;
+ return size;
+}
+
+int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
+{
+ int ret;
+ h->decoding_extradata = 1;
+ ret = ff_h264_decode_extradata_internal(h, buf, size);
+ h->decoding_extradata = 0;
+ return ret;
}
av_cold int ff_h264_decode_init(AVCodecContext *avctx)
continue;
again:
+ /* Ignore every NAL unit type except PPS and SPS during extradata
+ * parsing. Decoding slices is not possible in codec init
+ * with frame-mt */
+ if (parse_extradata && HAVE_THREADS &&
+ (s->avctx->active_thread_type & FF_THREAD_FRAME) &&
+ (hx->nal_unit_type != NAL_PPS &&
+ hx->nal_unit_type != NAL_SPS)) {
+ av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
+ "extradata parsing\n", hx->nal_unit_type);
+ hx->nal_unit_type = NAL_FF_IGNORE;
+ }
err = 0;
+
+ if (h->decoding_extradata) {
+ switch (hx->nal_unit_type) {
+ case NAL_IDR_SLICE:
+ case NAL_SLICE:
+ case NAL_DPA:
+ case NAL_DPB:
+ case NAL_DPC:
+ case NAL_AUXILIARY_SLICE:
+ av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header\n", hx->nal_unit_type);
+ hx->nal_unit_type = NAL_FILLER_DATA;
+ }
+ }
+
switch (hx->nal_unit_type) {
case NAL_IDR_SLICE:
- if (h->nal_unit_type != NAL_IDR_SLICE) {
+ if (first_slice != NAL_IDR_SLICE) {
av_log(h->s.avctx, AV_LOG_ERROR,
"Invalid mix of idr and non-idr slices\n");
buf_index = -1;
return buf_index;
}
+ if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
+ int cnt= buf[5]&0x1f;
+ const uint8_t *p= buf+6;
+ while(cnt--){
+ int nalsize= AV_RB16(p) + 2;
+ if(nalsize > buf_size - (p-buf) || p[2]!=0x67)
+ goto not_extra;
+ p += nalsize;
+ }
+ cnt = *(p++);
+ if(!cnt)
+ goto not_extra;
+ while(cnt--){
+ int nalsize= AV_RB16(p) + 2;
+ if(nalsize > buf_size - (p-buf) || p[2]!=0x68)
+ goto not_extra;
+ p += nalsize;
+ }
+
+ return ff_h264_decode_extradata(h, buf, buf_size);
+ }
+not_extra:
- buf_index = decode_nal_units(h, buf, buf_size);
+ buf_index = decode_nal_units(h, buf, buf_size, 0);
if (buf_index < 0)
return -1;