linux之x86裁剪移植---ffmpeg的H264解碼顯示(420、422)

在虛擬機上yuv420可以正常顯示 ,而945(D525)模塊上卻無法顯示 ,后來驗證了directdraw的yuv420也無法顯示 ,由此懷疑顯卡不支持 ,后把420轉換為422顯示。

420顯示如下:

/*
編譯命令: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.agcc -o test test.c -I/usr/local/ffmpeg/include/   -L/usr/local/ffmpeg/lib/ -lswresample -lavformat -lavutil -lavcodec -lswscale  -lx264 -lSDL */
#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 "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(AV_CODEC_ID_H264);//得到264的解碼器類if(!videoCodec){printf("avcodec_find_decoder error\n");return -1;}AVCodecParserContext *avParserContext = av_parser_init(AV_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_ = av_frame_alloc();// 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*1280, pFrame_->data[0]+i*pFrame_->linesize[0], 720);                               }for(i=0;i<288;i++){memcpy(overlay->pixels[2]+i*640, pFrame_->data[1]+i*pFrame_->linesize[1], 360);memcpy(overlay->pixels[1]+i*640, 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);//sdlSDL_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);}

422顯示如下:

/*
編譯命令: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.agcc -o test test.c -I/usr/local/ffmpeg/include/   -L/usr/local/ffmpeg/lib/ -lswresample -lavformat -lavutil -lavcodec -lswscale  -lx264 -lSDL */
#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 "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(AV_CODEC_ID_H264);//得到264的解碼器類if(!videoCodec){printf("avcodec_find_decoder error\n");return -1;}AVCodecParserContext *avParserContext = av_parser_init(AV_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_ = av_frame_alloc();// 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( 720, 576, 32, SDL_SWSURFACE );SDL_Overlay* overlay = SDL_CreateYUVOverlay(w, h, SDL_YUY2_OVERLAY, screen);SDL_LockSurface(screen);SDL_LockYUVOverlay(overlay);
unsigned char yuv422[768*576*2];
//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);                                                                      }*/int k=0,y,x;	//yuv420  -> yuv422for( y=0;y<576;y++){for( x=0;x<720;x++){yuv422[k++] = pFrame_->data[0][y*pFrame_->linesize[0]+x];yuv422[k++] = x%2==0?pFrame_->data[1][(y/2)*pFrame_->linesize[1]+x/2]:pFrame_->data[2][(y/2)*pFrame_->linesize[2]+x/2];}}memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);SDL_UnlockYUVOverlay(overlay);SDL_UnlockSurface(screen);rect.w = w;rect.h = h;rect.x = rect.y = 0;SDL_DisplayYUVOverlay(overlay, &rect);//sdlSDL_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);}

采用sws_scale 實現的數據轉換

/*
編譯命令: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.agcc -o test test.c -I/usr/local/ffmpeg/include/   -L/usr/local/ffmpeg/lib/ -lswresample -lavformat -lavutil -lavcodec -lswscale  -lx264 -lSDL */
#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 "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,*pFrameYUV;struct SwsContext *img_convert_ctx =NULL;pFrameYUV =av_frame_alloc();/* find the video encoder */AVCodec *videoCodec = avcodec_find_decoder(AV_CODEC_ID_H264);//得到264的解碼器類if(!videoCodec){printf("avcodec_find_decoder error\n");return -1;}AVCodecParserContext *avParserContext = av_parser_init(AV_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_ = av_frame_alloc();// 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( 720, 576, 32, SDL_SWSURFACE );SDL_Overlay* overlay = SDL_CreateYUVOverlay(w, h, SDL_YUY2_OVERLAY, screen);SDL_LockSurface(screen);SDL_LockYUVOverlay(overlay);
//
//int numBytes = avpicture_get_size(AV_PIX_FMT_YUYV422, codec_->width,  codec_->height);  uint8_t* yuv422 = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));  avpicture_fill((AVPicture *)pFrameYUV, yuv422, AV_PIX_FMT_YUYV422,  codec_->width, codec_->height); 
///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);                                                                      }*/img_convert_ctx = sws_getContext(codec_->width, codec_->height, codec_->pix_fmt, codec_->width, codec_->height, AV_PIX_FMT_YUYV422, 2, NULL, NULL, NULL);   sws_scale(img_convert_ctx, (const uint8_t* const*) pFrame_->data,  pFrame_->linesize, 0, codec_->height, pFrameYUV->data,pFrameYUV->linesize);  memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);SDL_UnlockYUVOverlay(overlay);SDL_UnlockSurface(screen);rect.w = w;rect.h = h;rect.x = rect.y = 0;SDL_DisplayYUVOverlay(overlay, &rect);//sdlSDL_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);}



