Mercurial > hg > forks > libbpg
comparison x265_glue.c @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children | 33594243ce31 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:772086c29cc7 |
---|---|
1 /* | |
2 * x265 encoder front-end | |
3 * | |
4 * Copyright (c) 2014 Fabrice Bellard | |
5 * | |
6 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 * of this software and associated documentation files (the "Software"), to deal | |
8 * in the Software without restriction, including without limitation the rights | |
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 * copies of the Software, and to permit persons to whom the Software is | |
11 * furnished to do so, subject to the following conditions: | |
12 * | |
13 * The above copyright notice and this permission notice shall be included in | |
14 * all copies or substantial portions of the Software. | |
15 * | |
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 * THE SOFTWARE. | |
23 */ | |
24 #include <stdlib.h> | |
25 #include <stdio.h> | |
26 #include <string.h> | |
27 #include <inttypes.h> | |
28 #include <unistd.h> | |
29 | |
30 #include "bpgenc.h" | |
31 | |
32 #include "x265.h" | |
33 | |
34 struct HEVCEncoderContext { | |
35 const x265_api *api; | |
36 x265_encoder *enc; | |
37 x265_picture *pic; | |
38 uint8_t *buf; | |
39 int buf_len, buf_size; | |
40 }; | |
41 | |
42 static HEVCEncoderContext *x265_open(const HEVCEncodeParams *params) | |
43 { | |
44 HEVCEncoderContext *s; | |
45 x265_param *p; | |
46 int preset_index; | |
47 const char *preset; | |
48 | |
49 s = malloc(sizeof(HEVCEncoderContext)); | |
50 memset(s, 0, sizeof(*s)); | |
51 | |
52 s->api = x265_api_get(params->bit_depth); | |
53 if (!s->api) { | |
54 fprintf(stderr, "x265 supports bit depths of 8, 10 or 12.\n"); | |
55 return NULL; | |
56 } | |
57 #if 0 | |
58 /* Note: the x265 library included in libbpg supported gray encoding */ | |
59 if (params->chroma_format == BPG_FORMAT_GRAY) { | |
60 fprintf(stderr, "x265 does not support monochrome (or alpha) data yet. Plase use the jctvc encoder.\n"); | |
61 return NULL; | |
62 } | |
63 #endif | |
64 | |
65 p = s->api->param_alloc(); | |
66 | |
67 preset_index = params->compress_level; /* 9 is placebo */ | |
68 | |
69 preset = x265_preset_names[preset_index]; | |
70 if (params->verbose) | |
71 printf("Using x265 preset: %s\n", preset); | |
72 | |
73 s->api->param_default_preset(p, preset, "ssim"); | |
74 | |
75 p->bRepeatHeaders = 1; | |
76 p->decodedPictureHashSEI = params->sei_decoded_picture_hash; | |
77 p->sourceWidth = params->width; | |
78 p->sourceHeight = params->height; | |
79 switch(params->chroma_format) { | |
80 case BPG_FORMAT_GRAY: | |
81 p->internalCsp = X265_CSP_I400; | |
82 break; | |
83 case BPG_FORMAT_420: | |
84 p->internalCsp = X265_CSP_I420; | |
85 break; | |
86 case BPG_FORMAT_422: | |
87 p->internalCsp = X265_CSP_I422; | |
88 break; | |
89 case BPG_FORMAT_444: | |
90 p->internalCsp = X265_CSP_I444; | |
91 break; | |
92 default: | |
93 abort(); | |
94 } | |
95 if (params->intra_only) { | |
96 p->keyframeMax = 1; /* only I frames */ | |
97 p->totalFrames = 1; | |
98 } else { | |
99 p->keyframeMax = 250; | |
100 p->totalFrames = 0; | |
101 p->maxNumReferences = 1; | |
102 p->bframes = 0; | |
103 } | |
104 p->bEnableRectInter = 1; | |
105 p->bEnableAMP = 1; /* cannot use 0 due to header restriction */ | |
106 p->internalBitDepth = params->bit_depth; | |
107 p->bEmitInfoSEI = 0; | |
108 if (params->verbose) | |
109 p->logLevel = X265_LOG_INFO; | |
110 else | |
111 p->logLevel = X265_LOG_NONE; | |
112 | |
113 /* dummy frame rate */ | |
114 p->fpsNum = 25; | |
115 p->fpsDenom = 1; | |
116 | |
117 p->rc.rateControlMode = X265_RC_CQP; | |
118 p->rc.qp = params->qp; | |
119 p->bLossless = params->lossless; | |
120 | |
121 s->enc = s->api->encoder_open(p); | |
122 | |
123 s->pic = s->api->picture_alloc(); | |
124 s->api->picture_init(p, s->pic); | |
125 | |
126 s->pic->colorSpace = p->internalCsp; | |
127 | |
128 s->api->param_free(p); | |
129 | |
130 return s; | |
131 } | |
132 | |
133 static void add_nal(HEVCEncoderContext *s, const uint8_t *data, int data_len) | |
134 { | |
135 int new_size, size; | |
136 | |
137 size = s->buf_len + data_len; | |
138 if (size > s->buf_size) { | |
139 new_size = (s->buf_size * 3) / 2; | |
140 if (new_size < size) | |
141 new_size = size; | |
142 s->buf = realloc(s->buf, new_size); | |
143 s->buf_size = new_size; | |
144 } | |
145 memcpy(s->buf + s->buf_len, data, data_len); | |
146 s->buf_len += data_len; | |
147 } | |
148 | |
149 static int x265_encode(HEVCEncoderContext *s, Image *img) | |
150 { | |
151 int c_count, i, ret; | |
152 x265_picture *pic; | |
153 uint32_t nal_count; | |
154 x265_nal *p_nal; | |
155 | |
156 pic = s->pic; | |
157 | |
158 if (img->format == BPG_FORMAT_GRAY) | |
159 c_count = 1; | |
160 else | |
161 c_count = 3; | |
162 for(i = 0; i < c_count; i++) { | |
163 pic->planes[i] = img->data[i]; | |
164 pic->stride[i] = img->linesize[i]; | |
165 } | |
166 pic->bitDepth = img->bit_depth; | |
167 | |
168 ret = s->api->encoder_encode(s->enc, &p_nal, &nal_count, pic, NULL); | |
169 if (ret > 0) { | |
170 for(i = 0; i < nal_count; i++) { | |
171 add_nal(s, p_nal[i].payload, p_nal[i].sizeBytes); | |
172 } | |
173 } | |
174 return 0; | |
175 } | |
176 | |
177 static int x265_close(HEVCEncoderContext *s, uint8_t **pbuf) | |
178 { | |
179 int buf_len, ret, i; | |
180 uint32_t nal_count; | |
181 x265_nal *p_nal; | |
182 | |
183 /* get last compressed pictures */ | |
184 for(;;) { | |
185 ret = s->api->encoder_encode(s->enc, &p_nal, &nal_count, NULL, NULL); | |
186 if (ret <= 0) | |
187 break; | |
188 for(i = 0; i < nal_count; i++) { | |
189 add_nal(s, p_nal[i].payload, p_nal[i].sizeBytes); | |
190 } | |
191 } | |
192 | |
193 if (s->buf_len < s->buf_size) { | |
194 s->buf = realloc(s->buf, s->buf_len); | |
195 } | |
196 | |
197 *pbuf = s->buf; | |
198 buf_len = s->buf_len; | |
199 | |
200 s->api->encoder_close(s->enc); | |
201 s->api->picture_free(s->pic); | |
202 free(s); | |
203 return buf_len; | |
204 } | |
205 | |
206 HEVCEncoder x265_hevc_encoder = { | |
207 .open = x265_open, | |
208 .encode = x265_encode, | |
209 .close = x265_close, | |
210 }; |