Skip to content

Commit

Permalink
vcapf,vopp/matrix2: supp fmts converted over Y416
Browse files Browse the repository at this point in the history
+ do not print the BT.601 hint if matrix with 601->709 conv used
  • Loading branch information
MartinPulec committed Oct 3, 2024
1 parent f08f56f commit d693e74
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 20 deletions.
111 changes: 93 additions & 18 deletions src/capture_filter/matrix2.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,22 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @todo
* * support for RGB formats
*/

#include <errno.h> // for errno
#include <stdbool.h> // for bool, false, true
#include <stdint.h> // for uint16_t
#include <stdlib.h> // for NULL, free, calloc
#include <string.h> // for strcmp, memcpy

#include "capture_filter.h" // for CAPTURE_FILTER_AB...
#include "debug.h" // for LOG_LEVEL_ERROR, MSG
#include "lib_common.h" // for REGISTER_MODULE
#include "pixfmt_conv.h" // for get_decoder_from_to
#include "types.h" // for tile, video_frame
#include "utils/color_out.h" // for color_printf, TBOLD
#include "utils/macros.h" // for STR_LEN, snprintf_ch
Expand All @@ -67,6 +75,8 @@ struct state_capture_filter_matrix2 {
double transform_matrix[MATRIX_VOL];
void *vo_pp_out_buffer; ///< buffer to write to if we use vo_pp wrapper
///< (otherwise unused)
void *y416_tmp_buffer;
size_t y416_tmp_buffer_sz;
};

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

static struct video_frame *
filter(void *state, struct video_frame *in)
static void
apply_to_uyvy(struct state_capture_filter_matrix2 *s, struct video_frame *in,
struct video_frame *out)
{
struct state_capture_filter_matrix2 *s = state;
struct video_desc desc = video_desc_from_frame(in);
struct video_frame *out = vf_alloc_desc(desc);
if (s->vo_pp_out_buffer) {
out->tiles[0].data = s->vo_pp_out_buffer;
} else {
out->tiles[0].data = malloc(out->tiles[0].data_len);
out->callbacks.data_deleter = vf_data_deleter;
}
out->callbacks.dispose = vf_free;

if (in->color_spec != UYVY) {
MSG(ERROR, "Sorry, only UYVY supported by now.\n");
}
unsigned char *in_data = (unsigned char *) in->tiles[0].data;
unsigned char *out_data = (unsigned char *) out->tiles[0].data;

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

VIDEO_FRAME_DISPOSE(in);
static bool
convert_apply_y416(struct state_capture_filter_matrix2 *s,
struct video_frame *in, struct video_frame *out)
{
decoder_t from = get_decoder_from_to(in->color_spec, Y416);
decoder_t to = get_decoder_from_to(Y416, in->color_spec);
if (from == NULL || to == NULL) {
return false;
}

const size_t tmp_len =
vc_get_datalen(in->tiles[0].width, in->tiles[0].height, Y416);
if (s->y416_tmp_buffer_sz <= tmp_len) {
free(s->y416_tmp_buffer);
s->y416_tmp_buffer = malloc(tmp_len);
s->y416_tmp_buffer_sz = tmp_len;
}
from((unsigned char *) s->y416_tmp_buffer,
(unsigned char *) in->tiles[0].data, (int) tmp_len, 0, 0, 0);
uint16_t *data = s->y416_tmp_buffer;
for (unsigned int i = 0; i < tmp_len; i += 8) {
double u = data[0] - (1 << 15);
double y = data[1] - (1 << 12);
double v = data[2] - (1 << 15);
// U
*data++ = (1 << 15) + s->transform_matrix[3] * y +
s->transform_matrix[4] * u +
s->transform_matrix[5] * v;
// Y
*data++ = (1 << 12) + s->transform_matrix[0] * y +
s->transform_matrix[1] * u +
s->transform_matrix[2] * v;
// V
*data++ = (1 << 15) + s->transform_matrix[6] * y +
s->transform_matrix[7] * u +
s->transform_matrix[8] * v;
// A
*data++ = 0xFFFF;
}

to((unsigned char *) out->tiles[0].data,
(unsigned char *) s->y416_tmp_buffer, (int) tmp_len, DEFAULT_R_SHIFT,
DEFAULT_G_SHIFT, DEFAULT_B_SHIFT);
return true;
}

static struct video_frame *
filter(void *state, struct video_frame *in)
{
struct state_capture_filter_matrix2 *s = state;
struct video_desc desc = video_desc_from_frame(in);
struct video_frame *out = vf_alloc_desc(desc);
if (s->vo_pp_out_buffer) {
out->tiles[0].data = s->vo_pp_out_buffer;
} else {
out->tiles[0].data = malloc(out->tiles[0].data_len);
out->callbacks.data_deleter = vf_data_deleter;
}
out->callbacks.dispose = vf_free;

if (in->color_spec == UYVY) {
apply_to_uyvy(s, in, out);
} else {
if (codec_is_a_rgb(in->color_spec) ||
!convert_apply_y416(s, in, out)) {
MSG(ERROR,
"Sorry, only UYVY and YCbCr modes convertible to "
"and from Y416 are supported by now (have %s).\n",
get_codec_name(in->color_spec));
VIDEO_FRAME_DISPOSE(in);
return out;
}
}

VIDEO_FRAME_DISPOSE(in);
return out;
}

Expand Down
6 changes: 4 additions & 2 deletions src/libavcodec/from_lavc_vid_conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3024,10 +3024,12 @@ get_cs_for_conv(AVFrame *f, codec_t interm_pf, codec_t out_pf)
"UltraGrid!\n",
av_color_space_name(f->colorspace));
}
if (src_601 && get_default_cs() != CS_601_LIM) {
const bool have_pp = tok_in_argv(uv_argv, "y601_to_y709");
if (src_601 && get_default_cs() != CS_601_LIM && !have_pp) {
MSG(WARNING,
"Got %s CS but not converted - consider \"--param "
"color-601\" as a hint for supported displays\n",
"color-601\" as a hint for supported displays or "
"\"-p matrix2:y601_to_y709\"\n",
av_color_space_name(f->colorspace));
}
return CS_DFL; // doesn't matter - won't be used anyways
Expand Down

0 comments on commit d693e74

Please sign in to comment.