您的位置:首页 > 其它

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

2015-02-11 15:03 846 查看

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

很多人一直不知道怎么利用ffmpeg从AVFrame取出yuv数据到保存到char*中,下面代码将yuv420p和yuv422p的数据取出并保存到char*buf中。
其他格式可以自己去扩展,前提先看戏yuv的各种格式,yuv的各种格式链接:http://blog.csdn.net/zhuweigangzwg/article/details/17222535

//如果是视频
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(1,video_decode_size * 3 * 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 = 0 ; i < pstream_info->dec_ctx->height ; i++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
pDecodeFrame->data[0]+pDecodeFrame->linesize[0]*i,
pstream_info->dec_ctx->width);
}
for(j = 0 ; j < pstream_info->dec_ctx->height/2 ; j++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j,
pDecodeFrame->data[1]+pDecodeFrame->linesize[1]*j,
pstream_info->dec_ctx->width/2);
}
for(k  =0 ; k < pstream_info->dec_ctx->height/2 ; k++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j+pstream_info->dec_ctx->width/2*k,
pDecodeFrame->data[2]+pDecodeFrame->linesize[2]*k,
pstream_info->dec_ctx->width/2);
}
}
else if (pstream_info->dec_ctx->pix_fmt == AV_PIX_FMT_YUV422P)//如果是yuv422p的
{
for(i = 0 ; i < pstream_info->dec_ctx->height ; i++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
pDecodeFrame->data[0]+pDecodeFrame->linesize[0]*i,
pstream_info->dec_ctx->width);
}
for(j = 0 ; j < pstream_info->dec_ctx->height ; j++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j,
pDecodeFrame->data[1]+pDecodeFrame->linesize[1]*j,
pstream_info->dec_ctx->width/2);
}
for(k  =0 ; k < pstream_info->dec_ctx->height ; k++)
{
memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j+pstream_info->dec_ctx->width/2*k,
pDecodeFrame->data[2]+pDecodeFrame->linesize[2]*k,
pstream_info->dec_ctx->width/2);
}
}
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 = 0;
frame_info->timebase_den = 0;
frame_info->timebase_num = 0;
frame_info->bufsize = 0;
memset(frame_info->buf,0,MAX_FRAME_SIZE);
}
if (video_decode_buf)
{
free(video_decode_buf);
video_decode_buf = NULL;
}
video_decode_size = 0;
}


交流请加QQ群:62054820

QQ:379969650
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: