FFmpeg解码视频和SDL显示

来源:互联网 发布:淘宝刷收藏 编辑:程序博客网 时间:2024/05/22 06:40
/*************************************************************************    > File Name: decode_video.c    > Author: charein    > Mail: chenyayun9@163.com     > Created Time: Sat 08 Feb 2014 08:20:16 PM CST ************************************************************************/#include <stdio.h>#include <libavformat/avformat.h>#include <libavcodec/avcodec.h>#include <libavutil/mem.h>#include <libswscale/swscale.h>#include <SDL/SDL.h>#include <SDL/SDL_thread.h>static int sws_flags = SWS_BICUBIC;void print_log(char *tag, char *text, char *key){if (strcmp (key, "yes") != 0)return;printf("tag%s\n", text);}int main(int argc, char **argv){AVFormatContext *pFormatCtx = NULL;AVCodecContext *pCodecCtx;// 保存了 流 的 详细信细AVCodec *pCodec;// 编解码 器AVFrame *pFrame;// 保存数据 帧的 数据 结够构AVPacket packet;//解析文件时会 将 音/视帧读入到 packet中 int videoStream = -1;int audioStream = -1;int i;int frameFinished;int numBytes;uint8_t *buffer;SDL_Overlay *bmp;SDL_Surface *screen;SDL_Rect rect;SDL_Event event;if (argc < 2) {fprintf(stderr, "error usage\n");exit(1);}av_register_all();  //Init all support codec and decodeif (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) //return -1;if (avformat_find_stream_info(pFormatCtx, NULL) < 0)//return -1;av_dump_format(pFormatCtx, -1, argv[1], 0);//print file infoprintf("~~~~~~~~~~~~~~~~~~~~~\n");// Find the first video streamfor (i=0; i<pFormatCtx->nb_streams; i++) if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {videoStream = i;break;}// Find the first audio streamfor (i=0; i<pFormatCtx->nb_streams; i++)if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {audioStream = i;break;}if ((videoStream == -1) || (audioStream == -1))return -1;printf("videoStream : %d\naudioStream : %d\n", videoStream, audioStream);pCodecCtx = pFormatCtx->streams[videoStream]->codec;pCodec = avcodec_find_decoder(pCodecCtx->codec_id);if (pCodec == NULL) {fprintf(stderr, "Unsupported codec!\n");return -1;}//Open codecif (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)return -1;pFrame = avcodec_alloc_frame();if (pFrame == NULL)return -1;numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);buffer = (uint8_t)av_malloc(numBytes*sizeof(uint8_t));if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());exit(1);}//创 建Surfacescreen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);if (!screen) {fprintf(stderr, "SDL: could not set video mode - exiting\n");exit(1);}//创 建一 个 YUV覆盖bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,\ SDL_YV12_OVERLAY, screen);//变换 图像 格式static struct SwsContext *img_convert_ctx;if (img_convert_ctx == NULL) {img_convert_ctx =sws_getContext(pCodecCtx->width, pCodecCtx->height, \pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, \PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);if (img_convert_ctx == NULL) {fprintf(stderr, "Cannot initialize the conversion context\n");exit(1);}}//从 文件中 读取音 视频帧并 解码 while (av_read_frame(pFormatCtx, &packet) >= 0) {if (packet.stream_index == videoStream) {// Decode video frameavcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);//frameFinished > 0 ,表 示解码 到 了 pFrameif (frameFinished) {SDL_LockYUVOverlay(bmp);AVPicture pict;pict.data[0] = bmp->pixels[0];pict.data[1] = bmp->pixels[2];pict.data[2] = bmp->pixels[1];pict.linesize[0] = bmp->pitches[0];pict.linesize[1] = bmp->pitches[2];pict.linesize[2] = bmp->pitches[1];// Convert the image into YUV format that SDL usessws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, \0, pCodecCtx->height, pict.data, pict.linesize);SDL_UnlockYUVOverlay(bmp);rect.x = 0;rect.y = 0;rect.w = pCodecCtx->width;rect.h = pCodecCtx->height;SDL_DisplayYUVOverlay(bmp, &rect);}}//else if (packet.stream_index == audioStream) {//}av_free_packet(&packet);SDL_PollEvent(&event);switch(event.type) {case SDL_QUIT:SDL_Quit();break;default: break;}}// 释放图像 和 关 閉 文件av_free(buffer);av_free(pFrame);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);return 0;}

存在问题:播放速度不正常。
0 0
原创粉丝点击