ffmpeg | branch: master | Derek Buitenhuis <derek.buitenh...@gmail.com> | Tue Apr 26 13:38:45 2016 +0100| [3c4ca4c5d7992e545a6cbad440287f9e27f1a696] | committer: Derek Buitenhuis
Merge commit 'fa936a307f5cddfc2664600157a8207ca8080af6' * commit 'fa936a307f5cddfc2664600157a8207ca8080af6': hevc_parse: rename into h2645_parse Merged-by: Derek Buitenhuis <derek.buitenh...@gmail.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3c4ca4c5d7992e545a6cbad440287f9e27f1a696 --- libavcodec/Makefile | 6 +-- libavcodec/{hevc_parse.c => h2645_parse.c} | 19 ++++---- libavcodec/h2645_parse.h | 68 ++++++++++++++++++++++++++++ libavcodec/hevc.c | 8 ++-- libavcodec/hevc.h | 42 +---------------- libavcodec/hevc_parser.c | 17 +++---- libavcodec/qsvenc_hevc.c | 5 +- 7 files changed, 99 insertions(+), 66 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 679f2f2..36b65f7 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -318,9 +318,9 @@ OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \ hevc_cabac.o hevc_refs.o hevcpred.o \ - hevcdsp.o hevc_filter.o hevc_parse.o hevc_data.o + hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o -OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o hevc_parse.o +OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o h2645_parse.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ canopus.o @@ -901,7 +901,7 @@ OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o OBJS-$(CONFIG_H261_PARSER) += h261_parser.o OBJS-$(CONFIG_H263_PARSER) += h263_parser.o OBJS-$(CONFIG_H264_PARSER) += h264_parser.o -OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_parse.o hevc_ps.o hevc_data.o +OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o h2645_parse.o hevc_ps.o hevc_data.o OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ diff --git a/libavcodec/hevc_parse.c b/libavcodec/h2645_parse.c similarity index 94% rename from libavcodec/hevc_parse.c rename to libavcodec/h2645_parse.c index 6ee8496..373f1d3 100644 --- a/libavcodec/hevc_parse.c +++ b/libavcodec/h2645_parse.c @@ -1,5 +1,5 @@ /* - * HEVC common code + * H.264/HEVC common parsing code * * This file is part of FFmpeg. * @@ -26,11 +26,12 @@ #include "libavutil/mem.h" #include "hevc.h" +#include "h2645_parse.h" /* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication * between these functions would be nice. */ -int ff_hevc_extract_rbsp(const uint8_t *src, int length, - HEVCNAL *nal) +int ff_h2645_extract_rbsp(const uint8_t *src, int length, + H2645NAL *nal) { int i, si, di; uint8_t *dst; @@ -181,7 +182,7 @@ static const char *nal_unit_name(int nal_type) * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit, * 0 if the unit should be skipped, 1 otherwise */ -static int hls_nal_unit(HEVCNAL *nal, AVCodecContext *avctx) +static int hevc_parse_nal_header(H2645NAL *nal, AVCodecContext *avctx) { GetBitContext *gb = &nal->gb; int nuh_layer_id; @@ -204,14 +205,14 @@ static int hls_nal_unit(HEVCNAL *nal, AVCodecContext *avctx) } -int ff_hevc_split_packet(HEVCPacket *pkt, const uint8_t *buf, int length, - AVCodecContext *avctx, int is_nalff, int nal_length_size) +int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, + AVCodecContext *avctx, int is_nalff, int nal_length_size) { int consumed, ret = 0; pkt->nb_nals = 0; while (length >= 4) { - HEVCNAL *nal; + H2645NAL *nal; int extract_length = 0; if (is_nalff) { @@ -268,7 +269,7 @@ int ff_hevc_split_packet(HEVCPacket *pkt, const uint8_t *buf, int length, } nal = &pkt->nals[pkt->nb_nals]; - consumed = ff_hevc_extract_rbsp(buf, extract_length, nal); + consumed = ff_h2645_extract_rbsp(buf, extract_length, nal); if (consumed < 0) return consumed; @@ -278,7 +279,7 @@ int ff_hevc_split_packet(HEVCPacket *pkt, const uint8_t *buf, int length, if (ret < 0) return ret; - ret = hls_nal_unit(nal, avctx); + ret = hevc_parse_nal_header(nal, avctx); if (ret <= 0) { if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n", diff --git a/libavcodec/h2645_parse.h b/libavcodec/h2645_parse.h new file mode 100644 index 0000000..1724756 --- /dev/null +++ b/libavcodec/h2645_parse.h @@ -0,0 +1,68 @@ +/* + * H.264/HEVC common parsing code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H2645_PARSE_H +#define AVCODEC_H2645_PARSE_H + +#include <stdint.h> + +#include "avcodec.h" +#include "get_bits.h" + +typedef struct H2645NAL { + uint8_t *rbsp_buffer; + int rbsp_buffer_size; + + int size; + const uint8_t *data; + + int raw_size; + const uint8_t *raw_data; + + GetBitContext gb; + + int type; + int temporal_id; + + int skipped_bytes; + int skipped_bytes_pos_size; + int *skipped_bytes_pos; +} H2645NAL; + +/* an input packet split into unescaped NAL units */ +typedef struct H2645Packet { + H2645NAL *nals; + int nb_nals; + int nals_allocated; +} H2645Packet; + +/** + * Extract the raw (unescaped) bitstream. + */ +int ff_h2645_extract_rbsp(const uint8_t *src, int length, + H2645NAL *nal); + +/** + * Split an input packet into NAL units. + */ +int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, + AVCodecContext *avctx, int is_nalff, int nal_length_size); + +#endif /* AVCODEC_H2645_PARSE_H */ diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 785aa7e..f012c41 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -2448,7 +2448,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int return 0; } -static int hls_slice_data_wpp(HEVCContext *s, const HEVCNAL *nal) +static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) { const uint8_t *data = nal->data; int length = nal->size; @@ -2714,7 +2714,7 @@ fail: return ret; } -static int decode_nal_unit(HEVCContext *s, const HEVCNAL *nal) +static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) { HEVCLocalContext *lc = s->HEVClc; GetBitContext *gb = &lc->gb; @@ -2866,8 +2866,8 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) /* split the input packet into NAL units, so we know the upper bound on the * number of slices in the frame */ - ret = ff_hevc_split_packet(&s->pkt, buf, length, s->avctx, s->is_nalff, - s->nal_length_size); + ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff, + s->nal_length_size); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error splitting the input into NAL units.\n"); diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 5865f65..f44fa49 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -31,6 +31,7 @@ #include "cabac.h" #include "get_bits.h" #include "hevcpred.h" +#include "h2645_parse.h" #include "hevcdsp.h" #include "internal.h" #include "thread.h" @@ -746,33 +747,6 @@ typedef struct HEVCFrame { uint8_t flags; } HEVCFrame; -typedef struct HEVCNAL { - uint8_t *rbsp_buffer; - int rbsp_buffer_size; - - int size; - const uint8_t *data; - - int raw_size; - const uint8_t *raw_data; - - GetBitContext gb; - - enum NALUnitType type; - int temporal_id; - - int skipped_bytes; - int skipped_bytes_pos_size; - int *skipped_bytes_pos; -} HEVCNAL; - -/* an input packet split into unescaped NAL units */ -typedef struct HEVCPacket { - HEVCNAL *nals; - int nb_nals; - int nals_allocated; -} HEVCPacket; - typedef struct HEVCLocalContext { uint8_t cabac_state[HEVC_CONTEXTS]; @@ -906,7 +880,7 @@ typedef struct HEVCContext { const uint8_t *data; - HEVCPacket pkt; + H2645Packet pkt; // type of the first VCL NAL of the current frame enum NALUnitType first_nal_type; @@ -1077,18 +1051,6 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size); -/** - * Extract the raw (unescaped) HEVC bitstream. - */ -int ff_hevc_extract_rbsp(const uint8_t *src, int length, - HEVCNAL *nal); - -/** - * Split an input packet into NAL units. - */ -int ff_hevc_split_packet(HEVCPacket *pkt, const uint8_t *buf, int length, - AVCodecContext *avctx, int is_nalff, int nal_length_size); - int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, uint8_t *buf, int buf_size); diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 59893bb..71887a8 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -24,6 +24,7 @@ #include "golomb.h" #include "hevc.h" +#include "h2645_parse.h" #include "parser.h" #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes @@ -35,7 +36,7 @@ typedef struct HEVCParserContext { ParseContext pc; - HEVCPacket pkt; + H2645Packet pkt; HEVCParamSets ps; int parsed_extradata; @@ -46,7 +47,7 @@ typedef struct HEVCParserContext { } HEVCParserContext; #if !ADVANCED_PARSER -static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal, +static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, AVCodecContext *avctx) { HEVCParserContext *ctx = s->priv_data; @@ -88,12 +89,12 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, HEVCParserContext *ctx = s->priv_data; int ret, i; - ret = ff_hevc_split_packet(NULL, &ctx->pkt, buf, buf_size, avctx, 0, 0); + ret = ff_h2645_split_packet(&ctx->pkt, buf, buf_size, avctx, 0, 0); if (ret < 0) return ret; for (i = 0; i < ctx->pkt.nb_nals; i++) { - HEVCNAL *nal = &ctx->pkt.nals[i]; + H2645NAL *nal = &ctx->pkt.nals[i]; /* ignore everything except parameter sets and VCL NALUs */ switch (nal->type) { @@ -189,10 +190,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, GetBitContext *gb; SliceHeader *sh = &h->sh; HEVCParamSets *ps = &h->ps; - HEVCPacket *pkt = &ctx->pkt; + H2645Packet *pkt = &ctx->pkt; const uint8_t *buf_end = buf + buf_size; int state = -1, i; - HEVCNAL *nal; + H2645NAL *nal; int is_global = buf == avctx->extradata; if (!h->HEVClc) @@ -213,7 +214,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, return 0; if (pkt->nals_allocated < 1) { - HEVCNAL *tmp = av_realloc_array(pkt->nals, 1, sizeof(*tmp)); + H2645NAL *tmp = av_realloc_array(pkt->nals, 1, sizeof(*tmp)); if (!tmp) return AVERROR(ENOMEM); pkt->nals = tmp; @@ -239,7 +240,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, src_length = 20; } - consumed = ff_hevc_extract_rbsp(buf, src_length, nal); + consumed = ff_h2645_extract_rbsp(buf, src_length, nal); if (consumed < 0) return consumed; diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index e0bead9..1d1e801 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -31,6 +31,7 @@ #include "bytestream.h" #include "get_bits.h" #include "hevc.h" +#include "h2645_parse.h" #include "internal.h" #include "qsv.h" #include "qsv_internal.h" @@ -54,7 +55,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) PutByteContext pbc; GetBitContext gb; - HEVCNAL sps_nal = { NULL }; + H2645NAL sps_nal = { NULL }; HEVCSPS sps = { 0 }; HEVCVPS vps = { 0 }; uint8_t vps_buf[128], vps_rbsp_buf[128]; @@ -68,7 +69,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) } /* parse the SPS */ - ret = ff_hevc_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal); + ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n"); return ret; ====================================================================== diff --cc libavcodec/Makefile index 679f2f2,e253e7e..36b65f7 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@@ -318,9 -261,10 +318,9 @@@ OBJS-$(CONFIG_HAP_DECODER) OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \ hevc_cabac.o hevc_refs.o hevcpred.o \ - hevcdsp.o hevc_filter.o hevc_parse.o hevc_data.o + hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o -OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o - OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o hevc_parse.o + OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o h2645_parse.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ canopus.o diff --cc libavcodec/h2645_parse.c index 6ee8496,794c954..373f1d3 --- a/libavcodec/h2645_parse.c +++ b/libavcodec/h2645_parse.c @@@ -1,9 -1,9 +1,9 @@@ /* - * HEVC common code + * H.264/HEVC common parsing code * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. @@@ -25,7 -25,7 +25,8 @@@ #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" +#include "hevc.h" + #include "h2645_parse.h" /* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication * between these functions would be nice. */ @@@ -256,19 -198,12 +257,19 @@@ int ff_h2645_packet_split(H2645Packet * pkt->nals = tmp; memset(pkt->nals + pkt->nals_allocated, 0, - (new_size - pkt->nals_allocated) * sizeof(*tmp)); + (new_size - pkt->nals_allocated) * sizeof(*pkt->nals)); + + nal = &pkt->nals[pkt->nb_nals]; + nal->skipped_bytes_pos_size = 1024; // initial buffer size + nal->skipped_bytes_pos = av_malloc_array(nal->skipped_bytes_pos_size, sizeof(*nal->skipped_bytes_pos)); + if (!nal->skipped_bytes_pos) + return AVERROR(ENOMEM); + pkt->nals_allocated = new_size; } - nal = &pkt->nals[pkt->nb_nals++]; + nal = &pkt->nals[pkt->nb_nals]; - consumed = ff_hevc_extract_rbsp(buf, extract_length, nal); + consumed = ff_h2645_extract_rbsp(buf, extract_length, nal); if (consumed < 0) return consumed; diff --cc libavcodec/h2645_parse.h index 0000000,4901ccf..1724756 mode 000000,100644..100644 --- a/libavcodec/h2645_parse.h +++ b/libavcodec/h2645_parse.h @@@ -1,0 -1,64 +1,68 @@@ + /* + * H.264/HEVC common parsing code + * - * This file is part of Libav. ++ * This file is part of FFmpeg. + * - * Libav is free software; you can redistribute it and/or ++ * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * - * Libav is distributed in the hope that it will be useful, ++ * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software ++ * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #ifndef AVCODEC_H2645_PARSE_H + #define AVCODEC_H2645_PARSE_H + + #include <stdint.h> + + #include "avcodec.h" + #include "get_bits.h" + + typedef struct H2645NAL { + uint8_t *rbsp_buffer; + int rbsp_buffer_size; + + int size; + const uint8_t *data; + + int raw_size; + const uint8_t *raw_data; + + GetBitContext gb; + + int type; + int temporal_id; ++ ++ int skipped_bytes; ++ int skipped_bytes_pos_size; ++ int *skipped_bytes_pos; + } H2645NAL; + + /* an input packet split into unescaped NAL units */ + typedef struct H2645Packet { + H2645NAL *nals; + int nb_nals; + int nals_allocated; + } H2645Packet; + + /** + * Extract the raw (unescaped) bitstream. + */ + int ff_h2645_extract_rbsp(const uint8_t *src, int length, + H2645NAL *nal); + + /** + * Split an input packet into NAL units. + */ + int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, + AVCodecContext *avctx, int is_nalff, int nal_length_size); + + #endif /* AVCODEC_H2645_PARSE_H */ diff --cc libavcodec/hevc.c index 785aa7e,69c4f26..f012c41 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@@ -2360,190 -2303,31 +2360,190 @@@ static int hls_decode_entry(AVCodecCont return ctb_addr_ts; } -static void restore_tqb_pixels(HEVCContext *s) +static int hls_slice_data(HEVCContext *s) { - int min_pu_size = 1 << s->ps.sps->log2_min_pu_size; - int x, y, c_idx; - - for (c_idx = 0; c_idx < 3; c_idx++) { - ptrdiff_t stride = s->frame->linesize[c_idx]; - int hshift = s->ps.sps->hshift[c_idx]; - int vshift = s->ps.sps->vshift[c_idx]; - for (y = 0; y < s->ps.sps->min_pu_height; y++) { - for (x = 0; x < s->ps.sps->min_pu_width; x++) { - if (s->is_pcm[y * s->ps.sps->min_pu_width + x]) { - int n; - int len = min_pu_size >> hshift; - uint8_t *src = &s->frame->data[c_idx][((y << s->ps.sps->log2_min_pu_size) >> vshift) * stride + (((x << s->ps.sps->log2_min_pu_size) >> hshift) << s->ps.sps->pixel_shift)]; - uint8_t *dst = &s->sao_frame->data[c_idx][((y << s->ps.sps->log2_min_pu_size) >> vshift) * stride + (((x << s->ps.sps->log2_min_pu_size) >> hshift) << s->ps.sps->pixel_shift)]; - for (n = 0; n < (min_pu_size >> vshift); n++) { - memcpy(dst, src, len); - src += stride; - dst += stride; - } - } + int arg[2]; + int ret[2]; + + arg[0] = 0; + arg[1] = 1; + + s->avctx->execute(s->avctx, hls_decode_entry, arg, ret , 1, sizeof(int)); + return ret[0]; +} +static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int job, int self_id) +{ + HEVCContext *s1 = avctxt->priv_data, *s; + HEVCLocalContext *lc; + int ctb_size = 1<< s1->ps.sps->log2_ctb_size; + int more_data = 1; + int *ctb_row_p = input_ctb_row; + int ctb_row = ctb_row_p[job]; + int ctb_addr_rs = s1->sh.slice_ctb_addr_rs + ctb_row * ((s1->ps.sps->width + ctb_size - 1) >> s1->ps.sps->log2_ctb_size); + int ctb_addr_ts = s1->ps.pps->ctb_addr_rs_to_ts[ctb_addr_rs]; + int thread = ctb_row % s1->threads_number; + int ret; + + s = s1->sList[self_id]; + lc = s->HEVClc; + + if(ctb_row) { + ret = init_get_bits8(&lc->gb, s->data + s->sh.offset[ctb_row - 1], s->sh.size[ctb_row - 1]); + + if (ret < 0) + return ret; + ff_init_cabac_decoder(&lc->cc, s->data + s->sh.offset[(ctb_row)-1], s->sh.size[ctb_row - 1]); + } + + while(more_data && ctb_addr_ts < s->ps.sps->ctb_size) { + int x_ctb = (ctb_addr_rs % s->ps.sps->ctb_width) << s->ps.sps->log2_ctb_size; + int y_ctb = (ctb_addr_rs / s->ps.sps->ctb_width) << s->ps.sps->log2_ctb_size; + + hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts); + + ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP); + + if (avpriv_atomic_int_get(&s1->wpp_err)){ + ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); + return 0; + } + + ff_hevc_cabac_init(s, ctb_addr_ts); + hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size); + more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0); + + if (more_data < 0) { + s->tab_slice_address[ctb_addr_rs] = -1; + avpriv_atomic_int_set(&s1->wpp_err, 1); + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); + return more_data; + } + + ctb_addr_ts++; + + ff_hevc_save_states(s, ctb_addr_ts); + ff_thread_report_progress2(s->avctx, ctb_row, thread, 1); + ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size); + + if (!more_data && (x_ctb+ctb_size) < s->ps.sps->width && ctb_row != s->sh.num_entry_point_offsets) { + avpriv_atomic_int_set(&s1->wpp_err, 1); + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); + return 0; + } + + if ((x_ctb+ctb_size) >= s->ps.sps->width && (y_ctb+ctb_size) >= s->ps.sps->height ) { + ff_hevc_hls_filter(s, x_ctb, y_ctb, ctb_size); + ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); + return ctb_addr_ts; + } + ctb_addr_rs = s->ps.pps->ctb_addr_ts_to_rs[ctb_addr_ts]; + x_ctb+=ctb_size; + + if(x_ctb >= s->ps.sps->width) { + break; + } + } + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); + + return 0; +} + - static int hls_slice_data_wpp(HEVCContext *s, const HEVCNAL *nal) ++static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) +{ + const uint8_t *data = nal->data; + int length = nal->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)); + int64_t offset; + int64_t startheader, cmpt = 0; + int i, j, res = 0; + + if (!ret || !arg) { + av_free(ret); + av_free(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; + } + + 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)); + s->HEVClcList[i] = av_mallocz(sizeof(HEVCLocalContext)); + s->sList[i]->HEVClc = s->HEVClcList[i]; + } + } + + offset = (lc->gb.index >> 3); + + for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < nal->skipped_bytes; j++) { + if (nal->skipped_bytes_pos[j] >= offset && nal->skipped_bytes_pos[j] < startheader) { + startheader--; + cmpt++; + } + } + + for (i = 1; i < s->sh.num_entry_point_offsets; i++) { + offset += (s->sh.entry_point_offset[i - 1] - cmpt); + for (j = 0, cmpt = 0, startheader = offset + + s->sh.entry_point_offset[i]; j < nal->skipped_bytes; j++) { + if (nal->skipped_bytes_pos[j] >= offset && nal->skipped_bytes_pos[j] < startheader) { + startheader--; + cmpt++; } } + s->sh.size[i - 1] = s->sh.entry_point_offset[i] - cmpt; + s->sh.offset[i - 1] = offset; + + } + 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; + } + s->data = data; + + for (i = 1; i < s->threads_number; i++) { + s->sList[i]->HEVClc->first_qp_group = 1; + s->sList[i]->HEVClc->qp_y = s->sList[0]->HEVClc->qp_y; + memcpy(s->sList[i], s, sizeof(HEVCContext)); + s->sList[i]->HEVClc = s->HEVClcList[i]; + } + + avpriv_atomic_int_set(&s->wpp_err, 0); + ff_reset_entries(s->avctx); + + for (i = 0; i <= s->sh.num_entry_point_offsets; i++) { + arg[i] = i; + ret[i] = 0; + } + + if (s->ps.pps->entropy_coding_sync_enabled_flag) + s->avctx->execute2(s->avctx, hls_decode_entry_wpp, arg, ret, s->sh.num_entry_point_offsets + 1); + + for (i = 0; i <= s->sh.num_entry_point_offsets; i++) + res += ret[i]; +error: + av_free(ret); + av_free(arg); + return res; } static int set_side_data(HEVCContext *s) @@@ -2714,9 -2429,9 +2714,9 @@@ fail return ret; } - static int decode_nal_unit(HEVCContext *s, const HEVCNAL *nal) + static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; GetBitContext *gb = &lc->gb; int ctb_addr_ts, ret; diff --cc libavcodec/hevc.h index 5865f65,d15af71..f44fa49 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@@ -30,7 -33,7 +30,8 @@@ #include "bswapdsp.h" #include "cabac.h" #include "get_bits.h" +#include "hevcpred.h" + #include "h2645_parse.h" #include "hevcdsp.h" #include "internal.h" #include "thread.h" @@@ -746,38 -705,24 +747,11 @@@ typedef struct HEVCFrame uint8_t flags; } HEVCFrame; - typedef struct HEVCNAL { - uint8_t *rbsp_buffer; - int rbsp_buffer_size; - - int size; - const uint8_t *data; - - int raw_size; - const uint8_t *raw_data; - - GetBitContext gb; - - enum NALUnitType type; - int temporal_id; - - int skipped_bytes; - int skipped_bytes_pos_size; - int *skipped_bytes_pos; - } HEVCNAL; - - /* an input packet split into unescaped NAL units */ - typedef struct HEVCPacket { - HEVCNAL *nals; - int nb_nals; - int nals_allocated; - } HEVCPacket; - -struct HEVCContext; - -typedef struct HEVCPredContext { - void (*intra_pred[4])(struct HEVCContext *s, int x0, int y0, int c_idx); - - void (*pred_planar[4])(uint8_t *src, const uint8_t *top, - const uint8_t *left, ptrdiff_t stride); - void (*pred_dc)(uint8_t *src, const uint8_t *top, const uint8_t *left, - ptrdiff_t stride, int log2_size, int c_idx); - void (*pred_angular[4])(uint8_t *src, const uint8_t *top, - const uint8_t *left, ptrdiff_t stride, - int c_idx, int mode); -} HEVCPredContext; - typedef struct HEVCLocalContext { - DECLARE_ALIGNED(16, int16_t, mc_buffer[(MAX_PB_SIZE + 24) * MAX_PB_SIZE]); uint8_t cabac_state[HEVC_CONTEXTS]; + uint8_t stat_coeff[4]; + uint8_t first_qp_group; GetBitContext gb; @@@ -901,12 -830,7 +875,12 @@@ typedef struct HEVCContext uint16_t seq_decode; uint16_t seq_output; + int enable_parallel_tiles; + int wpp_err; + + const uint8_t *data; + - HEVCPacket pkt; + H2645Packet pkt; // type of the first VCL NAL of the current frame enum NALUnitType first_nal_type; @@@ -1066,29 -994,13 +1040,17 @@@ void ff_hevc_deblocking_boundary_streng int log2_trafo_size); int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s); int ff_hevc_cu_qp_delta_abs(HEVCContext *s); -void ff_hevc_hls_filter(HEVCContext *s, int x, int y); +int ff_hevc_cu_chroma_qp_offset_flag(HEVCContext *s); +int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s); +void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size); void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size); +void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, + int log2_trafo_size, enum ScanType scan_idx, + int c_idx); -void ff_hevc_pps_free(HEVCPPS **ppps); +void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size); -void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth); - /** - * Extract the raw (unescaped) HEVC bitstream. - */ - int ff_hevc_extract_rbsp(const uint8_t *src, int length, - HEVCNAL *nal); - - /** - * Split an input packet into NAL units. - */ - int ff_hevc_split_packet(HEVCPacket *pkt, const uint8_t *buf, int length, - AVCodecContext *avctx, int is_nalff, int nal_length_size); - int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id, uint8_t *buf, int buf_size); diff --cc libavcodec/hevc_parser.c index 59893bb,20eae54..71887a8 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@@ -39,14 -38,9 +40,14 @@@ typedef struct HEVCParserContext HEVCParamSets ps; int parsed_extradata; + +#if ADVANCED_PARSER + HEVCContext h; +#endif } HEVCParserContext; +#if !ADVANCED_PARSER - static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal, + static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, AVCodecContext *avctx) { HEVCParserContext *ctx = s->priv_data; @@@ -88,7 -82,7 +89,7 @@@ static int parse_nal_units(AVCodecParse HEVCParserContext *ctx = s->priv_data; int ret, i; - ret = ff_hevc_split_packet(NULL, &ctx->pkt, buf, buf_size, avctx, 0, 0); - ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, 0, 0); ++ ret = ff_h2645_split_packet(&ctx->pkt, buf, buf_size, avctx, 0, 0); if (ret < 0) return ret; @@@ -172,213 -161,7 +173,213 @@@ static int hevc_find_frame_end(AVCodecP return END_NOT_FOUND; } -static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx, +#if ADVANCED_PARSER +/** + * Parse NAL units of found picture and decode some basic information. + * + * @param s parser context. + * @param avctx codec context. + * @param buf buffer with field/frame data. + * @param buf_size size of the buffer. + */ +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 = &ctx->pkt; ++ H2645Packet *pkt = &ctx->pkt; + const uint8_t *buf_end = buf + buf_size; + int state = -1, i; - HEVCNAL *nal; ++ H2645NAL *nal; + int is_global = buf == avctx->extradata; + + 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)); ++ H2645NAL *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; + int ret; + 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(buf, src_length, nal); ++ consumed = ff_h2645_extract_rbsp(buf, src_length, nal); + if (consumed < 0) + return consumed; + + ret = init_get_bits8(gb, nal->data + 2, nal->size); + if (ret < 0) + return ret; + + 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: + + if (is_global) { + av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit: %d\n", h->nal_unit_type); + return AVERROR_INVALIDDATA; + } + + 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 = get_bitsz(gb, slice_address_length); + 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! */ + if (!is_global) + av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n"); + return -1; +} +#endif + +static int hevc_parse(AVCodecParserContext *s, + AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog