/*
编译命令:arm-linux-gcc -o show2642 264showyuv2.c -I/usr/local/ffmpeg_arm/include/   -L/usr/local/ffmpeg_arm/lib/ -lswresample -lavformat -lavutil -lavcodec -lswscale -lx264   libSDL.a
*/
#include "stdio.h"
#include "stdlib.h"#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswresample/swresample.h"
#include "libavutil/opt.h"
#include "libavutil/channel_layout.h"
#include "libavutil/parseutils.h"
#include "libavutil/samplefmt.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
#include "libavutil/imgutils.h"
#include "libavutil/timestamp.h"
#include "libavutil/bprint.h"
#include "libavutil/time.h"
#include "libavutil/threadmessage.h"
#include "/usr/local/ffmpeg_arm/include/SDL/SDL.h"#include "libavfilter/avcodec.h"
#include "libavcodec/avcodec.h"#if HAVE_SYS_RESOURCE_H
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#elif HAVE_GETPROCESSTIMES
#include <windows.h>
#endif
#if HAVE_GETPROCESSMEMORYINFO
#include <windows.h>
#include <psapi.h>
#endif#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif#if HAVE_TERMIOS_H
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <termios.h>
#elif HAVE_KBHIT
#include <conio.h>
#endif#if HAVE_PTHREADS
#include <pthread.h>
#endif#include <time.h>#include "libavutil/avassert.h"#define MAX_LEN  1024 * 50此方法參考官网的样例
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,FILE *f)
{//  FILE *f;int i;// f = fopen(filename,"w");// fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);for (i = 0; i < ysize; i++)fwrite(buf + i * wrap, 1, xsize, f);//  fclose(f);
}int main()
{//以下初始化h264解码库//avcodec_init();int w = 720;int h = 576,retu;SDL_Rect rect;av_register_all();AVFrame *pFrame_ = NULL;/* find the video encoder */AVCodec *videoCodec = avcodec_find_decoder(CODEC_ID_H264);//得到264的解码器类if(!videoCodec){printf("avcodec_find_decoder error\n");return -1;}AVCodecParserContext *avParserContext = av_parser_init(CODEC_ID_H264);//得到解析帧类。主要用于后面的帧头查找if(!avParserContext){printf("av_parser_init  error\n");return -1;}AVCodecContext *codec_ = avcodec_alloc_context3(videoCodec);//解码会话层if(!codec_){printf("avcodec_alloc_context3  error\n");return -1;}//初始化參数,以下的參数应该由详细的业务决定codec_->time_base.num = 1;codec_->frame_number = 1; //每包一个视频帧codec_->codec_type = AVMEDIA_TYPE_VIDEO;codec_->bit_rate = 0;codec_->time_base.den = 25;//帧率codec_->width = 720;//视频宽codec_->height = 576;//视频高if(avcodec_open2(codec_, videoCodec, NULL) >= 0)//打开解码器{pFrame_ = avcodec_alloc_frame();// Allocate video frame    成功打开解码器后, 此时能够分配帧内存, 当然你也能够在后面每次都分配、释放, 在此我省功夫, 仅仅在開始分配一次if (!pFrame_) {fprintf(stderr, "Could not allocate video frame\n");exit(1);}}else{printf("avcodec_open2 error\n");return -1;}AVPacket packet = {0};int dwBufsize = 10;int frameFinished = dwBufsize;//这个是随便填入数字,没什么作用av_init_packet(&packet);packet.data = NULL;//这里填入一个指向完整H264数据帧的指针packet.size = 0;//这个填入H264数据帧的大小FILE *myH264 = fopen("1.264", "rb");//解码的文件264if(myH264 == NULL){perror("cant open 264 file\n");return -1;}FILE *yuvfile = fopen("my264.yuv", "wb");//成功解码后保存成的YUV文件, 能够用YUV工具打开浏览if(yuvfile == NULL){perror("cant open YUV file\n");return -1;}int readFileLen = 1;char readBuf[MAX_LEN];unsigned char *parseBuf = malloc(20*MAX_LEN);//这个地方浪费了我一个下午时间, 当时我用的是栈内存。即unsigned char parseBuf[20*MAX_LEN]。 结果执行程序一直报错, 此处须要用堆内存才干正常解码int  parseBufLen = 0;int frameCount = 0;printf("begin...\n");printf("readBuf address  is %x\n", readBuf);
/SDL initSDL_Surface* hello = NULL;SDL_Surface* screen = NULL;//Start SDL// SDL_Init( SDL_INIT_EVERYTHING );SDL_Init(SDL_INIT_VIDEO);//Set up screenscreen = SDL_SetVideoMode( 1024, 768, 32, SDL_SWSURFACE );SDL_Overlay* overlay = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, screen);SDL_LockSurface(screen);SDL_LockYUVOverlay(overlay);
//while(readFileLen > 0)//開始解码工作{//printf("begin...\n");readFileLen = fread(readBuf, 1, sizeof(readBuf), myH264);//首先从文件中读出数据if(readFileLen <= 0){printf("read over\n");break;}else{int handleLen = 0;int handleFileLen = readFileLen;while(handleFileLen > 0){int nLength = av_parser_parse2(avParserContext, codec_, &parseBuf, &parseBufLen, readBuf + handleLen, handleFileLen, 0, 0, 0);//查找264帧头handleFileLen -= nLength;handleLen += nLength;if(parseBufLen <= 0)//当parseBufLen大于0时,说明查找到了帧头{continue;}packet.size = parseBufLen;//将查找到的帧长度送入packet.data = parseBuf;//将查找到的帧内存送入if(frameCount>100)break;//printf("parseBuf address is %x\n", parseBuf);while(packet.size > 0){//以下開始真正的解码int decodeLen = avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);if(decodeLen < 0)break;packet.size -= decodeLen;packet.data += decodeLen;if(frameFinished > 0)//成功解码{int picSize = codec_->height * codec_->width;//int newSize = picSize * 1.5;//申请内存//unsigned char *buf = malloc(newSize);int height = pFrame_->height;int width = pFrame_->width;//printf("OK, get data\n");//printf("Frame height is %d\n", height);//printf("Frame width is %d\n", width);frameCount ++;printf("Frame count is %d\n", frameCount);pgm_save(pFrame_->data[0], pFrame_->linesize[0],//保存Ycodec_->width, codec_->height, yuvfile);pgm_save(pFrame_->data[1], pFrame_->linesize[1],//保存Ucodec_->width/2, codec_->height/2, yuvfile);pgm_save(pFrame_->data[2], pFrame_->linesize[2],//保存Vcodec_->width/2, codec_->height/2, yuvfile);///有了YUV数据。 后面能够用FFMPEG提供的转换方法。将其转成RGB数据,进行兴许的显示或其他的图像处理工作sdlint i;for(i=0;i<576;i++){//fwrite(buf + i * wrap, 1, xsize, f);memcpy(overlay->pixels[0]+i*720, pFrame_->data[0]+i*pFrame_->linesize[0], 720);                               }for(i=0;i<288;i++){memcpy(overlay->pixels[2]+i*360, pFrame_->data[1]+i*pFrame_->linesize[1], 360);memcpy(overlay->pixels[1]+i*360, pFrame_->data[2]+i*pFrame_->linesize[2], 360);                                                                      }SDL_UnlockYUVOverlay(overlay);SDL_UnlockSurface(screen);rect.w = w;rect.h = h;rect.x = rect.y = 0;SDL_DisplayYUVOverlay(overlay, &rect);//sdl//SDL_Delay(40);}elseprintf("failed to decodec\n");}}}}//释放工作avcodec_close(codec_);av_free(codec_);av_free_packet(&packet);av_frame_free(&pFrame_);//SDLSDL_FreeYUVOverlay(overlay);SDL_FreeSurface(screen);//Quit SDLSDL_Quit();fclose(yuvfile);fclose(myH264);}

嵌入式linux------ffmpeg移植 解码H264(am335x解码H264到yuv420并通过SDL显示)相关推荐

  1. 嵌入式Linux小项目之图片编解码播放器学习导读

      首先欢迎大家阅读本篇文章,在这里我将会为大家简要介绍一下图片编解码播放器系列文章的学习路线.   该小项目共有七篇文章,分别为<嵌入式Linux小项目之图片编解码播放器(1-7)>,这 ...

  2. 嵌入式linux rtsp移植,嵌入式网络收音机的ARM实现 - ARM - 电子发烧友网

    3 系统的的软件设计 3.1 嵌入式Linux的移植 嵌入式Linux内核的版本很多,一般情况下版本越高,系统越稳定,驱动更完善,本系统选择了2.6.18的Linux内核.其实对于2.6以后版本的Li ...

  3. 嵌入式linux系统移植的四大步骤_嵌入式系统移植步骤

    在嵌入式系统移植中重要的一部分是操作系统的移植,与其它操作系统相比,Linux大的特点:它是一款遵循GPL的操作系统,我们可以自由地使用.修改.和扩展它.正是由于这一特色,嵌入式系统移植过程中Linu ...

  4. linux 挂iscisc存储,基于arm的嵌入式linux操作系统的移植研究-通信与信息系统专业论文.docx...

    基于arm的嵌入式linux操作系统的移植研究-通信与信息系统专业论文 Classified Index: TP316.8 U.D.C: 621.38 Dissertation for the Mas ...

  5. 嵌入式linux操作系统的移植 实验报告,嵌入式linux系统移植试题

    [A] 内核不支持当前处理器 [B] 内核不支持当前开发平台 [C ] 内核获取不到bootloader传递来的参数 [D ] 内核初始化终端出现错误 18. 内核启动过程中,如果终端出现" ...

  6. 嵌入式Linux系统移植的四大步骤

    最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的命 ...

  7. 深度实践嵌入式linux系,深度实践嵌入式Linux系统移植 完整pdf_操作系统教程_源雷技术空间...

    资源名称:深度实践嵌入式Linux系统移植 完整pdf 第1章嵌入式系统架构与移植环境搭建2 第2章u-boot工程与编译系统14 第3章u-boot启动流程分析41 第4章ARM9/S3C2440 ...

  8. 嵌入式Linux系统移植的四大步骤(详细长文,慎入!)

    关注.星标公众号,直达精彩内容 来源:网路素材 最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们 ...

  9. 外网访问arm嵌入式linux系统_嵌入式Linux系统移植的四大步骤

    最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的命 ...

  10. 深度实践嵌入式linux系统移植 光盘下载地址

    深度实践嵌入式Linux系统移植这本书,翻了翻,感觉挺好,但要获得这本书的配套光盘文件真不容易, 书的序言部分给了一个支持站点 ,但是打不开.另外一种方式就是在以在华章网站下载.但是华章网站需要注册才 ...

最新文章

  1. 关于js中的this
  2. 2019 神策春招 | “数”天下神人,都“据”于此
  3. 【CSS3】table的css属性
  4. 【读书笔记】2015年考研英语二真题翻译(帮你克服艰难之路的真理+熟路效应)
  5. adb shell——Android虚拟机调试必须知道的命令
  6. Java字符串找出4个字节长度的字符
  7. 作者:邓景文(1982-),女,中国联合网络通信集团有限公司电子商务部工程师...
  8. 二级java编写用户界面例题,单选题11—20:2012年计算机二级VB用户界面设计练习题及答案-计算机二级-233网校...
  9. 转 文件路径相关的字符串操作
  10. 三次元的世界里,机械臂的手活儿也无敌了
  11. 从Linux程序中执行shell(程序、脚本)并获得输出结果(转)
  12. MySQL 入门(六)—— 索引
  13. scare机器人如何手眼标定_SCARA机器人手眼标定之目标抓取
  14. 自己做的商城系统流程图,分享给大家.
  15. 计算机怎么硬盘重做系统,怎么直接从硬盘装系统 直接从硬盘安装系统教程
  16. 计算机与信息技术基础读书笔记,信息技术读书笔记3篇
  17. Nginx代理静态页面
  18. 【docker-gpu】报错:W: GPG error:xxx, InRelease: The following signatures couldn‘t be verified because th
  19. 词霸天下---词根214【-mand- = -mend- 命 令】
  20. Destroying assets is not permitted to avoid data loss.解决思路

热门文章

  1. 反编译android的apk
  2. Sa身份登陆SQL SERVER失败的解决方案
  3. Docker 修改运行中的容器端口映射
  4. Windows PE变形练手2-开发一套自己的PE嵌入模板
  5. hdu 5059 判断数字表示方式以及范围合法(int型之内)
  6. 【Android FFMPEG 开发】OpenSLES 播放音频 ( 创建引擎 | 输出混音设置 | 配置输入输出 | 创建播放器 | 获取播放/队列接口 | 回调函数 | 开始播放 | 激活回调 )
  7. 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件
  8. 【Android 应用开发】Android中的回调Callback
  9. python3.6+RF连接mysql
  10. 通过sort()方法实现升序和降序排列