c语言实现给yuv文件添加帧序号
来源:互联网 发布:任子行网络公 编辑:程序博客网 时间:2024/06/03 22:47
这是我14年刚工作时候写的代码。当时领导提出给yuv文件加帧序号,我就实现了这么一个算法。后来其实也没怎么用过,但是实现的思路挺有意思的。无意中给翻出来了,挂到网上来,更新一下我许久都没有更新的博客。。。。
先看图
main函数
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#include "fun.h"int main(int argc, char *argv[]){ char InputVideoName[100]; char OutputVideoName[100]; int width; int height; int FrameNum; enum VideoFormat format = YUV444; enum NumColor color = BLACK; enum NumPosition position = LeftBottom; YuvVideoFrame yuv_video_frame; time_t start_time, end_time; FILE *ifp, *ofp; int y_pixel_num, u_pixel_num, v_pixel_num; struct NumColorInfo num_color_info; struct LineInfo line_info; int x, y; // 数字的位置坐标 if(argc != 9) { printf("Error!\n"); return -1; } strcpy(InputVideoName, argv[1]); strcpy(OutputVideoName, argv[2]); width = atoi(argv[3]); height = atoi(argv[4]); FrameNum = atoi(argv[5]); // 帧数 format = (enum VideoFormat)atoi(argv[6]); // 格式 0表示yuv444,1表示yuv420 planar, 2表示yuv422 planar color = (enum NumColor)atoi(argv[7]); // 字体颜色 0表示黑色,1表示白色,2表示红色,3表示绿色,4表示蓝色 position = (enum NumPosition)atoi(argv[8]); // 帧序号的位置 0表示左上角,1表示右上角,2表示左下角,3表示右下角 start_time = time(NULL); // 初始化帧 yuv_video_frame = (YuvVideoFrame)malloc(sizeof(struct YuvFrame)); if(NULL == yuv_video_frame) { printf("run out of memory\n"); exit(0); } InitializeFrame(width, height, format, yuv_video_frame); // 初始化颜色信息 InitializeNumColorInfo(color, num_color_info); // 初始化数字线条和起始位置信息 InitializeLineAndPositionInfo(width, height, position, line_info, x, y); // 打开输入输出文件 if((ifp = fopen(InputVideoName, "rb")) == NULL) { printf("cannot open %s\n", InputVideoName); return -1; } if((ofp = fopen(OutputVideoName, "ab")) == NULL) { printf("cannot open %s\n", OutputVideoName); return -1; } y_pixel_num = width * height; switch(yuv_video_frame->format) { case YUV444: u_pixel_num = y_pixel_num; v_pixel_num = y_pixel_num; break; case YUV420: u_pixel_num = y_pixel_num / 4; v_pixel_num = y_pixel_num / 4; break; case YUV422: u_pixel_num = y_pixel_num / 2; v_pixel_num = y_pixel_num / 2; break; default: break; } for(int frame_num = 0; frame_num < FrameNum; frame_num++) { fread(yuv_video_frame->y_component, sizeof(uchar), y_pixel_num, ifp); fread(yuv_video_frame->u_component, sizeof(uchar), u_pixel_num, ifp); fread(yuv_video_frame->v_component, sizeof(uchar), v_pixel_num, ifp); AddNumInYuvVideo(frame_num, x, y, line_info, num_color_info, yuv_video_frame); fwrite(yuv_video_frame->y_component, sizeof(uchar), y_pixel_num, ofp); fwrite(yuv_video_frame->u_component, sizeof(uchar), u_pixel_num, ofp); fwrite(yuv_video_frame->v_component, sizeof(uchar), v_pixel_num, ofp); } fclose(ifp); fclose(ofp); DisposeFrame(yuv_video_frame); end_time = time(NULL); //printf("\ntime = %d\n", end_time - start_time); return 0;}
头文件 fun.h
enum VideoFormat{YUV444, YUV420, YUV422}; // 视频格式enum NumColor{BLACK, WHITE, RED, GREEN, BLUE}; // 数字颜色enum NumPosition{LeftTop, RightTop, LeftBottom, RightBottom}; // 数字的位置typedef unsigned char uchar;typedef struct YuvFrame *YuvVideoFrame;#define MAX(a, b) ((a) > (b) ? (a) : (b))// YUV视频帧struct YuvFrame{ int width; // 视频帧宽 int height; // 视频帧高 enum VideoFormat format; // 视频的格式 uchar *y_component; // y分量 uchar *u_component; // u分量 uchar *v_component; // v分量};// 数字颜色信息struct NumColorInfo{ uchar y_value; uchar u_value; uchar v_value;};// 数字线条信息struct LineInfo{ int length; // 线条长 int width; // 线条宽};// 将字符串转换为数字int atoi(char *s);/****************************************************************************InitializeFrame: 初始化视频帧input: int width 视频帧的宽 int height 视频帧的高 enum VideoFormat format 视频的格式output: YuvVideoFrame yuv_video_framereturn:****************************************************************************/void InitializeFrame(int width, int height, enum VideoFormat format, YuvVideoFrame yuv_video_frame);/****************************************************************************DisposeFrame: 释放视频帧input: YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void DisposeFrame(YuvVideoFrame yuv_video_frame);/****************************************************************************AddLine: 在YUV视频帧上添加线条input: int x 位置坐标 int y int width 添加线条的宽 int height 添加线条的高 struct NumColorInfo num_color_info 数字的颜色 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddLine(int x, int y, int width, int height, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame);/****************************************************************************AddDigit: 在YUV视频上添加数字input: int digit 添加数字 int x 位置坐标 int y struct LineInfo info_line 数字线条信息 struct NumColorInfo num_color_info 数字颜色 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddDigit(int digit, int x, int y, struct LineInfo info_line, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame);/****************************************************************************AddNumInYuvVideo: 在YUV视频上添加帧序号input: int frame_num 帧序号 int x 数字起始位置坐标 int y struct LineInfo line_info 数字线条信息 struct NumColorInfo num_color_info 颜色信息 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddNumInYuvVideo(int frame_num, int x, int y, struct LineInfo line_info, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame);/****************************************************************************InitializeNumColorInfo: 初始化数字的颜色信息input: enum NumColor coloroutput: struct NumColorInfo &num_color_inforeturn:****************************************************************************/void InitializeNumColorInfo(enum NumColor color, struct NumColorInfo &num_color_info);/****************************************************************************InitializeLineAndPositionInfo: 初始化线条和位置信息input: int width 视频帧宽 int height 视频帧高 enum NumPosition positionoutput: struct LineInfo &line_info 线条信息 int &x 数字起始坐标 int &yreturn:****************************************************************************/void InitializeLineAndPositionInfo(int width, int height, enum NumPosition position, struct LineInfo &line_info, int &x, int &y);
调用的函数,文件fun.cpp
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "fun.h"// 将字符串转换为数字int atoi(char *s){ int sign; int n; while(*s == ' ') s++; sign = (*s == '-') ? -1 : 1; if('-' == *s || '+' == *s) s++; for(n = 0; isdigit(*s); s++) { n = n * 10 + (*s - '0'); } return n * sign;}/****************************************************************************InitializeFrame: 初始化视频帧input: int width 视频帧的宽 int height 视频帧的高 enum VideoFormat format 视频的格式output: YuvVideoFrame yuv_video_framereturn:****************************************************************************/void InitializeFrame(int width, int height, enum VideoFormat format, YuvVideoFrame yuv_video_frame){ int y_pixel_num, u_pixel_num, v_pixel_num; yuv_video_frame->width = width; yuv_video_frame->height = height; yuv_video_frame->format = format; y_pixel_num = width * height; switch(format) { case YUV444: u_pixel_num = width * height; v_pixel_num = width * height; break; case YUV420: u_pixel_num = width * height / 4; v_pixel_num = width * height / 4; break; case YUV422: u_pixel_num = width * height / 2; v_pixel_num = width * height / 2; break; default: break; } yuv_video_frame->y_component = (uchar *)malloc(y_pixel_num * sizeof(uchar)); if(NULL == yuv_video_frame->y_component) { printf("run out of memory\n"); exit(0); } yuv_video_frame->u_component = (uchar *)malloc(u_pixel_num * sizeof(uchar)); if(NULL == yuv_video_frame->u_component) { printf("run out of memory\n"); exit(0); } yuv_video_frame->v_component = (uchar *)malloc(v_pixel_num * sizeof(uchar)); if(NULL == yuv_video_frame->v_component) { printf("run out of memory\n"); exit(0); }}/****************************************************************************DisposeFrame: 释放视频帧input: YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void DisposeFrame(YuvVideoFrame yuv_video_frame){ free(yuv_video_frame->y_component); free(yuv_video_frame->u_component); free(yuv_video_frame->v_component); free(yuv_video_frame);}/****************************************************************************AddLine: 在YUV视频帧上添加线条input: int x 位置坐标 int y int width 添加线条的宽 int height 添加线条的高 struct NumColorInfo num_color_info 数字的颜色 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddLine(int x, int y, int width, int height, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame){ int i, j; if(YUV444 == yuv_video_frame->format) { for(i = 0; i < height; i++) { for(j = 0; j < width; j++) { *(yuv_video_frame->y_component + (y + i) * yuv_video_frame->width + (x + j)) = num_color_info.y_value; *(yuv_video_frame->u_component + (y + i) * yuv_video_frame->width + (x + j)) = num_color_info.u_value; *(yuv_video_frame->v_component + (y + i) * yuv_video_frame->width + (x + j)) = num_color_info.v_value; } } } if(YUV420 == yuv_video_frame->format) { for(i = 0; i < height; i++) { for(j = 0; j < width; j++) { *(yuv_video_frame->y_component + (y + i) * yuv_video_frame->width + (x + j)) = num_color_info.y_value; *(yuv_video_frame->u_component + (y + i) / 2 * yuv_video_frame->width / 2 + (x + j) / 2) = num_color_info.u_value; *(yuv_video_frame->v_component + (y + i) / 2 * yuv_video_frame->width / 2 + (x + j) / 2) = num_color_info.v_value; } } } if(YUV422 == yuv_video_frame->format) { for(i = 0; i < height; i++) { for(j = 0; j < width; j++) { *(yuv_video_frame->y_component + (y + i) * yuv_video_frame->width + (x + j)) = num_color_info.y_value; *(yuv_video_frame->u_component + (y + i) * yuv_video_frame->width / 2 + (x + j) / 2) = num_color_info.u_value; *(yuv_video_frame->v_component + (y + i) * yuv_video_frame->width / 2 + (x + j) / 2) = num_color_info.v_value; } } }}/****************************************************************************AddDigit: 在YUV视频上添加数字input: int digit 添加数字 int x 位置坐标 int y struct LineInfo info_line 数字线条信息 struct NumColorInfo num_color_info 数字颜色 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddDigit(int digit, int x, int y, struct LineInfo info_line, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame){ int line_width = info_line.width; int line_length = info_line.length; if(0 == digit || 4 == digit || 5 == digit || 6 == digit || 8 == digit || 9 == digit) { AddLine(x, y + line_width, line_width, line_length, num_color_info, yuv_video_frame); } if(0 == digit || 2 == digit || 6 == digit || 8 == digit) { AddLine(x, y + line_width * 2 + line_length, line_width, line_length, num_color_info, yuv_video_frame); } if(0 == digit || 1 == digit || 2 == digit || 3 == digit || 4 == digit || 7 == digit || 8 == digit || 9 == digit) { AddLine(x + line_width + line_length, y + line_width, line_width, line_length, num_color_info, yuv_video_frame); } if(0 == digit || 1 == digit || 3 == digit || 4 == digit || 5 == digit || 6 == digit || 7 == digit || 8 == digit || 9 == digit) { AddLine(x + line_width + line_length, y + line_width * 2 + line_length, line_width, line_length, num_color_info, yuv_video_frame); } if(0 == digit || 2 == digit || 3 == digit || 5 == digit || 6 == digit || 7 == digit || 8 == digit || 9 == digit) { AddLine(x + line_width, y, line_length, line_width, num_color_info, yuv_video_frame); } if(2 == digit || 3 == digit || 4 == digit || 5 == digit || 6 == digit || 8 == digit || 9 == digit) { AddLine(x + line_width, y + line_width + line_length, line_length, line_width, num_color_info, yuv_video_frame); } if(0 == digit || 2 == digit || 3 == digit || 5 == digit || 6 == digit || 8 == digit) { AddLine(x + line_width, y + line_width * 2 + line_length * 2, line_length, line_width, num_color_info, yuv_video_frame); }}/****************************************************************************AddNumInYuvVideo: 在YUV视频上添加帧序号input: int frame_num 帧序号 int x 数字起始位置坐标 int y struct LineInfo line_info 数字线条信息 struct NumColorInfo num_color_info 颜色信息 YuvVideoFrame yuv_video_frameoutput:return:****************************************************************************/void AddNumInYuvVideo(int frame_num, int x, int y, struct LineInfo line_info, struct NumColorInfo num_color_info, YuvVideoFrame yuv_video_frame){ int distance; int i; int digit; distance = line_info.width * 6 + line_info.length; i = 0; do{ digit = frame_num % 10; AddDigit(digit, x - i * distance, y, line_info, num_color_info, yuv_video_frame); i++; }while(frame_num /= 10);}/****************************************************************************InitializeNumColorInfo: 初始化数字的颜色信息input: enum NumColor coloroutput: struct NumColorInfo &num_color_inforeturn:****************************************************************************/void InitializeNumColorInfo(enum NumColor color, struct NumColorInfo &num_color_info){ switch(color) { case BLACK: // 黑色 num_color_info.y_value = 16; num_color_info.u_value = 128; num_color_info.v_value = 128; break; case WHITE: // 白色 num_color_info.y_value = 235; num_color_info.u_value = 128; num_color_info.v_value = 128; break; case RED: // 红色 num_color_info.y_value = 65; num_color_info.u_value = 100; num_color_info.v_value = 212; break; case GREEN: // 绿色 num_color_info.y_value = 112; num_color_info.u_value = 72; num_color_info.v_value = 58; break; case BLUE: // 蓝色 num_color_info.y_value = 35; num_color_info.u_value = 212; num_color_info.v_value = 114; break; default: // 其他情况黑色 num_color_info.y_value = 16; num_color_info.u_value = 128; num_color_info.v_value = 128; break; }}/****************************************************************************InitializeLineAndPositionInfo: 初始化线条和位置信息input: int width 视频帧宽 int height 视频帧高 enum NumPosition positionoutput: struct LineInfo &line_info 线条信息 int &x 数字起始坐标 int &yreturn:****************************************************************************/void InitializeLineAndPositionInfo(int width, int height, enum NumPosition position, struct LineInfo &line_info, int &x, int &y){ line_info.length = width / 100; // 线条的长度 line_info.width = MAX(width / 400, 1); // 线条的宽度 // 数字的起始位置 switch(position) { case LeftTop: // 左上角 x = line_info.width * 22 + line_info.length * 3; y = line_info.width * 4; break; case RightTop: // 右上角 x = width - line_info.width * 6 - line_info.length; y = line_info.width * 4; break; case LeftBottom: // 左下角 x = line_info.width * 22 + line_info.length * 3; y = height - line_info.width * 7 - line_info.length * 2; break; case RightBottom: // 右下角 x = width - line_info.width * 6 - line_info.length; y = height - line_info.width * 7 - line_info.length * 2; break; default: break; }}
0 0
- c语言实现给yuv文件添加帧序号
- 给repeater添加序号
- Python实现文件前添加序号
- 给datatable添加序号列
- 给重复文件追加序号
- ASP.NET(C#)--Repeater中生成“序号”列&&给Repeater控件里添加序号的5种方法
- 给DataGrid添加index序号,自动编号
- 给GridView添加行头序号并居中
- 利用js给li标签添加序号
- dataGridView1自动给行添加序号
- SQL 如何给各自分组添加序号
- 给ireport的报表添加序号
- 给mysql查询结果添加序号
- 给datattable中的每行数据添加序号
- 在Visual Studio中给C语言工程的exe文件添加图标和版本说明
- MySQL:给查询结果编号(添加ID,添加序号)
- 给查询出的SQL记录添加序号列 SQL添加序号列
- 实现DataGrid序号列的添加
- Scala 学习(六)--- 单机实现wordcount详细解读
- 三里人家微商发货系统开发
- 2017阿里算法实习生招聘HR面回顾
- 3种方法求乘法逆元
- 201403-2 窗口
- c语言实现给yuv文件添加帧序号
- opencv结合MFC进行人脸检测
- angularjS 入门级教程 第二讲
- 这是一个新的起点
- 第九单元
- 一键批量改文件名
- 【centos】文件过多情况处理 inodes占用100%
- 宋宝华:关于罪与欲望的深渊
- camel File 组件使用