Particularly those that will be needed by the QSV decoder.
More can be added later as necessary.
... | ... |
@@ -2057,6 +2057,7 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" |
2057 | 2057 |
|
2058 | 2058 |
# parsers |
2059 | 2059 |
h264_parser_select="h264_decoder" |
2060 |
+hevc_parser_select="golomb" |
|
2060 | 2061 |
mpegvideo_parser_select="mpegvideo" |
2061 | 2062 |
mpeg4video_parser_select="error_resilience h263dsp mpeg_er mpegvideo qpeldsp" |
2062 | 2063 |
vc1_parser_select="mpegvideo startcode vc1_decoder" |
... | ... |
@@ -697,7 +697,7 @@ OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o |
697 | 697 |
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o |
698 | 698 |
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o |
699 | 699 |
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o |
700 |
-OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o |
|
700 |
+OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_parse.o |
|
701 | 701 |
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o |
702 | 702 |
OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o |
703 | 703 |
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ |
... | ... |
@@ -22,11 +22,99 @@ |
22 | 22 |
|
23 | 23 |
#include "libavutil/common.h" |
24 | 24 |
|
25 |
-#include "parser.h" |
|
25 |
+#include "golomb.h" |
|
26 | 26 |
#include "hevc.h" |
27 |
+#include "parser.h" |
|
27 | 28 |
|
28 | 29 |
#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes |
29 | 30 |
|
31 |
+#define IS_IRAP_NAL(nal) (nal->type >= 16 && nal->type <= 23) |
|
32 |
+ |
|
33 |
+typedef struct HEVCParserContext { |
|
34 |
+ ParseContext pc; |
|
35 |
+ |
|
36 |
+ HEVCPacket pkt; |
|
37 |
+ HEVCParamSets ps; |
|
38 |
+ |
|
39 |
+ int parsed_extradata; |
|
40 |
+} HEVCParserContext; |
|
41 |
+ |
|
42 |
+static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal, |
|
43 |
+ AVCodecContext *avctx) |
|
44 |
+{ |
|
45 |
+ HEVCParserContext *ctx = s->priv_data; |
|
46 |
+ GetBitContext *gb = &nal->gb; |
|
47 |
+ |
|
48 |
+ HEVCPPS *pps; |
|
49 |
+ HEVCSPS *sps; |
|
50 |
+ unsigned int pps_id; |
|
51 |
+ |
|
52 |
+ get_bits1(gb); // first slice in pic |
|
53 |
+ if (IS_IRAP_NAL(nal)) |
|
54 |
+ get_bits1(gb); // no output of prior pics |
|
55 |
+ |
|
56 |
+ pps_id = get_ue_golomb_long(gb); |
|
57 |
+ if (pps_id >= MAX_PPS_COUNT || !ctx->ps.pps_list[pps_id]) { |
|
58 |
+ av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); |
|
59 |
+ return AVERROR_INVALIDDATA; |
|
60 |
+ } |
|
61 |
+ pps = (HEVCPPS*)ctx->ps.pps_list[pps_id]->data; |
|
62 |
+ sps = (HEVCSPS*)ctx->ps.sps_list[pps->sps_id]->data; |
|
63 |
+ |
|
64 |
+ /* export the stream parameters */ |
|
65 |
+ s->coded_width = sps->width; |
|
66 |
+ s->coded_height = sps->height; |
|
67 |
+ s->width = sps->output_width; |
|
68 |
+ s->height = sps->output_height; |
|
69 |
+ s->format = sps->pix_fmt; |
|
70 |
+ avctx->profile = sps->ptl.general_ptl.profile_idc; |
|
71 |
+ avctx->level = sps->ptl.general_ptl.level_idc; |
|
72 |
+ |
|
73 |
+ /* ignore the rest for now*/ |
|
74 |
+ |
|
75 |
+ return 0; |
|
76 |
+} |
|
77 |
+ |
|
78 |
+static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, |
|
79 |
+ int buf_size, AVCodecContext *avctx) |
|
80 |
+{ |
|
81 |
+ HEVCParserContext *ctx = s->priv_data; |
|
82 |
+ int ret, i; |
|
83 |
+ |
|
84 |
+ ret = ff_hevc_split_packet(&ctx->pkt, buf, buf_size, avctx, 0, 0); |
|
85 |
+ if (ret < 0) |
|
86 |
+ return ret; |
|
87 |
+ |
|
88 |
+ for (i = 0; i < ctx->pkt.nb_nals; i++) { |
|
89 |
+ HEVCNAL *nal = &ctx->pkt.nals[i]; |
|
90 |
+ |
|
91 |
+ /* ignore everything except parameter sets and VCL NALUs */ |
|
92 |
+ switch (nal->type) { |
|
93 |
+ case NAL_VPS: ff_hevc_decode_nal_vps(&nal->gb, avctx, &ctx->ps); break; |
|
94 |
+ case NAL_SPS: ff_hevc_decode_nal_sps(&nal->gb, avctx, &ctx->ps, 1); break; |
|
95 |
+ case NAL_PPS: ff_hevc_decode_nal_pps(&nal->gb, avctx, &ctx->ps); break; |
|
96 |
+ case NAL_TRAIL_R: |
|
97 |
+ case NAL_TRAIL_N: |
|
98 |
+ case NAL_TSA_N: |
|
99 |
+ case NAL_TSA_R: |
|
100 |
+ case NAL_STSA_N: |
|
101 |
+ case NAL_STSA_R: |
|
102 |
+ case NAL_BLA_W_LP: |
|
103 |
+ case NAL_BLA_W_RADL: |
|
104 |
+ case NAL_BLA_N_LP: |
|
105 |
+ case NAL_IDR_W_RADL: |
|
106 |
+ case NAL_IDR_N_LP: |
|
107 |
+ case NAL_CRA_NUT: |
|
108 |
+ case NAL_RADL_N: |
|
109 |
+ case NAL_RADL_R: |
|
110 |
+ case NAL_RASL_N: |
|
111 |
+ case NAL_RASL_R: hevc_parse_slice_header(s, nal, avctx); break; |
|
112 |
+ } |
|
113 |
+ } |
|
114 |
+ |
|
115 |
+ return 0; |
|
116 |
+} |
|
117 |
+ |
|
30 | 118 |
/** |
31 | 119 |
* Find the end of the current frame in the bitstream. |
32 | 120 |
* @return the position of the first byte of the next frame, or END_NOT_FOUND |
... | ... |
@@ -34,8 +122,9 @@ |
34 | 34 |
static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, |
35 | 35 |
int buf_size) |
36 | 36 |
{ |
37 |
+ HEVCParserContext *ctx = s->priv_data; |
|
38 |
+ ParseContext *pc = &ctx->pc; |
|
37 | 39 |
int i; |
38 |
- ParseContext *pc = s->priv_data; |
|
39 | 40 |
|
40 | 41 |
for (i = 0; i < buf_size; i++) { |
41 | 42 |
int nut; |
... | ... |
@@ -76,7 +165,14 @@ static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx, |
76 | 76 |
const uint8_t *buf, int buf_size) |
77 | 77 |
{ |
78 | 78 |
int next; |
79 |
- ParseContext *pc = s->priv_data; |
|
79 |
+ |
|
80 |
+ HEVCParserContext *ctx = s->priv_data; |
|
81 |
+ ParseContext *pc = &ctx->pc; |
|
82 |
+ |
|
83 |
+ if (avctx->extradata && !ctx->parsed_extradata) { |
|
84 |
+ parse_nal_units(s, avctx->extradata, avctx->extradata_size, avctx); |
|
85 |
+ ctx->parsed_extradata = 1; |
|
86 |
+ } |
|
80 | 87 |
|
81 | 88 |
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { |
82 | 89 |
next = buf_size; |
... | ... |
@@ -89,6 +185,8 @@ static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx, |
89 | 89 |
} |
90 | 90 |
} |
91 | 91 |
|
92 |
+ parse_nal_units(s, buf, buf_size, avctx); |
|
93 |
+ |
|
92 | 94 |
*poutbuf = buf; |
93 | 95 |
*poutbuf_size = buf_size; |
94 | 96 |
return next; |
... | ... |
@@ -116,10 +214,30 @@ static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size) |
116 | 116 |
return 0; |
117 | 117 |
} |
118 | 118 |
|
119 |
+static void hevc_parser_close(AVCodecParserContext *s) |
|
120 |
+{ |
|
121 |
+ HEVCParserContext *ctx = s->priv_data; |
|
122 |
+ int i; |
|
123 |
+ |
|
124 |
+ for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.vps_list); i++) |
|
125 |
+ av_buffer_unref(&ctx->ps.vps_list[i]); |
|
126 |
+ for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.sps_list); i++) |
|
127 |
+ av_buffer_unref(&ctx->ps.sps_list[i]); |
|
128 |
+ for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.pps_list); i++) |
|
129 |
+ av_buffer_unref(&ctx->ps.pps_list[i]); |
|
130 |
+ |
|
131 |
+ for (i = 0; i < ctx->pkt.nals_allocated; i++) |
|
132 |
+ av_freep(&ctx->pkt.nals[i].rbsp_buffer); |
|
133 |
+ av_freep(&ctx->pkt.nals); |
|
134 |
+ ctx->pkt.nals_allocated = 0; |
|
135 |
+ |
|
136 |
+ av_freep(&ctx->pc.buffer); |
|
137 |
+} |
|
138 |
+ |
|
119 | 139 |
AVCodecParser ff_hevc_parser = { |
120 | 140 |
.codec_ids = { AV_CODEC_ID_HEVC }, |
121 |
- .priv_data_size = sizeof(ParseContext), |
|
141 |
+ .priv_data_size = sizeof(HEVCParserContext), |
|
122 | 142 |
.parser_parse = hevc_parse, |
123 |
- .parser_close = ff_parse_close, |
|
143 |
+ .parser_close = hevc_parser_close, |
|
124 | 144 |
.split = hevc_split, |
125 | 145 |
}; |