static int tc_y4m_init(TCModuleInstance *self, uint32_t features) { Y4MPrivateData *pd = NULL; TC_MODULE_SELF_CHECK(self, "init"); TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); pd = tc_malloc(sizeof(Y4MPrivateData)); if (pd == NULL) { return TC_ERROR; } pd->width = 0; pd->height = 0; pd->fd_vid = -1; y4m_init_stream_info(&(pd->streaminfo)); /* frameinfo will be initialized at each multiplex call */ if (verbose) { tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); } self->userdata = pd; return TC_OK; }
static lives_yuv4m_t *lives_yuv4mpeg_alloc(void) { lives_yuv4m_t *yuv4mpeg = (lives_yuv4m_t *) malloc(sizeof(lives_yuv4m_t)); if (yuv4mpeg==NULL) return NULL; yuv4mpeg->sar = y4m_sar_UNKNOWN; yuv4mpeg->dar = y4m_dar_4_3; y4m_init_stream_info(&(yuv4mpeg->streaminfo)); y4m_init_frame_info(&(yuv4mpeg->frameinfo)); yuv4mpeg->filename=NULL; yuv4mpeg->name=NULL; yuv4mpeg->fd=-1; yuv4mpeg->ready=FALSE; return yuv4mpeg; }
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 main(int argc, char *argv[]) { AVFormatContext *pFormatCtx; AVInputFormat *avif = NULL; int i, videoStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrame444; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer; int fdOut = 1 ; int yuv_interlacing = Y4M_UNKNOWN; int yuv_ss_mode = Y4M_UNKNOWN; y4m_ratio_t yuv_frame_rate; y4m_ratio_t yuv_aspect; // need something for chroma subsampling type. int write_error_code; int header_written = 0; int convert = 0; int stream = 0; enum PixelFormat convert_mode; const static char *legal_flags = "chI:F:A:S:o:s:f:"; int y; int frame_data_size ; uint8_t *yuv_data[3] ; y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; y4m_init_stream_info(&streaminfo); y4m_init_frame_info(&frameinfo); yuv_frame_rate.d = 0; yuv_aspect.d = 0; // Register all formats and codecs av_register_all(); while ((i = getopt (argc, argv, legal_flags)) != -1) { switch (i) { case 'I': switch (optarg[0]) { case 'p': yuv_interlacing = Y4M_ILACE_NONE; break; case 't': yuv_interlacing = Y4M_ILACE_TOP_FIRST; break; case 'b': yuv_interlacing = Y4M_ILACE_BOTTOM_FIRST; break; default: mjpeg_error("Unknown value for interlace: '%c'", optarg[0]); return -1; break; } break; case 'F': if( Y4M_OK != y4m_parse_ratio(&yuv_frame_rate, optarg) ) mjpeg_error_exit1 ("Syntax for frame rate should be Numerator:Denominator"); break; case 'A': if( Y4M_OK != y4m_parse_ratio(&yuv_aspect, optarg) ) { if (!strcmp(optarg,PAL)) { y4m_parse_ratio(&yuv_aspect, "128:117"); } else if (!strcmp(optarg,PAL_WIDE)) { y4m_parse_ratio(&yuv_aspect, "640:351"); } else if (!strcmp(optarg,NTSC)) { y4m_parse_ratio(&yuv_aspect, "4320:4739"); } else if (!strcmp(optarg,NTSC_WIDE)) { y4m_parse_ratio(&yuv_aspect, "5760:4739"); } else { mjpeg_error_exit1 ("Syntax for aspect ratio should be Numerator:Denominator"); } } break; case 'S': yuv_ss_mode = y4m_chroma_parse_keyword(optarg); if (yuv_ss_mode == Y4M_UNKNOWN) { mjpeg_error("Unknown subsampling mode option: %s", optarg); mjpeg_error("Try: 420mpeg2 444 422 411"); return -1; } break; case 'o': fdOut = open (optarg,O_CREAT|O_WRONLY,0644); if (fdOut == -1) { mjpeg_error_exit1 ("Cannot open file for writing"); } break; case 'c': convert = 1; break; case 's': stream = atoi(optarg); break; case 'f': avif = av_find_input_format (optarg); break; case 'h': case '?': print_usage (argv); return 0 ; break; } } //fprintf (stderr,"optind: %d\n",optind); optind--; argc -= optind; argv += optind; if (argc == 1) { print_usage (argv); return 0 ; } // Open video file if(av_open_input_file(&pFormatCtx, argv[1], avif, 0, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error dump_format(pFormatCtx, 0, argv[1], 0); // Find the first video stream videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) { // mark debug //fprintf (stderr,"Video Codec ID: %d (%s)\n",pFormatCtx->streams[i]->codec->codec_id ,pFormatCtx->streams[i]->codec->codec_name); if (videoStream == -1 && stream == 0) { // May still be overridden by the -s option videoStream=i; } if (stream == i) { videoStream=i; break; } } if(videoStream==-1) return -1; // Didn't find a video stream // Get a pointer to the codec context for the video stream pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) return -1; // Codec not found // Open codec if(avcodec_open(pCodecCtx, pCodec)<0) return -1; // Could not open codec // Read framerate, aspect ratio and chroma subsampling from Codec if (yuv_frame_rate.d == 0) { yuv_frame_rate.n = pFormatCtx->streams[videoStream]->r_frame_rate.num; yuv_frame_rate.d = pFormatCtx->streams[videoStream]->r_frame_rate.den; } if (yuv_aspect.d == 0) { yuv_aspect.n = pCodecCtx-> sample_aspect_ratio.num; yuv_aspect.d = pCodecCtx-> sample_aspect_ratio.den; } // 0:0 is an invalid aspect ratio default to 1:1 if (yuv_aspect.d == 0 || yuv_aspect.n == 0 ) { yuv_aspect.n=1; yuv_aspect.d=1; } if (convert) { if (yuv_ss_mode == Y4M_UNKNOWN) { print_usage(); return 0; } else { y4m_accept_extensions(1); switch (yuv_ss_mode) { case Y4M_CHROMA_420MPEG2: convert_mode = PIX_FMT_YUV420P; break; case Y4M_CHROMA_422: convert_mode = PIX_FMT_YUV422P; break; case Y4M_CHROMA_444: convert_mode = PIX_FMT_YUV444P; break; case Y4M_CHROMA_411: convert_mode = PIX_FMT_YUV411P; break; case Y4M_CHROMA_420JPEG: convert_mode = PIX_FMT_YUVJ420P; break; default: mjpeg_error_exit1("Cannot convert to this chroma mode"); break; } } } else if (yuv_ss_mode == Y4M_UNKNOWN) { switch (pCodecCtx->pix_fmt) { case PIX_FMT_YUV420P: yuv_ss_mode=Y4M_CHROMA_420MPEG2; break; case PIX_FMT_YUV422P: yuv_ss_mode=Y4M_CHROMA_422; break; case PIX_FMT_YUV444P: yuv_ss_mode=Y4M_CHROMA_444; break; case PIX_FMT_YUV411P: yuv_ss_mode=Y4M_CHROMA_411; break; case PIX_FMT_YUVJ420P: yuv_ss_mode=Y4M_CHROMA_420JPEG; break; default: yuv_ss_mode=Y4M_CHROMA_444; convert_mode = PIX_FMT_YUV444P; // is there a warning function mjpeg_error("Unsupported Chroma mode. Upsampling to YUV444\n"); // enable advanced yuv stream y4m_accept_extensions(1); convert = 1; break; } } // Allocate video frame pFrame=avcodec_alloc_frame(); // Output YUV format details // is there some mjpeg_info functions? fprintf (stderr,"YUV Aspect Ratio: %d:%d\n",yuv_aspect.n,yuv_aspect.d); fprintf (stderr,"YUV frame rate: %d:%d\n",yuv_frame_rate.n,yuv_frame_rate.d); fprintf (stderr,"YUV Chroma Subsampling: %d\n",yuv_ss_mode); // Set the YUV stream details // Interlace is handled when the first frame is read. y4m_si_set_sampleaspect(&streaminfo, yuv_aspect); y4m_si_set_framerate(&streaminfo, yuv_frame_rate); y4m_si_set_chroma(&streaminfo, yuv_ss_mode); // Loop until nothing read while(av_read_frame(pFormatCtx, &packet)>=0) { // Is this a packet from the video stream? if(packet.stream_index==videoStream) { // Decode video frame avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); // Did we get a video frame? if(frameFinished) { // Save the frame to disk // As we don't know interlacing until the first frame // we wait until the first frame is read before setting the interlace flag // and outputting the YUV header // It also appears that some codecs don't set width or height until the first frame either if (!header_written) { if (yuv_interlacing == Y4M_UNKNOWN) { if (pFrame->interlaced_frame) { if (pFrame->top_field_first) { yuv_interlacing = Y4M_ILACE_TOP_FIRST; } else { yuv_interlacing = Y4M_ILACE_BOTTOM_FIRST; } } else { yuv_interlacing = Y4M_ILACE_NONE; } } if (convert) { // initialise conversion to different chroma subsampling pFrame444=avcodec_alloc_frame(); numBytes=avpicture_get_size(convert_mode, pCodecCtx->width, pCodecCtx->height); buffer=(uint8_t *)malloc(numBytes); avpicture_fill((AVPicture *)pFrame444, buffer, convert_mode, pCodecCtx->width, pCodecCtx->height); } y4m_si_set_interlace(&streaminfo, yuv_interlacing); y4m_si_set_width(&streaminfo, pCodecCtx->width); y4m_si_set_height(&streaminfo, pCodecCtx->height); chromalloc(yuv_data,&streaminfo); fprintf (stderr,"YUV interlace: %d\n",yuv_interlacing); fprintf (stderr,"YUV Output Resolution: %dx%d\n",pCodecCtx->width, pCodecCtx->height); if ((write_error_code = y4m_write_stream_header(fdOut, &streaminfo)) != Y4M_OK) { mjpeg_error("Write header failed: %s", y4m_strerr(write_error_code)); } header_written = 1; } if (convert) { // convert to 444 /* +#ifdef HAVE_LIBSWSCALE + struct SwsContext* img_convert_ctx = + sws_getContext(context->width, context->height, PIX_FMT_RGB24, + context->width, context->height, context->pix_fmt, + SWS_BICUBIC, NULL, NULL, NULL); + + sws_scale(img_convert_ctx, pict->data, pict->linesize, + 0, context->height, encodable->data, + encodable->linesize); + + sws_freeContext (img_convert_ctx); +#else img_convert((AVPicture *)encodable, context->pix_fmt, (AVPicture *)pict, PIX_FMT_RGB24, context->width, context->height); - + (AVPicture *)pict, PIX_FMT_RGB24, + context->width, context->height); +#endif */ struct SwsContext* img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrame444->data, pFrame444->linesize); sws_freeContext (img_convert_ctx); //img_convert((AVPicture *)pFrame444, convert_mode, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); chromacpy(yuv_data,pFrame444,&streaminfo); } else { chromacpy(yuv_data,pFrame,&streaminfo); } write_error_code = y4m_write_frame( fdOut, &streaminfo, &frameinfo, yuv_data); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } y4m_fini_stream_info(&streaminfo); y4m_fini_frame_info(&frameinfo); free(yuv_data[0]); free(yuv_data[1]); free(yuv_data[2]); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); return 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); } }
static int yw_open_video(YWPrivateData *pd, vob_t *vob) { int errnum = Y4M_OK; int ch_mode = 0; /* initialize stream-information */ y4m_accept_extensions(1); y4m_init_stream_info(&pd->streaminfo); y4m_init_frame_info(&pd->frameinfo); if (vob->im_v_codec == TC_CODEC_YUV420P) { pd->dstfmt = IMG_YUV_DEFAULT; } else if (vob->im_v_codec == TC_CODEC_RGB24) { pd->dstfmt = IMG_RGB_DEFAULT; } else { tc_log_error(MOD_NAME, "unsupported video format %d", vob->im_v_codec); return(TC_EXPORT_ERROR); } /* we trust autoprobing */ pd->width = vob->im_v_width; pd->height = vob->im_v_height; pd->fd_vid = open(vob->video_in_file, O_RDONLY); if (pd->fd_vid == -1) { tc_log_error(MOD_NAME, "can't open video source '%s'" " (reason: %s)", vob->video_in_file, strerror(errno)); } else { if (verbose >= TC_DEBUG) { tc_log_info(MOD_NAME, "using video source: %s", vob->video_in_file); } } pd->tcvhandle = tcv_init(); if (!pd->tcvhandle) { tc_log_error(MOD_NAME, "image conversion init failed"); return(TC_EXPORT_ERROR); } errnum = y4m_read_stream_header(pd->fd_vid, &pd->streaminfo); if (errnum != Y4M_OK) { tc_log_error(MOD_NAME, "Couldn't read YUV4MPEG header: %s!", y4m_strerr(errnum)); tcv_free(pd->tcvhandle); close(pd->fd_vid); return(TC_IMPORT_ERROR); } if (y4m_si_get_plane_count(&pd->streaminfo) != 3) { tc_log_error(MOD_NAME, "Only 3-plane formats supported"); close(pd->fd_vid); return(TC_IMPORT_ERROR); } ch_mode = y4m_si_get_chroma(&pd->streaminfo); if (ch_mode != Y4M_CHROMA_420JPEG && ch_mode != Y4M_CHROMA_420MPEG2 && ch_mode != Y4M_CHROMA_420PALDV) { tc_log_error(MOD_NAME, "sorry, chroma mode `%s' (%i) not supported", y4m_chroma_description(ch_mode), ch_mode); tcv_free(pd->tcvhandle); close(pd->fd_vid); return(TC_IMPORT_ERROR); } if (verbose) { tc_log_info(MOD_NAME, "chroma mode: %s", y4m_chroma_description(ch_mode)); } return(TC_IMPORT_OK); }
static int tc_y4m_open_video(Y4MPrivateData *pd, const char *filename, vob_t *vob) { int asr, ret; y4m_ratio_t framerate; y4m_ratio_t asr_rate; /* avoid fd loss in case of failed configuration */ if (pd->fd_vid == -1) { pd->fd_vid = open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (pd->fd_vid == -1) { tc_log_error(MOD_NAME, "failed to open video stream file '%s'" " (reason: %s)", filename, strerror(errno)); return TC_ERROR; } } y4m_init_stream_info(&(pd->streaminfo)); //note: this is the real framerate of the raw stream framerate = (vob->ex_frc == 0) ?mpeg_conform_framerate(vob->ex_fps) :mpeg_framerate(vob->ex_frc); if (framerate.n == 0 && framerate.d == 0) { framerate.n = vob->ex_fps * 1000; framerate.d = 1000; } asr = (vob->ex_asr < 0) ?vob->im_asr :vob->ex_asr; tc_asr_code_to_ratio(asr, &asr_rate.n, &asr_rate.d); y4m_init_stream_info(&(pd->streaminfo)); y4m_si_set_framerate(&(pd->streaminfo), framerate); if (vob->encode_fields == TC_ENCODE_FIELDS_TOP_FIRST) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_TOP_FIRST); } else if (vob->encode_fields == TC_ENCODE_FIELDS_BOTTOM_FIRST) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_BOTTOM_FIRST); } else if (vob->encode_fields == TC_ENCODE_FIELDS_PROGRESSIVE) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_NONE); } /* XXX */ y4m_si_set_sampleaspect(&(pd->streaminfo), y4m_guess_sar(pd->width, pd->height, asr_rate)); y4m_si_set_height(&(pd->streaminfo), pd->height); y4m_si_set_width(&(pd->streaminfo), pd->width); /* Y4M_CHROMA_420JPEG 4:2:0, H/V centered, for JPEG/MPEG-1 */ /* Y4M_CHROMA_420MPEG2 4:2:0, H cosited, for MPEG-2 */ /* Y4M_CHROMA_420PALDV 4:2:0, alternating Cb/Cr, for PAL-DV */ y4m_si_set_chroma(&(pd->streaminfo), Y4M_CHROMA_420JPEG); // XXX ret = y4m_write_stream_header(pd->fd_vid, &(pd->streaminfo)); if (ret != Y4M_OK) { tc_log_warn(MOD_NAME, "failed to write video YUV4MPEG2 header: %s", y4m_strerr(ret)); return TC_ERROR; } return TC_OK; }
// ************************************************************************************* // MAIN // ************************************************************************************* int main (int argc, char *argv[]) { int verbose = 1 ; // LOG_ERROR ? int drop_frames = 0; int fdIn = 0 ; int fdOut = 1 ; y4m_stream_info_t in_streaminfo,out_streaminfo; int src_interlacing = Y4M_UNKNOWN; y4m_ratio_t src_frame_rate; const static char *legal_flags = "v:m:s:n"; int max_shift = 0, search = 0; int noshift=0; int c; while ((c = getopt (argc, argv, legal_flags)) != -1) { switch (c) { case 'v': verbose = atoi (optarg); if (verbose < 0 || verbose > 2) mjpeg_error_exit1 ("Verbose level must be [0..2]"); break; case 'm': max_shift = atof(optarg); break; case 's': search = atof(optarg); break; case 'n': noshift=1; break; case '?': print_usage (argv); return 0 ; break; } } // mjpeg tools global initialisations mjpeg_default_handler_verbosity (verbose); // Initialize input streams y4m_init_stream_info (&in_streaminfo); y4m_init_stream_info (&out_streaminfo); // *************************************************************** // Get video stream informations (size, framerate, interlacing, aspect ratio). // The streaminfo structure is filled in // *************************************************************** // INPUT comes from stdin, we check for a correct file header if (y4m_read_stream_header (fdIn, &in_streaminfo) != Y4M_OK) mjpeg_error_exit1 ("Could'nt read YUV4MPEG header!"); src_frame_rate = y4m_si_get_framerate( &in_streaminfo ); y4m_copy_stream_info( &out_streaminfo, &in_streaminfo ); // Information output /* in that function we do all the important work */ if (!noshift) y4m_write_stream_header(fdOut,&out_streaminfo); process( fdIn,&in_streaminfo,fdOut,&out_streaminfo,max_shift,search,noshift); y4m_fini_stream_info (&in_streaminfo); y4m_fini_stream_info (&out_streaminfo); return 0; }
// ************************************************************************************* // MAIN // ************************************************************************************* int main (int argc, char *argv[]) { int verbose = 4; // LOG_ERROR ; int fdIn = 0 ; int fdOut = 1 ; y4m_stream_info_t in_streaminfo,out_streaminfo; const static char *legal_flags = "d:m:V:"; int c, *matrix,matlen; float divisor=0; while ((c = getopt (argc, argv, legal_flags)) != -1) { switch (c) { case 'V': verbose = atoi (optarg); if (verbose < 0 || verbose > 2) mjpeg_error_exit1 ("Verbose level must be [0..2]"); break; case 'd': divisor = atof(optarg); if (divisor == 0) { mjpeg_error_exit1 ("Divisor must not be 0"); } break; case 'm': // strlen should be longer than the matrix = (int *) malloc (sizeof(int) * strlen(optarg)); matlen = parse_matrix(optarg,matrix); if (matlen == 0) { mjpeg_error_exit1 ("Invalid matrix"); } break; case '?': print_usage (argv); return 0 ; break; } } if (divisor == 0) { divisor = sum_matrix(matrix,matlen); } if (divisor == 0) { mjpeg_warn("divisor defaulting to 1\n"); divisor = 1; } // mjpeg tools global initialisations mjpeg_default_handler_verbosity (verbose); // Initialize input streams y4m_init_stream_info (&in_streaminfo); y4m_init_stream_info (&out_streaminfo); // *************************************************************** // Get video stream informations (size, framerate, interlacing, aspect ratio). // The streaminfo structure is filled in // *************************************************************** // INPUT comes from stdin, we check for a correct file header if (y4m_read_stream_header (fdIn, &in_streaminfo) != Y4M_OK) mjpeg_error_exit1 ("Could'nt read YUV4MPEG header!"); y4m_ratio_t src_frame_rate = y4m_si_get_framerate( &in_streaminfo ); y4m_copy_stream_info( &out_streaminfo, &in_streaminfo ); // Information output mjpeg_info ("yuvconvolve (version " YUVRFPS_VERSION ") performs a convolution matrix on yuv streams"); mjpeg_info ("yuvconvolve -? for help"); y4m_write_stream_header(fdOut,&out_streaminfo); /* in that function we do all the important work */ fprintf (stderr,"matrix square: %d\n",matlen); convolve( fdIn,&in_streaminfo,fdOut,&out_streaminfo,matrix,divisor,matlen); y4m_fini_stream_info (&in_streaminfo); y4m_fini_stream_info (&out_streaminfo); return 0; }
int main(int argc, char **argv) { int c, err, ilace; int fd_in = fileno(stdin), fd_out = fileno(stdout); y4m_ratio_t rate; y4m_stream_info_t si, so; y4m_frame_info_t fi; uint8_t *top1[3], *bot1[3], *top2[3], *bot2[3]; opterr = 0; while ((c = getopt(argc, argv, "h")) != EOF) { switch (c) { case 'h': case '?': default: usage(); } } y4m_accept_extensions(1); y4m_init_stream_info(&si); y4m_init_stream_info(&so); y4m_init_frame_info(&fi); err = y4m_read_stream_header(fd_in, &si); if (err != Y4M_OK) mjpeg_error_exit1("Input stream error: %s\n", y4m_strerr(err)); if (y4m_si_get_plane_count(&si) != 3) mjpeg_error_exit1("only 3 plane formats supported"); rate = y4m_si_get_framerate(&si); if (!Y4M_RATIO_EQL(rate, y4m_fps_NTSC)) mjpeg_error_exit1("input stream not NTSC 30000:1001"); ilace = y4m_si_get_interlace(&si); if (ilace != Y4M_ILACE_BOTTOM_FIRST && ilace != Y4M_ILACE_TOP_FIRST) mjpeg_error_exit1("input stream not interlaced"); top1[0] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,0) / 2); top1[1] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,1) / 2); top1[2] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,2) / 2); bot1[0] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,0) / 2); bot1[1] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,1) / 2); bot1[2] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,2) / 2); top2[0] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,0) / 2); top2[1] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,1) / 2); top2[2] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,2) / 2); bot2[0] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,0) / 2); bot2[1] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,1) / 2); bot2[2] = (uint8_t *) malloc(y4m_si_get_plane_length(&si,2) / 2); y4m_copy_stream_info(&so, &si); y4m_si_set_framerate(&so, y4m_fps_NTSC_FILM); y4m_si_set_interlace(&so, Y4M_ILACE_NONE); /* * At this point the input stream has been verified to be interlaced NTSC, * the output stream rate set to NTSC_FILM, interlacing tag changed to * progressive, and the field buffers allocated. * * Time to write the output stream header and commence processing input. */ y4m_write_stream_header(fd_out, &so); while (1) { err = y4m_read_fields(fd_in, &si, &fi, top1, bot1); if (err != Y4M_OK) goto done; y4m_write_fields(fd_out, &so, &fi, top1, bot1); /* A */ err = y4m_read_fields(fd_in, &si, &fi, top1, bot1); if (err != Y4M_OK) goto done; y4m_write_fields(fd_out, &so, &fi, top1, bot1); /* B */ err = y4m_read_fields(fd_in, &si, &fi, top1, bot1); if (err != Y4M_OK) goto done; err = y4m_read_fields(fd_in, &si, &fi, top2, bot2); if (err != Y4M_OK) { /* * End of input when reading the 2nd "mixed field" frame (C+D). The previous * frame was the first "mixed field" frame (B+C). Rather than emit a mixed * interlaced frame duplicate a field and output the previous frame. */ if (ilace == Y4M_ILACE_BOTTOM_FIRST) y4m_write_fields(fd_out, &so, &fi, bot1,bot1); else y4m_write_fields(fd_out, &so, &fi, top1,top1); goto done; } /* * Now the key part of the processing - effectively discarding the first mixed * frame with fields from frames B + C and creating the C frame from the two * mixed frames. For a BOTTOM FIELD FIRST stream use the 'top' field from * frame 3 and the 'bottom' fields from frame 4. With a TOP FIELD FIRST stream * it's the other way around - use the 'bottom' field from frame 3 and the * 'top' field from frame 4. */ if (ilace == Y4M_ILACE_BOTTOM_FIRST) y4m_write_fields(fd_out, &so, &fi, top1, bot2); /* C */ else y4m_write_fields(fd_out, &so, &fi, top2, bot1); /* C */ err = y4m_read_fields(fd_in, &si, &fi, top1, bot1); y4m_write_fields(fd_out, &so, &fi, top1, bot1); /* D */ } done: y4m_fini_frame_info(&fi); y4m_fini_stream_info(&si); y4m_fini_stream_info(&so); exit(0); }
int main(int argc, char **argv) { int sts, c, width = 640, height = 480, noheader = 0; int Y = 16, U = 128, V = 128, chroma_mode = Y4M_CHROMA_420MPEG2; int numframes = 1, force = 0; y4m_ratio_t rate_ratio = y4m_fps_NTSC; y4m_ratio_t aspect_ratio = y4m_sar_SQUARE; int plane_length[3]; u_char *yuv[3]; y4m_stream_info_t ostream; y4m_frame_info_t oframe; char interlace = Y4M_ILACE_NONE; opterr = 0; y4m_accept_extensions(1); while ((c = getopt(argc, argv, "Hfx:w:h:r:i:a:Y:U:V:n:")) != EOF) { switch (c) { case 'H': noheader = 1; break; case 'a': sts = y4m_parse_ratio(&aspect_ratio, optarg); if (sts != Y4M_OK) mjpeg_error_exit1("Invalid aspect: %s", optarg); break; case 'w': width = atoi(optarg); break; case 'h': height = atoi(optarg); break; case 'r': sts = y4m_parse_ratio(&rate_ratio, optarg); if (sts != Y4M_OK) mjpeg_error_exit1("Invalid rate: %s", optarg); break; case 'Y': Y = atoi(optarg); break; case 'U': U = atoi(optarg); break; case 'V': V = atoi(optarg); break; case 'i': switch (optarg[0]) { case 'p': interlace = Y4M_ILACE_NONE; break; case 't': interlace = Y4M_ILACE_TOP_FIRST; break; case 'b': interlace = Y4M_ILACE_BOTTOM_FIRST; break; default: usage(); } break; case 'x': chroma_mode = y4m_chroma_parse_keyword(optarg); if (chroma_mode == Y4M_UNKNOWN) { if (strcmp(optarg, "help") != 0) mjpeg_error("Invalid -x arg '%s'", optarg); chroma_usage(); } break; case 'f': force = 1; break; case 'n': numframes = atoi(optarg); break; case '?': default: usage(); } } if (width <= 0) mjpeg_error_exit1("Invalid Width: %d", width); if (height <= 0) mjpeg_error_exit1("Invalid Height: %d", height); if (!force && (Y < 16 || Y > 235)) mjpeg_error_exit1("16 < Y < 235"); if (!force && (U < 16 || U > 240)) mjpeg_error_exit1("16 < U < 240"); if (!force && (V < 16 || V > 240)) mjpeg_error_exit1("16 < V < 240"); y4m_init_stream_info(&ostream); y4m_init_frame_info(&oframe); y4m_si_set_width(&ostream, width); y4m_si_set_height(&ostream, height); y4m_si_set_interlace(&ostream, interlace); y4m_si_set_framerate(&ostream, rate_ratio); y4m_si_set_sampleaspect(&ostream, aspect_ratio); y4m_si_set_chroma(&ostream, chroma_mode); if (y4m_si_get_plane_count(&ostream) != 3) mjpeg_error_exit1("Only the 3 plane formats supported"); plane_length[0] = y4m_si_get_plane_length(&ostream, 0); plane_length[1] = y4m_si_get_plane_length(&ostream, 1); plane_length[2] = y4m_si_get_plane_length(&ostream, 2); yuv[0] = malloc(plane_length[0]); yuv[1] = malloc(plane_length[1]); yuv[2] = malloc(plane_length[2]); /* * Now fill the array once with black but use the provided Y, U and V values */ memset(yuv[0], Y, plane_length[0]); memset(yuv[1], U, plane_length[1]); memset(yuv[2], V, plane_length[2]); if (noheader == 0) y4m_write_stream_header(fileno(stdout), &ostream); while (numframes--) y4m_write_frame(fileno(stdout), &ostream, &oframe, yuv); free(yuv[0]); free(yuv[1]); free(yuv[2]); y4m_fini_stream_info(&ostream); y4m_fini_frame_info(&oframe); exit(0); }
static int generate_YUV4MPEG(parameters_t *param) { uint32_t frame; //size_t pngsize; char pngname[FILENAME_MAX]; uint8_t *yuv[3]; /* buffer for Y/U/V planes of decoded PNG */ y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; if ((param->width % 2) == 0) param->new_width = param->width; else { param->new_width = ((param->width >> 1) + 1) << 1; printf("Setting new, even image width %d", param->new_width); } mjpeg_info("Now generating YUV4MPEG stream."); y4m_init_stream_info(&streaminfo); y4m_init_frame_info(&frameinfo); y4m_si_set_width(&streaminfo, param->new_width); y4m_si_set_height(&streaminfo, param->height); y4m_si_set_interlace(&streaminfo, param->interlace); y4m_si_set_framerate(&streaminfo, param->framerate); y4m_si_set_chroma(&streaminfo, param->ss_mode); yuv[0] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[0][0])); yuv[1] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[1][0])); yuv[2] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[2][0])); y4m_write_stream_header(STDOUT_FILENO, &streaminfo); for (frame = param->begin; (frame < param->numframes + param->begin) || (param->numframes == -1); frame++) { // if (frame < 25) // else //snprintf(pngname, sizeof(pngname), param->pngformatstr, frame - 25); snprintf(pngname, sizeof(pngname), param->pngformatstr, frame); raw0 = yuv[0]; raw1 = yuv[1]; raw2 = yuv[2]; if (decode_png(pngname, 1, param) == -1) { mjpeg_info("Read from '%s' failed: %s", pngname, strerror(errno)); if (param->numframes == -1) { mjpeg_info("No more frames. Stopping."); break; /* we are done; leave 'while' loop */ } else { mjpeg_info("Rewriting latest frame instead."); } } else { #if 0 mjpeg_debug("Preparing frame"); /* Now open this PNG file, and examine its header to retrieve the YUV4MPEG info that shall be written */ if ((param->interlace == Y4M_ILACE_NONE) || (param->interleave == 1)) { mjpeg_info("Processing non-interlaced/interleaved %s.", pngname, pngsize); decode_png(imagedata, 0, 420, yuv[0], yuv[1], yuv[2], param->width, param->height, param->new_width); #if 0 if (param->make_z_alpha) { mjpeg_info("Writing Z/Alpha data.\n"); za_write(real_z_imagemap, param->width, param->height,z_alpha_fp,frame); } #endif } else { mjpeg_error_exit1("Can't handle interlaced PNG information (yet) since there is no standard for it.\n" "Use interleaved mode (-L option) to create interlaced material."); switch (param->interlace) { case Y4M_ILACE_TOP_FIRST: mjpeg_info("Processing interlaced, top-first %s", pngname); #if 0 decode_jpeg_raw(jpegdata, jpegsize, Y4M_ILACE_TOP_FIRST, 420, param->width, param->height, yuv[0], yuv[1], yuv[2]); #endif break; case Y4M_ILACE_BOTTOM_FIRST: mjpeg_info("Processing interlaced, bottom-first %s", pngname); #if 0 decode_jpeg_raw(jpegdata, jpegsize, Y4M_ILACE_BOTTOM_FIRST, 420, param->width, param->height, yuv[0], yuv[1], yuv[2]); #endif break; default: mjpeg_error_exit1("FATAL logic error?!?"); break; } } #endif mjpeg_debug("Converting frame to YUV format."); /* Transform colorspace, then subsample (in place) */ convert_RGB_to_YCbCr(yuv, param->height * param->new_width); chroma_subsample(param->ss_mode, yuv, param->new_width, param->height); mjpeg_debug("Frame decoded, now writing to output stream."); } mjpeg_debug("Frame decoded, now writing to output stream."); y4m_write_frame(STDOUT_FILENO, &streaminfo, &frameinfo, yuv); } #if 0 if (param->make_z_alpha) { za_write_end(z_alpha_fp); fclose(z_alpha_fp); } #endif y4m_fini_stream_info(&streaminfo); y4m_fini_frame_info(&frameinfo); free(yuv[0]); free(yuv[1]); free(yuv[2]); return 0; }
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); }
static void read_streaminfo(demuxer_t *demuxer) { y4m_priv_t *priv = demuxer->priv; sh_video_t *sh = demuxer->video->sh; y4m_ratio_t ratio; int err; if (priv->is_older) { char buf[4]; int frame_rate_code; stream_skip(demuxer->stream, 8); /* YUV4MPEG */ stream_skip(demuxer->stream, 1); /* space */ stream_read(demuxer->stream, (char *)&buf[0], 3); buf[3] = 0; sh->disp_w = atoi(buf); stream_skip(demuxer->stream, 1); /* space */ stream_read(demuxer->stream, (char *)&buf[0], 3); buf[3] = 0; sh->disp_h = atoi(buf); stream_skip(demuxer->stream, 1); /* space */ stream_read(demuxer->stream, (char *)&buf[0], 1); buf[1] = 0; frame_rate_code = atoi(buf); stream_skip(demuxer->stream, 1); /* new-line */ if (!sh->fps) { /* values from xawtv */ switch(frame_rate_code) { case 1: sh->fps = 23.976f; break; case 2: sh->fps = 24.0f; break; case 3: sh->fps = 25.0f; break; case 4: sh->fps = 29.97f; break; case 5: sh->fps = 30.0f; break; case 6: sh->fps = 50.0f; break; case 7: sh->fps = 59.94f; break; case 8: sh->fps = 60.0f; break; default: sh->fps = 25.0f; } } sh->frametime = 1.0f/sh->fps; } else { y4m_init_stream_info(priv->si); if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK) mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err)); if(!sh->fps) { ratio = y4m_si_get_framerate(priv->si); if (ratio.d != 0) sh->fps=(float)ratio.n/(float)ratio.d; else sh->fps=15.0f; } sh->frametime=1.0f/sh->fps; ratio = y4m_si_get_sampleaspect(priv->si); sh->disp_w = y4m_si_get_width(priv->si); sh->disp_h = y4m_si_get_height(priv->si); if (ratio.d != 0 && ratio.n != 0) sh->aspect = (float)(sh->disp_w*ratio.n)/(float)(sh->disp_h*ratio.d); demuxer->seekable = 0; } sh->format = mmioFOURCC('Y', 'V', '1', '2'); sh->bih->biSize=40; sh->bih->biWidth = sh->disp_w; sh->bih->biHeight = sh->disp_h; sh->bih->biPlanes=3; sh->bih->biBitCount=12; sh->bih->biCompression=sh->format; sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3/2; /* YV12 */ mp_msg(MSGT_DEMUX, MSGL_INFO, "YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n", demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth, sh->bih->biHeight); }
// ************************************************************************************* // MAIN // ************************************************************************************* int main (int argc, char *argv[]) { int verbose = 4; // LOG_ERROR ; int fdIn = 0 ; int fdOut = 1 ; y4m_stream_info_t in_streaminfo ; int c ; const static char *legal_flags = "q:f:hv:"; char *format_string = NULL; char *default_format_string = "frame%03d.jpg"; int qual = 95; while ((c = getopt (argc, argv, legal_flags)) != -1) { switch (c) { case 'v': verbose = atoi (optarg); if (verbose < 0 || verbose > 2) mjpeg_error_exit1 ("Verbose level must be [0..2]"); break; case 'q': qual=atoi(optarg); if (qual < 0 || qual > 100) mjpeg_error_exit1 ("Quality must be [0..100]"); break; case 'f': format_string=malloc(strlen(optarg)+1); strcpy(format_string,optarg); break; case 'h': case '?': print_usage (argv); return 0 ; break; } } if (format_string == NULL) { format_string=malloc(strlen(default_format_string)+1); strcpy(format_string,default_format_string); } // mjpeg tools global initialisations mjpeg_default_handler_verbosity (verbose); // Initialize input streams y4m_init_stream_info (&in_streaminfo); // *************************************************************** // Get video stream informations (size, framerate, interlacing, aspect ratio). // The streaminfo structure is filled in // *************************************************************** // INPUT comes from stdin, we check for a correct file header if (y4m_read_stream_header (fdIn, &in_streaminfo) != Y4M_OK) mjpeg_error_exit1 ("Could'nt read YUV4MPEG header!"); // Information output mjpeg_info ("yuv (version " VERSION ") is a tool for converting yuv streams into jpeg files."); mjpeg_info ("(C) Mark Heath <mjpeg0 at silicontrip.org>"); /* in that function we do all the important work */ filter(fdIn, &in_streaminfo,qual,format_string); free(format_string); 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); }
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 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) { cl_info_t cl; y4m_stream_info_t sinfo; y4m_frame_info_t finfo; uint8_t *buffers[Y4M_MAX_NUM_PLANES]; /* R'G'B' or Y'CbCr */ uint8_t *buffers2[Y4M_MAX_NUM_PLANES]; /* R'G'B' or Y'CbCr */ ppm_info_t ppm; int field_height; int fdout = 1; int err, i, count, repeating_last; y4m_accept_extensions(1); y4m_init_stream_info(&sinfo); y4m_init_frame_info(&finfo); parse_args(&cl, argc, argv); ppm.width = 0; ppm.height = 0; for (i = 0; i < 3; i++) { buffers[i] = NULL; buffers2[i] = NULL; } /* Read first PPM frame/field-pair, to get dimensions */ if (read_ppm_frame(cl.fdin, &ppm, buffers, buffers2, cl.interlace, cl.interleave, cl.bgr)) mjpeg_error_exit1("Failed to read first frame."); /* Setup streaminfo and write output header */ setup_output_stream(fdout, &cl, &sinfo, &ppm, &field_height); /* Loop 'framecount' times, or possibly forever... */ for (count = 0, repeating_last = 0; (count < (cl.offset + cl.framecount)) || (cl.framecount == 0); count++) { if (repeating_last) goto WRITE_FRAME; /* Read PPM frame/field */ /* ...but skip reading very first frame, already read prior to loop */ if (count > 0) { err = read_ppm_frame(cl.fdin, &ppm, buffers, buffers2, cl.interlace, cl.interleave, cl.bgr); if (err == 1) { /* clean input EOF */ if (cl.repeatlast) { repeating_last = 1; goto WRITE_FRAME; } else if (cl.framecount != 0) { mjpeg_error_exit1("Input frame shortfall (only %d converted).", count - cl.offset); } else { break; /* input is exhausted; we are done! time to go home! */ } } else if (err) mjpeg_error_exit1("Error reading ppm frame"); } /* ...skip transforms if we are just going to skip this frame anyway. BUT, if 'cl.repeatlast' is on, we must process/buffer every frame, because we don't know when we will see the last one. */ if ((count >= cl.offset) || (cl.repeatlast)) { /* Transform colorspace, then subsample (in place) */ convert_RGB_to_YCbCr(buffers, ppm.width * field_height); chroma_subsample(cl.ss_mode, buffers, ppm.width, field_height); if (cl.interlace != Y4M_ILACE_NONE) { convert_RGB_to_YCbCr(buffers2, ppm.width * field_height); chroma_subsample(cl.ss_mode, buffers2, ppm.width, field_height); } } WRITE_FRAME: /* Write converted frame to output */ if (count >= cl.offset) { switch (cl.interlace) { case Y4M_ILACE_NONE: if ((err = y4m_write_frame(fdout, &sinfo, &finfo, buffers)) != Y4M_OK) mjpeg_error_exit1("Write frame failed: %s", y4m_strerr(err)); break; case Y4M_ILACE_TOP_FIRST: if ((err = y4m_write_fields(fdout, &sinfo, &finfo, buffers, buffers2)) != Y4M_OK) mjpeg_error_exit1("Write fields failed: %s", y4m_strerr(err)); break; case Y4M_ILACE_BOTTOM_FIRST: if ((err = y4m_write_fields(fdout, &sinfo, &finfo, buffers2, buffers)) != Y4M_OK) mjpeg_error_exit1("Write fields failed: %s", y4m_strerr(err)); break; default: mjpeg_error_exit1("Unknown ilace type! %d", cl.interlace); break; } } } for (i = 0; i < 3; i++) { free(buffers[i]); free(buffers2[i]); } y4m_fini_stream_info(&sinfo); y4m_fini_frame_info(&finfo); mjpeg_debug("Done."); return 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 */ }