轉載于:https://www.cnblogs.com/mao0504/p/5589743.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374675.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374675.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374675.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring依賴注入技術的發展

回顧Spring框架的歷史&#xff0c;您會發現實現依賴注入的方式在每個發行版中都在增加。 如果您使用該框架已經超過一個月&#xff0c;那么在這篇回顧性文章中可能不會發現任何有趣的東西。 除了Scala中的最后一個示例&#xff0c;沒有其他希望&#xff0c;這種語言在Spring中意…

JS encode decode

網上查到的全都是escape&#xff0c;和需要的編碼不是一回事&#xff0c;好不容易找到的結果 保存下來以備以后使用js對文字進行編碼涉及3個函數&#xff1a;escape,encodeURI,encodeURIComponent&#xff0c;相應3個解碼函數&#xff1a;unescape,decodeURI,decodeURIComponen…

流媒體服務器 筆記

1.sip服務器回SBC Port Unreachable 說明轉碼器接收RTCP的端口沒有打開 轉載于:https://www.cnblogs.com/luoyinjie/p/7219359.html

力扣151. 翻轉字符串里的單詞

給你一個字符串 s &#xff0c;逐個翻轉字符串中的所有 單詞 。 單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。 請你返回一個翻轉 s 中單詞順序并用單個空格相連的字符串。 沒思路&#xff0c;看到的官方給的&#xff0c;簡潔明了&…

Spring 3 HornetQ 2.1集成教程

通過Spring框架使用JBoss的新超高性能消息傳遞系統。 HornetQ是一個開放源代碼項目&#xff0c;用于構建多協議&#xff0c;可嵌入&#xff0c;非常高性能的集群異步消息傳遞系統。 它是用Java編寫的&#xff0c;并且可以在具有Java 5或更高版本運行時的任何平臺上運行。 Horn…

B/S和C/S架構圖解

軟件&#xff1a;B/S和C/S兩種架構模式。接下來用三張圖片解釋&#xff0c;什么是B/S什么是C/S。 圖片一&#xff1a;軟件架構模式 圖片二&#xff1a;C/S結構模式 圖片三&#xff1a;B/S結構模式 相信圖解勝過冗長文字的解釋&#xff0c;什么是B/S什么是C/S一目了然。 轉載于:…

557. 反轉字符串中的單詞 III

給定一個字符串&#xff0c;你需要反轉字符串中每個單詞的字符順序&#xff0c;同時仍保留空格和單詞的初始順序。 class Solution {public String reverseWords(String s) {StringBuffer res new StringBuffer();int length s.length();int i 0;while(i < length){int …

休眠陷阱

我已經使用Hibernate已有一段時間了&#xff0c;當我一段時間不使用Hibernate項目時&#xff0c;發現自己犯的錯誤與上次相同。 因此&#xff0c;這是我的監視清單&#xff0c;希望對其他人也有用。 實現hashCode和equals 一般而言&#xff0c;應該始終實現這些方法&#xff…

HDU 5371 Hotaru's problem (Manacher,回文串)

題意&#xff1a;給一個序列&#xff0c;找出1個連續子序列&#xff0c;將其平分成前&#xff0c;中&#xff0c;后等長的3段子序列&#xff0c;要求【前】和【中】是回文&#xff0c;【中】和【后】是回文。求3段最長為多少&#xff1f;由于平分的關系&#xff0c;所以答案應該…

bash 與 dash

Ubuntu 的 bash和dash的區別 什么是bash &#xff1f; Bash(GNU Bourne-Again Shell)是許多Linux平臺的內定Shell&#xff0c;事實上&#xff0c;還有許多傳統UNIX上用的Shell&#xff0c;像tcsh、csh、ash、bsh、ksh等 等&#xff0c;Shell Script大致都類同&#xff0c;當您學…

