Skip to content

Commit d693e74

Browse files
committed
vcapf,vopp/matrix2: supp fmts converted over Y416
+ do not print the BT.601 hint if matrix with 601->709 conv used
1 parent f08f56f commit d693e74

File tree

2 files changed

+97
-20
lines changed

2 files changed

+97
-20
lines changed

src/capture_filter/matrix2.c

Lines changed: 93 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,22 @@
3434
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3535
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636
*/
37+
/**
38+
* @file
39+
* @todo
40+
* * support for RGB formats
41+
*/
3742

3843
#include <errno.h> // for errno
44+
#include <stdbool.h> // for bool, false, true
45+
#include <stdint.h> // for uint16_t
3946
#include <stdlib.h> // for NULL, free, calloc
4047
#include <string.h> // for strcmp, memcpy
4148

4249
#include "capture_filter.h" // for CAPTURE_FILTER_AB...
4350
#include "debug.h" // for LOG_LEVEL_ERROR, MSG
4451
#include "lib_common.h" // for REGISTER_MODULE
52+
#include "pixfmt_conv.h" // for get_decoder_from_to
4553
#include "types.h" // for tile, video_frame
4654
#include "utils/color_out.h" // for color_printf, TBOLD
4755
#include "utils/macros.h" // for STR_LEN, snprintf_ch
@@ -67,6 +75,8 @@ struct state_capture_filter_matrix2 {
6775
double transform_matrix[MATRIX_VOL];
6876
void *vo_pp_out_buffer; ///< buffer to write to if we use vo_pp wrapper
6977
///< (otherwise unused)
78+
void *y416_tmp_buffer;
79+
size_t y416_tmp_buffer_sz;
7080
};
7181

7282
static void
@@ -83,7 +93,9 @@ usage(void)
8393
"matrix [a b c; d e f; g h i], decimals.\n"
8494
"Coefficients are applied to unpacked pixels (eg. on Y Cb "
8595
"and Cr channels of UYVY).\n");
86-
color_printf("\nCurrently only " TBOLD("UYVY") " is supported.\n");
96+
color_printf("\n" TBOLD("Note: ") "Currently only " TBOLD(
97+
"YCbCr") " codecs are supported. "
98+
"Let us know if interested in " TBOLD("RGB") " ones.\n");
8799
color_printf(
88100
"\nSee also " TBOLD("matrix") " capture filter/postprocessor.\n");
89101
color_printf("\n");
@@ -146,26 +158,15 @@ init(struct module *parent, const char *cfg, void **state)
146158
static void
147159
done(void *state)
148160
{
161+
struct state_capture_filter_matrix2 *s = state;
162+
free(s->y416_tmp_buffer);
149163
free(state);
150164
}
151165

152-
static struct video_frame *
153-
filter(void *state, struct video_frame *in)
166+
static void
167+
apply_to_uyvy(struct state_capture_filter_matrix2 *s, struct video_frame *in,
168+
struct video_frame *out)
154169
{
155-
struct state_capture_filter_matrix2 *s = state;
156-
struct video_desc desc = video_desc_from_frame(in);
157-
struct video_frame *out = vf_alloc_desc(desc);
158-
if (s->vo_pp_out_buffer) {
159-
out->tiles[0].data = s->vo_pp_out_buffer;
160-
} else {
161-
out->tiles[0].data = malloc(out->tiles[0].data_len);
162-
out->callbacks.data_deleter = vf_data_deleter;
163-
}
164-
out->callbacks.dispose = vf_free;
165-
166-
if (in->color_spec != UYVY) {
167-
MSG(ERROR, "Sorry, only UYVY supported by now.\n");
168-
}
169170
unsigned char *in_data = (unsigned char *) in->tiles[0].data;
170171
unsigned char *out_data = (unsigned char *) out->tiles[0].data;
171172

@@ -192,9 +193,83 @@ filter(void *state, struct video_frame *in)
192193
s->transform_matrix[1] * u +
193194
s->transform_matrix[2] * v;
194195
}
196+
}
195197

