📄 yuvinactive.c
字号:
/**************************************************************************** * yuvinactive.c * Copyright (C) 2003 Bernhard Praschinger * * Sets a area in the yuv frame to black * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****************************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <sys/types.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <string.h>#include "yuv4mpeg.h"#define LUMA 16#define CHROMA 128/* some defintions *//* extern char *__progname; */struct area_s { int width; /**< width of the area */ int height; /**< height of the area */ int voffset; /**< vertical offset from the top left boarder */ int hoffset; /**< horizontal offest from the top left boarder */ };struct color_yuv { int luma; /**< the luma to use */ int chroma_b; /**< the chroma Cb to use */ int chroma_r; /**< the chroma Cr to use */ };int verbose = 1;/* protoypes */static void print_usage(char *progname);void copy_area(struct area_s , int , int , uint8_t *frame[], int );void process_commandline(int argc, char *argv[], struct area_s *inarea, int *darker, int *copy_pixel, struct color_yuv *coloryuv, int *average_pixel);void fillarea(char area[20], struct area_s *inarea);void set_darker(struct area_s inarea, int horz, int vert, uint8_t *frame[], int darker);void set_inactive(struct area_s inarea, int horz, int vert, uint8_t *frame[], struct color_yuv *coloryuv);void set_yuvcolor(char area[20], struct color_yuv *coloryuv);void average_area(struct area_s inarea, int horz, int vert, uint8_t *frame[], int average_pixel);void average_block(int go_h, int go_w, int horz, int plane, int *orig_offset, uint8_t *frame[]);/* Here we start the programm *//** The typical help output */static void print_usage(char *progname){ fprintf(stderr, "%s usage: -i XxY+XOFF+YOFF\n\n",progname); fprintf(stderr, " -h -H - print out this help\n"); fprintf(stderr, " -i X+Y+XOFF+YOFF - the area which will be set inactive, from top left\n"); fprintf(stderr, " - X=Width, Y=Height, XOFF=VerticalOffset, YOFF=HorizonalOffset\n"); fprintf(stderr, " -s luma,Cb,Cr - set the filling color in yuv format\n"); fprintf(stderr, " -d num [1-100] - set how much darker the area will be, in percent\n"); fprintf(stderr, " -c num - copy num sourrounding lines into the area\n"); fprintf(stderr, " -a num - use num pixles for on square to average the area\n"); fprintf(stderr, "\n"); exit(1);}/** Here we process the command line options */void process_commandline(int argc, char *argv[], struct area_s *inarea, int *darker, int *copy_pixel, struct color_yuv *coloryuv, int *average_pixel){int c;char area [20];while ((c = getopt(argc, argv, "Hhv:i:s:d:c:a:")) != -1) { switch (c) { case 'v': verbose = atoi(optarg); if ( verbose < 0 || verbose > 2) print_usage(argv[0]); if (verbose == 2) mjpeg_info("Set Verbose = %i", verbose); break; case 'i': strncpy(area, optarg, 20); /* This part shows how to process */ fillarea(area, inarea); /* command line options */ break; case 's': strncpy(area, optarg, 20); set_yuvcolor(area, coloryuv); break; case 'd': *darker = atoi(optarg); break; case 'c': *copy_pixel = atoi(optarg); break; case 'a': *average_pixel = atoi(optarg); break; case 'H': case 'h': print_usage(argv[0]); } }/* Checking if we have used the -i option */if ( ((*inarea).height == 0) && ((*inarea).width == 0) ) mjpeg_error_exit1("You have to use the -i option");/* Checking the range of the darker -d option */if ( (*darker < 0) || (*darker > 100) ) mjpeg_error_exit1("You can only make the area 1-100 percent darker");else mjpeg_info("Setting the area %i percent darker", *darker);/* Checking the copy pixel option */if (*copy_pixel != 0) { if ( ((*inarea).height/2) < *copy_pixel) { mjpeg_error("You can only copy half of the height into the area"); mjpeg_error_exit1("lower the copy pixel value below: %i ", ((*inarea).height/2)); } if ( (*copy_pixel % 2) != 0) mjpeg_error_exit1("you have to use a even number of lines to copy into the field"); if ( ((*inarea).height % *copy_pixel) != 0) mjpeg_error_exit1("the height has to be a multiply of the copy pixel value"); mjpeg_info("Number of rows using for coping into the area %i", *copy_pixel); }/* Checking the average pixel option */if (*average_pixel != 0) { if ( (*average_pixel > (*inarea).height) || (*average_pixel > (*inarea).width) ) mjpeg_error_exit1("The pixles used for the average must be less the the inactive area"); if ( (*average_pixel % 2) != 0) mjpeg_error_exit1("you have to use a even number for the average pixels"); mjpeg_info("Number of pixels used for averaging %i", *average_pixel); }} /** Here we set the color to use for filling the area */void set_yuvcolor(char area[20], struct color_yuv *coloryuv){int i;unsigned int u1, u2, u3; i = sscanf (area, "%i,%i,%i", &u1, &u2, &u3); if ( 3 == i ) { (*coloryuv).luma = u1; (*coloryuv).chroma_b = u2; (*coloryuv).chroma_r = u3; if ( ((*coloryuv).luma > 235) || ((*coloryuv).luma < 16) ) mjpeg_error_exit1("out of range value for luma given: %i, \n" " allowed values 16-235", (*coloryuv).luma); if ( ((*coloryuv).chroma_b > 240) || ((*coloryuv).chroma_b < 16) ) mjpeg_error_exit1("out of range value for Cb given: %i, \n" " allowed values 16-240", (*coloryuv).chroma_b); if ( ((*coloryuv).chroma_r > 240) || ((*coloryuv).chroma_r < 16) ) mjpeg_error_exit1("out of range value for Cr given: %i, \n" " allowed values 16-240", (*coloryuv).chroma_r); mjpeg_info("got luma %i, Cb %i, Cr %i ", (*coloryuv).luma, (*coloryuv).chroma_b, (*coloryuv).chroma_r ); } else mjpeg_error_exit1("Wrong number of colors given, %s", area);}/** Here we cut out the number of the area string */void fillarea(char area[20], struct area_s *inarea){int i;unsigned int u1, u2, u3, u4; /* Cuting out the numbers of the stream */ i = sscanf (area, "%ix%i+%i+%i", &u1, &u2, &u3, &u4); if ( 4 == i) /* Checking if we have got 4 numbers */ { (*inarea).width = u1; (*inarea).height = u2; (*inarea).hoffset = u3; (*inarea).voffset = u4; if ( (((*inarea).width % 2) != 0) || (((*inarea).height % 2) != 0) || (((*inarea).hoffset% 2)!= 0) || (((*inarea).voffset% 2) != 0) ) mjpeg_error_exit1("At least one argument no even number"); if (verbose >= 1) mjpeg_info("got the area : W %i, H %i, Xoff %i, Yoff %i", (*inarea).width,(*inarea).height,(*inarea).hoffset,(*inarea).voffset); } else mjpeg_error_exit1("Wrong inactive sting given: %s", area);}/** Here we copy the surrounding information into the area */void copy_area(struct area_s inarea, int horz, int vert, uint8_t *frame[], int copy_pixel){uint8_t *plane_l, *plane_cb, *plane_cr;unsigned char *temp_pix_l, *temp_pix_cb, *temp_pix_cr;int i,j, offset_pix, copy_offset_pix, chroma_lines;temp_pix_l = (unsigned char *)malloc(inarea.width);temp_pix_cb = (unsigned char *)malloc(inarea.width/2);temp_pix_cr = (unsigned char *)malloc(inarea.width/2);plane_l = frame[0];plane_cb = frame[1];plane_cr = frame[2];/* In the first step we copy the luma data*/offset_pix = (horz * inarea.voffset) + inarea.hoffset;i=0;while (i < (inarea.height/2)) /* copying lines from the top down */ { copy_offset_pix = (horz * (inarea.voffset - copy_pixel) + inarea.hoffset); for (j = 0; j < copy_pixel; j++) { memcpy(temp_pix_l, (plane_l+(copy_offset_pix+(j*horz))), inarea.width); memcpy((plane_l+offset_pix), temp_pix_l, inarea.width); offset_pix += horz;//mjpeg_info("copy_offset %i, offset %i von j %i, von i %i", copy_offset_pix, offset_pix, j ,i); } i += copy_pixel; /* we copy more lines in one step */ }while (i < inarea.height) /* copying lines from the bottom up */ { copy_offset_pix = (horz * (inarea.voffset + inarea.height) + inarea.hoffset); for (j = 0; j < copy_pixel; j++) { memcpy(temp_pix_l, (plane_l+copy_offset_pix+(j*horz)), inarea.width); memcpy((plane_l+offset_pix), temp_pix_l, inarea.width); offset_pix += horz;// mjpeg_info("wert von offset_pix %i, von j %i, von i %i", copy_offset_pix, j ,i); } i += copy_pixel; /* we copy more lines in one step */ }/* In the 2nd step we copy the chroma data */offset_pix = (horz * inarea.voffset)/4 + (inarea.hoffset/2);if ((inarea.height%4) != 0) chroma_lines = ((inarea.height/2 -1) /2);else chroma_lines = inarea.height /4;i=0;while ( i < chroma_lines) { copy_offset_pix = ((horz/2) * (inarea.voffset/2 + inarea.height/2) + inarea.hoffset/2); for (j = 0; j < (copy_pixel/2); j++) { memcpy(temp_pix_cb,(plane_cb+copy_offset_pix+(j*horz)),(inarea.width/2)); memcpy((plane_cb+offset_pix), temp_pix_cb, (inarea.width/2)); memcpy(temp_pix_cr,(plane_cr+copy_offset_pix+(j*horz)),(inarea.width/2)); memcpy((plane_cr+offset_pix), temp_pix_cr, (inarea.width/2)); offset_pix += (horz/2); } i += (copy_pixel/2); /* we copy more lines in one step */ }while ( i < (inarea.height/2)) { copy_offset_pix = ((horz/2) * (inarea.voffset/2 + inarea.height/2) + inarea.hoffset/2); for (j = 0; j < (copy_pixel/2); j++) { memcpy(temp_pix_cb,(plane_cb+copy_offset_pix+(j*horz)),(inarea.width/2)); memcpy((plane_cb+offset_pix), temp_pix_cb, (inarea.width/2)); memcpy(temp_pix_cr,(plane_cr+copy_offset_pix+(j*horz)),(inarea.width/2)); memcpy((plane_cr+offset_pix), temp_pix_cr, (inarea.width/2)); offset_pix += (horz/2); } i += (copy_pixel/2); /* we copy more lines in one step */ }free(temp_pix_l);temp_pix_l = NULL;free(temp_pix_cb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -