summaryrefslogtreecommitdiff
path: root/libavcodec/hevc_parser.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2015-07-13 02:07:15 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-07-13 02:14:58 +0200
commit4496ccc724689c796db6a9936b53349d089db982 (patch)
tree762f8fb2b2eb1d26aa59c7833aacc5662bad86eb /libavcodec/hevc_parser.c
parent9e810a98a26391fd32f94e984a0a997ad77b77fe (diff)
downloadffmpeg-4496ccc724689c796db6a9936b53349d089db982.tar.gz
avcodec/hevc_parser: Reenable the old parser under ADVANCED_PARSER define
Feel free to use either, they both work but the old one provides more information but needs the hevc decoder Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec/hevc_parser.c')
-rw-r--r--libavcodec/hevc_parser.c371
1 files changed, 197 insertions, 174 deletions
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index fee13a84d1..77ca017bd7 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -30,6 +30,8 @@
#define IS_IRAP_NAL(nal) (nal->type >= 16 && nal->type <= 23)
+#define ADVANCED_PARSER
+
typedef struct HEVCParserContext {
ParseContext pc;
@@ -37,6 +39,10 @@ typedef struct HEVCParserContext {
HEVCParamSets ps;
int parsed_extradata;
+
+#ifdef ADVANCED_PARSER
+ HEVCContext h;
+#endif
} HEVCParserContext;
static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal,
@@ -75,6 +81,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal,
return 0;
}
+#ifndef ADVANCED_PARSER
static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
int buf_size, AVCodecContext *avctx)
{
@@ -114,6 +121,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
return 0;
}
+#endif
/**
* Find the end of the current frame in the bitstream.
@@ -166,180 +174,190 @@ static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
* @param buf buffer with field/frame data.
* @param buf_size size of the buffer.
*/
-// static inline int parse_nal_unitsX(AVCodecParserContext *s, AVCodecContext *avctx,
-// const uint8_t *buf, int buf_size)
-// {
-// HEVCContext *h = &((HEVCParseContext *)s->priv_data)->h;
-// GetBitContext *gb = &h->HEVClc->gb;
-// SliceHeader *sh = &h->sh;
-// HEVCParamSets *ps = &h->ps;
-// HEVCPacket *pkt = &h->pkt;
-// const uint8_t *buf_end = buf + buf_size;
-// int state = -1, i;
-// HEVCNAL *nal;
-//
-// /* set some sane default values */
-// s->pict_type = AV_PICTURE_TYPE_I;
-// s->key_frame = 0;
-// s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
-//
-// h->avctx = avctx;
-//
-// if (!buf_size)
-// return 0;
-//
-// if (pkt->nals_allocated < 1) {
-// HEVCNAL *tmp = av_realloc_array(pkt->nals, 1, sizeof(*tmp));
-// if (!tmp)
-// return AVERROR(ENOMEM);
-// pkt->nals = tmp;
-// memset(pkt->nals, 0, sizeof(*tmp));
-// pkt->nals_allocated = 1;
-// }
-//
-// nal = &pkt->nals[0];
-//
-// for (;;) {
-// int src_length, consumed;
-// buf = avpriv_find_start_code(buf, buf_end, &state);
-// if (--buf + 2 >= buf_end)
-// break;
-// src_length = buf_end - buf;
-//
-// h->nal_unit_type = (*buf >> 1) & 0x3f;
-// h->temporal_id = (*(buf + 1) & 0x07) - 1;
-// if (h->nal_unit_type <= NAL_CRA_NUT) {
-// // Do not walk the whole buffer just to decode slice segment header
-// if (src_length > 20)
-// src_length = 20;
-// }
-//
-// consumed = ff_hevc_extract_rbsp(h, buf, src_length, nal);
-// if (consumed < 0)
-// return consumed;
-//
-// init_get_bits8(gb, nal->data + 2, nal->size);
-// switch (h->nal_unit_type) {
-// case NAL_VPS:
-// ff_hevc_decode_nal_vps(gb, avctx, ps);
-// break;
-// case NAL_SPS:
-// ff_hevc_decode_nal_sps(gb, avctx, ps, h->apply_defdispwin);
-// break;
-// case NAL_PPS:
-// ff_hevc_decode_nal_pps(gb, avctx, ps);
-// break;
-// case NAL_SEI_PREFIX:
-// case NAL_SEI_SUFFIX:
-// ff_hevc_decode_nal_sei(h);
-// break;
-// case NAL_TRAIL_N:
-// case NAL_TRAIL_R:
-// case NAL_TSA_N:
-// case NAL_TSA_R:
-// case NAL_STSA_N:
-// case NAL_STSA_R:
-// case NAL_RADL_N:
-// case NAL_RADL_R:
-// case NAL_RASL_N:
-// case NAL_RASL_R:
-// case NAL_BLA_W_LP:
-// case NAL_BLA_W_RADL:
-// case NAL_BLA_N_LP:
-// case NAL_IDR_W_RADL:
-// case NAL_IDR_N_LP:
-// case NAL_CRA_NUT:
-// sh->first_slice_in_pic_flag = get_bits1(gb);
-// s->picture_structure = h->picture_struct;
-// s->field_order = h->picture_struct;
-//
-// if (IS_IRAP(h)) {
-// s->key_frame = 1;
-// sh->no_output_of_prior_pics_flag = get_bits1(gb);
-// }
-//
-// sh->pps_id = get_ue_golomb(gb);
-// if (sh->pps_id >= MAX_PPS_COUNT || !ps->pps_list[sh->pps_id]) {
-// av_log(h->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
-// return AVERROR_INVALIDDATA;
-// }
-// ps->pps = (HEVCPPS*)ps->pps_list[sh->pps_id]->data;
-//
-// if (ps->pps->sps_id >= MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) {
-// av_log(h->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id);
-// return AVERROR_INVALIDDATA;
-// }
-// if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) {
-// ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data;
-// ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data;
-// }
-//
-// if (!sh->first_slice_in_pic_flag) {
-// int slice_address_length;
-//
-// if (ps->pps->dependent_slice_segments_enabled_flag)
-// sh->dependent_slice_segment_flag = get_bits1(gb);
-// else
-// sh->dependent_slice_segment_flag = 0;
-//
-// slice_address_length = av_ceil_log2_c(ps->sps->ctb_width *
-// ps->sps->ctb_height);
-// sh->slice_segment_addr = slice_address_length ? get_bits(gb, slice_address_length) : 0;
-// if (sh->slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) {
-// av_log(h->avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n",
-// sh->slice_segment_addr);
-// return AVERROR_INVALIDDATA;
-// }
-// } else
-// sh->dependent_slice_segment_flag = 0;
-//
-// if (sh->dependent_slice_segment_flag)
-// break;
-//
-// for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++)
-// skip_bits(gb, 1); // slice_reserved_undetermined_flag[]
-//
-// sh->slice_type = get_ue_golomb(gb);
-// if (!(sh->slice_type == I_SLICE || sh->slice_type == P_SLICE ||
-// sh->slice_type == B_SLICE)) {
-// av_log(h->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
-// sh->slice_type);
-// return AVERROR_INVALIDDATA;
-// }
-// s->pict_type = sh->slice_type == B_SLICE ? AV_PICTURE_TYPE_B :
-// sh->slice_type == P_SLICE ? AV_PICTURE_TYPE_P :
-// AV_PICTURE_TYPE_I;
-//
-// if (ps->pps->output_flag_present_flag)
-// sh->pic_output_flag = get_bits1(gb);
-//
-// if (ps->sps->separate_colour_plane_flag)
-// sh->colour_plane_id = get_bits(gb, 2);
-//
-// if (!IS_IDR(h)) {
-// sh->pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb);
-// s->output_picture_number = h->poc = ff_hevc_compute_poc(h, sh->pic_order_cnt_lsb);
-// } else
-// s->output_picture_number = h->poc = 0;
-//
-// if (h->temporal_id == 0 &&
-// h->nal_unit_type != NAL_TRAIL_N &&
-// h->nal_unit_type != NAL_TSA_N &&
-// h->nal_unit_type != NAL_STSA_N &&
-// h->nal_unit_type != NAL_RADL_N &&
-// h->nal_unit_type != NAL_RASL_N &&
-// h->nal_unit_type != NAL_RADL_R &&
-// h->nal_unit_type != NAL_RASL_R)
-// h->pocTid0 = h->poc;
-//
-// return 0; /* no need to evaluate the rest */
-// }
-// buf += consumed;
-// }
-// /* didn't find a picture! */
-// av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
-// return -1;
-// }
+#ifdef ADVANCED_PARSER
+static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
+ int buf_size, AVCodecContext *avctx)
+{
+ HEVCParserContext *ctx = s->priv_data;
+ HEVCContext *h = &ctx->h;
+ GetBitContext *gb;
+ SliceHeader *sh = &h->sh;
+ HEVCParamSets *ps = &h->ps;
+ HEVCPacket *pkt = &h->pkt;
+ const uint8_t *buf_end = buf + buf_size;
+ int state = -1, i;
+ HEVCNAL *nal;
+
+ if (!h->HEVClc)
+ h->HEVClc = av_mallocz(sizeof(HEVCLocalContext));
+ if (!h->HEVClc)
+ return AVERROR(ENOMEM);
+
+ gb = &h->HEVClc->gb;
+
+ /* set some sane default values */
+ s->pict_type = AV_PICTURE_TYPE_I;
+ s->key_frame = 0;
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
+
+ h->avctx = avctx;
+
+ if (!buf_size)
+ return 0;
+
+ if (pkt->nals_allocated < 1) {
+ HEVCNAL *tmp = av_realloc_array(pkt->nals, 1, sizeof(*tmp));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ pkt->nals = tmp;
+ memset(pkt->nals, 0, sizeof(*tmp));
+ pkt->nals_allocated = 1;
+ }
+
+ nal = &pkt->nals[0];
+
+ for (;;) {
+ int src_length, consumed;
+ buf = avpriv_find_start_code(buf, buf_end, &state);
+ if (--buf + 2 >= buf_end)
+ break;
+ src_length = buf_end - buf;
+
+ h->nal_unit_type = (*buf >> 1) & 0x3f;
+ h->temporal_id = (*(buf + 1) & 0x07) - 1;
+ if (h->nal_unit_type <= NAL_CRA_NUT) {
+ // Do not walk the whole buffer just to decode slice segment header
+ if (src_length > 20)
+ src_length = 20;
+ }
+
+ consumed = ff_hevc_extract_rbsp(NULL, buf, src_length, nal);
+ if (consumed < 0)
+ return consumed;
+
+ init_get_bits8(gb, nal->data + 2, nal->size);
+ switch (h->nal_unit_type) {
+ case NAL_VPS:
+ ff_hevc_decode_nal_vps(gb, avctx, ps);
+ break;
+ case NAL_SPS:
+ ff_hevc_decode_nal_sps(gb, avctx, ps, 1);
+ break;
+ case NAL_PPS:
+ ff_hevc_decode_nal_pps(gb, avctx, ps);
+ break;
+ case NAL_SEI_PREFIX:
+ case NAL_SEI_SUFFIX:
+ ff_hevc_decode_nal_sei(h);
+ break;
+ case NAL_TRAIL_N:
+ case NAL_TRAIL_R:
+ case NAL_TSA_N:
+ case NAL_TSA_R:
+ case NAL_STSA_N:
+ case NAL_STSA_R:
+ case NAL_RADL_N:
+ case NAL_RADL_R:
+ case NAL_RASL_N:
+ case NAL_RASL_R:
+ case NAL_BLA_W_LP:
+ case NAL_BLA_W_RADL:
+ case NAL_BLA_N_LP:
+ case NAL_IDR_W_RADL:
+ case NAL_IDR_N_LP:
+ case NAL_CRA_NUT:
+ sh->first_slice_in_pic_flag = get_bits1(gb);
+ s->picture_structure = h->picture_struct;
+ s->field_order = h->picture_struct;
+
+ if (IS_IRAP(h)) {
+ s->key_frame = 1;
+ sh->no_output_of_prior_pics_flag = get_bits1(gb);
+ }
+
+ sh->pps_id = get_ue_golomb(gb);
+ if (sh->pps_id >= MAX_PPS_COUNT || !ps->pps_list[sh->pps_id]) {
+ av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ ps->pps = (HEVCPPS*)ps->pps_list[sh->pps_id]->data;
+
+ if (ps->pps->sps_id >= MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) {
+ av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) {
+ ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data;
+ ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data;
+ }
+
+ if (!sh->first_slice_in_pic_flag) {
+ int slice_address_length;
+
+ if (ps->pps->dependent_slice_segments_enabled_flag)
+ sh->dependent_slice_segment_flag = get_bits1(gb);
+ else
+ sh->dependent_slice_segment_flag = 0;
+
+ slice_address_length = av_ceil_log2_c(ps->sps->ctb_width *
+ ps->sps->ctb_height);
+ sh->slice_segment_addr = slice_address_length ? get_bits(gb, slice_address_length) : 0;
+ if (sh->slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n",
+ sh->slice_segment_addr);
+ return AVERROR_INVALIDDATA;
+ }
+ } else
+ sh->dependent_slice_segment_flag = 0;
+
+ if (sh->dependent_slice_segment_flag)
+ break;
+
+ for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++)
+ skip_bits(gb, 1); // slice_reserved_undetermined_flag[]
+
+ sh->slice_type = get_ue_golomb(gb);
+ if (!(sh->slice_type == I_SLICE || sh->slice_type == P_SLICE ||
+ sh->slice_type == B_SLICE)) {
+ av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
+ sh->slice_type);
+ return AVERROR_INVALIDDATA;
+ }
+ s->pict_type = sh->slice_type == B_SLICE ? AV_PICTURE_TYPE_B :
+ sh->slice_type == P_SLICE ? AV_PICTURE_TYPE_P :
+ AV_PICTURE_TYPE_I;
+
+ if (ps->pps->output_flag_present_flag)
+ sh->pic_output_flag = get_bits1(gb);
+
+ if (ps->sps->separate_colour_plane_flag)
+ sh->colour_plane_id = get_bits(gb, 2);
+
+ if (!IS_IDR(h)) {
+ sh->pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb);
+ s->output_picture_number = h->poc = ff_hevc_compute_poc(h, sh->pic_order_cnt_lsb);
+ } else
+ s->output_picture_number = h->poc = 0;
+
+ if (h->temporal_id == 0 &&
+ h->nal_unit_type != NAL_TRAIL_N &&
+ h->nal_unit_type != NAL_TSA_N &&
+ h->nal_unit_type != NAL_STSA_N &&
+ h->nal_unit_type != NAL_RADL_N &&
+ h->nal_unit_type != NAL_RASL_N &&
+ h->nal_unit_type != NAL_RADL_R &&
+ h->nal_unit_type != NAL_RASL_R)
+ h->pocTid0 = h->poc;
+
+ return 0; /* no need to evaluate the rest */
+ }
+ buf += consumed;
+ }
+ /* didn't find a picture! */
+ av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+ return -1;
+}
+#endif
static int hevc_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
@@ -400,6 +418,11 @@ static void hevc_parser_close(AVCodecParserContext *s)
HEVCParserContext *ctx = s->priv_data;
int i;
+#ifdef ADVANCED_PARSER
+ HEVCContext *h = &ctx->h;
+ av_freep(&h->HEVClc);
+#endif
+
for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.vps_list); i++)
av_buffer_unref(&ctx->ps.vps_list[i]);
for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.sps_list); i++)