From: Michael Niedermayer Date: Thu, 9 Jul 2015 03:04:13 +0000 (+0200) Subject: Merge commit '69ab9f53f901eac6a649e22d28cf093357870627' X-Git-Tag: n2.8~1170 X-Git-Url: http://git.videolan.org/?p=ffmpeg.git;a=commitdiff_plain;h=07ae8fa20ef202206157efebf0a09db9a9cb9634 Merge commit '69ab9f53f901eac6a649e22d28cf093357870627' * commit '69ab9f53f901eac6a649e22d28cf093357870627': hevc: split bitstream unescaping to a separate file Conflicts: libavcodec/Makefile libavcodec/hevc.c See: afa93d198aaf2cc661c4df6d4095cd030265d30a Merged-by: Michael Niedermayer --- 07ae8fa20ef202206157efebf0a09db9a9cb9634 diff --cc libavcodec/Makefile index db8d818137,e04ee55b90..a062833ffc --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@@ -285,7 -240,8 +285,7 @@@ OBJS-$(CONFIG_HAP_DECODER) OBJS-$(CONFIG_HAP_ENCODER) += hapenc.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 + hevcdsp.o hevc_filter.o hevc_parse.o -OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.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/hevc.c index f7f0552498,ce4533e639..38734f017d --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@@ -2954,46 -2694,18 +2841,44 @@@ static int decode_nal_units(HEVCContex } s->nals = tmp; memset(s->nals + s->nals_allocated, 0, - (new_size - s->nals_allocated) * sizeof(*tmp)); + (new_size - s->nals_allocated) * sizeof(*s->nals)); + + tmp = av_realloc_array(s->skipped_bytes_nal, new_size, sizeof(*s->skipped_bytes_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_nal = tmp; + + tmp = av_realloc_array(s->skipped_bytes_pos_size_nal, new_size, sizeof(*s->skipped_bytes_pos_size_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_pos_size_nal = tmp; + + tmp = av_realloc_array(s->skipped_bytes_pos_nal, new_size, sizeof(*s->skipped_bytes_pos_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_pos_nal = tmp; + + s->skipped_bytes_pos_size_nal[s->nals_allocated] = 1024; // initial buffer size + s->skipped_bytes_pos_nal[s->nals_allocated] = av_malloc_array(s->skipped_bytes_pos_size_nal[s->nals_allocated], sizeof(*s->skipped_bytes_pos)); + if (!s->skipped_bytes_pos_nal[s->nals_allocated]) + goto fail; s->nals_allocated = new_size; } - nal = &s->nals[s->nb_nals++]; + s->skipped_bytes_pos_size = s->skipped_bytes_pos_size_nal[s->nb_nals]; + s->skipped_bytes_pos = s->skipped_bytes_pos_nal[s->nb_nals]; + nal = &s->nals[s->nb_nals]; - consumed = ff_hevc_extract_rbsp(buf, extract_length, nal); + consumed = ff_hevc_extract_rbsp(s, buf, extract_length, nal); - - s->skipped_bytes_nal[s->nb_nals] = s->skipped_bytes; - s->skipped_bytes_pos_size_nal[s->nb_nals] = s->skipped_bytes_pos_size; - s->skipped_bytes_pos_nal[s->nb_nals++] = s->skipped_bytes_pos; - - if (consumed < 0) { ret = consumed; goto fail; } - ret = init_get_bits8(&s->HEVClc.gb, nal->data, nal->size); ++ s->skipped_bytes_nal[s->nb_nals] = s->skipped_bytes; ++ s->skipped_bytes_pos_size_nal[s->nb_nals] = s->skipped_bytes_pos_size; ++ s->skipped_bytes_pos_nal[s->nb_nals++] = s->skipped_bytes_pos; ++ + ret = init_get_bits8(&s->HEVClc->gb, nal->data, nal->size); if (ret < 0) goto fail; hls_nal_unit(s); diff --cc libavcodec/hevc.h index 8ab9f84f6f,8b06e1f4cd..bd0c48bf81 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@@ -1040,17 -995,19 +1037,23 @@@ 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, ++int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length, + HEVCNAL *nal); + extern const uint8_t ff_hevc_qpel_extra_before[4]; extern const uint8_t ff_hevc_qpel_extra_after[4]; extern const uint8_t ff_hevc_qpel_extra[4]; diff --cc libavcodec/hevc_parse.c index 0000000000,32a440bf92..260f1e1aa6 mode 000000,100644..100644 --- a/libavcodec/hevc_parse.c +++ b/libavcodec/hevc_parse.c @@@ -1,0 -1,129 +1,145 @@@ + /* + * HEVC common 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 + */ + + #include + + #include "config.h" + + #include "libavutil/intreadwrite.h" + #include "libavutil/mem.h" + + #include "hevc.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, ++int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length, + HEVCNAL *nal) + { + int i, si, di; + uint8_t *dst; + ++ if (s) ++ s->skipped_bytes = 0; + #define STARTCODE_TEST \ + if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ + if (src[i + 2] != 3) { \ + /* startcode, so we must be past the end */ \ + length = i; \ + } \ + break; \ + } + #if HAVE_FAST_UNALIGNED + #define FIND_FIRST_ZERO \ + if (i > 0 && !src[i]) \ + i--; \ + while (src[i]) \ + i++ + #if HAVE_FAST_64BIT + for (i = 0; i + 1 < length; i += 9) { + if (!((~AV_RN64A(src + i) & + (AV_RN64A(src + i) - 0x0100010001000101ULL)) & + 0x8000800080008080ULL)) + continue; + FIND_FIRST_ZERO; + STARTCODE_TEST; + i -= 7; + } + #else + for (i = 0; i + 1 < length; i += 5) { + if (!((~AV_RN32A(src + i) & + (AV_RN32A(src + i) - 0x01000101U)) & + 0x80008080U)) + continue; + FIND_FIRST_ZERO; + STARTCODE_TEST; + i -= 3; + } + #endif /* HAVE_FAST_64BIT */ + #else + for (i = 0; i + 1 < length; i += 2) { + if (src[i]) + continue; + if (i > 0 && src[i - 1] == 0) + i--; + STARTCODE_TEST; + } + #endif /* HAVE_FAST_UNALIGNED */ + + if (i >= length - 1) { // no escaped 0 + nal->data = + nal->raw_data = src; + nal->size = + nal->raw_size = length; + return length; + } + + av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size, + length + FF_INPUT_BUFFER_PADDING_SIZE); + if (!nal->rbsp_buffer) + return AVERROR(ENOMEM); + + dst = nal->rbsp_buffer; + + memcpy(dst, src, i); + si = di = i; + while (si + 2 < length) { + // remove escapes (very rare 1:2^22) + if (src[si + 2] > 3) { + dst[di++] = src[si++]; + dst[di++] = src[si++]; + } else if (src[si] == 0 && src[si + 1] == 0) { + if (src[si + 2] == 3) { // escape + dst[di++] = 0; + dst[di++] = 0; + si += 3; + ++ if (s) { ++ s->skipped_bytes++; ++ if (s->skipped_bytes_pos_size < s->skipped_bytes) { ++ s->skipped_bytes_pos_size *= 2; ++ av_reallocp_array(&s->skipped_bytes_pos, ++ s->skipped_bytes_pos_size, ++ sizeof(*s->skipped_bytes_pos)); ++ if (!s->skipped_bytes_pos) ++ return AVERROR(ENOMEM); ++ } ++ if (s->skipped_bytes_pos) ++ s->skipped_bytes_pos[s->skipped_bytes-1] = di - 1; ++ } + continue; + } else // next start code + goto nsc; + } + + dst[di++] = src[si++]; + } + while (si < length) + dst[di++] = src[si++]; + + nsc: + memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + nal->data = dst; + nal->size = di; + nal->raw_data = src; + nal->raw_size = si; + return si; + } ++