in libvmaf/tools/vmaf.c [71:167]
static int fetch_picture(video_input *vid, VmafPicture *pic, int depth)
{
int ret;
video_input_ycbcr ycbcr;
video_input_info info;
ret = video_input_fetch_frame(vid, ycbcr, NULL);
if (ret < 1) return !ret;
video_input_get_info(vid, &info);
ret = vmaf_picture_alloc(pic, pix_fmt_map(info.pixel_fmt), depth,
info.pic_w, info.pic_h);
if (ret) {
fprintf(stderr, "problem allocating picture.\n");
return -1;
}
if (info.depth == depth) {
if (info.depth == 8) {
for (unsigned i = 0; i < 3; i++) {
int xdec = i&&!(info.pixel_fmt&1);
int ydec = i&&!(info.pixel_fmt&2);
uint8_t *ycbcr_data = ycbcr[i].data +
(info.pic_y >> ydec) * ycbcr[i].stride +
(info.pic_x >> xdec);
uint8_t *pic_data = pic->data[i];
for (unsigned j = 0; j < pic->h[i]; j++) {
memcpy(pic_data, ycbcr_data, sizeof(*pic_data) * pic->w[i]);
pic_data += pic->stride[i];
ycbcr_data += ycbcr[i].stride;
}
}
} else {
for (unsigned i = 0; i < 3; i++) {
int xdec = i&&!(info.pixel_fmt&1);
int ydec = i&&!(info.pixel_fmt&2);
uint16_t *ycbcr_data = (uint16_t*) ycbcr[i].data +
(info.pic_y >> ydec) * (ycbcr[i].stride / 2) +
(info.pic_x >> xdec);
uint16_t *pic_data = pic->data[i];
for (unsigned j = 0; j < pic->h[i]; j++) {
memcpy(pic_data, ycbcr_data, sizeof(*pic_data) * pic->w[i]);
pic_data += pic->stride[i] / 2;
ycbcr_data += ycbcr[i].stride / 2;
}
}
}
} else if (depth > 8) {
// unequal bit-depth
// therefore depth must be > 8 since we do not support depth < 8
int left_shift = depth - info.depth;
if (info.depth == 8) {
for (unsigned i = 0; i < 3; i++) {
int xdec = i&&!(info.pixel_fmt&1);
int ydec = i&&!(info.pixel_fmt&2);
uint8_t *ycbcr_data = ycbcr[i].data +
(info.pic_y >> ydec) * ycbcr[i].stride +
(info.pic_x >> xdec);
uint16_t *pic_data = (uint16_t*)pic->data[i];
for (unsigned j = 0; j < pic->h[i]; j++) {
for (unsigned k = 0; k < pic->w[i]; k++) {
pic_data[k] = ycbcr_data[k] << left_shift;
}
pic_data += pic->stride[i] / 2;
ycbcr_data += ycbcr[i].stride;
}
}
} else {
for (unsigned i = 0; i < 3; i++) {
int xdec = i&&!(info.pixel_fmt&1);
int ydec = i&&!(info.pixel_fmt&2);
uint16_t *ycbcr_data = (uint16_t*) ycbcr[i].data +
(info.pic_y >> ydec) * (ycbcr[i].stride / 2) +
(info.pic_x >> xdec);
uint16_t *pic_data = pic->data[i];
for (unsigned j = 0; j < pic->h[i]; j++) {
for (unsigned k = 0; k < pic->w[i]; k++) {
pic_data[k] = ycbcr_data[k] << left_shift;
}
pic_data += pic->stride[i] / 2;
ycbcr_data += ycbcr[i].stride / 2;
}
}
}
} else {
fprintf(stderr, "expect depth > 8\n");
return -1;
}
return 0;
}