YUV420数据和字符信息如何利用滤镜方法进行编码?

YUV420数据和字符信息如何利用滤镜方法进行编码?
我希望用ffmpeg中的filter方法,把YUV420数据和字符信息一起编码,该怎么办呢?

本人目前只实现了把yuv420的数据进行h.264的编码了。

本人成功实现利用ffmpeg中的滤镜 filter功能,在码流中进行字符叠加,太不容易了!

本人使用的是ffmpeg 1.0.7的代码

部分代码如下:

//设定输出格式列表,支持PIX_FMT_YUV420P,PIX_FMT_GRAY8,PIX_FMT_RGB24
//enum FFmpegPixFmt::PixelFormat pix_fmts[] = {PIX_FMT_GRAY8, PIX_FMT_NONE };
//初始化滤镜所用的变量
static int init_filters(const char *filters_descr)
{
char args[512];
int ret;
AVFilter *buffersrc  = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("ffbuffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs  = avfilter_inout_alloc();
enum PixelFormat pix_fmts[] = {PIX_FMT_YUV420P, PIX_FMT_NONE };
AVBufferSinkParams *buffersink_params;

filter_graph = avfilter_graph_alloc();

/* buffer video source: the decoded frames from the decoder will be inserted here. */
_snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
dec_ctx->time_base.num, dec_ctx->time_base.den,
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);

ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",args, NULL, filter_graph);
if (ret < 0) 
{
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
return ret;
}

/* buffer video sink: to terminate the filter chain. */
buffersink_params = av_buffersink_params_alloc();
buffersink_params->pixel_fmts = pix_fmts;
ret = avfilter_graph_create_filter(&buffersink_ctx,buffersink,"out",NULL,buffersink_params, filter_graph);
av_free(buffersink_params);
if (ret < 0) 
{
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
return ret;
}

/* Endpoints for the filter graph. */
outputs->name       = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx    = 0;
outputs->next       = NULL;

inputs->name       = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx    = 0;
inputs->next       = NULL;

if ((ret = avfilter_graph_parse(filter_graph, filters_descr,&inputs, &outputs, NULL)) < 0)
return ret;

if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
return ret;
return 0;
}

char *outfilename = "D:\\out.yuv";
FILE *fp = fopen(outfilename, "a+b");  //所有视频帧都存在同一个文件
//fp = fopen(outfilename, "wb");//每次存一个文件

//滤镜描述字符串
const CHAR *filter_descr="drawtext=fontfile=simfont.ttf:fontcolor=white:shadowcolor=black:text=‘测试视频‘:x=10:y=10";

int ret=0;
AVPacket packet;
AVFrame m_frame;
int got_frame;

avcodec_register_all();
av_register_all();
avfilter_register_all();

if ((ret = open_input_file("input.h264")) < 0)
goto end;
if ((ret = init_filters(filter_descr)) < 0)
goto end;

/* read all packets */
while (1) 
{
AVFilterBufferRef *picref;
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
break;

if (packet.stream_index != video_stream_index) 
continue;

avcodec_get_frame_defaults(&m_frame);
got_frame = 0;
ret = avcodec_decode_video2(dec_ctx, &m_frame, &got_frame, &packet);
if (ret < 0) 
{
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
break;
}

if (got_frame) 
{
m_frame.pts = av_frame_get_best_effort_timestamp(&m_frame);

if (av_buffersrc_add_frame(buffersrc_ctx, &m_frame, 0) < 0)
{
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
break;
}

while (1) 
{
ret = av_buffersink_get_buffer_ref(buffersink_ctx, &picref, 0);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;

if (picref) 
{
fwrite(picref->data[0], 1, picref->buf->w * picref->buf->h * 3 / 2, fp);
fflush(fp);// fclose(fp); 
//display_picref(picref, buffersink_ctx->inputs[0]->time_base);
avfilter_unref_bufferp(&picref);
}
}
}

av_free_packet(&packet);
}
end:
avfilter_graph_free(&filter_graph);
if (dec_ctx)
avcodec_close(dec_ctx);

avformat_close_input(&fmt_ctx);

if (ret < 0 && ret != AVERROR_EOF) 
{
char buf[1024];
av_strerror(ret, buf, sizeof(buf));
fprintf(stderr, "Error occurred: %s\n", buf);
exit(1);
}

MessageBox("解码完成!");

http://bbs.csdn.net/topics/390498269

时间: 2024-10-07 18:40:54

YUV420数据和字符信息如何利用滤镜方法进行编码?的相关文章

(四) 一起学 APUE 之 系统数据文件和信息

