Permalink
Browse files

Support for monochrome

  • Loading branch information...
1 parent e21a66d commit dcd14602164b2b39af6331081cdafcfbb2cd82d3 Arild Fuldseth (arilfuld) committed with Thomas Davies Dec 23, 2016
Showing with 206 additions and 108 deletions.
  1. +24 −7 common/common_frame.c
  2. +5 −0 common/inter_prediction.c
  3. +6 −1 common/snr.c
  4. +20 −15 common/temporal_interp.c
  5. +4 −2 dec/decode_block.c
  6. +5 −3 dec/decode_frame.c
  7. +7 −3 dec/maindec.c
  8. +56 −37 dec/read_bits.c
  9. +24 −7 enc/encode_block.c
  10. +5 −3 enc/encode_frame.c
  11. +8 −3 enc/mainenc.c
  12. +10 −4 enc/strings.c
  13. +32 −23 enc/write_bits.c
View
@@ -435,7 +435,7 @@ void TEMPLATE(create_yuv_frame)(yuv_frame_t *frame, int width, int height, int
{
int align;
- int sub = frame->sub = subsample == 420;
+ int sub = frame->sub = subsample == 400 ? 31 : subsample == 420;
frame->subsample = subsample;
frame->width = width;
frame->height = height;
@@ -450,25 +450,28 @@ void TEMPLATE(create_yuv_frame)(yuv_frame_t *frame, int width, int height, int
frame->area_y = ((height + 2*frame->pad_ver_y) * frame->stride_y + 16 + 15) & ~15;
frame->area_c = (((height >> sub) + 2*frame->pad_ver_c) * frame->stride_c + 16 + 15) & ~15;
frame->y = (SAMPLE *)malloc(frame->area_y*sizeof(SAMPLE))+frame->offset_y;
- frame->u = (SAMPLE *)malloc(2*frame->area_c*sizeof(SAMPLE))+frame->offset_c;
- frame->v = frame->u + frame->area_c;
-
align = (16 - ((int)(uintptr_t)frame->y)) & 15;
frame->offset_y += align;
frame->y += align;
+ frame->bitdepth = bitdepth;
+ frame->input_bitdepth = input_bitdepth;
+
+ if (frame->subsample == 400)
+ return;
+ frame->u = (SAMPLE *)malloc(2*frame->area_c*sizeof(SAMPLE))+frame->offset_c;
+ frame->v = frame->u + frame->area_c;
align = (16 - ((int)(uintptr_t)frame->u)) & 15;
frame->offset_c += align;
frame->u += align;
frame->v += align;
- frame->bitdepth = bitdepth;
- frame->input_bitdepth = input_bitdepth;
}
void TEMPLATE(close_yuv_frame)(yuv_frame_t *frame)
{
free(frame->y-frame->offset_y);
- free(frame->u-frame->offset_c);
+ if (frame->subsample != 400)
+ free(frame->u-frame->offset_c);
}
void TEMPLATE(read_yuv_frame)(yuv_frame_t *frame, FILE *infile)
@@ -495,6 +498,9 @@ void TEMPLATE(read_yuv_frame)(yuv_frame_t *frame, FILE *infile)
}
}
+ if (frame->subsample == 400)
+ return;
+
for (int i=0; i<height>>sub; ++i) {
if (fread(&frame->u[i*frame->stride_c], 1 + (frame->input_bitdepth > 8), width>>wsub, infile) != width>>wsub)
fatalerror("Error reading U from file");
@@ -569,6 +575,10 @@ void TEMPLATE(write_yuv_frame)(yuv_frame_t *frame, FILE *outfile)
if (fwrite(out, 1 + (frame->input_bitdepth != 8), width, outfile) != width)
fatalerror("Error writing Y to file");
}
+
+ if (frame->subsample == 400)
+ return;
+
for (int i=0; i<height>>sub; ++i) {
void *out = 0;
if (frame->input_bitdepth == 8) {
@@ -601,6 +611,10 @@ void TEMPLATE(write_yuv_frame)(yuv_frame_t *frame, FILE *outfile)
if (fwrite(out, 1 + (frame->input_bitdepth != 8), width>>wsub, outfile) != width>>wsub)
fatalerror("Error writing U to file");
}
+
+ if (frame->subsample == 400)
+ return;
+
for (int i=0; i<height>>sub; ++i) {
void *out = 0;
if (frame->input_bitdepth == 8) {
@@ -676,6 +690,9 @@ void TEMPLATE(pad_yuv_frame)(yuv_frame_t * f)
memcpy(&f->y[i*sy-f->pad_hor_y], &f->y[(h-1)*sy-f->pad_hor_y], (w+2*f->pad_hor_y)*frame_bitdepth / 8);
}
+ if (f->subsample == 400)
+ return;
+
/* UV */
/* Left and right */
@@ -233,6 +233,8 @@ void TEMPLATE(get_inter_prediction_yuv)(yuv_frame_t *ref, SAMPLE *pblock_y, SAMP
mv = mv_arr[index];
TEMPLATE(clip_mv)(&mv, yposY, xposY, width, height, bwidth, bheight, sign);
TEMPLATE(get_inter_prediction_luma)(pblock_y + offsetpY, ref_y + offsetrY, bwidth, bheight, rstride_y, pstride, &mv, sign, enable_bipred, width, height, xposY, yposY, bitdepth); //get_inter_prediction_yuv()
+ if (ref->subsample == 400)
+ continue;
if (ref->sub) {
get_inter_prediction_chroma(pblock_u + offsetpC, ref_u + offsetrC, bwidth >> ref->sub, bheight >> ref->sub, rstride_c, pstride >> ref->sub, &mv, sign, width >> ref->sub, height >> ref->sub, xposC, yposC, bitdepth);
get_inter_prediction_chroma(pblock_v + offsetpC, ref_v + offsetrC, bwidth >> ref->sub, bheight >> ref->sub, rstride_c, pstride >> ref->sub, &mv, sign, width >> ref->sub, height >> ref->sub, xposC, yposC, bitdepth);
@@ -257,6 +259,7 @@ void TEMPLATE(average_blocks_all)(SAMPLE *rec_y, SAMPLE *rec_u, SAMPLE *rec_v, S
rec_y[i*sizeY + j] = (SAMPLE)(((int)pblock0_y[i*sizeY + j] + (int)pblock1_y[i*sizeY + j]) >> 1);
}
}
+
for (i = 0; i < bheight >> sub; i++) {
for (j = 0; j < bwidth >> sub; j++) {
rec_u[i*sizeC + j] = (SAMPLE)(((int)pblock0_u[i*sizeC + j] + (int)pblock1_u[i*sizeC + j]) >> 1);
@@ -418,6 +421,8 @@ void TEMPLATE(get_inter_prediction_temp)(int width, int height, yuv_frame_t *ref
for (i = 0; i < MIN_PB_SIZE; i++) {
memcpy(pblock_y + (m + i)*size + n, pblock2_y + i*MIN_PB_SIZE, MIN_PB_SIZE*sizeof(SAMPLE));
}
+ if (ref0->subsample == 400)
+ continue;
for (i = 0; i < MIN_PB_SIZE / 2; i++) {
memcpy(pblock_u + (m / 2 + i)*size / 2 + n / 2, pblock2_u + i*MIN_PB_SIZE / 2, MIN_PB_SIZE*sizeof(SAMPLE) / 2);
memcpy(pblock_v + (m / 2 + i)*size / 2 + n / 2, pblock2_v + i*MIN_PB_SIZE / 2, MIN_PB_SIZE*sizeof(SAMPLE) / 2);
View
@@ -63,7 +63,12 @@ int TEMPLATE(snr_yuv)(snrvals *psnr,yuv_frame_t *f1,yuv_frame_t *f2,int height,i
}
plse = sumsqr / (maxsignal * maxsignal * ydim * xdim);
psnr->y = -10 * log10(plse);
-
+
+ if (f1->subsample == 400) {
+ psnr->u = psnr->v = 0;
+ return 0;
+ }
+
/* Calculate psnr for U */
sumsqr = 0;
for (i = 0; i < ydim_chr; i++)
@@ -158,8 +158,8 @@ static void scale_frame_down2x2(yuv_frame_t* sin, yuv_frame_t* sout)
}
}
- ho /= 2;
- wo /= 2;
+ ho >>= sin->sub;
+ wo >>= sin->sub;
for (int i=0; i<ho; ++i) {
for (j=0; j<wo; ++j) {
@@ -409,25 +409,26 @@ static uint32_t sad_cost(int xstart, int ystart, yuv_frame_t* pic[2], mv_t mv[2]
}
}
#if TEMP_INTERP_USE_CHROMA
+ int csize = size >> &pic[0]->sub;
if (bcost < best_cost) {
uint32_t ccost=0;
int cpos0=(ys[0]/2)*sc0+(xs[0]/2);
int cpos1=(ys[1]/2)*sc1+(xs[1]/2);
if (use_simd && size >= 8) {
- ccost += TEMPLATE(sad_calc_simd_unaligned)(&pic[0]->u[cpos0], &pic[1]->u[cpos1], sc0, sc1, size/2, size/2);
- ccost += TEMPLATE(sad_calc_simd_unaligned)(&pic[0]->v[cpos0], &pic[1]->v[cpos1], sc0, sc1, size/2, size/2);
+ ccost += TEMPLATE(sad_calc_simd_unaligned)(&pic[0]->u[cpos0], &pic[1]->u[cpos1], sc0, sc1, csize, csize);
+ ccost += TEMPLATE(sad_calc_simd_unaligned)(&pic[0]->v[cpos0], &pic[1]->v[cpos1], sc0, sc1, csize, csize);
} else {
p0=&pic[0]->u[cpos0];
p1=&pic[1]->u[cpos1];
- for (int i=0; i<size/2; ++i) {
- for (int j=0; j<size/2; ++j) {
+ for (int i=0; i<csize; ++i) {
+ for (int j=0; j<csize; ++j) {
ccost += abs(p1[i*sc1+j]-p0[i*sc0+j]);
}
}
p0=&pic[0]->v[cpos0];
p1=&pic[1]->v[cpos1];
- for (int i=0; i<size/2; ++i) {
- for (int j=0; j<size/2; ++j) {
+ for (int i=0; i<csize; ++i) {
+ for (int j=0; j<csize; ++j) {
ccost += abs(p1[i*sc1+j]-p0[i*sc0+j]);
}
}
@@ -513,16 +514,17 @@ static void skip_test(mv_data_t* mv_data, yuv_frame_t* picdata[2], int xp, int y
}
#if TEMP_INTERP_USE_CHROMA
if (skip) {
+ int sub = &picdata[0]->sub;
int thrC=thr/4;
int s0C=picdata[0]->stride_c;
int s1C=picdata[1]->stride_c;
- xstart /= 2;
- ystart /= 2;
- size /= 2;
- mv0.x /= 2;
- mv0.y /= 2;
- mv1.x /= 2;
- mv1.y /= 2;
+ xstart >>= sub;
+ ystart >>= sub;
+ size >>= sub;
+ mv0.x >>= sub;
+ mv0.y >>= sub;
+ mv1.x >>= sub;
+ mv1.y >>= sub;
for (int p=ystart; p<ystart+size && skip; p+=8) {
for (int q=xstart; q<xstart+size && skip; q+=8) {
@@ -893,6 +895,9 @@ static void interpolate_frame(mv_data_t* mv_data, yuv_frame_t* indata0, yuv_fram
interpolate_comp(mv_data, pic[0]->y, pic[0]->stride_y, pic[1]->y, pic[1]->stride_y, outdata->y, outdata->stride_y, wP, hP, pad, 0);
+ if (indata0->subsample == 400)
+ return;
+
// U
interpolate_comp(mv_data, pic[0]->u, pic[0]->stride_c, pic[1]->u, pic[1]->stride_c, outdata->u, outdata->stride_c, wPc, hPc, padc, indata0->sub);
View
@@ -299,7 +299,8 @@ static void decode_block(decoder_info_t *decoder_info,int size,int ypos,int xpos
//int downleft_available = get_downleft_available(ypos, xpos, size, height, 1 << decoder_info->log2_sb_size);
int tb_split = block_info.block_param.tb_split;
decode_and_reconstruct_block_intra(rec_y,rec->stride_y,sizeY,qpY,pblock_y,coeff_y,tb_split,upright_available,downleft_available,intra_mode,yposY,xposY,width,0,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][0][1] : NULL);
- decode_and_reconstruct_block_intra_uv(rec_u,rec_v,rec->stride_c,sizeC,qpC,pblock_u,pblock_v,coeff_u,coeff_v,tb_split && sizeC > 4,upright_available,downleft_available,intra_mode,yposC,xposC,width>>sub,1,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][1][1] : NULL, decoder_info->cfl_intra ? pblock_y : 0, rec_y, rec->stride_y, sub);
+ if (decoder_info->subsample != 400)
+ decode_and_reconstruct_block_intra_uv(rec_u,rec_v,rec->stride_c,sizeC,qpC,pblock_u,pblock_v,coeff_u,coeff_v,tb_split && sizeC > 4,upright_available,downleft_available,intra_mode,yposC,xposC,width>>sub,1,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][1][1] : NULL, decoder_info->cfl_intra ? pblock_y : 0, rec_y, rec->stride_y, sub);
}
else
{
@@ -429,7 +430,8 @@ static void decode_block(decoder_info_t *decoder_info,int size,int ypos,int xpos
/* Dequantize, invere tranform and reconstruct */
int ql = decoder_info->qmtx ? qp_to_qlevel(qpY,decoder_info->qmtx_offset) : 0;
decode_and_reconstruct_block_inter(rec_y,rec->stride_y,sizeY,qpY,pblock_y,coeff_y,tb_split,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][0][0] : NULL);
- if (decoder_info->cfl_inter) // Use reconstructed luma to improve chroma prediction
+ // Use reconstructed luma to improve chroma prediction
+ if (decoder_info->cfl_inter && decoder_info->subsample != 400)
TEMPLATE(improve_uv_prediction)(pblock_y, pblock_u, pblock_v, rec_y, sizeY, sizeY, rec->stride_y, sub, decoder_info->bitdepth);
decode_and_reconstruct_block_inter(rec_u,rec->stride_c,sizeC,qpC,pblock_u,coeff_u,tb_split&&sizeC>4,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][1][0] : NULL);
decode_and_reconstruct_block_inter(rec_v,rec->stride_c,sizeC,qpC,pblock_v,coeff_v,tb_split&&sizeC>4,decoder_info->bitdepth,decoder_info->qmtx ? decoder_info->iwmatrix[ql][2][0] : NULL);
View
@@ -120,7 +120,7 @@ void decode_frame(decoder_info_t *decoder_info, yuv_frame_t* rec_buffer)
//Generate new interpolated frame
for (k=0;k<num_sb_ver;k++){
for (l=0;l<num_sb_hor;l++){
- int sub = decoder_info->subsample == 420;
+ int sub = decoder_info->subsample == 400 ? 31 : decoder_info->subsample == 420;
int xposY = l*sb_size;
int yposY = k*sb_size;
TEMPLATE(process_block_dec)(decoder_info, sb_size, yposY, xposY, sub);
@@ -141,8 +141,10 @@ void decode_frame(decoder_info_t *decoder_info, yuv_frame_t* rec_buffer)
if (decoder_info->deblocking){
TEMPLATE(deblock_frame_y)(decoder_info->rec, decoder_info->deblock_data, width, height, qp, decoder_info->bitdepth);
- int qpc = decoder_info->subsample != 444 ? chroma_qp[qp] : qp;
- TEMPLATE(deblock_frame_uv)(decoder_info->rec, decoder_info->deblock_data, width, height, qpc, decoder_info->bitdepth);
+ if (decoder_info->subsample != 400) {
+ int qpc = decoder_info->subsample != 444 ? chroma_qp[qp] : qp;
+ TEMPLATE(deblock_frame_uv)(decoder_info->rec, decoder_info->deblock_data, width, height, qpc, decoder_info->bitdepth);
+ }
}
if (decoder_info->clpf) {
View
@@ -155,9 +155,13 @@ int main(int argc, char** argv)
decoder_info.deblock_data = (deblock_data_t *)malloc((height/MIN_PB_SIZE) * (width/MIN_PB_SIZE) * sizeof(deblock_data_t));
if (y4m_output) {
- fprintf(outfile,
- "YUV4MPEG2 W%d H%d F%d:1 Ip A%d:%d C%d",
- width, height, 30, 1, 1, decoder_info.subsample);
+ fprintf(outfile,
+ "YUV4MPEG2 W%d H%d F%d:1 Ip A%d:%d C",
+ width, height, 30, 1, 1);
+ if (decoder_info.subsample == 400)
+ fprintf(outfile, "mono");
+ else
+ fprintf(outfile, "%d", decoder_info.subsample);
if (decoder_info.input_bitdepth > 8)
fprintf(outfile, "p%d XYSCSS=%dp%d", decoder_info.input_bitdepth, decoder_info.subsample, decoder_info.input_bitdepth);
fprintf(outfile, "\x0a");
View
@@ -63,12 +63,15 @@ void read_sequence_header(decoder_info_t *decoder_info, stream_t *stream) {
if (decoder_info->qmtx) {
decoder_info->qmtx_offset = get_flc(6, stream) - 32;
}
- decoder_info->subsample = get_flc(1, stream) ? 420 : 444;
- if (decoder_info->subsample == 444 && !get_flc(1, stream))
- decoder_info->subsample = 422;
+ decoder_info->subsample = get_flc(2, stream);
+ decoder_info->subsample = // 0: 400 1: 420 2: 422 3: 444
+ (decoder_info->subsample & 1) * 20 + (decoder_info->subsample & 2) * 22 +
+ ((decoder_info->subsample & 3) == 3) * 2 + 400;
decoder_info->num_reorder_pics = get_flc(4, stream);
- decoder_info->cfl_intra = get_flc(1, stream);
- decoder_info->cfl_inter = get_flc(1, stream);
+ if (decoder_info->subsample != 400) {
+ decoder_info->cfl_intra = get_flc(1, stream);
+ decoder_info->cfl_inter = get_flc(1, stream);
+ }
decoder_info->bitdepth = get_flc(1, stream) ? 10 : 8;
if (decoder_info->bitdepth == 10)
decoder_info->bitdepth += 2 * get_flc(1, stream);
@@ -528,41 +531,54 @@ int read_block(decoder_info_t *decoder_info,stream_t *stream,block_info_dec_t *b
if (mode!=MODE_SKIP){
int tmp;
int cbp_table[8] = {1,0,5,2,6,3,7,4};
-
- bit_start = stream->bitcnt;
- code = get_vlc(0,stream);
- int off = (mode == MODE_MERGE) ? 1 : 2;
- if (decoder_info->tb_split_enable) {
- tb_split = code == off;
- if (code > off) code -= 1;
- if (tb_split)
- decoder_info->bit_count.cbp2_stat[0][stat_frame_type][mode-1][log2i(size)-3][8] += 1;
- }
- else{
- tb_split = 0;
+ code = 0;
+
+ if (decoder_info->subsample == 400) {
+ tb_split = cbp.u = cbp.v = 0;
+ cbp.y = get_flc(1,stream);
+ if (decoder_info->tb_split_enable && cbp.y) {
+ // 0: cbp=split=0, 10: cbp=1,split=0, 11: split=1
+ tb_split = get_flc(1,stream);
+ cbp.y &= !tb_split;
+ }
+ } else {
+ bit_start = stream->bitcnt;
+ code = get_vlc(0,stream);
+ int off = (mode == MODE_MERGE) ? 1 : 2;
+ if (decoder_info->tb_split_enable) {
+ tb_split = code == off;
+ if (code > off) code -= 1;
+ if (tb_split)
+ decoder_info->bit_count.cbp2_stat[0][stat_frame_type][mode-1][log2i(size)-3][8] += 1;
+ }
+ else{
+ tb_split = 0;
+ }
}
block_info->block_param.tb_split = tb_split;
decoder_info->bit_count.cbp[stat_frame_type] += (stream->bitcnt - bit_start);
if (tb_split == 0){
- tmp = 0;
- if (mode==MODE_MERGE){
- if (code==7)
- code = 1;
- else if (code>0)
- code = code+1;
- }
- else {
- if (decoder_info->block_context->cbp == 0 && code < 2) {
- code = 1 - code;
+ if (decoder_info->subsample != 400) {
+ tmp = 0;
+ if (mode==MODE_MERGE){
+ if (code==7)
+ code = 1;
+ else if (code>0)
+ code = code+1;
}
- }
- while (tmp < 8 && code != cbp_table[tmp]) tmp++;
- decoder_info->bit_count.cbp2_stat[max(0,decoder_info->block_context->cbp)][stat_frame_type][mode-1][log2i(size)-3][tmp] += 1;
+ else {
+ if (decoder_info->block_context->cbp == 0 && code < 2) {
+ code = 1 - code;
+ }
+ }
+ while (tmp < 8 && code != cbp_table[tmp]) tmp++;
+ decoder_info->bit_count.cbp2_stat[max(0,decoder_info->block_context->cbp)][stat_frame_type][mode-1][log2i(size)-3][tmp] += 1;
- cbp.y = ((tmp>>0)&1);
- cbp.u = ((tmp>>1)&1);
- cbp.v = ((tmp>>2)&1);
+ cbp.y = ((tmp>>0)&1);
+ cbp.u = ((tmp>>1)&1);
+ cbp.v = ((tmp>>2)&1);
+ }
block_info->cbp = cbp;
if (cbp.y){
@@ -672,10 +688,13 @@ int read_block(decoder_info_t *decoder_info,stream_t *stream,block_info_dec_t *b
}
bit_start = stream->bitcnt;
- int tmp;
- tmp = get_vlc(13, stream);
- cbp.u = tmp & 1;
- cbp.v = (tmp >> 1) & 1;
+ if (decoder_info->subsample != 400) {
+ int tmp;
+ tmp = get_vlc(13, stream);
+ cbp.u = tmp & 1;
+ cbp.v = (tmp >> 1) & 1;
+ } else
+ cbp.u = cbp.v = 0;
decoder_info->bit_count.cbp[stat_frame_type] += (stream->bitcnt - bit_start);
if (cbp.u){
bit_start = stream->bitcnt;
Oops, something went wrong.

0 comments on commit dcd1460

Please sign in to comment.