void copyfield(uint8_t *m[3],uint8_t *n[3],y4m_stream_info_t *sinfo, int which) { int r = 0; int h,w,cw,ch; h = y4m_si_get_plane_height(sinfo,0); w = y4m_si_get_plane_width(sinfo,0); cw = y4m_si_get_plane_width(sinfo,1); ch = y4m_si_get_plane_height(sinfo,1); if (which==Y4M_ILACE_TOP_FIRST) { r=0; } else if (which==Y4M_ILACE_BOTTOM_FIRST) { r=1; } else { mjpeg_warn("copyfield() invalid interlace selected (%d)",which); } for (; r < h; r += 2) { memcpy(&m[0][r * w], &n[0][r * w], w); if (r<ch) { memcpy(&m[1][r*cw], &n[1][r*cw], cw); memcpy(&m[2][r*cw], &n[2][r*cw], cw); } } }
// Allocate a uint8_t frame int chromalloc(uint8_t *m[3], y4m_stream_info_t *sinfo) { int fs,cfs; fs = y4m_si_get_plane_length(sinfo,0); cfs = y4m_si_get_plane_length(sinfo,1); // I'm gonna cheat and use this as an initialisation function. sic.h = y4m_si_get_plane_height(sinfo,0); sic.w = y4m_si_get_plane_width(sinfo,0); sic.ch = y4m_si_get_plane_height(sinfo,1); sic.cw = y4m_si_get_plane_width(sinfo,1); m[0] = (uint8_t *)malloc( fs ); m[1] = (uint8_t *)malloc( cfs); m[2] = (uint8_t *)malloc( cfs); if( !m[0] || !m[1] || !m[2]) { return -1; } else { return 0; } }
int xchroma (int x, y4m_stream_info_t *si) { int cwr; cwr = y4m_si_get_plane_width(si,0) / y4m_si_get_plane_width(si,1); if ( cwr == 1 ) { return x; } else if ( cwr == 2) { return x >> 1; } else if (cwr == 4) {
int search_video (int m, int s, int line, uint8_t *yuv_data[3],y4m_stream_info_t *sinfo) { int w,x1,diff; int max,c=0,linew; w = y4m_si_get_plane_width(sinfo,0); linew= w * line; for (x1=0; x1<m; x1++) { if (yuv_data[0][linew+x1] >=16) return x1; // if (yuv_data[0][linew+x1]>= 32) return x1; } /* for (x1=1;x1<m;x1++) { // it appears that sync is outside of the mpeg video range. if (abs(yuv_data[0][linew+x1] - yuv_data[0][linew+x1+1] ) > 6) { return x1-1; } } */ // fprintf(stderr," %d",diff); // fprintf (stderr,"\n"); return 0; }
int y4m_si_get_plane_length(const y4m_stream_info_t *si, int plane) { int w = y4m_si_get_plane_width(si, plane); int h = y4m_si_get_plane_height(si, plane); if ((w != Y4M_UNKNOWN) && (h != Y4M_UNKNOWN)) return (w * h); else return Y4M_UNKNOWN; }
// this method isn't too effective int search_video_1 (int m, int s, int line, uint8_t *yuv_data[3],y4m_stream_info_t *sinfo) { int w,h; int x1,x2; int min,shift,tot; int linew, line1w; int ilace = y4m_si_get_interlace(sinfo); w = y4m_si_get_plane_width(sinfo,0); h = y4m_si_get_plane_height(sinfo,0); linew = line * w; if (ilace == Y4M_ILACE_NONE) line1w = (line+1) * w ; else line1w = (line+2) * w; line1w = (line+2) * w; mjpeg_debug("search_video %d",line); // 2 or 1 dependent on interlace or not. if (line+2 > h) { mjpeg_warn("line > height"); return 0; } shift = 0; for (x1=-m; x1<m; x1++) { tot = 0; for(x2=0; x2<s; x2++) { // don't know if I should apply a standard addition to pixels outside the box. if (x1+x2 >=0 && x1+x2 < w) tot += abs ( *(yuv_data[0]+x1+x2+linew) - *(yuv_data[0]+x2+line1w)); else tot += 128; } // ok it wasn't max afterall, it was min. if (x1==0) min = tot; if (tot < min) { min = tot; shift = x1; } } mjpeg_debug("exit search_video %d",line); return shift; }
void set_pixel(uint8_t val,int x, int y, int plane, uint8_t *m[3],y4m_stream_info_t *si) { int w,h; h = y4m_si_get_plane_height(si,plane); w = y4m_si_get_plane_width(si,plane); if (x >= 0 && x < w && y >= 0 && y < h) { *(m[plane]+x+y*w) = val; } }
void chromacpy (uint8_t *dst[3], AVFrame *src, y4m_stream_info_t *sinfo) { int y,h,w; int cw,ch; w = y4m_si_get_plane_width(sinfo,0); h = y4m_si_get_plane_height(sinfo,0); cw = y4m_si_get_plane_width(sinfo,1); ch = y4m_si_get_plane_height(sinfo,1); for (y=0; y<h; y++) { memcpy(dst[0]+y*w,(src->data[0])+y*src->linesize[0],w); if (y<ch) { memcpy(dst[1]+y*cw,(src->data[1])+y*src->linesize[1],cw); memcpy(dst[2]+y*cw,(src->data[2])+y*src->linesize[2],cw); } } }
int y4m_read_frame_data_cb(y4m_cb_reader_t * fd, const y4m_stream_info_t *si, y4m_frame_info_t *fi, uint8_t * const *frame) { int planes = y4m_si_get_plane_count(si); int p; /* Read each plane */ for (p = 0; p < planes; p++) { int w = y4m_si_get_plane_width(si, p); int h = y4m_si_get_plane_height(si, p); if (y4m_read_cb(fd, frame[p], w*h)) return Y4M_ERR_SYSTEM; } return Y4M_OK; }
int y4m_write_fields_cb(y4m_cb_writer_t * fd, const y4m_stream_info_t *si, const y4m_frame_info_t *fi, uint8_t * const *upper_field, uint8_t * const *lower_field) { int p, err; int planes = y4m_si_get_plane_count(si); int numwbuf=0; const int maxwbuf=32*1024; uint8_t *wbuf; /* Write frame header */ if ((err = y4m_write_frame_header_cb(fd, si, fi)) != Y4M_OK) return err; /* Write each plane */ wbuf=_y4m_alloc(maxwbuf); for (p = 0; p < planes; p++) { uint8_t *srctop = upper_field[p]; uint8_t *srcbot = lower_field[p]; int height = y4m_si_get_plane_height(si, p); int width = y4m_si_get_plane_width(si, p); int y; /* alternately write one line from each field */ for (y = 0; y < height; y += 2) { if( width*2 >= maxwbuf ) { if (y4m_write_cb(fd, srctop, width)) goto y4merr; if (y4m_write_cb(fd, srcbot, width)) goto y4merr; } else { if (numwbuf + 2 * width > maxwbuf) { if(y4m_write_cb(fd, wbuf, numwbuf)) goto y4merr; numwbuf=0; } veejay_memcpy(wbuf+numwbuf,srctop,width); numwbuf += width; veejay_memcpy(wbuf+numwbuf,srcbot,width); numwbuf += width; } srctop += width; srcbot += width; } } if( numwbuf ) if( y4m_write_cb(fd, wbuf, numwbuf) ) goto y4merr; _y4m_free(wbuf); return Y4M_OK; y4merr: _y4m_free(wbuf); return Y4M_ERR_SYSTEM; }
int y4m_write_frame_cb(y4m_cb_writer_t * fd, const y4m_stream_info_t *si, const y4m_frame_info_t *fi, uint8_t * const *frame) { int planes = y4m_si_get_plane_count(si); int err, p; /* Write frame header */ if ((err = y4m_write_frame_header_cb(fd, si, fi)) != Y4M_OK) return err; /* Write each plane */ for (p = 0; p < planes; p++) { int w = y4m_si_get_plane_width(si, p); int h = y4m_si_get_plane_height(si, p); if (y4m_write_cb(fd, frame[p], w*h)) return Y4M_ERR_SYSTEM; } return Y4M_OK; }
int y4m_read_fields_data_cb(y4m_cb_reader_t * fd, const y4m_stream_info_t *si, y4m_frame_info_t *fi, uint8_t * const *upper_field, uint8_t * const *lower_field) { int p; int planes = y4m_si_get_plane_count(si); const int maxrbuf=32*1024; uint8_t *rbuf=_y4m_alloc(maxrbuf); int rbufpos=0,rbuflen=0; /* Read each plane */ for (p = 0; p < planes; p++) { uint8_t *dsttop = upper_field[p]; uint8_t *dstbot = lower_field[p]; int height = y4m_si_get_plane_height(si, p); int width = y4m_si_get_plane_width(si, p); int y; /* alternately read one line into each field */ for (y = 0; y < height; y += 2) { if( width*2 >= maxrbuf ) { if (y4m_read_cb(fd, dsttop, width)) goto y4merr; if (y4m_read_cb(fd, dstbot, width)) goto y4merr; } else { if( rbufpos==rbuflen ) { rbuflen=(height-y)*width; if( rbuflen>maxrbuf ) rbuflen=maxrbuf-maxrbuf%(2*width); if( y4m_read_cb(fd,rbuf,rbuflen) ) goto y4merr; rbufpos=0; } veejay_memcpy(dsttop,rbuf+rbufpos,width); rbufpos+=width; veejay_memcpy(dstbot,rbuf+rbufpos,width); rbufpos+=width; } dsttop+=width; dstbot+=width; } } _y4m_free(rbuf); return Y4M_OK; y4merr: _y4m_free(rbuf); return Y4M_ERR_SYSTEM; }
int y4m_js_decode_frame(y4m_cb_reader_t *r, y4m_stream_info_t *si, y4m_frame_info_t *fi, uint8_t *rgba) { int i, j; uint8_t *ycbcr[3]; int32_t plane_length[3]; int32_t width; int32_t height; int32_t ret_value; if(NULL == r || NULL == si || NULL == fi || NULL == rgba) { return Y4M_UNKNOWN; } if(3 != y4m_si_get_plane_count(si)) { return Y4M_UNKNOWN; } width = y4m_si_get_plane_width(si, 0); height = y4m_si_get_plane_height(si, 0); for(i = 0; i < 3; ++i) { plane_length[i] = y4m_si_get_plane_length(si, i); if(NULL == (ycbcr[i] = malloc(width * height))) { return Y4M_UNKNOWN; } } ret_value = y4m_read_frame_cb(r, si, fi, ycbcr); if(Y4M_OK != ret_value) { return ret_value; } chroma_supersample(Y4M_CHROMA_420JPEG, ycbcr, width, height); convert_YCbCr_to_RGB(ycbcr, width * height); for(i = 0; i < width * height; ++i) { for(j = 0; j < 3; ++j) { rgba[i * 4 + j] = ycbcr[j][i]; } } return Y4M_OK; }
static void convolve( int fdIn , y4m_stream_info_t *inStrInfo, int fdOut, y4m_stream_info_t *outStrInfo, int *mat, int div, int mlen) { y4m_frame_info_t in_frame ; uint8_t *yuv_data[3],*yuv_odata[3]; int read_error_code ; int write_error_code ; int src_frame_counter ; float vy,vu,vv; int x,y,w,h,cw,ch,mx,my,count; w = y4m_si_get_plane_width(inStrInfo,0); h = y4m_si_get_plane_height(inStrInfo,0); cw = y4m_si_get_plane_width(inStrInfo,1); ch = y4m_si_get_plane_height(inStrInfo,1); if (chromalloc(yuv_data, inStrInfo)) mjpeg_error_exit1 ("Could'nt allocate memory for the YUV4MPEG data!"); if (chromalloc(yuv_odata, inStrInfo)) mjpeg_error_exit1 ("Could'nt allocate memory for the YUV4MPEG data!"); write_error_code = Y4M_OK ; src_frame_counter = 0 ; // initialise and read the first number of frames y4m_init_frame_info( &in_frame ); read_error_code = y4m_read_frame(fdIn,inStrInfo,&in_frame,yuv_data ); while( Y4M_ERR_EOF != read_error_code && write_error_code == Y4M_OK ) { for (x=0; x<w; x++) { for (y=0; y<h; y++) { // perform magic vy = 0; count = 0; // need to be handled differently for interlace for (my=-mlen/2;my <=mlen/2; my++) { for (mx=-mlen/2;mx <=mlen/2; mx++) { // fprintf (stderr," x %d - y %d\n",mx,my); if ((x + mx >=0) && (x + mx <w) && (y + my >=0) && (y + my <h) ) { // fprintf (stderr,"matrix: %d => %d\n", count,mat[count]); vy += *(yuv_data[0]+x+mx+(y+my)*w) * mat[count]; } count++; } } vy /= div; if (vy < 16) vy = 16; if (vy > 240) vy= 240; *(yuv_odata[0]+x+y*w) = vy; if ((x < cw) && (y<ch)) { vu = 0; vv = 0; count = 0; // may need to be handled differently for interlace for (my=-mlen/2;my <=mlen/2; my++) { for (mx=-mlen/2;mx <=mlen/2; mx++) { if ((x + mx >=0) && (x + mx <cw) && (y + my >=0) && (y + my <ch) ) { vu += (*(yuv_data[1]+x+mx+(y+my)*cw) -128) * mat[count]; vv += (*(yuv_data[2]+x+mx+(y+my)*cw) -128) * mat[count]; } count ++; } } vu /= div; vv /= div; if (vu < -112) vu = -112; if (vu > 112) vu = 112; if (vv < -112) vv = -112; if (vv > 112) vv = 112; *(yuv_odata[1]+x+y*cw) = vu + 128; *(yuv_odata[2]+x+y*cw) = vv + 128; } } } write_error_code = y4m_write_frame( fdOut, outStrInfo, &in_frame, yuv_odata ); y4m_fini_frame_info( &in_frame ); y4m_init_frame_info( &in_frame ); read_error_code = y4m_read_frame(fdIn,inStrInfo,&in_frame,yuv_data ); ++src_frame_counter ; } // Clean-up regardless an error happened or not y4m_fini_frame_info( &in_frame ); free( yuv_data[0] ); free( yuv_data[1] ); free( yuv_data[2] ); free( yuv_odata[0] ); free( yuv_odata[1] ); free( yuv_odata[2] ); if( read_error_code != Y4M_ERR_EOF ) mjpeg_error_exit1 ("Error reading from input stream!"); if( write_error_code != Y4M_OK ) mjpeg_error_exit1 ("Error writing output stream!"); }
void shift_video (int s, int line, uint8_t *yuv_data[3],y4m_stream_info_t *sinfo) { int x,w,cw,cs; int vss; int linew,linecw; // mjpeg_debug("shift_video %d %d",s,line); w = y4m_si_get_plane_width(sinfo,0); cw = y4m_si_get_plane_width(sinfo,1); vss = y4m_si_get_plane_height(sinfo,0) / y4m_si_get_plane_height(sinfo,1); cs = s * cw / w; linew = line * w; linecw = line * cw; // could memcpy() do this? if (s>0) { for (x=w-1; x>=0; x--) if (x>=s) *(yuv_data[0]+x+(linew))= *(yuv_data[0]+(x-s)+(linew)); else *(yuv_data[0]+x+(linew))= 16; // one day I should start catering for more or less than 3 planes. // have to take proper interlace chroma into account. // would be easier to work with 422 or 444 if (line % vss) { for (x=cw; x>=0; x--) { if (x>=cs) { *(yuv_data[1]+x+linecw)= *(yuv_data[1]+(x-cs)+linecw); *(yuv_data[2]+x+linecw)= *(yuv_data[2]+(x-cs)+linecw); } else { *(yuv_data[1]+x+linecw)= 128; *(yuv_data[2]+x+linecw)= 128; } } } } if (s<0) { for (x=0; x<=w; x++) if (x-s < w) *(yuv_data[0]+x+(linew))= *(yuv_data[0]+(x-s)+(linew)); else *(yuv_data[0]+x+linew)=16; // one day I should start catering for more or less than 3 planes. if (line % vss) { for (x=0; x<=cw; x++) { if (x-cs<=cw) { *(yuv_data[1]+x+(linecw))= *(yuv_data[1]+(x-cs)+(linecw)); *(yuv_data[2]+x+(linecw))= *(yuv_data[2]+(x-cs)+(linecw)); } else { *(yuv_data[1]+x+(linecw))= 128; *(yuv_data[2]+x+(linecw))= 128; } } } } // mjpeg_debug("exit shift_video %d %d",s,line); }
int main(int argc, char **argv) { int i, c, interlace, frames, err; int ywidth, yheight, uvwidth, uvheight, ylen, uvlen; int verbose = 0, fdin; int NlumaX = 4, NlumaY = 4, NchromaX = 4, NchromaY = 4; float BWlumaX = 0.8, BWlumaY = 0.8, BWchromaX = 0.7, BWchromaY = 0.7; struct filter *lumaXtaps, *lumaYtaps, *chromaXtaps, *chromaYtaps; u_char *yuvinout[3]; float *yuvtmp1,*yuvtmp2; y4m_stream_info_t istream, ostream; y4m_frame_info_t iframe; fdin = fileno(stdin); y4m_accept_extensions(1); /* read command line */ opterr = 0; while ((c = getopt(argc, argv, "hvL:C:x:X:y:Y:")) != EOF) { switch (c) { case 'L': sscanf(optarg,"%d,%f,%d,%f",&NlumaX,&BWlumaX,&NlumaY,&BWlumaY); break; case 'C': sscanf(optarg,"%d,%f,%d,%f",&NchromaX,&BWchromaX,&NchromaY,&BWchromaY); break; case 'x': sscanf(optarg,"%d,%f",&NchromaX,&BWchromaX); break; case 'X': sscanf(optarg,"%d,%f",&NlumaX,&BWlumaX); break; case 'y': sscanf(optarg,"%d,%f",&NchromaY,&BWchromaY); break; case 'Y': sscanf(optarg,"%d,%f",&NlumaY,&BWlumaY); break; case 'v': verbose++; break; case '?': case 'h': default: usage(); } } if (BWlumaX <= 0.0 || BWlumaX > 1.0) mjpeg_error_exit1("Horizontal luma bandwidth '%f' not >0 and <=1.0", BWlumaX); if (BWlumaY <= 0.0 || BWlumaY > 1.0) mjpeg_error_exit1("Vertical luma bandwidth '%f' not >0 and <=1.0", BWlumaY); if (BWchromaX <= 0.0 || BWchromaX > 1.0) mjpeg_error_exit1("Horizontal chroma bandwidth '%f' not >0 and <=1.0", BWchromaX); if (BWchromaY <= 0.0 || BWchromaY > 1.0) mjpeg_error_exit1("Vertical chroma bandwidth '%f' not >0 and <=1.0", BWchromaY); /* initialize input stream and check chroma subsampling and interlacing */ y4m_init_stream_info(&istream); y4m_init_frame_info(&iframe); err = y4m_read_stream_header(fdin, &istream); if (err != Y4M_OK) mjpeg_error_exit1("Input stream error: %s\n", y4m_strerr(err)); if (y4m_si_get_plane_count(&istream) != 3) mjpeg_error_exit1("Only the 3 plane formats supported"); i = y4m_si_get_interlace(&istream); switch (i) { case Y4M_ILACE_NONE: interlace = 0; break; case Y4M_ILACE_BOTTOM_FIRST: case Y4M_ILACE_TOP_FIRST: interlace = 1; break; default: mjpeg_warn("Unknown interlacing '%d', assuming non-interlaced", i); interlace = 0; break; } ywidth = y4m_si_get_width(&istream); /* plane 0 = Y */ yheight = y4m_si_get_height(&istream); ylen = ywidth * yheight; uvwidth = y4m_si_get_plane_width(&istream, 1); /* planes 1&2 = U+V */ uvheight = y4m_si_get_plane_height(&istream, 1); uvlen = y4m_si_get_plane_length(&istream, 1); /* initialize output stream */ y4m_init_stream_info(&ostream); y4m_copy_stream_info(&ostream, &istream); y4m_write_stream_header(fileno(stdout), &ostream); /* allocate input and output buffers */ yuvinout[0] = my_malloc(ylen*sizeof(u_char)); yuvinout[1] = my_malloc(uvlen*sizeof(u_char)); yuvinout[2] = my_malloc(uvlen*sizeof(u_char)); yuvtmp1 = my_malloc(MAX(ylen,uvlen)*sizeof(float)); yuvtmp2 = my_malloc(MAX(ylen,uvlen)*sizeof(float)); /* get filter taps */ lumaXtaps = get_coeff(NlumaX, BWlumaX); lumaYtaps = get_coeff(NlumaY, BWlumaY); chromaXtaps = get_coeff(NchromaX, BWchromaX); chromaYtaps = get_coeff(NchromaY, BWchromaY); set_accel(uvwidth,uvheight); if (verbose) y4m_log_stream_info(mjpeg_loglev_t("info"), "", &istream); /* main processing loop */ for (frames=0; y4m_read_frame(fdin,&istream,&iframe,yuvinout) == Y4M_OK; frames++) { if (verbose && ((frames % 100) == 0)) mjpeg_info("Frame %d\n", frames); convolveFrame(yuvinout[0],ywidth,yheight,interlace,lumaXtaps,lumaYtaps,yuvtmp1,yuvtmp2); convolveFrame(yuvinout[1],uvwidth,uvheight,interlace,chromaXtaps,chromaYtaps,yuvtmp1,yuvtmp2); convolveFrame(yuvinout[2],uvwidth,uvheight,interlace,chromaXtaps,chromaYtaps,yuvtmp1,yuvtmp2); y4m_write_frame(fileno(stdout), &ostream, &iframe, yuvinout); } /* clean up */ y4m_fini_frame_info(&iframe); y4m_fini_stream_info(&istream); y4m_fini_stream_info(&ostream); exit(0); }
/** * put_jpeg_yuv420p_file * Converts an YUV420P coded image to a jpeg image and writes * it to an already open file. * * Inputs: * - image is the image in YUV420P format. * - width and height are the dimensions of the image * - quality is the jpeg encoding quality 0-100% * * Output: * - The jpeg is written directly to the file given by the file pointer fp * * Returns nothing */ static void put_jpeg_yuv420p_file(FILE *fp, uint8_t *image[3], y4m_stream_info_t *si, int quality) { int i, j; JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane) JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5 struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; y4m_ratio_t pixelaspect; int w,h,cw,ch; data[0] = y; data[1] = cb; data[2] = cr; // fprintf (stderr,"TRACE: put_jpeg_yuv420p_file in\n"); cinfo.err = jpeg_std_error(&jerr); // Errors get written to stderr ch = y4m_si_get_plane_height(si,0) / y4m_si_get_plane_height(si,1); cw = y4m_si_get_plane_width(si,0) / y4m_si_get_plane_width(si,1); h = y4m_si_get_plane_height(si,0); w = y4m_si_get_plane_width(si,0); jpeg_create_compress(&cinfo); cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; jpeg_set_defaults(&cinfo); jpeg_set_colorspace(&cinfo, JCS_YCbCr); cinfo.raw_data_in = TRUE; // Supply downsampled data #if JPEG_LIB_VERSION >= 70 #warning using JPEG_LIB_VERSION >= 70 cinfo.do_fancy_downsampling = FALSE; // Fix segfault with v7 #endif pixelaspect = y4m_si_get_sampleaspect(si); cinfo.X_density = pixelaspect.n; cinfo.Y_density = pixelaspect.d; cinfo.comp_info[0].h_samp_factor = cw; cinfo.comp_info[0].v_samp_factor = ch; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; cinfo.comp_info[2].v_samp_factor = 1; jpeg_set_quality(&cinfo, quality, TRUE); cinfo.dct_method = JDCT_FASTEST; jpeg_stdio_dest(&cinfo, fp); // Data written to file jpeg_start_compress(&cinfo, TRUE); // fprintf (stderr,"jpeg write for j\n"); for (j = 0; j < h; j += 16) { for (i = 0; i < 16; i++) { y[i] = image[0] + cinfo.image_width * (i + j); // need to handle other chroma subsampling if (i % ch == 0) { cb[i / ch] = image[1] + w / cw * ((i + j) / cw); cr[i / ch] = image[2] + w / cw * ((i + j) / cw); } } // fprintf (stderr,"jpeg write raw data\n"); jpeg_write_raw_data(&cinfo, data, 16); // fprintf (stderr,"jpeg write raw data finish\n"); } // fprintf (stderr,"jpeg finish compress\n"); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); }
int main(int argc, char **argv) { int fdin, fdout, err, c, i, verbose = 1; y4m_stream_info_t istream, ostream; y4m_frame_info_t iframe; fdin = fileno(stdin); fdout = fileno(stdout); y4m_accept_extensions(1); y4m_init_stream_info(&istream); y4m_init_frame_info(&iframe); while ((c = getopt(argc, argv, "L:C:hv:N")) != EOF) { switch (c) { case 'N': lowuv = lowy = 0; lowuv = highy = 255; break; case 'L': i = sscanf(optarg, "%lf,%lf,%d", &y_radius, &y_amount, &y_threshold); if (i != 3) { mjpeg_error("-L r,a,t"); usage(argv[0]); } break; case 'C': i = sscanf(optarg, "%lf,%lf,%d", &uv_radius, &uv_amount, &uv_threshold); if (i != 3) { mjpeg_error("-C r,a,t"); usage(argv[0]); } break; case 'v': verbose = atoi(optarg); if (verbose < 0 || verbose > 2) mjpeg_error_exit1("-v 0|1|2"); break; case 'h': default: usage(argv[0]); break; } } if (isatty(fdout)) mjpeg_error_exit1("stdout must not be a terminal"); mjpeg_default_handler_verbosity(verbose); err = y4m_read_stream_header(fdin, &istream); if (err != Y4M_OK) mjpeg_error_exit1("Couldn't read input stream header"); switch (y4m_si_get_interlace(&istream)) { case Y4M_ILACE_NONE: interlaced = 0; break; case Y4M_ILACE_BOTTOM_FIRST: case Y4M_ILACE_TOP_FIRST: interlaced = 1; break; default: mjpeg_error_exit1("Unsupported/unknown interlacing"); } if (y4m_si_get_plane_count(&istream) != 3) mjpeg_error_exit1("Only 3 plane formats supported"); yheight = y4m_si_get_plane_height(&istream, 0); uvheight = y4m_si_get_plane_height(&istream, 1); ywidth = y4m_si_get_plane_width(&istream, 0); uvwidth = y4m_si_get_plane_width(&istream, 1); ylen = y4m_si_get_plane_length(&istream, 0); uvlen = y4m_si_get_plane_length(&istream, 1); /* Input and output frame buffers */ i_yuv[0] = (u_char *)malloc(ylen); i_yuv[1] = (u_char *)malloc(uvlen); i_yuv[2] = (u_char *)malloc(uvlen); o_yuv[0] = (u_char *)malloc(ylen); o_yuv[1] = (u_char *)malloc(uvlen); o_yuv[2] = (u_char *)malloc(uvlen); /* * general purpose row/column scratch buffers. Slightly over allocated to * simplify life. */ cur_col = (u_char *)malloc(MAX(ywidth, yheight)); dest_col = (u_char *)malloc(MAX(ywidth, yheight)); cur_row = (u_char *)malloc(MAX(ywidth, yheight)); dest_row = (u_char *)malloc(MAX(ywidth, yheight)); /* * Generate the convolution matrices. The generation routine allocates the * memory and returns the length. */ cmatrix_y_len = gen_convolve_matrix(y_radius, &cmatrix_y); cmatrix_uv_len = gen_convolve_matrix(uv_radius, &cmatrix_uv); ctable_y = gen_lookup_table(cmatrix_y, cmatrix_y_len); ctable_uv = gen_lookup_table(cmatrix_uv, cmatrix_uv_len); y4m_init_stream_info(&ostream); y4m_copy_stream_info(&ostream, &istream); y4m_write_stream_header(fileno(stdout), &ostream); mjpeg_info("Luma radius: %f", y_radius); mjpeg_info("Luma amount: %f", y_amount); mjpeg_info("Luma threshold: %d", y_threshold); if (uv_radius != -1.0) { mjpeg_info("Chroma radius: %f", uv_radius); mjpeg_info("Chroma amount: %f", uv_amount); mjpeg_info("Chroma threshold: %d", uv_threshold); } for (frameno = 0; y4m_read_frame(fdin, &istream, &iframe, i_yuv) == Y4M_OK; frameno++) { y4munsharp(); err = y4m_write_frame(fdout, &ostream, &iframe, o_yuv); if (err != Y4M_OK) { mjpeg_error("y4m_write_frame err at frame %d", frameno); break; } } y4m_fini_frame_info(&iframe); y4m_fini_stream_info(&istream); y4m_fini_stream_info(&ostream); exit(0); }