196-
VIDEO_FRAME_DISPOSE(in);
198+
static bool
199+
convert_apply_y416(struct state_capture_filter_matrix2 *s,
200+
struct video_frame *in, struct video_frame *out)
201+
{
202+
decoder_t from = get_decoder_from_to(in->color_spec, Y416);
203+
decoder_t to = get_decoder_from_to(Y416, in->color_spec);
204+
if (from == NULL || to == NULL) {
205+
return false;
206+
}
207+
208+
const size_t tmp_len =
209+
vc_get_datalen(in->tiles[0].width, in->tiles[0].height, Y416);
210+
if (s->y416_tmp_buffer_sz <= tmp_len) {
211+
free(s->y416_tmp_buffer);
212+
s->y416_tmp_buffer = malloc(tmp_len);
213+
s->y416_tmp_buffer_sz = tmp_len;
214+
}
215+
from((unsigned char *) s->y416_tmp_buffer,
216+
(unsigned char *) in->tiles[0].data, (int) tmp_len, 0, 0, 0);
217+
uint16_t *data = s->y416_tmp_buffer;
218+
for (unsigned int i = 0; i < tmp_len; i += 8) {
219+
double u = data[0] - (1 << 15);
220+
double y = data[1] - (1 << 12);
221+
double v = data[2] - (1 << 15);
222+
// U
223+
*data++ = (1 << 15) + s->transform_matrix[3] * y +
224+
s->transform_matrix[4] * u +
225+
s->transform_matrix[5] * v;
226+
// Y
227+
*data++ = (1 << 12) + s->transform_matrix[0] * y +
228+
s->transform_matrix[1] * u +
229+
s->transform_matrix[2] * v;
230+
// V
231+
*data++ = (1 << 15) + s->transform_matrix[6] * y +
232+
s->transform_matrix[7] * u +
233+
s->transform_matrix[8] * v;
234+
// A
235+
*data++ = 0xFFFF;
236+
}
237+
238+
to((unsigned char *) out->tiles[0].data,
239+
(unsigned char *) s->y416_tmp_buffer, (int) tmp_len, DEFAULT_R_SHIFT,
240+
DEFAULT_G_SHIFT, DEFAULT_B_SHIFT);
241+
return true;
242+
}
243+
244+
static struct video_frame *
245+
filter(void *state, struct video_frame *in)
246+
{
247+
struct state_capture_filter_matrix2 *s = state;
248+
struct video_desc desc = video_desc_from_frame(in);
249+
struct video_frame *out = vf_alloc_desc(desc);
250+
if (s->vo_pp_out_buffer) {
251+
out->tiles[0].data = s->vo_pp_out_buffer;
252+
} else {
253+
out->tiles[0].data = malloc(out->tiles[0].data_len);
254+
out->callbacks.data_deleter = vf_data_deleter;
255+
}
256+
out->callbacks.dispose = vf_free;
257+
258+
if (in->color_spec == UYVY) {
259+
apply_to_uyvy(s, in, out);
260+
} else {
261+
if (codec_is_a_rgb(in->color_spec) ||
262+
!convert_apply_y416(s, in, out)) {
263+
MSG(ERROR,
264+
"Sorry, only UYVY and YCbCr modes convertible to "
265+
"and from Y416 are supported by now (have %s).\n",
266+
get_codec_name(in->color_spec));
267+
VIDEO_FRAME_DISPOSE(in);
268+
return out;
269+
}
270+
}
197271

272+
VIDEO_FRAME_DISPOSE(in);
198273
return out;
199274
}
200275

src/libavcodec/from_lavc_vid_conv.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,10 +3024,12 @@ get_cs_for_conv(AVFrame *f, codec_t interm_pf, codec_t out_pf)
30243024
"UltraGrid!\n",
30253025
av_color_space_name(f->colorspace));
30263026
}
3027-
if (src_601 && get_default_cs() != CS_601_LIM) {
3027+
const bool have_pp = tok_in_argv(uv_argv, "y601_to_y709");
3028+
if (src_601 && get_default_cs() != CS_601_LIM && !have_pp) {
30283029
MSG(WARNING,
30293030
"Got %s CS but not converted - consider \"--param "
3030-
"color-601\" as a hint for supported displays\n",
3031+
"color-601\" as a hint for supported displays or "
3032+
"\"-p matrix2:y601_to_y709\"\n",
30313033
av_color_space_name(f->colorspace));
30323034
}
30333035
return CS_DFL; // doesn't matter - won't be used anyways

0 commit comments

Comments
 (0)