// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_y4m_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) { demux_stream_t *ds=demux->video; demux_packet_t *dp; y4m_priv_t *priv=demux->priv; y4m_frame_info_t fi; unsigned char *buf[3]; int err, size; y4m_init_frame_info(&fi); demux->filepos=stream_tell(demux->stream); size = ((sh_video_t*)ds->sh)->disp_w*((sh_video_t*)ds->sh)->disp_h; dp = new_demux_packet(3*size/2); /* swap U and V components */ buf[0] = dp->buffer; buf[1] = dp->buffer + 5*size/4; buf[2] = dp->buffer + size; if (priv->is_older) { int c; c = stream_read_char(demux->stream); /* F */ if (c == -256) return 0; /* EOF */ if (c != 'F') { mp_msg(MSGT_DEMUX, MSGL_V, "Bad frame at %d\n", (int)stream_tell(demux->stream)-1); return 0; } stream_skip(demux->stream, 5); /* RAME\n */ stream_read(demux->stream, buf[0], size); stream_read(demux->stream, buf[1], size/4); stream_read(demux->stream, buf[2], size/4); } else { if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) { mp_msg(MSGT_DEMUX, MSGL_V, "error reading frame %s\n", y4m_strerr(err)); return 0; } } /* This seems to be the right way to calculate the presentation time stamp */ dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps; priv->framenum++; dp->pos=demux->filepos; dp->flags=0; ds_add_packet(ds, dp); return 1; }
int ysSource::read_frame(int fdin, y4m_frame_info_t *frameinfo, uint8_t **frame) { switch (_fake_progressive) { case FAKE_NO_FAKE: return y4m_read_frame(fdin, _stream.streaminfo(), frameinfo, frame); case FAKE_TOP_ONLY: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); case FAKE_BOT_ONLY: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); } return -1; /*????? */ }
static int yw_decode_video(YWPrivateData *pd, transfer_t *param) { int errnum = 0; YUV_INIT_PLANES(pd->planes, param->buffer, pd->dstfmt, pd->width, pd->height); errnum = y4m_read_frame(pd->fd_vid, &pd->streaminfo, &pd->frameinfo, pd->planes); if (errnum != Y4M_OK) { if (verbose & TC_DEBUG) { tc_log_warn(MOD_NAME, "YUV4MPEG2 video read failed: %s", y4m_strerr(errnum)); } return(TC_IMPORT_ERROR); } return(TC_IMPORT_OK); }
int main(int argc, char **argv) { int i, fdin, ss_v, ss_h, chroma_ss, textout; int do_vectorscope; int pwidth, pheight; /* Needed for the vectorscope */ int plane0_l, plane1_l, plane2_l; u_char *yuv[3], *cp; #ifdef HAVE_SDLgfx int j; int temp_x, temp_y; u_char *cpx, *cpy; #endif y4m_stream_info_t istream; y4m_frame_info_t iframe; do_vectorscope = 0; scalepercent = 0; #ifdef HAVE_SDLgfx textout = 0; #else textout = 1; #endif while ((i = getopt(argc, argv, "tps:")) != EOF) { switch (i) { case 't': textout = 1; break; case 'p': scalepercent = 1; break; case 's': do_vectorscope = atoi(optarg); break; default: usage(); } } #ifdef HAVE_SDLgfx if ( (do_vectorscope < 0) || (do_vectorscope >16) ) usage(); /* Initialize SDL */ desired_bpp = 8; video_flags = 0; video_flags |= SDL_DOUBLEBUF; number_of_frames = 1; memset(fy_stats, '\0', sizeof (fy_stats)); memset(ly_stats, '\0', sizeof (ly_stats)); if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) mjpeg_error_exit1("Couldn't initialize SDL:%s",SDL_GetError()); atexit(SDL_Quit); /* Clean up on exit */ /* Initialize the display */ if (do_vectorscope == 0) screen = SDL_SetVideoMode(width,heigth,desired_bpp,video_flags); else screen=SDL_SetVideoMode(width_v,heigth,desired_bpp,video_flags); if (screen == NULL) mjpeg_error_exit1("Couldn't set %dx%dx%d video mode: %s", width, heigth, desired_bpp, SDL_GetError()); SDL_WM_SetCaption("y4mhistogram", "y4mhistogram"); y4m_init_area(screen); /* Here we draw the basic layout */ #endif /* HAVE_SDLgfx */ fdin = fileno(stdin); y4m_accept_extensions(1); y4m_init_stream_info(&istream); y4m_init_frame_info(&iframe); if (y4m_read_stream_header(fdin, &istream) != Y4M_OK) mjpeg_error_exit1("stream header error"); if (y4m_si_get_plane_count(&istream) != 3) mjpeg_error_exit1("Only 3 plane formats supported"); pwidth = y4m_si_get_width(&istream); pheight = y4m_si_get_height(&istream); chroma_ss = y4m_si_get_chroma(&istream); ss_h = y4m_chroma_ss_x_ratio(chroma_ss).d; ss_v = y4m_chroma_ss_y_ratio(chroma_ss).d; plane0_l = y4m_si_get_plane_length(&istream, 0); plane1_l = y4m_si_get_plane_length(&istream, 1); plane2_l = y4m_si_get_plane_length(&istream, 2); yuv[0] = malloc(plane0_l); if (yuv[0] == NULL) mjpeg_error_exit1("malloc(%d) plane 0", plane0_l); yuv[1] = malloc(plane1_l); if (yuv[1] == NULL) mjpeg_error_exit1(" malloc(%d) plane 1", plane1_l); yuv[2] = malloc(plane2_l); if (yuv[2] == NULL) mjpeg_error_exit1(" malloc(%d) plane 2\n", plane2_l); while (y4m_read_frame(fdin,&istream,&iframe,yuv) == Y4M_OK) { for (i = 0, cp = yuv[0]; i < plane0_l; i++, cp++) y_stats[*cp]++; /* Y' */ for (i = 0, cp = yuv[1]; i < plane1_l; i++, cp++) u_stats[*cp]++; /* U */ for (i = 0, cp = yuv[2]; i < plane2_l; i++, cp++) v_stats[*cp]++; /* V */ #ifdef HAVE_SDLgfx if (do_vectorscope >= 1 ) { for (i=0; i<260; i++) /* Resetting the vectorfield */ for (j=0;j<260;j++) vectorfield[i][j]=0; cpx = yuv[1]; cpy = yuv[2]; for (i=0; i < (pheight/ss_h); i++) { for (j = 0; j < (pwidth/ss_v); j++) { cpx++; cpy++; /* Have no idea why I have to multiply it with that values But than the vectorsscope works correct. If someone has a explantion or better fix tell me. Bernhard */ temp_x = round( 128+ ((*cpx-128) * 0.7857) ); temp_y = round( 128+ ((*cpy-128) * 1.1143) ); vectorfield[temp_x][temp_y*-1]=1; } /* Here we got to the n'th next line if needed */ i = i + (do_vectorscope-1); cpy = cpy + (pwidth/ss_v) * (do_vectorscope-1); cpx = cpx + (pwidth/ss_v) * (do_vectorscope-1); } } make_stat(); /* showing the sats */ SDL_UpdateRect(screen,0,0,0,0); /* updating all */ /* Events for SDL */ HandleEvent(); #endif } y4m_fini_frame_info(&iframe); y4m_fini_stream_info(&istream); if (textout) { for (i = 0; i < 255; i++) printf("Y %d %lld\n", i, y_stats[i]); for (i = 0; i < 255; i++) printf("U %d %lld\n", i, u_stats[i]); for (i = 0; i < 255; i++) printf("V %d %lld\n", i, v_stats[i]); } exit(0); }
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); }
int main (int argc, char *argv[]) { extern char *optarg; int cpucap = cpu_accel (); char c; int fd_in = 0; int fd_out = 1; int errno = 0; int have_framerate = 0; int force_interlacing = 0; y4m_frame_info_t iframeinfo; y4m_stream_info_t istreaminfo; y4m_frame_info_t oframeinfo; y4m_stream_info_t ostreaminfo; int output_frame_number = 0; int input_frame_number = 0; y4m_ratio_t output_frame_rate, input_frame_rate, frame_rate_ratio; float ratio = 0; // input/output, output should be > input ) int scene_change; y4m_ratio_t ratio_percent_frame; float percent_threshold = 0.02; /* percent_threshold is there to avoid interpolating frames when the output frame * is very close to an input frame */ mjpeg_log (LOG_INFO, "-------------------------------------------------"); mjpeg_log (LOG_INFO, " Motion-Compensating-Frame-Rate-Converter "); mjpeg_log (LOG_INFO, "-------------------------------------------------"); while ((c = getopt (argc, argv, "hvb:p:r:t:s:f")) != -1) { switch (c) { case 'h': { mjpeg_log (LOG_INFO, "Usage "); mjpeg_log (LOG_INFO, "-------------------------"); mjpeg_log (LOG_INFO, " This program converts frame rates"); mjpeg_log (LOG_INFO, "with a smart algorithm that estimates the motion of the elements"); mjpeg_log (LOG_INFO, "to smooth the motion, rather than duplicating frames."); mjpeg_log (LOG_INFO, " It's way smoother, but introduces a bit of blocking and/or"); mjpeg_log (LOG_INFO, " maybe blurryness when things move too fast."); mjpeg_log (LOG_INFO, " "); mjpeg_log (LOG_INFO, " -r Frame rate for the resulting stream (in X:Y fractional form)"); mjpeg_log (LOG_INFO, " -b block size (default = 8, will be rounded to even number )"); mjpeg_log (LOG_INFO, " -p search path radius (default = 8, do not use high values ~ > 20)"); mjpeg_log (LOG_INFO, "-t frame approximation threshold (default=50, higher=better)"); mjpeg_log (LOG_INFO, "-s scene change threshold (default=8, 0=disable scene change detection)"); mjpeg_log (LOG_INFO, "-r Frame rate for the resulting stream (in X:Y fractional form)"); mjpeg_log (LOG_INFO, " -f force processing interlaced input (don't know what it does)"); mjpeg_log (LOG_INFO, " -v verbose/debug"); exit (0); break; } case 'v': { verbose = 1; break; } case 'f': { force_interlacing = 1; break; } case 'b': { block_size = strtol (optarg, (char **) NULL, 10); /* we only want even block sizes */ if (block_size % 1 != 0) { block_size = block_size + 1; mjpeg_log (LOG_WARN, "Block size changed to %d", block_size); } else mjpeg_log (LOG_INFO, "Block size: %d", block_size); break; } case 'p': { search_path_radius = strtol (optarg, (char **) NULL, 10); /* safer atoi */ mjpeg_log (LOG_INFO, "Search radius %d", search_path_radius); break; } case 'r': { if (Y4M_OK != y4m_parse_ratio (&output_frame_rate, optarg)) mjpeg_error_exit1 ("Syntax for frame rate should be Numerator:Denominator"); mjpeg_log (LOG_INFO, "New Frame rate %d:%d", output_frame_rate.n, output_frame_rate.d); have_framerate = 1; break; } case 't': { percent_threshold = strtol (optarg, (char **) NULL, 10); if ((percent_threshold > 1) && (percent_threshold <= 1024)) percent_threshold = 1.0 / percent_threshold; else mjpeg_error_exit1 ("Threshold should be between 2 and 1024"); mjpeg_log (LOG_INFO, "Approximation threshold %d", (int) ((float) 1.0 / percent_threshold)); break; } case 's': { scene_change_threshold = strtol (optarg, (char **) NULL, 10); if (scene_change_threshold == 0) mjpeg_log (LOG_INFO, "Scene change detection disabled"); else mjpeg_log (LOG_INFO, "Scene change threshold: %d00 percent", scene_change_threshold); break; } } } if (!have_framerate) { mjpeg_error_exit1 ("Please specify a frame rate; yuvmotionfps -h for more info"); } /* initialize motion_library */ init_motion_search (); /* initialize MMX transforms (fixme) */ if ((cpucap & ACCEL_X86_MMXEXT) != 0 || (cpucap & ACCEL_X86_SSE) != 0) { #if 0 mjpeg_log (LOG_INFO, "FIXME: could use MMX/SSE Block/Frame-Copy/Blend if I had one ;-)"); #endif } /* initialize stream-information */ y4m_accept_extensions (1); y4m_init_stream_info (&istreaminfo); y4m_init_frame_info (&iframeinfo); y4m_init_stream_info (&ostreaminfo); y4m_init_frame_info (&oframeinfo); /* open input stream */ if ((errno = y4m_read_stream_header (fd_in, &istreaminfo)) != Y4M_OK) { mjpeg_log (LOG_ERROR, "Couldn't read YUV4MPEG header: %s!", y4m_strerr (errno)); exit (1); } /* get format information */ width = y4m_si_get_width (&istreaminfo); height = y4m_si_get_height (&istreaminfo); input_chroma_subsampling = y4m_si_get_chroma (&istreaminfo); mjpeg_log (LOG_INFO, "Y4M-Stream is %ix%i(%s)", width, height, input_chroma_subsampling == Y4M_CHROMA_420JPEG ? "4:2:0 MPEG1" : input_chroma_subsampling == Y4M_CHROMA_420MPEG2 ? "4:2:0 MPEG2" : input_chroma_subsampling == Y4M_CHROMA_420PALDV ? "4:2:0 PAL-DV" : input_chroma_subsampling == Y4M_CHROMA_444 ? "4:4:4" : input_chroma_subsampling == Y4M_CHROMA_422 ? "4:2:2" : input_chroma_subsampling == Y4M_CHROMA_411 ? "4:1:1 NTSC-DV" : input_chroma_subsampling == Y4M_CHROMA_MONO ? "MONOCHROME" : input_chroma_subsampling == Y4M_CHROMA_444ALPHA ? "4:4:4:4 ALPHA" : "unknown"); /* if chroma-subsampling isn't supported bail out ... */ switch (input_chroma_subsampling) { case Y4M_CHROMA_420JPEG: break; case Y4M_CHROMA_420PALDV: case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_411: mjpeg_log (LOG_WARN, "This chroma subsampling mode has not been thoroughly tested"); break; default: mjpeg_error_exit1 ("Y4M-Stream is not 4:2:0. Other chroma-modes currently not allowed. Sorry."); } /* the output is progressive 4:2:0 MPEG 1 */ y4m_si_set_interlace (&ostreaminfo, Y4M_ILACE_NONE); y4m_si_set_chroma (&ostreaminfo, Y4M_CHROMA_420JPEG); y4m_si_set_width (&ostreaminfo, width); y4m_si_set_height (&ostreaminfo, height); y4m_si_set_sampleaspect (&ostreaminfo, y4m_si_get_sampleaspect (&istreaminfo)); input_frame_rate = y4m_si_get_framerate (&istreaminfo); y4m_si_set_framerate (&ostreaminfo, output_frame_rate); if (width % block_size != 0) { mjpeg_log (LOG_WARN, "Warning, stream width(%d) is not a multiple of block_size (%d)", width, block_size); mjpeg_log (LOG_WARN, "The right side of the image might not be what you want"); } if (height % block_size != 0) { mjpeg_log (LOG_WARN, "Warning, stream height(%d) is not a multiple of block_size (%d)", height, block_size); mjpeg_log (LOG_WARN, "The lower side of the image might not be what you want"); } /* Calculate the different ratios: * ratio is (input framerate / output framerate) * ratio_percent_frame is the fractional representation of percent frame */ frame_rate_ratio.n = input_frame_rate.n * output_frame_rate.d; frame_rate_ratio.d = input_frame_rate.d * output_frame_rate.n; y4m_ratio_reduce (&frame_rate_ratio); ratio = (float) frame_rate_ratio.n / frame_rate_ratio.d; ratio_percent_frame.d = 1; ratio_percent_frame.n = 0; if (ratio == 0) mjpeg_error_exit1 ("Cannot have ratio =0 "); else if (ratio > 128) mjpeg_error_exit1 ("Cannot have ratio >128 "); if ((y4m_si_get_interlace (&istreaminfo) != Y4M_ILACE_NONE) && (!force_interlacing)) { mjpeg_error_exit1 ("Sorry, can only convert progressive streams"); } /* write the outstream header */ y4m_write_stream_header (fd_out, &ostreaminfo); /* now allocate the needed buffers */ { /* calculate the memory offset needed to allow the processing * functions to overshot. The biggest overshot is needed for the * MC-functions, so we'll use 8*width... */ buff_offset = width * 8; buff_size = buff_offset * 2 + width * height; inframe[0] = buff_offset + (uint8_t *) malloc (buff_size); inframe[1] = buff_offset + (uint8_t *) malloc (buff_size); inframe[2] = buff_offset + (uint8_t *) malloc (buff_size); reconstructed[0] = buff_offset + (uint8_t *) malloc (buff_size); reconstructed[1] = buff_offset + (uint8_t *) malloc (buff_size); reconstructed[2] = buff_offset + (uint8_t *) malloc (buff_size); frame1[0] = buff_offset + (uint8_t *) malloc (buff_size); frame1[1] = buff_offset + (uint8_t *) malloc (buff_size); frame1[2] = buff_offset + (uint8_t *) malloc (buff_size); mjpeg_log (LOG_INFO, "Buffers allocated."); } /* initialize motion-search-pattern */ init_search_pattern (); errno = y4m_read_frame (fd_in, &istreaminfo, &iframeinfo, frame1); if (errno != Y4M_OK) goto The_end; /* read every frame until the end of the input stream and process it */ while (Y4M_OK == (errno = y4m_read_frame (fd_in, &istreaminfo, &iframeinfo, inframe))) { /* frame1 contains the previous input frame * inframe contains the current input frame * reconstructed contains the current output frame * percent_frame is the amount of time after which the output frame is sent * in percent of the time between input frames * * Input: * frame1 . . . . . . . . . . . . . . . . . . inframe * Output: * . . . . . . . . . . .reconstructed. . . . . . . * |<- - percent_frame - - - ->| * |< - - - - - - - - - -100% - - - - - - - - - >| * * The variable ratio_percent_frame is the fractional representation of * percent_frame; it is there to avoid rounding errors */ input_frame_number++; if (verbose) { mjpeg_log (LOG_INFO, "Input frame number %d", input_frame_number); } while (percent_frame < (1.0 - percent_threshold)) { output_frame_number++; if (verbose) { mjpeg_log (LOG_INFO, "Output frame number %d", output_frame_number); } #define ABS(value) ((value)<0)?-(value):(value) if (ABS (percent_frame) <= percent_threshold) { /* I put a threshold here to avoid wasting time */ /* The output frame coincides with the input frame * so there is no need to do any processing * just copy the input frame as is */ y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, frame1); if (verbose) mjpeg_log (LOG_INFO, "Percent %f rounded to next frame", percent_frame); } else { /* We have to interpolate the frame (between the current inframe * and the previous frame1 * if there is a scene change, motion_compensate_field will * return 1 and we use the previous frame */ if (verbose) mjpeg_log (LOG_INFO, "Percent %f", percent_frame); scene_change = motion_compensate_field (); if (scene_change) { mjpeg_log (LOG_INFO, "Scene change at frame %d", input_frame_number); y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, frame1); } else { y4m_write_frame (fd_out, &ostreaminfo, &oframeinfo, reconstructed); } } ratio_percent_frame = add_ratio (ratio_percent_frame, frame_rate_ratio); percent_frame = Y4M_RATIO_DBL (ratio_percent_frame); } /* Skip input frames if downsampling (ratio > 1) * when upsampling, ratio < 1 * so we have ( 1< percent_frame < 2) at this point * hence we don't go in in the loop */ while (percent_frame >= 2) { percent_frame = percent_frame - 1; ratio_percent_frame = ratio_minus_1 (ratio_percent_frame); if (Y4M_OK != (errno = y4m_read_frame (fd_in, &istreaminfo, &iframeinfo, inframe))) goto The_end; } ratio_percent_frame = ratio_minus_1 (ratio_percent_frame); percent_frame = percent_frame - 1; /* store the previous frame */ memcpy (frame1[0], inframe[0], width * height); memcpy (frame1[1], inframe[1], width * height / 4); memcpy (frame1[2], inframe[2], width * height / 4); } The_end: /* free allocated buffers */ { free (inframe[0] - buff_offset); free (inframe[1] - buff_offset); free (inframe[2] - buff_offset); free (reconstructed[0] - buff_offset); free (reconstructed[1] - buff_offset); free (reconstructed[2] - buff_offset); free (frame1[0] - buff_offset); free (frame1[1] - buff_offset); free (frame1[2] - buff_offset); mjpeg_log (LOG_INFO, "Buffers freed."); } /* did stream end unexpectedly ? */ if (errno != Y4M_ERR_EOF) mjpeg_error_exit1 ("%s", y4m_strerr (errno)); /* Exit gently */ return (0); }
int ysSource::read_frame(int fdin, y4m_frame_info_t *frameinfo, uint8_t **frame) { #if 1 switch (_fake_progressive) { case FAKE_NO_FAKE: switch (_stream.subsampling().mode()) { case ysSubsampling::SS_444: return internal_read_444_frame(fdin, _stream.streaminfo(), frameinfo, frame); case ysSubsampling::SS_422: return internal_read_422_frame(fdin, _stream.streaminfo(), frameinfo, frame); case ysSubsampling::SS_411: case ysSubsampling::SS_420_JPEG: case ysSubsampling::SS_420_MPEG2: case ysSubsampling::SS_420_PALDV: default: return y4m_read_frame(fdin, _stream.streaminfo(), frameinfo, frame); } case FAKE_TOP_ONLY: switch (_stream.subsampling().mode()) { case ysSubsampling::SS_411: return internal_read_411_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); case ysSubsampling::SS_444: return internal_read_444_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); case ysSubsampling::SS_422: return internal_read_422_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); case ysSubsampling::SS_420_JPEG: case ysSubsampling::SS_420_MPEG2: case ysSubsampling::SS_420_PALDV: default: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); } case FAKE_BOT_ONLY: switch (_stream.subsampling().mode()) { case ysSubsampling::SS_411: return internal_read_411_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); case ysSubsampling::SS_444: return internal_read_444_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); case ysSubsampling::SS_422: return internal_read_422_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); case ysSubsampling::SS_420_JPEG: case ysSubsampling::SS_420_MPEG2: case ysSubsampling::SS_420_PALDV: default: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); } } return -1; /*????? */ #else switch (_fake_progressive) { case FAKE_NO_FAKE: return y4m_read_frame(fdin, _stream.streaminfo(), frameinfo, frame); case FAKE_TOP_ONLY: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, frame, _fake_field); case FAKE_BOT_ONLY: return y4m_read_fields(fdin, _real_stream.streaminfo(), frameinfo, _fake_field, frame); } return -1; /*????? */ #endif }
int main(int argc, char *argv[]) { int verbosity = 1; double time_between_frames = 0.0; double frame_rate = 0.0; struct timeval time_now; int n, frame; unsigned char *yuv[3]; int in_fd = 0; int screenwidth=0, screenheight=0; y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; int frame_width; int frame_height; int wait_for_sync = 1; char *window_title = NULL; while ((n = getopt(argc, argv, "hs:t:f:cv:")) != EOF) { switch (n) { case 'c': wait_for_sync = 0; break; case 's': if (sscanf(optarg, "%dx%d", &screenwidth, &screenheight) != 2) { mjpeg_error_exit1( "-s option needs two arguments: -s 10x10"); exit(1); } break; case 't': window_title = optarg; break; case 'f': frame_rate = atof(optarg); if( frame_rate <= 0.0 || frame_rate > 200.0 ) mjpeg_error_exit1( "-f option needs argument > 0.0 and < 200.0"); break; case 'v': verbosity = atoi(optarg); if ((verbosity < 0) || (verbosity > 2)) mjpeg_error_exit1("-v needs argument from {0, 1, 2} (not %d)", verbosity); break; case 'h': case '?': usage(); exit(1); break; default: usage(); exit(1); } } mjpeg_default_handler_verbosity(verbosity); y4m_accept_extensions(1); y4m_init_stream_info(&streaminfo); y4m_init_frame_info(&frameinfo); if ((n = y4m_read_stream_header(in_fd, &streaminfo)) != Y4M_OK) { mjpeg_error("Couldn't read YUV4MPEG2 header: %s!", y4m_strerr(n)); exit (1); } switch (y4m_si_get_chroma(&streaminfo)) { case Y4M_CHROMA_420JPEG: case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_420PALDV: break; default: mjpeg_error_exit1("Cannot handle non-4:2:0 streams yet!"); } frame_width = y4m_si_get_width(&streaminfo); frame_height = y4m_si_get_height(&streaminfo); if ((screenwidth <= 0) || (screenheight <= 0)) { /* no user supplied screen size, so let's use the stream info */ y4m_ratio_t aspect = y4m_si_get_sampleaspect(&streaminfo); if (!(Y4M_RATIO_EQL(aspect, y4m_sar_UNKNOWN))) { /* if pixel aspect ratio present, use it */ #if 1 /* scale width, but maintain height (line count) */ screenheight = frame_height; screenwidth = frame_width * aspect.n / aspect.d; #else if ((frame_width * aspect.d) < (frame_height * aspect.n)) { screenwidth = frame_width; screenheight = frame_width * aspect.d / aspect.n; } else { screenheight = frame_height; screenwidth = frame_height * aspect.n / aspect.d; } #endif } else { /* unknown aspect ratio -- assume square pixels */ screenwidth = frame_width; screenheight = frame_height; } } /* Initialize the SDL library */ if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { mjpeg_error("Couldn't initialize SDL: %s", SDL_GetError()); exit(1); } /* set window title */ SDL_WM_SetCaption(window_title, NULL); /* yuv params */ yuv[0] = malloc(frame_width * frame_height * sizeof(unsigned char)); yuv[1] = malloc(frame_width * frame_height / 4 * sizeof(unsigned char)); yuv[2] = malloc(frame_width * frame_height / 4 * sizeof(unsigned char)); screen = SDL_SetVideoMode(screenwidth, screenheight, 0, SDL_SWSURFACE); if ( screen == NULL ) { mjpeg_error("SDL: Couldn't set %dx%d: %s", screenwidth, screenheight, SDL_GetError()); exit(1); } else { mjpeg_debug("SDL: Set %dx%d @ %d bpp", screenwidth, screenheight, screen->format->BitsPerPixel); } /* since IYUV ordering is not supported by Xv accel on maddog's system * (Matrox G400 --- although, the alias I420 is, but this is not * recognized by SDL), we use YV12 instead, which is identical, * except for ordering of Cb and Cr planes... * we swap those when we copy the data to the display buffer... */ yuv_overlay = SDL_CreateYUVOverlay(frame_width, frame_height, SDL_YV12_OVERLAY, screen); if ( yuv_overlay == NULL ) { mjpeg_error("SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError()); exit(1); } if ( yuv_overlay->hw_overlay ) mjpeg_debug("SDL: Using hardware overlay."); rect.x = 0; rect.y = 0; rect.w = screenwidth; rect.h = screenheight; SDL_DisplayYUVOverlay(yuv_overlay, &rect); signal (SIGINT, sigint_handler); frame = 0; if ( frame_rate == 0.0 ) { /* frame rate has not been set from command-line... */ if (Y4M_RATIO_EQL(y4m_fps_UNKNOWN, y4m_si_get_framerate(&streaminfo))) { mjpeg_info("Frame-rate undefined in stream... assuming 25Hz!" ); frame_rate = 25.0; } else { frame_rate = Y4M_RATIO_DBL(y4m_si_get_framerate(&streaminfo)); } } time_between_frames = 1.e6 / frame_rate; gettimeofday(&time_now,0); while ((n = y4m_read_frame(in_fd, &streaminfo, &frameinfo, yuv)) == Y4M_OK && (!got_sigint)) { /* Lock SDL_yuv_overlay */ if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) break; } if (SDL_LockYUVOverlay(yuv_overlay) < 0) break; /* let's draw the data (*yuv[3]) on a SDL screen (*screen) */ memcpy(yuv_overlay->pixels[0], yuv[0], frame_width * frame_height); memcpy(yuv_overlay->pixels[1], yuv[2], frame_width * frame_height / 4); memcpy(yuv_overlay->pixels[2], yuv[1], frame_width * frame_height / 4); /* Unlock SDL_yuv_overlay */ if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } SDL_UnlockYUVOverlay(yuv_overlay); /* Show, baby, show! */ SDL_DisplayYUVOverlay(yuv_overlay, &rect); mjpeg_info("Playing frame %4.4d - %s", frame, print_status(frame, frame_rate)); if (wait_for_sync) while(get_time_diff(time_now) < time_between_frames) { usleep(1000); } frame++; gettimeofday(&time_now,0); } if ((n != Y4M_OK) && (n != Y4M_ERR_EOF)) mjpeg_error("Couldn't read frame: %s", y4m_strerr(n)); for (n=0; n<3; n++) { free(yuv[n]); } mjpeg_info("Played %4.4d frames (%s)", frame, print_status(frame, frame_rate)); SDL_FreeYUVOverlay(yuv_overlay); SDL_Quit(); y4m_fini_frame_info(&frameinfo); y4m_fini_stream_info(&streaminfo); return 0; }
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); }
static void filter( int fdIn , y4m_stream_info_t *inStrInfo, int qual, char *format ) { y4m_frame_info_t in_frame ; uint8_t *yuv_data[3] ; int read_error_code ; int write_error_code ; FILE *fh; char filename[1024]; // has potential for buffer overflow int frame_count=1; // to be moved to command line parameters //char *format = "frame%03d.jpg"; //int qual = 95; // Allocate memory for the YUV channels if (chromalloc(yuv_data,inStrInfo)) mjpeg_error_exit1 ("Could'nt allocate memory for the YUV4MPEG data!"); /* Initialize counters */ write_error_code = Y4M_OK ; 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 ) { // do work if (read_error_code == Y4M_OK) { // fprintf(stderr,"sprintf filename\n"); sprintf(filename,format,frame_count); // fprintf(stderr,"fopen filename\n"); // fprintf(stderr,"filename: %s\n",filename); fh = fopen(filename , "w"); // should check for error // fprintf(stderr,"call put_jpeg_yuv420p_file\n"); if (fh != NULL) { put_jpeg_yuv420p_file(fh,yuv_data,inStrInfo,qual); fclose (fh); } else { perror ("fopen jpeg file"); } } y4m_fini_frame_info( &in_frame ); y4m_init_frame_info( &in_frame ); read_error_code = y4m_read_frame(fdIn, inStrInfo,&in_frame,yuv_data ); frame_count++; } // 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] ); if( read_error_code != Y4M_ERR_EOF ) mjpeg_error_exit1 ("Error reading from input stream!"); }
static void process( int fdIn , y4m_stream_info_t *inStrInfo, int fdOut, y4m_stream_info_t *outStrInfo, int max,int search, int noshift) { y4m_frame_info_t in_frame ; uint8_t *yuv_data[3],*yuv_odata[3]; // int result[720]; // will change to malloc based on max shift int *lineresult; int y_frame_data_size, uv_frame_data_size ; int read_error_code = Y4M_OK; int write_error_code = Y4M_OK ; int src_frame_counter ; int x,y,w,h,cw,ch; h = y4m_si_get_plane_height(inStrInfo,0); ch = y4m_si_get_plane_height(inStrInfo,1); lineresult = (int *) malloc(sizeof(int) * h); chromalloc(yuv_data,inStrInfo); // 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 (y=0; y<h-1; y++) lineresult[y] = search_video(max,search,y,yuv_data,inStrInfo); if (noshift) { /* graphing this would be nice */ for (x=0; x < h; x++) { if (x!=0) printf(", "); printf ("%d",lineresult[x]); } printf("\n"); } else { int shifter = 0; for (y=0; y<h-1; y++) { // shifter += lineresult[y]; shifter = -lineresult[y]; shift_video(shifter,y,yuv_data,inStrInfo); } write_error_code = y4m_write_frame( fdOut, outStrInfo, &in_frame, yuv_data ); } 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 (lineresult); chromafree(yuv_data); 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!"); }
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!"); }
int main(int argc, char *argv[]) { int i; long long avg, total; int input_fd = 0; int output_fd = 1; int horz; int vert; int c; int frame_count; y4m_stream_info_t istream, ostream; y4m_frame_info_t iframe; y4m_accept_extensions(1); while((c = getopt(argc, argv, "r:R:t:T:v:S:hI:w:fc:")) != EOF) { switch(c) { case 'r': radius_luma = atoi(optarg); break; case 'R': radius_chroma = atoi(optarg); break; case 't': threshold_luma = atoi(optarg); break; case 'T': threshold_chroma = atoi(optarg); break; case 'I': interlace = atoi (optarg); if (interlace != 0 && interlace != 1) { Usage (argv[0]); exit (1); } break; case 'S': param_skip = atoi (optarg); break; case 'f': param_fast = 1; break; case 'w': if (strcmp (optarg, "8") == 0) param_weight_type = 1; else if (strcmp (optarg, "2.667") == 0) param_weight_type = 2; else if (strcmp (optarg, "13.333") == 0) param_weight_type = 3; else if (strcmp (optarg, "24") == 0) param_weight_type = 4; else param_weight_type = 0; param_weight = atof (optarg); break; case 'c': cutoff = atof(optarg); break; case 'v': verbose = atoi (optarg); if (verbose < 0 || verbose >2) { Usage (argv[0]); exit (1); } break; case 'h': Usage (argv[0]); default: exit(0); } } if( param_weight < 0 ) { if( param_fast ) param_weight = 8.0; else param_weight = 1.0; } for( i=1; i<NUMAVG; i++ ) { avg_replace[i]=0; divisor[i]=((1<<DIVISORBITS)+(i>>1))/i; divoffset[i]=divisor[i]*(i>>1)+(divisor[i]>>1); } #ifdef HAVE_ASM_MMX if( cpu_accel() & ACCEL_X86_MMXEXT ) domean8=1; #endif mjpeg_info ("fast %d, weight type %d\n", param_fast, param_weight_type); if (radius_luma <= 0 || radius_chroma <= 0) mjpeg_error_exit1("radius values must be > 0!"); if (threshold_luma < 0 || threshold_chroma < 0) mjpeg_error_exit1("threshold values must be >= 0!"); (void)mjpeg_default_handler_verbosity(verbose); y4m_init_stream_info(&istream); y4m_init_stream_info(&ostream); y4m_init_frame_info(&iframe); i = y4m_read_stream_header(input_fd, &istream); if (i != Y4M_OK) mjpeg_error_exit1("Input stream error: %s", y4m_strerr(i)); if (y4m_si_get_plane_count(&istream) != 3) mjpeg_error_exit1("Only 3 plane formats supported"); chroma_mode = y4m_si_get_chroma(&istream); SS_H = y4m_chroma_ss_x_ratio(chroma_mode).d; SS_V = y4m_chroma_ss_y_ratio(chroma_mode).d; mjpeg_debug("chroma subsampling: %dH %dV\n",SS_H,SS_V); if (interlace == -1) { 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; } } if( interlace && y4m_si_get_height(&istream) % 2 != 0 ) mjpeg_error_exit1("Input images have odd number of lines - can't treats as interlaced!" ); horz = y4m_si_get_width(&istream); vert = y4m_si_get_height(&istream); mjpeg_debug("width=%d height=%d luma_r=%d chroma_r=%d luma_t=%d chroma_t=%d", horz, vert, radius_luma, radius_chroma, threshold_luma, threshold_chroma); y4m_copy_stream_info(&ostream, &istream); input_frame[0] = malloc(horz * vert); input_frame[1] = malloc((horz / SS_H) * (vert / SS_V)); input_frame[2] = malloc((horz / SS_H) * (vert / SS_V)); output_frame[0] = malloc(horz * vert); output_frame[1] = malloc((horz / SS_H) * (vert / SS_V)); output_frame[2] = malloc((horz / SS_H) * (vert / SS_V)); y4m_write_stream_header(output_fd, &ostream); frame_count = 0; while (y4m_read_frame(input_fd, &istream, &iframe, input_frame) == Y4M_OK) { frame_count++; if (frame_count > param_skip) { filter(horz, vert, input_frame, output_frame); y4m_write_frame(output_fd, &ostream, &iframe, output_frame); } else y4m_write_frame(output_fd, &ostream, &iframe, input_frame); } for (total=0, avg=0, i=0; i < NUMAVG; i++) { total += avg_replace[i]; avg += avg_replace[i] * i; } mjpeg_info("frames=%d avg=%3.1f", frame_count, ((double)avg)/((double)total)); for (i=0; i < NUMAVG; i++) { mjpeg_debug( "%02d: %6.2f", i, (((double)avg_replace[i]) * 100.0)/(double)(total)); } y4m_fini_stream_info(&istream); y4m_fini_stream_info(&ostream); y4m_fini_frame_info(&iframe); exit(0); }
int main (int argc, char *argv[]) { int verbose = 1; int in_fd = 0; /* stdin */ int out_fd = 1; /* stdout */ unsigned char *yuv0[3]; /* input 0 */ unsigned char *yuv1[3]; /* input 1 */ unsigned char *yuv[3]; /* output */ int w, h, len, lensr2; int i, j, opacity, opacity_range, frame, numframes, r = 0; unsigned int param_opacity0 = 0; /* opacity of input1 at the beginning */ unsigned int param_opacity1 = 255; /* opacity of input1 at the end */ unsigned int param_duration = 0; /* duration of transistion effect */ unsigned int param_skipframes = 0; /* # of frames to skip */ unsigned int param_numframes = 0; /* # of frames to (process - skip+num) * framerepeat <= duration */ unsigned int param_framerep = 1; /* # of repititions per frame */ y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; y4m_init_stream_info (&streaminfo); y4m_init_frame_info (&frameinfo); while ((i = getopt(argc, argv, "v:o:O:d:s:n:r:")) != -1) { switch (i) { case 'v': verbose = atoi (optarg); if( verbose < 0 || verbose >2 ) { usage (); exit (1); } break; case 'o': param_opacity0 = atoi (optarg); if (param_opacity0 > 255) { mjpeg_warn( "start opacity > 255"); param_opacity0 = 255; } break; case 'O': param_opacity1 = atoi (optarg); if (param_opacity1 > 255) { mjpeg_warn( "end opacity > 255"); param_opacity1 = 255; } break; case 'd': param_duration = atoi (optarg); if (param_duration == 0) { mjpeg_error_exit1( "error: duration = 0 frames"); } break; case 's': param_skipframes = atoi (optarg); break; case 'n': param_numframes = atoi (optarg); break; case 'r': param_framerep = atoi (optarg); break; } } if (param_numframes == 0) param_numframes = (param_duration - param_skipframes) / param_framerep; if (param_duration == 0) { usage (); exit (1); } numframes = (param_skipframes + param_numframes) * param_framerep; if (numframes > param_duration) { mjpeg_error_exit1( "skip + num > duration"); } (void)mjpeg_default_handler_verbosity(verbose); i = y4m_read_stream_header (in_fd, &streaminfo); if (i != Y4M_OK) { fprintf (stderr, "%s: input stream error - %s\n", argv[0], y4m_strerr(i)); exit (1); } w = y4m_si_get_width(&streaminfo); h = y4m_si_get_height(&streaminfo); len = w*h; lensr2 = len >> 2; yuv[0] = malloc (len); yuv0[0] = malloc (len); yuv1[0] = malloc (len); yuv[1] = malloc (lensr2); yuv0[1] = malloc (lensr2); yuv1[1] = malloc (lensr2); yuv[2] = malloc (lensr2); yuv0[2] = malloc (lensr2); yuv1[2] = malloc (lensr2); y4m_write_stream_header (out_fd, &streaminfo); frame = param_skipframes; param_duration--; opacity_range = param_opacity1 - param_opacity0; while (1) { if (!r) { r = param_framerep; i = y4m_read_frame(in_fd, &streaminfo, &frameinfo, yuv0); if (i != Y4M_OK) exit (frame < numframes); j = y4m_read_frame(in_fd, &streaminfo, &frameinfo, yuv1); if (j != Y4M_OK) exit (frame < numframes); } r--; opacity = param_opacity0 + ((frame * opacity_range) / param_duration); blend (yuv0, yuv1, opacity, len, yuv); y4m_write_frame (out_fd, &streaminfo, &frameinfo, yuv); if (++frame == numframes) exit (0); } }
/** MAIN */ int main( int argc, char **argv) { int i, frame_count; int horz, vert; /* width and height of the frame */ uint8_t *frame[3]; /*pointer to the 3 color planes of the input frame */ struct area_s inarea; struct color_yuv coloryuv; int input_fd = 0; /* std in */ int output_fd = 1; /* std out */ int darker = 0; /* how much darker should the image be */ int copy_pixel = 0; /* how much pixels we should use for filling up the area */ int average_pixel = 0; /* how much pixel to use for average */ y4m_stream_info_t istream, ostream; y4m_frame_info_t iframe; inarea.width=0; inarea.height=0; inarea.voffset=0; inarea.hoffset=0; coloryuv.luma = LUMA; /*Setting the luma to black */ coloryuv.chroma_b = CHROMA; /*Setting the chroma to center, means white */ coloryuv.chroma_r = CHROMA; /*Setting the chroma to center, means white */ (void)mjpeg_default_handler_verbosity(verbose); /* processing commandline */ process_commandline(argc, argv, &inarea, &darker, ©_pixel, &coloryuv, &average_pixel); y4m_init_stream_info(&istream); y4m_init_stream_info(&ostream); y4m_init_frame_info(&iframe); /* First read the header of the y4m stream */ i = y4m_read_stream_header(input_fd, &istream); if ( i != Y4M_OK) /* a basic check if we really have y4m stream */ mjpeg_error_exit1("Input stream error: %s", y4m_strerr(i)); else { /* Here we copy the input stream info to the output stream info header */ y4m_copy_stream_info(&ostream, &istream); /* Here we write the new output header to the output fd */ y4m_write_stream_header(output_fd, &ostream); horz = y4m_si_get_width(&istream); /* get the width of the frame */ vert = y4m_si_get_height(&istream); /* get the height of the frame */ if ( (inarea.width + inarea.hoffset) > horz) mjpeg_error_exit1("Input width and offset larger than framewidth,exit"); if ( (inarea.height + inarea.voffset) > vert) mjpeg_error_exit1("Input height and offset larger than frameheight,exit"); /* Here we allocate the memory for on frame */ frame[0] = malloc( horz * vert ); frame[1] = malloc( (horz/2) * (vert/2) ); frame[2] = malloc( (horz/2) * (vert/2) ); /* Here we set the initial number of of frames */ /* We do not need it. Just for showing that is does something */ frame_count = 0 ; /* This is the main loop here can filters effects, scaling and so on be done with the video frames. Just up to your mind */ /* We read now a single frame with the header and check if it does not have any problems or we have alreaddy processed the last without data */ while(y4m_read_frame(input_fd, &istream, &iframe, frame) == Y4M_OK) { frame_count++; /* You can do something usefull here */ if (darker != 0) set_darker(inarea, horz, vert, frame, darker); else if (copy_pixel != 0) copy_area(inarea, horz, vert, frame, copy_pixel); else if (average_pixel != 0) average_area(inarea, horz, vert, frame, average_pixel); else set_inactive(inarea, horz, vert, frame, &coloryuv); /* Now we put out the read frame */ y4m_write_frame(output_fd, &ostream, &iframe, frame); } /* Cleaning up the data structures */ y4m_fini_stream_info(&istream); y4m_fini_stream_info(&ostream); y4m_fini_frame_info(&iframe); } /* giving back the memory to the system */ free(frame[0]); frame[0] = 0; free(frame[1]); frame[1] = 0; free(frame[2]); frame[2] = 0; exit(0); /* exiting */ }