void h264_to_annexb_init(h264_annexb_ctx_t *ctx, const uint8_t *data, int len) { int i, n, s; uint8_t buf[4] = {0,0,0,1}; if(len < 7 || data[0] != 1) return; int lsize = (data[4] & 0x3) + 1; n = data[5] & 0x1f; data += 6; len -= 6; for(i = 0; i < n && len >= 2; i++) { s = ((data[0] << 8) | data[1]) + 2; if(len < s) break; append_extradata(ctx, buf, 4); append_extradata(ctx, data + 2, s - 2); data += s; len -= s; } if(len < 1) return; n = *data++; len--; for(i = 0; i < n && len >= 2; i++) { s = ((data[0] << 8) | data[1]) + 2; if(len < s) break; append_extradata(ctx, buf, 4); append_extradata(ctx, data + 2, s - 2); data += s; len -= s; } ctx->lsize = lsize; }
int bgav_bsf_init_avcC(bgav_bsf_t * bsf) { uint8_t * ptr; avcc_t * priv; int num_units; int i; int len; bsf->filter = filter_avcc; bsf->cleanup = cleanup_avcc; priv = calloc(1, sizeof(*priv)); bsf->priv = priv; /* Parse extradata */ ptr = bsf->s->ext_data; ptr += 4; // Version, profile, profile compat, level priv->nal_size_length = (*ptr & 0x3) + 1; ptr++; /* SPS */ num_units = *ptr & 0x1f; ptr++; for(i = 0; i < num_units; i++) { len = BGAV_PTR_2_16BE(ptr); ptr += 2; append_extradata(bsf, ptr, len); ptr += len; } /* PPS */ num_units = *ptr; ptr++; for(i = 0; i < num_units; i++) { len = BGAV_PTR_2_16BE(ptr); ptr += 2; append_extradata(bsf, ptr, len); ptr += len; } return 1; }
static int apng_read_header(AVFormatContext *s) { APNGDemuxContext *ctx = s->priv_data; AVIOContext *pb = s->pb; uint32_t len, tag; AVStream *st; int ret = AVERROR_INVALIDDATA, acTL_found = 0; /* verify PNGSIG */ if (avio_rb64(pb) != PNGSIG) return ret; /* parse IHDR (must be first chunk) */ len = avio_rb32(pb); tag = avio_rl32(pb); if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R')) return ret; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_APNG; st->codec->width = avio_rb32(pb); st->codec->height = avio_rb32(pb); if ((ret = av_image_check_size(st->codec->width, st->codec->height, 0, s)) < 0) return ret; /* extradata will contain every chunk up to the first fcTL (excluded) */ st->codec->extradata = av_malloc(len + 12 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); st->codec->extradata_size = len + 12; AV_WB32(st->codec->extradata, len); AV_WL32(st->codec->extradata+4, tag); AV_WB32(st->codec->extradata+8, st->codec->width); AV_WB32(st->codec->extradata+12, st->codec->height); if ((ret = avio_read(pb, st->codec->extradata+16, 9)) < 0) goto fail; while (!avio_feof(pb)) { if (acTL_found && ctx->num_play != 1) { int64_t size = avio_size(pb); int64_t offset = avio_tell(pb); if (size < 0) { ret = size; goto fail; } else if (offset < 0) { ret = offset; goto fail; } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); ctx->num_play = 1; } } if ((ctx->num_play == 1 || !acTL_found) && ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0)) goto fail; len = avio_rb32(pb); if (len > 0x7fffffff) { ret = AVERROR_INVALIDDATA; goto fail; } tag = avio_rl32(pb); switch (tag) { case MKTAG('a', 'c', 'T', 'L'): if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codec, pb, len + 12)) < 0) goto fail; acTL_found = 1; ctx->num_frames = AV_RB32(st->codec->extradata + ret + 8); ctx->num_play = AV_RB32(st->codec->extradata + ret + 12); av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n", ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'): if (!acTL_found) { ret = AVERROR_INVALIDDATA; goto fail; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) goto fail; return 0; default: if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codec, pb, len + 12)) < 0) goto fail; } } fail: if (st->codec->extradata_size) { av_freep(&st->codec->extradata); st->codec->extradata_size = 0; } return ret; }