void performdct() { float fourier1[N*N],fourier2[N*N],inverse[N*N]; //init_dct(); fdct(fourier1,mat1); fdct(fourier2,mat2); int i=0; for(i=0;i<64;i++) { fourier1[i]=(fourier1[i]+fourier2[i])/2.0; } idct(inverse,fourier1); printf("\n<"); for(i=0;i<64;i++) { if((i%8==0)) printf("\n"); printf("%d ",(int)inverse[i]); } printf(">\n"); }
int main() { tga_image tga; double dct_buf[8][8]; int i, j, k, l; load_tga(&tga, "in.tga"); k = 0; l = (tga.height / 8) * (tga.width / 8); for (j=0; j<tga.height/8; j++) for (i=0; i<tga.width/8; i++) { dct(&tga, dct_buf, i*8, j*8); quantize(dct_buf); idct(&tga, dct_buf, i*8, j*8); printf("processed %d/%d blocks.\r", ++k,l); fflush(stdout); } printf("\n"); DONTFAIL( tga_write_mono("out.tga", tga.image_data, tga.width, tga.height) ); tga_free_buffers(&tga); return EXIT_SUCCESS; }
dct_io_buffer_t* dct_result( void ) { uint32_t i; dct_io_buffer_t* io_buffer; io_buffer = NULL; if( current_io_buffer != NULL) { if( current_io_buffer->dct_mode == DCT_MODE_FDCT ) { for( i = 0; i < current_io_buffer->num_total_blocks; i++ ) { fdct(current_io_buffer->input[i], current_io_buffer->output[i]); } } else if( current_io_buffer->dct_mode == DCT_MODE_IDCT ) { for( i = 0; i < current_io_buffer->num_total_blocks; i++ ) { idct(current_io_buffer->input[i], current_io_buffer->output[i]); } } io_buffer = current_io_buffer; current_io_buffer = NULL; } return io_buffer; }
unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) { int i,k,q_scale,rl; int *iqtab; memset (blk, 0, 6*DCTSIZE2*4); iqtab = iq_uv; for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4) if (i>1) iqtab = iq_y; // zigzag transformation rl = *mdec_rl++; q_scale = RUNOF(rl); blk[0] = iqtab[0]*VALOF(rl); for(k = 0;;) { rl = *mdec_rl++; if (rl==NOP) break; k += RUNOF(rl)+1; // skip level zero-coefficients if (k > 63) break; blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16; } idct(blk,k+1); blk+=DCTSIZE2; } return mdec_rl; }
void Dct::doDCT(Matrix<short> *originMatrix, long (*resultMatrix)[MATRIX_SIZE+4], long dctRadius){ this->originMatrix = originMatrix; this->resultMatrix = resultMatrix; dct(); lpf(dctRadius); idct(); }
static void drawBasis(uint8_t *dst, int stride, int amp, int freq, int dc) { int src[64]; memset(src, 0, 64*sizeof(int)); src[0]= dc; if(amp) src[freq]= amp; idct(dst, stride, src); }
int main() { double *out = malloc(sizeOther*sizeof(double)); double *in = malloc(sizeOther*sizeof(double)); idct(in,out,sizeOther,&sw_cos); free(out); }
/* Performs Inverse DCT on all blocks */ static __inline void MBiDCT(int16_t data[6 * 64], const uint8_t cbp) { start_timer(); if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]); if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]); if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]); if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]); if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]); if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]); stop_idct_timer(); }
void grayDctDenoisingInvoker::operator() (const Range &range) const { for (int i = range.start; i <= range.end - 1; ++i) { int y = i / (src.cols - psize); int x = i % (src.cols - psize); Rect patchNum( x, y, psize, psize ); Mat patch(psize, psize, CV_32FC1); src(patchNum).copyTo( patch ); dct(patch, patch); float *data = (float *) patch.data; for (int k = 0; k < psize*psize; ++k) data[k] *= fabs(data[k]) > thresh; idct(patch, patches[i]); } }
void uncompress(image* in, image* out, const float* quantify) { Block block = block_new(); int colBlock = 0; int lineBlock = 0; int kIn = 0; int n,m; out->size = in->h*in->w; out->h = in->h; out->w = in->w; // Iterator on image : block by block for(int i = 0 ; i < in->h * in->w ; i += 64) { kIn = 0; ZIterator zit = zIterator_new(block, 8); // Z Parcours for reposition of blocks block.data[0] = in->data[i]; // First iterator value while(zIterator_hasNext(zit)) { block.data[zit.line*8 + zit.column] = in->data[i + (kIn++)]; zIterator_next(&zit); } block.data[zit.line*8 + zit.column] = in->data[i + (kIn++)]; // last pixel // Quantify for(n = 0; n < 8 ; ++n) { for(m = 0; m < 8 ; ++m) { block.data[n*8 + m] *= quantify[n*8 + m]; } } idct(out, block.data, colBlock, lineBlock); colBlock += 8; if(colBlock >= in->w) { colBlock = 0; lineBlock += 8; } } block_delete(&block); }
PROTO_THREAD_ROUTINE(dct, params) { uint32_t i; PRINT("DCT thread start\n"); while(1) { if( current_io_buffer == NULL ) { vp_os_mutex_lock(&dct_start_mutex); vp_os_cond_wait(&dct_start_cond); vp_os_mutex_unlock(&dct_start_mutex); } if( current_io_buffer->dct_mode == DCT_MODE_FDCT ) { for( i = 0; i < current_io_buffer->num_total_blocks; i++ ) { fdct(current_io_buffer->input[i], current_io_buffer->output[i]); } } else if( current_io_buffer->dct_mode == DCT_MODE_IDCT ) { for( i = 0; i < current_io_buffer->num_total_blocks; i++ ) { idct(current_io_buffer->input[i], current_io_buffer->output[i]); } } vp_os_mutex_lock(&critical_section); result_io_buffer = current_io_buffer; current_io_buffer = NULL; vp_os_mutex_unlock(&critical_section); } return 0; }
int main(){ double out[8][8]; double out2[8][8]; double out3[8][8]; double in[8][8]; double in2[8][8]; for(int y=0;y<N;y++) for(int x=0;x<N;x++){ mzero(in); in[y][x]=1; idct(in,out); for(int iy=0;iy<N;iy++) for(int ix=0;ix<N;ix++){ if(out[iy][ix]>=0) in2[iy][ix]=255; else in2[iy][ix]=0; } dct(in2,out2); if(x==0&&y==0) out3[y][x]=out2[0][0]; else out3[y][x]=mmax(out2); } // mmap(out3,(1.0/4)*); mmap(out3,round); mprint(out3); return true; }
int main() { int i; float src[N*N]; float ref_fdct[N*N], ref_idct[N*N]; float out_fdct[N*N], out_idct[N*N]; for (i = 0; i < N*N; i++) src[i] = random() % 256; init_dct(); fdct_ref(ref_fdct, src); fdct(out_fdct, src); if (check_output("FDCT", ref_fdct, out_fdct) < 0) return 1; idct_ref(ref_idct, ref_fdct); idct(out_idct, out_fdct); if (check_output("IDCT", ref_idct, out_idct) < 0) return 1; return 0; }
int blockIntra(bitstream *bs, mp4_private_t *priv, int block_num, int coded) { int i; int dct_dc_size, dct_dc_diff; event_t event; vop_header_t *h = &priv->vop_header; //clearblock(ld->block); // clearblock // dc coeff setDCscaler(priv, block_num); // calculate DC scaler if (block_num < 4) { dct_dc_size = getDCsizeLum(bs); if (dct_dc_size != 0) dct_dc_diff = getDCdiff(bs, dct_dc_size); else dct_dc_diff = 0; if (dct_dc_size > 8) get_bits(bs, 1); // marker bit } else { dct_dc_size = getDCsizeChr(bs); if (dct_dc_size != 0) dct_dc_diff = getDCdiff(bs, dct_dc_size); else dct_dc_diff = 0; if (dct_dc_size > 8) get_bits(bs, 1); // marker bit } //ld->block[0] = (short) dct_dc_diff; // dc reconstruction, prediction direction //dc_recon(block_num, &ld->block[0]); if (coded) { #if 0 unsigned int * zigzag; // zigzag scan dir if (h->ac_pred_flag == 1) { if (priv->coeff_pred.predict_dir == TOP) zigzag = priv->tables.alternate_horizontal_scan; else zigzag = priv->tables.alternate_vertical_scan; } else { zigzag = priv->tables.zig_zag_scan; } #endif i = 1; do // event vld { event = vld_intra_dct(bs, priv); /*** if (event.run == -1) { printf("Error: invalid vld code\n"); exit(201); } ***/ i+= event.run; //ld->block[zigzag[i]] = (short) event.level; // _Print("Vld Event: Run Level Last %d %d %d\n", event.run, event.level, event.last); i++; } while (! event.last); } #if 0 // ac reconstruction h->intrablock_rescaled = ac_rescaling(block_num, &ld->block[0]); if (! h->intrablock_rescaled) { ac_recon(block_num, &ld->block[0]); } ac_store(block_num, &ld->block[0]); if (h->quant_type == 0) { iquant(ld->block, 1); } else { iquant_typefirst(ld->block); } // inverse dct idct(ld->block); #endif return 1; }
int main(int argc, char *argv[]) { char *s, *infile = NULL, c; int i, j, k, n, iter, size2; double *x, *y, *pReal, *pImag; FILE *fp; Boolean comp = COMPLEX; if ((cmnd = strrchr(argv[0], '/')) == NULL) { cmnd = argv[0]; } else { cmnd++; } while (--argc) { if (*(s = *++argv) == '-') { c = *++s; if ((c == 'l') && (*++s == '\0')) { s = *++argv; --argc; } switch (c) { case 'l': /* IDCT size */ size = atoi(s); break; case 'c': /* use complex number */ comp = 1 - COMPLEX; break; case 'd': /* IDCT without FFT (DFT) */ dftmode = 1 - dftmode; break; case 'h': default: usage(); } } else { infile = s; } } if (infile) { fp = getfp(infile, "rb"); } else { fp = stdin; } /* memory allocation */ x = dgetmem(size2 = size + size); y = x + size; pReal = dgetmem(size2); pImag = pReal + size; while (!feof(fp)) { fillz(x, size2, sizeof(*x)); if (freadf(x, sizeof(*x), size, fp) == 0) { break; } if (comp) { if (freadf(y, sizeof(*y), size, fp) == 0) { break; } } /* decide wheather 'size' is a power of 2 or not */ for (iter = 0, i = size; (i /= 2) != 0; iter++); for (i = 1, j = 1; i <= iter; i++, j *= 2); /* IDCT-II (DCT-III) routine */ idct_create_table(size); idct(pReal, pImag, (const double *) x, (const double *) y, j); /* output IDCT sequence */ fwritef(pReal, sizeof(*pReal), size, stdout); if (comp) { fwritef(pImag, sizeof(*pImag), size, stdout); } } if (infile) { fclose(fp); } return (0); }
const char_t* TinfoDecVideo::TinfoValueDecVideo::getVal0(bool &wasChange, bool &splitline) { int percent; switch (item->type) { #ifdef OSDTIMETABALE case IDFF_OSDtype_timetable: tsprintf(s, _l("%3.2fms"), deciV->getOSDtime() / 10000.0); wasChange = true; return s; #endif case IDFF_OSDtype_TimeOnffdshow: percent = deciV->get_time_on_ffdshow_percent(); if (percent < 0 || percent > 300) { tsprintf(s, _l("%3dms (N/A )"), deciV->get_time_on_ffdshow()); } else { tsprintf(s, _l("%3dms (%3d%%)"), deciV->get_time_on_ffdshow(), percent); } wasChange = true; return s; case IDFF_OSDtype_inputSize: return getInputSize(s, wasChange); case IDFF_OSDtype_inputAspect: return getInputAspect(s, wasChange, countof(s)); case IDFF_OSDtype_inputSizeAspect: { bool wasChangeSize = false; getInputSize(sizeStr, wasChangeSize); bool wasChangeAspect = false; getInputAspect(aspectStr, wasChangeAspect, countof(aspectStr)); if (wasChange = (wasChangeSize || wasChangeAspect)) { tsnprintf_s(s, countof(s), _TRUNCATE, _l("%s, %s"), sizeStr, aspectStr); } return s; } case IDFF_OSDtype_meanQuant: { char_t news[60]; float q; if (deciV->calcMeanQuant(&q) == S_OK && q > 0) { tsprintf(news, _l("%-5.2f"), q); } else { ff_strncpy(news, _l("not available"), countof(news)); } if (strcmp(news, olds) != 0) { ff_strncpy(s, news, countof(s)); wasChange = true; } return s; } case IDFF_OSDtype_outputFOURCC: deciV->getOutputFourcc(s, 50); wasChange = strcmp(s, olds) != 0; return s; case IDFF_OSDtype_currentFrameTime: { int val; if (SUCCEEDED(deciV->getCurrentFrameTime((unsigned int*)&val))) { tsprintf(s, _l("%02i:%02i:%02i"), val / 3600, (val / 60) % 60, val % 60); wasChange = true; } else { strcpy(s, _l("failed")); wasChange = false; } return s; } case IDFF_OSDtype_remainingFrameTime: { int val; if (SUCCEEDED(deciV->getRemainingFrameTime((unsigned int*)&val))) { tsprintf(s, _l("%02i:%02i:%02i"), val / 3600, (val / 60) % 60, val % 60); wasChange = true; } else { strcpy(s, _l("failed")); wasChange = false; } return s; } case IDFF_OSDtype_accurDeblock: if (olds[0] == '\0') { tsprintf(s, deciV->quantsAvailable() == S_OK ? _l("yes") : _l("no")); wasChange = true; } return s; case IDFF_OSDtype_inputFPS: { unsigned int fps1000; if (deciV->getAVIfps(&fps1000) != S_OK) { s[0] = '\0'; } else { tsprintf(s, _l("%-7.3f"), float(fps1000 / 1000.0)); } wasChange = strcmp(s, olds) != 0; return s; } case IDFF_OSDtype_inputFOURCC: { fourcc2str(deciV->getMovieFOURCC(), s, countof(s)); wasChange = strcmp(s, olds) != 0; return s; } case IDFF_OSDtype_QueueCount: { int val = deciV->getQueuedCount(); wasChange = true; if (val >= 0) { tsprintf(s, _l("%2d"), val); } else { val = -1 * val; switch (val) { case IDD_QUEUEMSG_1: case IDD_QUEUEMSG_2: case IDD_QUEUEMSG_3: case IDD_QUEUEMSG_4: case IDD_QUEUEMSG_5: case IDD_QUEUEMSG_6: case IDD_QUEUEMSG_7: ff_strncpy(s, trans->translate(val), countof(s)); break; case IDD_QUEUEMSG_8: { int late = (int)((-1) * deciV->getLate() / 10000); tsnprintf_s(s, countof(s), _TRUNCATE, _l("%s %4dms"), trans->translate(val), late > 0 ? late : 0); } } } return s; } case IDFF_OSDtype_Late: { int late = (int)deciV->getLate() / 10000; tsprintf(s, _l("%7dms"), late > 0 ? late : 0); wasChange = true; return s; } case IDFF_OSDtype_idct: { const char *idct0 = deciV->get_current_idct(); if (idct0) { text<char_t> idct(idct0); ff_strncpy(s, (const char_t*)idct, countof(s)); } else { tsprintf(s, _l("unknown")); } return s; } case IDFF_OSDtype_AviSynth_Info: { const char *info0 = deciV->getAviSynthInfo(); if (info0) { text<char_t> info(info0); ff_strncpy(s, (const char_t*)info, countof(s)); } else { tsprintf(s, _l("unavailable")); } wasChange = true; return s; } default: return TinfoValueDec::getVal0(wasChange, splitline); } }
/*jpeg decode * args: * pic: pointer to picture data ( decoded image - yuyv format) * buf: pointer to input data ( compressed jpeg ) * with: picture width * height: picture height */ int jpeg_decode(uint8_t *pic, int stride, uint8_t *buf, int width, int height) { struct ctx ctx; struct jpeg_decdata *decdata; int i=0, j=0, m=0, tac=0, tdc=0; int intwidth=0, intheight=0; int mcusx=0, mcusy=0, mx=0, my=0; int ypitch=0 ,xpitch=0,x=0,y=0; int mb=0; int max[6]; ftopict convert; int err = 0; int isInitHuffman = 0; decdata = (struct jpeg_decdata*) calloc(1, sizeof(struct jpeg_decdata)); for(i=0;i<6;i++) max[i]=0; if (!decdata) { err = -1; goto error; } if (buf == NULL) { err = -1; goto error; } ctx.datap = buf; /*check SOI (0xFFD8)*/ if (getbyte(&ctx) != 0xff) { err = ERR_NO_SOI; goto error; } if (getbyte(&ctx) != M_SOI) { err = ERR_NO_SOI; goto error; } /*read tables - if exist, up to start frame marker (0xFFC0)*/ if (readtables(&ctx,M_SOF0, &isInitHuffman)) { err = ERR_BAD_TABLES; goto error; } getword(&ctx); /*header lenght*/ i = getbyte(&ctx); /*precision (8 bit)*/ if (i != 8) { err = ERR_NOT_8BIT; goto error; } intheight = getword(&ctx); /*height*/ intwidth = getword(&ctx); /*width */ if ((intheight & 7) || (intwidth & 7)) /*must be even*/ { err = ERR_BAD_WIDTH_OR_HEIGHT; goto error; } ctx.info.nc = getbyte(&ctx); /*number of components*/ if (ctx.info.nc > MAXCOMP) { err = ERR_TOO_MANY_COMPPS; goto error; } /*for each component*/ for (i = 0; i < ctx.info.nc; i++) { int h, v; ctx.comps[i].cid = getbyte(&ctx); /*component id*/ ctx.comps[i].hv = getbyte(&ctx); v = ctx.comps[i].hv & 15; /*vertical sampling */ h = ctx.comps[i].hv >> 4; /*horizontal sampling */ ctx.comps[i].tq = getbyte(&ctx); /*quantization table used*/ if (h > 3 || v > 3) { err = ERR_ILLEGAL_HV; goto error; } if (ctx.comps[i].tq > 3) { err = ERR_QUANT_TABLE_SELECTOR; goto error; } } /*read tables - if exist, up to start of scan marker (0xFFDA)*/ if (readtables(&ctx,M_SOS,&isInitHuffman)) { err = ERR_BAD_TABLES; goto error; } getword(&ctx); /* header lenght */ ctx.info.ns = getbyte(&ctx); /* number of scans */ if (!ctx.info.ns) { ALOGE("info ns %d/n",ctx.info.ns); err = ERR_NOT_YCBCR_221111; goto error; } /*for each scan*/ for (i = 0; i < ctx.info.ns; i++) { ctx.dscans[i].cid = getbyte(&ctx); /*component id*/ tdc = getbyte(&ctx); tac = tdc & 15; /*ac table*/ tdc >>= 4; /*dc table*/ if (tdc > 1 || tac > 1) { err = ERR_QUANT_TABLE_SELECTOR; goto error; } for (j = 0; j < ctx.info.nc; j++) if (ctx.comps[j].cid == ctx.dscans[i].cid) break; if (j == ctx.info.nc) { err = ERR_UNKNOWN_CID_IN_SCAN; goto error; } ctx.dscans[i].hv = ctx.comps[j].hv; ctx.dscans[i].tq = ctx.comps[j].tq; ctx.dscans[i].hudc.dhuff = dec_huffdc + tdc; ctx.dscans[i].huac.dhuff = dec_huffac + tac; } i = getbyte(&ctx); /*0 */ j = getbyte(&ctx); /*63*/ m = getbyte(&ctx); /*0 */ if (i != 0 || j != 63 || m != 0) { ALOGE("hmm FW error,not seq DCT ??\n"); } /*build huffman tables*/ if(!isInitHuffman) { if(huffman_init(&ctx) < 0) return -ERR_BAD_TABLES; } /* if (ctx->dscans[0].cid != 1 || ctx->dscans[1].cid != 2 || ctx->dscans[2].cid != 3) { err = ERR_NOT_YCBCR_221111; goto error; } if (ctx->dscans[1].hv != 0x11 || ctx->dscans[2].hv != 0x11) { err = ERR_NOT_YCBCR_221111; goto error; } */ /* if internal width and external are not the same or heigth too and pic not allocated realloc the good size and mark the change need 1 macroblock line more ?? */ if (intwidth > width || intheight > height) { return -ERR_BAD_WIDTH_OR_HEIGHT; #if 0 width = intwidth; height = intheight; // BytesperPixel 2 yuyv , 3 rgb24 *pic = (uint8_t*) realloc( *pic, intwidth * (intheight + 8) * 2); #endif } switch (ctx.dscans[0].hv) { case 0x22: // 411 mb=6; mcusx = width >> 4; mcusy = height >> 4; xpitch = 16 * 2; ypitch = 16 * stride; convert = yuv420pto422; //choose the right conversion function break; case 0x21: //422 mb=4; mcusx = width >> 4; mcusy = height >> 3; xpitch = 16 * 2; ypitch = 8 * stride; convert = yuv422pto422; //choose the right conversion function break; case 0x11: //444 mcusx = width >> 3; mcusy = height >> 3; xpitch = 8 * 2; ypitch = 8 * stride; if (ctx.info.ns==1) { mb = 1; convert = yuv400pto422; //choose the right conversion function } else { mb=3; convert = yuv444pto422; //choose the right conversion function } break; default: err = ERR_NOT_YCBCR_221111; goto error; break; } idctqtab(ctx.quant[ctx.dscans[0].tq], decdata->dquant[0]); idctqtab(ctx.quant[ctx.dscans[1].tq], decdata->dquant[1]); idctqtab(ctx.quant[ctx.dscans[2].tq], decdata->dquant[2]); setinput(&ctx.in, ctx.datap); dec_initscans(&ctx); ctx.dscans[0].next = 2; ctx.dscans[1].next = 1; ctx.dscans[2].next = 0; /* 4xx encoding */ for (my = 0,y=0; my < mcusy; my++,y+=ypitch) { for (mx = 0,x=0; mx < mcusx; mx++,x+=xpitch) { if (ctx.info.dri && !--ctx.info.nm) if (dec_checkmarker(&ctx)) { err = ERR_WRONG_MARKER; goto error; } switch (mb) { case 6: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]); idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]); idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]); idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 4: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]); idct(decdata->dcts + 128, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 192, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 3: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 128, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 1: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); break; } // switch enc411 convert(decdata->out,pic+y+x,stride); //convert to 422 } } m = dec_readmarker(&ctx.in); if (m != M_EOI) { err = ERR_NO_EOI; goto error; } free(decdata); return 0; error: free(decdata); return err; }
//----------------------------------------------------------------------------- // Name: displayFunc( ) // Desc: callback function invoked to draw the client area //----------------------------------------------------------------------------- void displayFunc( ) { static const int LP = 4; static long int count = 0; static char str[1024]; static unsigned int wf = 0; static SAMPLE buffer[LPC_BUFFER_SIZE], residue[LPC_BUFFER_SIZE], coefs[1024], coefs_dct[1024], noise[LPC_BUFFER_SIZE]; float pitch, power, fval; int i; // clear the color and depth buffers glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix( ); // rotate the sphere about y axis glRotatef( g_angle_y += g_inc, 0.0f, 1.0f, 0.0f ); // color waveform glColor3f( 0.4f, 0.4f, 1.0f ); // wait for data while( !g_ready ) #if !defined(__OS_WINDOWS__) usleep( 0 ); #else Sleep( 0 ); #endif // g_mutex.lock(); // get the window //memcpy( buffer, g_audio_buffer, g_buffer_size * sizeof(SAMPLE) ); //memset( g_another_buffer, 0, g_buffer_size * sizeof(SAMPLE) ); // g_mutex.unlock(); sf_readf_float( g_fin, buffer, LPC_BUFFER_SIZE ); memcpy( g_another_buffer, buffer, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); //apply_window( (float*)buffer, g_window, g_buffer_size ); lpc_analyze( g_lpc, buffer, g_buffer_size, coefs, 40, &power, &pitch, residue ); if( !g_ctf ) { lpc_synthesize( g_lpc, g_another_buffer, g_buffer_size, coefs, 40, power, 0 ); } else { // inverse window // dct dct( residue, LPC_BUFFER_SIZE ); lpc_analyze( g_lpc_freq, residue, g_buffer_size, coefs_dct, 10, &power, &pitch, NULL ); for( i = 0; i < LPC_BUFFER_SIZE; i++ ) { noise[i] = 2.0f * (float)rand() / RAND_MAX - 1.0f; noise[i] *= power * 32.0f; } // dct dct( noise, LPC_BUFFER_SIZE ); lpc_synthesize( g_lpc_freq, residue, g_buffer_size, coefs_dct, 10, power, pitch, noise ); // idct idct( residue, LPC_BUFFER_SIZE ); // window? //apply_window( (float *)residue, g_window, g_buffer_size ); lpc_synthesize( g_lpc, g_another_buffer, g_buffer_size, coefs, 40, power, pitch, residue ); memset(residue,0,LPC_BUFFER_SIZE*sizeof(SAMPLE)); } g_ready = FALSE; // apply the window GLfloat x = -1.8f, inc = 3.6f / g_buffer_size, y = 1.0f; // draw the time domain waveform glBegin( GL_LINE_STRIP ); GLint ii = ( g_buffer_size - (g_buffer_size/g_time_view) ) / 2; for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .75f * buffer[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 3.6f / g_buffer_size, y = .5f; glColor3f( 0.4f, 0.8f, 1.0f ); // draw the prediction glBegin( GL_LINE_STRIP ); for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * .75f * (buffer[i]-residue[i]) + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 3.6f / g_buffer_size, y = .0f; // draw the residue glColor3f( 0.8f, 0.8f, 0.4f ); glBegin( GL_LINE_STRIP ); for( i = ii; i < ii + g_buffer_size / g_time_view; i++ ) { glVertex3f( x, g_gain * g_time_scale * 5.0f * residue[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // apply the window x = -1.8f, inc = 0.3f/g_order, y = -0.5f; // draw the coefficients if( pitch == 0 ) glColor3f( 1.0f, .4f, .4f ); else glColor3f( 1.0f, 1.2f - pitch/g_buffer_size*4.0f, .4f ); glBegin( GL_LINE_STRIP ); for( i = 0; i < g_order; i++ ) { glVertex3f( x, coefs[i] + y, 0.0f ); x += inc * g_time_view; } glEnd(); // fft memcpy( residue, g_another_buffer, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); rfft( (float *)residue, g_buffer_size/2, FFT_FORWARD ); memcpy( buffer, residue, LPC_BUFFER_SIZE * sizeof(SAMPLE) ); x = -1.8f; y = -1.2f; inc = 3.6f / g_buffer_size; complex * cbuf = (complex *)buffer; // color the spectrum glColor3f( 0.4f, 1.0f, 0.4f ); // draw the frequency domain representation glBegin( GL_LINE_STRIP ); for( i = 0; i < g_buffer_size/g_freq_view; i++ ) { g_spectrums[wf][i].x = x; if( !g_usedb ) g_spectrums[wf][i].y = g_gain * g_freq_scale * .7f * ::pow( 25 * cmp_abs( cbuf[i] ), .5 ) + y; else g_spectrums[wf][i].y = g_gain * g_freq_scale * .8f * ( 20.0f * log10( cmp_abs(cbuf[i])/8.0 ) + 80.0f ) / 80.0f + y + .73f; x += inc * g_freq_view; } glEnd(); g_draw[wf] = true; for( i = 0; i < g_depth; i++ ) { if( g_draw[(wf+i)%g_depth] ) { Pt2D * pt = g_spectrums[(wf+i)%g_depth]; fval = (g_depth-i)/(float)g_depth; glColor3f( .4f * fval, 1.0f * fval, .4f * fval ); x = -1.8f; glBegin( GL_LINE_STRIP ); for( int j = 0; j < g_buffer_size/g_freq_view; j++, pt++ ) glVertex3f( x + j*(inc*g_freq_view), pt->y, -i * g_space + g_z ); glEnd(); } } if( !g_wutrfall ) g_draw[wf] = false; wf--; wf %= g_depth; /* for( int i = 0; i < 9; i++ ) fprintf( stderr, "%.4f ", coefs[i] ); fprintf( stderr, "power: %.8f pitch: %.4f\n", power, pitch ); for( int i = 0; i < 9; i++ ) fprintf( stderr, "%.4f ", lpc(i) ); fprintf( stderr, "power: %.8f pitch: %.4f\n", lpc(10), lpc(9) ); fprintf( stderr, "\n" ); */ draw_string( 0.4f, 0.8f, 0.0f, "original", .5f ); draw_string( 0.4f, 0.3f, 0.0f, "predicted", .5f ); draw_string( 0.4f, -.2f, 0.0f, "residue (error)", .5f ); draw_string( -1.8f, -.7f, 0.0f, "coefficients", .5f ); sprintf( str, "pitch factor: %.4f", g_speed ); glColor3f( 0.8f, .4f, .4f ); draw_string( 1.2f, -.25f, 0.0f, str, .35f ); sprintf( str, "LPC order: %i", g_order ); draw_string( 1.2f, -.35f, 0.0f, str, .35f ); SAMPLE sum = 0.0f; for( i = 0; i < g_buffer_size; i++ ) sum += fabs(buffer[i]); glPushMatrix(); if( pitch == 0 ) { glColor3f( 1.0f, .4f, .4f ); glTranslatef( 1.28f, -.45f, 0.0f ); } else { glColor3f( 1.0f, 1.2f - pitch/g_buffer_size*4.0f, .4f ); glTranslatef( 1.55f, -.45f, 0.0f ); } glutSolidSphere( .001f + sum/g_buffer_size * 120.0f, 10, 10 ); glPopMatrix(); draw_string( 1.2f, -.55f, 0.0f, "non-pitch | pitched", .35f ); draw_string( 1.2f, -.65f, 0.0f, g_ctf ? "both" : "time-only", .35f ); glPopMatrix( ); // swap the buffers glFlush( ); glutSwapBuffers( ); g_buffer_count_b++; }
uint16_t* uvlc_read_mb_layer_unquantize( video_controller_t* controller, video_macroblock_t* mb, uint16_t* out ) { int16_t* data; uint32_t code; video_zeromem32( (uint32_t*)mb->data, 6 * MCU_BLOCK_SIZE / 2 ); mb->azq = 0; video_read_data( &controller->in_stream, (uint32_t*)&mb->azq, 1 ); if( mb->azq == 0 ) { video_read_data( &controller->in_stream, &code, 8 ); mb->num_coeff_y0 = (code >> 0) & 1; mb->num_coeff_y1 = (code >> 1) & 1; mb->num_coeff_y2 = (code >> 2) & 1; mb->num_coeff_y3 = (code >> 3) & 1; mb->num_coeff_cb = (code >> 4) & 1; mb->num_coeff_cr = (code >> 5) & 1; mb->dquant = 0; if( (code >> 6) & 1 ) { video_read_data( &controller->in_stream, &code, 2 ); mb->dquant = (code < 2) ? ~code : code; } controller->quant += mb->dquant; /**************** Block Y0 ****************/ data = mb->data; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y0 ); idct(data, out); out += MCU_BLOCK_SIZE; /**************** Block Y1 ****************/ data += MCU_BLOCK_SIZE; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y1 ); idct(data, out); out += MCU_BLOCK_SIZE; /**************** Block Y2 ****************/ data += MCU_BLOCK_SIZE; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y2 ); idct(data, out); out += MCU_BLOCK_SIZE; /**************** Block Y3 ****************/ data += MCU_BLOCK_SIZE; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y3 ); idct(data, out); out += MCU_BLOCK_SIZE; /**************** Block CB ****************/ data += MCU_BLOCK_SIZE; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_cb ); idct(data, out); out += MCU_BLOCK_SIZE; /**************** Block CR ****************/ data += MCU_BLOCK_SIZE; uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_cr ); idct(data, out); out += MCU_BLOCK_SIZE; }
/* recv_packet processes a received audio packet. The packet has sequence number seqno, and consists of len bytes of data. In this case, it's just PCM, encoded in 16-bit linear format. The "strategy" parameter determines which of several possible loss concealment techniques to apply */ void recv_packet(int seqno, int len, char *data, FILE *ofile, int strategy) { static int prev_seqno = -1; static int16_t* prev_packet_samples = 0; int16_t *samples = (int16_t*)data; /* we receive a bunch of bytes from the (simulated) net, but we know they're really 16 bit sample values. In real life we'd convert them from network byte order to host byte order, but no need to do that here */ int num_samples = len/2; /* two bytes to a 16 bit integer */ printf("recv_packet: seqno=%d\n", seqno); if (prev_seqno != -1 && (prev_seqno+1 != seqno)) { /* there was missing data - we need to replace it */ int missing_seqno; switch(strategy) { case SILENCE: { /* create as many packet containing silence as we need to fill the gap */ missing_seqno = prev_seqno + 1; while (missing_seqno < seqno) { write_silence(ofile, num_samples); missing_seqno++; } break; } case REPEAT_PREV: { /* repeat the previous packet once to fill the gap. If the gap is longer than one packet, fill the remainder with silence */ fwrite(prev_packet_samples, 2, num_samples, ofile); missing_seqno = prev_seqno + 2; while (missing_seqno < seqno) { write_silence(ofile, num_samples); missing_seqno++; } break; } case REPEAT_NEXT: { /* play the next packet (twice) to fill the gap. If the gap is longer than one packet, first insert silence, then insert the next packet */ missing_seqno = prev_seqno + 1; while (missing_seqno < seqno) { if (missing_seqno == seqno-1) { /* only repeat back once */ /* write the current packet instead of the missing one */ fwrite(data, 2, num_samples, ofile); } else { write_silence(ofile, num_samples); } missing_seqno++; } break; } case REPEAT_BOTH: { /* we'll fill the gap with data from both before and after the gap. If the gap is one packet long, repeat the last half of the previous packet and the first half of the next packet. If the gap is two packets long, repeat the whole previous packet, then the whole next packet. If the gap is three of more packets long, fill the remainder with silence. */ missing_seqno = prev_seqno + 1; if (missing_seqno == seqno-1) { /* the gap is only one packet long */ /* fill with last half of prev packet, first half of current packet */ /* uncomment the next line to enable smoothing*/ #define SMOOTH #ifdef SMOOTH int16_t prev = ((prev_packet_samples[num_samples-1] * 0.66) + (samples[0] * 0.33)); int16_t prev2 = ((prev_packet_samples[num_samples-2] * 0.5) + (prev * 0.5)); int16_t next = ((prev_packet_samples[num_samples-1] * 0.33) + (samples[0] * 0.66)); int16_t next2 = ((next * 0.5) + (samples[1] * 0.5)); fwrite(prev_packet_samples+num_samples/2, 2, (num_samples/2) - 2, ofile); fwrite(&prev2, 2, 1, ofile); fwrite(&prev, 2, 1, ofile); fwrite(&next, 2, 1, ofile); fwrite(&next2, 2, 1, ofile); fwrite(samples + 2, 2, (num_samples/2) - 2, ofile); #else fwrite(prev_packet_samples+num_samples/2, 2, num_samples/2, ofile); fwrite(samples, 2, num_samples/2, ofile); #endif } else { /* the gap is two or more packets long */ /* first write the prev packet a second time */ fwrite(prev_packet_samples, 2, num_samples, ofile); missing_seqno++; while (missing_seqno < seqno) { if (missing_seqno == seqno-1) { /* write the current packet instead of the missing one */ fwrite(samples, 2, num_samples, ofile); } else { write_silence(ofile, num_samples); } missing_seqno++; } } break; } case INTERPOLATE: { /* We're going to interpolate a whole new packet (or several packets) in the frequency domain. */ if (seqno < (prev_seqno + 5)) { int *prev_coeff = dct(prev_packet_samples, num_samples); int *next_coeff = dct(samples, num_samples); missing_seqno = prev_seqno + 1; while (missing_seqno < seqno) { double next_weight = (double)(missing_seqno - prev_seqno)/(seqno - prev_seqno); double prev_weight = (double)(seqno - missing_seqno)/(seqno - prev_seqno); int new_coeff[num_samples]; int i; for (i = 0; i < num_samples; i++) { new_coeff[i] = (prev_weight * prev_coeff[i]) + (next_weight * next_coeff[i]); } fwrite(idct(new_coeff, num_samples), 2, num_samples, ofile); missing_seqno++; } } else { missing_seqno = prev_seqno + 1; while (missing_seqno < seqno) { write_silence(ofile, num_samples); missing_seqno++; } } break; } } } /* finally, don't forget to write out the packet that arrived after the gap */ fwrite(samples, 2, num_samples, ofile); /* hold onto the last received packet - we may need it */ if (prev_packet_samples != 0) free(prev_packet_samples); prev_packet_samples = samples; prev_seqno = seqno; };