350. 兩個數組的交集 II

給你兩個整數數組 nums1 和 nums2 &#xff0c;請你以數組形式返回兩數組的交集。返回結果中每個元素出現的次數&#xff0c;應與元素在兩個數組中都出現的次數一致&#xff08;如果出現次數不一致&#xff0c;則考慮取較小值&#xff09;。可以不考慮輸出結果的順序。 來源&a…

Eclipse:如何附加Java源代碼

在Eclipse中&#xff0c;當您按Ctrl按鈕并單擊任何類名稱時&#xff0c;IDE會將您帶到該類的源文件。 這是項目中具有的類的正常行為。 但是&#xff0c;如果您也希望Java核心類具有相同的行為&#xff0c;則可以通過將Java源代碼附加到Eclipse IDE來實現。 一旦附加了源代碼&a…

【樹狀數組】

問題的提出&#xff1a;是否可以用線性數據結構的方法解決動態統計子樹權和的問題呢&#xff1f; 有的&#xff0c;樹狀數組。 假設當前數組為a[]&#xff0c;元素個數為n。 1. 子區間的權和數組為sum&#xff0c;那么數組a[]中 i 到 j這段區間的數組元素和為sum[i,j] a[k]的累…

2013VS快捷鍵

VS2013常用快捷鍵&#xff1a; 1.回到上一個光標位置/前進到下一個光標位置 1&#xff09;回到上一個光標位置&#xff1a;使用組合鍵“Ctrl -”&#xff1b; 2&#xff09;前進到下一個光標位置&#xff1a;“Ctrl Shift - ”。 2.復制/剪切/刪除整行代碼 1&#xff09;如果…

GWT,GWT-Ext(SmartGWT),GXT(Ext GWT)常見任務

我在我們的JCG合作伙伴之一UI-Programming博客上瀏覽了一些舊文章&#xff0c;并注意到有很多簡短的文章&#xff0c;介紹了如何使用GWT&#xff0c;GWT-Ext&#xff08;SmartGWT&#xff09;和GXT&#xff08;Ext GWT&#xff09;執行一些常見任務。 &#xff09;。 我相信它們…

h.264 去塊濾波

塊效應及其產生原因 我們在觀看視頻的時候&#xff0c;在運動劇烈的場景常能觀察到圖像出現小方塊&#xff0c;小方塊在邊界處呈現不連續的效果&#xff08;如下圖&#xff09;&#xff0c;這種現象被稱為塊效應&#xff08;blocking artifact&#xff09;。 首先我們需要搞清楚…

android開發的知識點(一)

1.android中背景圖的設置&#xff1a; 將背景圖放入到項目中的res/drawable-hdpi或res/drawable-mdpi或res/drawable-xhdpi或res/drawable-xxhdpi等任一文件夾下。然后在layout的xml文件夾下使用android:background"drawable/背景圖名"&#xff0c;其中背景圖必須是p…

566. 重塑矩陣

在 MATLAB 中&#xff0c;有一個非常有用的函數 reshape &#xff0c;它可以將一個 m x n 矩陣重塑為另一個大小不同&#xff08;r x c&#xff09;的新矩陣&#xff0c;但保留其原始數據。 給你一個由二維數組 mat 表示的 m x n 矩陣&#xff0c;以及兩個正整數 r 和 c &…

RabbitMQ播放模塊! 構架

RabbitMQ提供了具有可預測且一致的吞吐量和延遲的高可用性&#xff0c;可伸縮和便攜式消息系統。 RabbitMQ是AMQP &#xff08;業務消息傳遞的開放標準&#xff09;的領先實現 &#xff0c;并且通過適配器支持XMPP&#xff0c;SMTP&#xff0c;STOMP和HTTP來進行輕量級Web消息傳…

Cyclic Nacklace - HDU 3746(next求循環節)

題目大意&#xff1a;給你一些串&#xff0c;問如果想讓這個串里面的循環節至少循環兩次&#xff0c;需要添加幾個字符&#xff08;只能在最前面或者最后面添加&#xff09;。比如ababc 需要添加5個就是添加ababc。 分析&#xff1a;其實字符串的長度len-next[len] 最小循環節…