ffmpeg从AVFrame取出yuv数据到保存到char*中

 
很多人一直不知道怎么利用ffmpeg从AVFrame取出yuv数据到保存到char*中,下面代码将yuv420p和yuv422p的数据取出并保存到char*buf中。
其他格式可以自己去扩展,前提先看戏yuv的各种格式,yuv的各种格式链接:数据格式分析
 
先确保视频格式sws_getContext()转换后是YUV格式:
     out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));//分配AVFrame所需内存
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);//填充AVFrame img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
那么在后续的视频数据处理时,可以把YUV视频格式数据进行存储:
 //如果是视频
else if (pstream_info[i].dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
{
int new_videosize = pkt.size;
int video_decode_size = avpicture_get_size(pstream_info->dec_ctx->pix_fmt, Zoom_Width,Zoom_Height);
uint8_t * video_decode_buf =( uint8_t *)calloc(,video_decode_size * * sizeof(char)); //最大分配的空间,能满足yuv的各种格式 // Decode video frame
avcodec_decode_video2(pstream_info->dec_ctx, pDecodeFrame, &frameFinished,&pkt);
if(frameFinished)
{
if (pstream_info->dec_ctx->pix_fmt == AV_PIX_FMT_YUV420P) //如果是yuv420p的
{
for(i = ; i < pstream_info->dec_ctx->height; i++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*i,
pstream_info->dec_ctx->width);
}
for(j = ; j < pstream_info->dec_ctx->height/; j++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/*j,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*j,
pstream_info->dec_ctx->width/);
}
for(k =; k < pstream_info->dec_ctx->height/; k++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/*j+pstream_info->dec_ctx->width/*k,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*k,
pstream_info->dec_ctx->width/);
}
}
else if (pstream_info->dec_ctx->pix_fmt == AV_PIX_FMT_YUV422P)//如果是yuv422p的
{
for(i = ; i < pstream_info->dec_ctx->height; i++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*i,
pstream_info->dec_ctx->width);
}
for(j = ; j < pstream_info->dec_ctx->height; j++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/*j,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*j,
pstream_info->dec_ctx->width/);
}
for(k =; k < pstream_info->dec_ctx->height; k++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/*j+pstream_info->dec_ctx->width/*k,
pDecodeFrame->data[]+pDecodeFrame->linesize[]*k,
pstream_info->dec_ctx->width/);
}
}
else
{
//可扩展
}
video_decode_size = avpicture_get_size(pstream_info->dec_ctx->pix_fmt, pstream_info->dec_ctx->width,pstream_info->dec_ctx->height);
new_videosize = video_decode_size; //缩放或格式转换
if (pstream_info->dec_ctx->width != Zoom_Width ||
pstream_info->dec_ctx->height != Zoom_Height ||
pstream_info->dec_ctx->pix_fmt != Zoom_pix_fmt)
{
new_videosize = VideoScaleYuvZoom(Is_flip,pstream_info->dec_ctx->width ,pstream_info->dec_ctx->height,(int)pstream_info->dec_ctx->pix_fmt,
Zoom_Width,Zoom_Height,Zoom_pix_fmt,video_decode_buf);
}
//这里可以取出数据
frame_info->stream_idx = pstream_info->stream_idx;
//frame_info->pts = pDecodeFrame->pkt_pts * 1000 * av_q2d(pstream_info->stream->time_base); //转化成毫秒
frame_info->pts = pDecodeFrame->pkt_pts;
frame_info->timebase_den = pstream_info->stream->time_base.den;
frame_info->timebase_num = pstream_info->stream->time_base.num;
frame_info->bufsize = new_videosize;
memcpy(frame_info->buf,video_decode_buf,new_videosize);
}
else
{
//缓存
frame_info->stream_idx = pstream_info->stream_idx;
frame_info->pts = ;
frame_info->timebase_den = ;
frame_info->timebase_num = ;
frame_info->bufsize = ;
memset(frame_info->buf,,MAX_FRAME_SIZE);
}
if (video_decode_buf)
{
free(video_decode_buf);
video_decode_buf = NULL;
}
video_decode_size = ;
}

也可以把YUV数据进行存储为PPM格式(Linux系统下的图片格式):

 //如果是视频
else if (pstream_info[i].dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
{
// Decode video frame
avcodec_decode_video2(pstream_info->dec_ctx, pDecodeFrame, &frameFinished,&pkt);
if(frameFinished)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, , pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
if((++k<=) && (k%==)) {
SaveFrame(pFrameYUV, pCodecCtx->width, pCodecCtx->height, k);
}
}
} void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[];
int y; SDL_Log("%d * %d", width, height);
// Open file
sprintf(szFilename, "frame/frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return; // Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height); // Write pixel data
for(y=; y<height; y++) {
fwrite(pFrame->data[]+y*pFrame->linesize[], , width*, pFile);
} // Close file
fclose(pFile);
}

ffmpeg从AVFrame取出yuv数据到保存到char*中的更多相关文章

  1. python 数据如何保存到excel中--xlwt

    第一步:下载xlwt 首先要下载xlwt,(前提是你已经安装好了Python) 下载地址:  https://pypi.python.org/pypi/xlwt/   下载第二个   第二步:安装xl ...

  2. (转) 从ffmpeg中提取出YUV数据

    有时需要从ffmpeg中提取出YUV数据用作预览,另存什么的. ffmpeg是先解码成YUV, 再以这个YUV作为输入进行编码,所以YUV数据有两种:  解码后的YUV数据, 以及  编码重建的YUV ...

  3. 1.scrapy爬取的数据保存到es中

    先建立es的mapping,也就是建立在es中建立一个空的Index,代码如下:执行后就会在es建lagou 这个index.     from datetime import datetime fr ...

  4. c# 抓取和解析网页,并将table数据保存到datatable中(其他格式也可以,自己去修改)

    使用HtmlAgilityPack 基础请参考这篇博客:https://www.cnblogs.com/fishyues/p/10232822.html 下面是根据抓取的页面string 来解析并保存 ...

  5. Redis使用场景一,查询出的数据保存到Redis中,下次查询的时候直接从Redis中拿到数据。不用和数据库进行交互。

    maven使用: <!--redis jar包--> <dependency> <groupId>redis.clients</groupId> < ...

  6. Android把图片保存到SQLite中

    1.bitmap保存到SQLite 中 数据格式:Blob db.execSQL("Create table " + TABLE_NAME + "( _id INTEGE ...

  7. 【redis,1】java操作redis: 将string、list、map、自己定义的对象保存到redis中

    一.操作string .list .map 对象 1.引入jar: jedis-2.1.0.jar   2.代码 /**      * @param args      */     public s ...

  8. 将数字n转换为字符串并保存到s中

    将数字n转换为字符串并保存到s中 参考 C程序设计语言 #include <stdio.h> #include <string.h> //reverse函数: 倒置字符串s中各 ...

  9. Flask实战第43天:把图片验证码和短信验证码保存到memcached中

    前面我们已经获取到图片验证码和短信验证码,但是我们还没有把它们保存起来.同样的,我们和之前的邮箱验证码一样,保存到memcached中 编辑commom.vews.py .. from utils i ...

随机推荐

  1. 远程出发jenkins jobs

    wget -O - -q "http://jenkins_server/job/ttt/buildWithParameters?TEST1=Value" wget -O - -q ...

  2. ASP.NET 大文件上传

    一 web.config 配置: 1). <system.webServer> <security> <requestFiltering> <!-- maxA ...

  3. web前端开发工程师,你了解吗?

    web前端开发工程师可以说是一个全新的职业,在IT整个行业中真正受到重视的时间没有超过5年,也正因为这样,大家越来越想了解web前端工程师的前景究竟怎么样?web前端培训就业前景如何?web前端工程师 ...

  4. iOS小技巧3

    将颜色合成图片 将颜色合成图片 +(UIImage *)imageWithColor:(UIColor *)color { CGRect rect = CGRectMake(0.0f, 0.0f, 1 ...

  5. Windows平台配置免安装的MySQL

    1.下载 官网下载免安装文件(本文使用的是mysql-5.6.33-win32.zip)解压到E:\MySQL\mysql-5.6.33打开E:\MySQL\mysql-5.6.33\my-defau ...

  6. 下载pdf_不同操作系统,无法正常下载(兼容性问题)

    [功能点]:下载pdf文件 [问题描述]:window上传附件,linux无法下载 [根本原因]:window中路径分割符为"\",linux中路径分割符为"/" ...

  7. KinderEditor编辑器使用

    KinderEditor编辑器的使用 分为简单的三步.1:添加引用部分 <script src="/KinderEditor/kindeditor-min.js">&l ...

  8. bootstrap入门-2.固定的内置样式

    HTML5文档类型(Doctype) Bootstrap使用了一些HTML5元素和CSS属性,所以需要使用HTML5文档类型. <!DOCTYPE html> <html> . ...

  9. 三维高斯模型 opencv实现

    OnProbabilityModel() { int i; for(int x=0;x<workImg->height;x++) { for(int y=0;y<workImg-&g ...

  10. 关于jvm的相关知识

    一.堆内存和栈内存 1.jvm中的栈内存主要存储的是基本类型的变量和对象的引用 2.jvm中的堆内存主要存储的是用new来创建的对象和数组,可变长字符串(StringBuilder和StringBuf ...