#include "cabac_functions.h"
#include "golomb.h"
#include "hevc.h"
+#include "profiles.h"
const uint8_t ff_hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 };
slice_address_length = av_ceil_log2(s->ps.sps->ctb_width *
s->ps.sps->ctb_height);
- sh->slice_segment_addr = slice_address_length ? get_bits(gb, slice_address_length) : 0;
+ sh->slice_segment_addr = get_bitsz(gb, slice_address_length);
if (sh->slice_segment_addr >= s->ps.sps->ctb_width * s->ps.sps->ctb_height) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid slice segment address: %u.\n",
av_freep(&sh->entry_point_offset);
av_freep(&sh->offset);
av_freep(&sh->size);
- sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int));
+ sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(unsigned));
sh->offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int));
sh->size = av_malloc_array(sh->num_entry_point_offsets, sizeof(int));
if (!sh->entry_point_offset || !sh->offset || !sh->size) {
HEVCLocalContext *lc = s->HEVClc;
int *ret = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int));
int *arg = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int));
- int offset;
- int startheader, cmpt = 0;
+ int64_t offset;
+ int64_t startheader, cmpt = 0;
int i, j, res = 0;
if (!ret || !arg) {
return AVERROR(ENOMEM);
}
+ if (s->sh.slice_ctb_addr_rs + s->sh.num_entry_point_offsets * s->ps.sps->ctb_width >= s->ps.sps->ctb_width * s->ps.sps->ctb_height) {
+ av_log(s->avctx, AV_LOG_ERROR, "WPP ctb addresses are wrong (%d %d %d %d)\n",
+ s->sh.slice_ctb_addr_rs, s->sh.num_entry_point_offsets,
+ s->ps.sps->ctb_width, s->ps.sps->ctb_height
+ );
+ res = AVERROR_INVALIDDATA;
+ goto error;
+ }
- if (!s->sList[1]) {
- ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
-
+ ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
+ if (!s->sList[1]) {
for (i = 1; i < s->threads_number; i++) {
s->sList[i] = av_malloc(sizeof(HEVCContext));
memcpy(s->sList[i], s, sizeof(HEVCContext));
}
if (s->sh.num_entry_point_offsets != 0) {
offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt;
+ if (length < offset) {
+ av_log(s->avctx, AV_LOG_ERROR, "entry_point_offset table is corrupted\n");
+ res = AVERROR_INVALIDDATA;
+ goto error;
+ }
s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset;
s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset;
for (i = 0; i <= s->sh.num_entry_point_offsets; i++)
res += ret[i];
+error:
av_free(ret);
av_free(arg);
return res;
#define OFFSET(x) offsetof(HEVCContext, x)
#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
-static const AVProfile profiles[] = {
- { FF_PROFILE_HEVC_MAIN, "Main" },
- { FF_PROFILE_HEVC_MAIN_10, "Main 10" },
- { FF_PROFILE_HEVC_MAIN_STILL_PICTURE, "Main Still Picture" },
- { FF_PROFILE_HEVC_REXT, "Rext" },
- { FF_PROFILE_UNKNOWN },
-};
-
static const AVOption options[] = {
{ "apply_defdispwin", "Apply default display window from VUI", OFFSET(apply_defdispwin),
- AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, PAR },
+ AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
{ "strict-displaywin", "stricly apply default display window size", OFFSET(apply_defdispwin),
- AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, PAR },
+ AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
{ NULL },
};
.init_thread_copy = hevc_init_thread_copy,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
- .profiles = NULL_IF_CONFIG_SMALL(profiles),
+ .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
};