. . . . . 目录 (一) 一起学 APUE 之 标准 IO (二) 一起学 APUE 之 文件 IO (三) 一起学 APUE 之 文件和目录 (四) 一起学 APUE 之 系统数据文件和信息 1.getpwnam(3).getpwuid(3) 1 getpwnam, getpwuid - get password file entry 2 3 #include <sys/types.h> 4 #include <pwd.h> 5 6 struct passwd *getp

Java集合-5. (List)已知有一个Worker 类如下: 完成下面的要求 1) 创建一个List,在List 中增加三个工人,基本信息如下: 姓名 年龄 工资 zhang3 18 3000 li4 25 3500 wang5 22 3200 2) 在li4 之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资3300 3) 删除wang5 的信息 4) 利用for 循

第六题 5. (List)已知有一个Worker 类如下: public class Worker { private int age; private String name; private double salary; public Worker (){} public Worker (String name, int age, double salary) { this.name = name; this.age = age; this.salary = salary; } public

APUE学习笔记:第六章 系统数据文件和信息

6.1 引言 UNIX系统的正常运行需要使用大量与系统有关的数据文件,针对这些数据文件的可移植接口是本章的主题.本章还介绍了系统标识函数.时间和日期函数 6.2 口令文件 UNIX系统的口令文件包含了下列各字段,这些字段包含在<pwd.h>中定义的passwd结构中 用户名 char *pw_name 加密口令 char *pw_passwd 数值用户ID uid_t pw_uid 数值组ID gid_t pw_gid 注释字段 char *pw_gecos 初始工作目录 char *pw_d

《UNIX环境高级编程》--6系统数据文件和信息

系统数据文件和信息 用户配置文件 1. /etc/passwd UNIX口令文件 /etc/passwd/是一个ASCII文件,每一行包含很多字段,字段之间用冒号分隔.这些字段包含在<pwd.h>头文件定义的passwd,该结构有如下成员: char *pw_name:用户名 char *pw_passwd:加密口令 uid_t pw_uid:数值用户ID gid_t pw_gid:数值组ID char *pw_gecos:注释字段 char *pw_dir:初始工作目录 char *pw_s

Unix环境高级编程学习笔记(三):标准I/O , 系统数据文件和信息

1 标准I/O函数不同于read,write函数,是其在流上进行操作, 当首次调用标准I/O函数时,系统会首先调用malloc,为流创造缓冲区, 2 fopen函数 #include<stdio.h> file * fopen(const char* pathname, const char * restrict name); 打开返回指针,出错返回NULL, type的取指有r(读),w(写),a(追加),r+/w+(读+写),a+(读+写+追加) int fclose(file* fp)

数据迁移至RDS-MySQL之利用RDS管理控制台

MySQL之利用RDS管理控制台数据迁移至RDS-MySQL之利用RDS管理控制台该方法是一种MySQL的在线迁移方法,可以不停服务就能够完成数据库的迁移工作,支持MySQL 5.1   5.5. 5.6(5.0版本只支持全量迁移)的迁移.更多迁移信息可参考:如何快速平稳的迁入RDS>>迁移注意事项1)MySQL的系统库将不允许迁移至RDS,不允许迁移的数据库包括:mysql,information_schema,perfermance_schema.这些数据库将不会显示在迁移列表中:2)不支

Node利用buffer操作,编码,解码二进制数据

Node利用buffer操作,编码,解码二进制数据 1.创建buffer 用utf-8编码的字符串来创建buffer: var buf = new Buffer('Hello World!'); 你也可以以其他编码的字符串来创建buffer,只要传入第二个传入,即编码类型 var buf = new Buffer('8b76fde713ce', 'base64'); 有三种编码方式可供选择:ascii/utf8/base64 如果你没有任何字符串传入来创建buffer的话,那么你必须要传入一个长

利用滤镜做一个太阳

这篇文章主要给大家讲解的是如何利用滤镜做一个太阳,只需要照着本教程操作一遍,你就可以做出一样的效果,想学的朋友一起来看看吧.

导入来自早期版本的 SQL Server 的本机格式数据和字符格式数据

导入来自早期版本的 SQL Server 的本机格式数据和字符格式数据 在 SQL Server 2014 中,您可以通过将 bcp 与 -V 开关一起使用,从 SQL Server 2000.SQL Server 2005.SQL Server 2008.SQL Server 2008 R2 或 SQL Server 2012 中导入本机和字符格式数据. -V 开关将使 SQL Server 2014 使用指定的 SQL Server 早期版本中的数据类型,并且数据文件格式与早期版本中的格式相