[FFmpeg-cvslog] Merge commit 'fa936a307f5cddfc2664600157a8207ca8080af6'
Derek Buitenhuis
git at videolan.org
Tue Apr 26 14:57:26 CEST 2016
ffmpeg | branch: master | Derek Buitenhuis <derek.buitenhuis at 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.buitenhuis at 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)
{
More information about the ffmpeg-cvslog
mailing list