FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale

本文介绍了FFMPEG中的swscale如何用于视频原始数据(如YUV420,YUV422,YUV444,RGB24等)之间的转换和分辨率变换。通过初始化设置及sws_getContext()函数调整目标格式,可以实现不同格式的转换。此外,还讨论了planar和packed两种存储方式的区别,以及如何根据数据格式正确写入文件。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

FFMPEG中的swscale提供了视频原始数据(YUV420,YUV422,YUV444,RGB24...)之间的转换,分辨率变换等操作,使用起来十分方便,在这里记录一下它的用法。

swscale主要用于在2个AVFrame之间进行转换。
下面来看一个视频解码的简单例子,这个程序完成了对"北京移动开发者大会茶歇视频2.flv"(其实就是优酷上的一个普通视频)的解码工作,并将解码后的数据保存为原始数据文件(例如YUV420,YUV422,RGB24等等)。其中略去了很多的代码。

//ffmpeg simple player////媒资检索系统子系统////2013 雷霄骅 leixiaohua1020@126.com//中国传媒大学/数字电视技术//#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){ AVFormatContext *pFormatCtx; int    i, videoindex; AVCodecContext *pCodecCtx; AVCodec   *pCodec; char filepath[]="北京移动开发者大会茶歇视频2.flv"; av_register_all(); avformat_network_init(); pFormatCtx = avformat_alloc_context(); if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){  printf("无法打开文件\n");  return -1; }  ......   AVFrame *pFrame,*pFrameYUV;  pFrame=avcodec_alloc_frame();  pFrameYUV=avcodec_alloc_frame();  uint8_t *out_buffer;  out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height)];  avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);/*  out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)];  avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);*//*  out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_UYVY422, pCodecCtx->width, pCodecCtx->height)];  avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_UYVY422, pCodecCtx->width, pCodecCtx->height);  out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_YUV422P, pCodecCtx->width, pCodecCtx->height)];  avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV422P, pCodecCtx->width, pCodecCtx->height);*/    ......    FILE *output=fopen("out.rgb","wb+");  //------------------------------  while(av_read_frame(pFormatCtx, packet)>=0)  {   if(packet->stream_index==videoindex)   {    ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);        if(ret < 0)    {     printf("解码错误\n");     return -1;    }    if(got_picture)    {     /*img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_UYVY422, SWS_BICUBIC, NULL, NULL, NULL);      sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);     img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV422P, SWS_BICUBIC, NULL, NULL, NULL);      sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);*/     //转换     img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);      sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);               //RGB     fwrite(pFrameYUV->data[0],(pCodecCtx->width)*(pCodecCtx->height)*3,1,output);     /*     //UYVY     fwrite(pFrameYUV->data[0],(pCodecCtx->width)*(pCodecCtx->height),2,output);     //YUV420P     fwrite(pFrameYUV->data[0],(pCodecCtx->width)*(pCodecCtx->height),1,output);     fwrite(pFrameYUV->data[1],(pCodecCtx->width)*(pCodecCtx->height)/4,1,output);     fwrite(pFrameYUV->data[2],(pCodecCtx->width)*(pCodecCtx->height)/4,1,output);     */     ......    }   }   av_free_packet(packet);  }  fclose(output);  ......  return 0;}

从代码中可以看出
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值