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

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

你可能感兴趣的:(ffmpeg)