No.08 Xcode(5.1.x) 使用FFmpeg
来源:互联网 发布:win10系统网络感叹号 编辑:程序博客网 时间:2024/05/21 09:50
1.从 https://github.com/kewlbear/FFmpeg-iOS-build-script 获取到一套能运行于armv7, armv7s, arm64, i386的ffmpeg库;
2.在工程配置中, 加入libz.dylib, libbz2.dylib, libiconv.dylib这三个系统库;
3.在代码中加入avcodec.h, swscale.h, avformat.h等ffmpeg的库文件, 其中avcodec.h是必要的, 其他则根据需要添加;
4.在工程配置中, 加入搜索路径 "$(PROJECT_DIR)/工程名/ffmpeg/lib" 和 "$(PROJECT_DIR)/工程名/ffmpeg/include"
5.填写代码, 可以参考 http://blog.csdn.net/smking/article/details/7561688
6.已经编译好的库: http://download.csdn.net/download/huayu608/7671881
以下是调用ffmpeg接口时的demo代码
#include "avcodec.h"#include "swscale.h"#include "avformat.h"typedef struct SwsContext SwsContext;typedef struct structVideoDecode { AVCodec* mAVCodec; AVCodecContext* mAVCodecContext; AVFrame* mAVFrame; AVPicture mAVPicture; SwsContext* mSwsContext;} VideoDecode;int videox_init(){ av_register_all(); avcodec_register_all(); return 0;}int videox_unit(){ return 0;}int videox_began(long video_format, long image_width, long image_height, long* out_vd_handle){ VideoDecode* vd = (VideoDecode*)malloc(sizeof(VideoDecode)); if (vd == 0) return -1; memset(vd, 0, sizeof(VideoDecode)); *out_vd_handle = (long)vd; // VIDEO_FORMAT_H264等宏是公司私有的标识 enum AVCodecID codeId = CODEC_ID_NONE; switch (video_format) { case VIDEO_FORMAT_H264: {codeId = AV_CODEC_ID_H264; break;} case VIDEO_FORMAT_MJPEG4: {codeId = AV_CODEC_ID_MJPEG; break;} default: {break;} } vd->mAVCodec = avcodec_find_decoder(codeId); if (!vd->mAVCodec) { return -2; } vd->mAVCodecContext = avcodec_alloc_context3(vd->mAVCodec); if(!vd->mAVCodecContext) { return -3; } vd->mAVCodecContext->width = image_width; vd->mAVCodecContext->height = image_height; vd->mAVCodecContext->pix_fmt = PIX_FMT_YUV420P; if (avcodec_open2(vd->mAVCodecContext, vd->mAVCodec, 0) < 0) // 需要加锁 { return -4; } vd->mAVFrame = av_frame_alloc(); if (!vd->mAVFrame) { return -5; } avpicture_alloc(&vd->mAVPicture, PIX_FMT_RGB24, vd->mAVCodecContext->width, vd->mAVCodecContext->height); vd->mSwsContext = sws_getCachedContext(0, vd->mAVCodecContext->width, vd->mAVCodecContext->height, vd->mAVCodecContext->pix_fmt, vd->mAVCodecContext->width, // 生成图像的宽度 vd->mAVCodecContext->height, // 生成图像的高度 PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); return 0;}int videox_ended(long vd_handle){ if (vd_handle == 0) return -1; VideoDecode* vd = (VideoDecode*)vd_handle; if(vd->mAVCodecContext) { avcodec_close(vd->mAVCodecContext); // 需要加锁av_free(vd->mAVCodecContext);vd->mAVCodecContext = 0; } if(vd->mAVFrame) {av_free(vd->mAVFrame);vd->mAVFrame = 0; } avpicture_free(&vd->mAVPicture); if (vd->mSwsContext) { sws_freeContext(vd->mSwsContext); } free(vd); vd = 0; return 0;}int videox_decode(long vd_handle, uint8_t* in_264Buffer, int in_264BufferSize, uint8_t** out_RGBBuffer, int* out_RGBBufferSize, long* out_image_width, long* out_image_height){ if (vd_handle == 0 || in_264Buffer == 0 || in_264BufferSize == 0) return -1; VideoDecode* dv = (VideoDecode*)vd_handle; AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = in_264Buffer; // packet data will be allocated by the encoder avpkt.size = in_264BufferSize; int got_picture; int consumed_bytes = avcodec_decode_video2(dv->mAVCodecContext, dv->mAVFrame, &got_picture, &avpkt); av_free_packet(&avpkt);if (consumed_bytes <= 0 || dv->mAVFrame->data[0] == 0) { return -2; } // 把数据从pFrame写到picture之中 sws_scale(dv->mSwsContext, dv->mAVFrame->data, dv->mAVFrame->linesize, 0, dv->mAVCodecContext->height, dv->mAVPicture.data, dv->mAVPicture.linesize); *out_RGBBuffer = dv->mAVPicture.data[0]; *out_RGBBufferSize = dv->mAVPicture.linesize[0] * dv->mAVCodecContext->height; *out_image_width = dv->mAVCodecContext->width; *out_image_height = dv->mAVCodecContext->height; return 0;}
if (mVideoDecode) videox_ended(mVideoDecode); videox_began(format, frame_head->width, frame_head->height, &mVideoDecode); ... ... long w = 0; long h = 0; uint8_t* RGBBuffer = 0; int RGBBufferSize = 0; int ret = videox_decode(mVideoDecode, (uint8_t*)a264Buffer, a264Length, &RGBBuffer, &RGBBufferSize, &w, &h); dispatch_async(dispatch_get_main_queue(), ^{ if (self.stream && ret >= 0) { CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, RGBBuffer, RGBBufferSize, kCFAllocatorNull); CGDataProviderRef provider = CGDataProviderCreateWithCFData(data); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); int bitsPerComponent = 8; // 8位存储一个Component int bitsPerPixel =3* bitsPerComponent; // RGB存储,只用三个字节,而不是像RGBA要用4个字节,所以这里一个像素点要3个8位来存储 int bytesPerRow =3* w; // 每行有width个象素点,每个点用3个字节,另外注意:pict.linesize[0]=bytesPerRow=1056 CGImageRef cgImage = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow, // pict.linesize[0],等效 colorSpace, kCGBitmapByteOrderDefault, provider, NULL, NO, kCGRenderingIntentDefault); mImageView.image = [UIImage imageWithCGImage:cgImage]; CGColorSpaceRelease(colorSpace); CGImageRelease(cgImage); CGDataProviderRelease(provider); CFRelease(data); } });
0 0
- No.08 Xcode(5.1.x) 使用FFmpeg
- No.07 Xcode(5.x) 使用SQLite
- No.06 Xcode(5.1.x) UINavigationController
- No.10 Xcode(5.1.x) UITabBarController
- No.14 Xcode(5.1.x) socket
- No.15 Xcode(5.1.x) libxml2
- No.03 Xcode(5.1.x) c,c++,objiective-c混编
- No.05 Xcode(5.1.x) 服务器消息推送
- No.11 Xcode(5.1.x) 设备或程序旋转
- No.12 Xcode(5.1.x) NSString, NSArray 和 NSDictionary
- No.13 Xcode(5.1.x) 获取设备信息, 系统信息
- No.09 Xcode(5.x) UITextField
- No.01 Xcode(7.x) 键盘
- No.04 Xcode(7.x) GCD相关
- No.04 Xcode(7.x) 蓝牙
- No.01 Xcode(5.1.x) 在Vmware中安装Mac OS X 10.8
- No.04 Xcode(5.x) app的测试与发布
- No.02 Xcode(7.x) 横竖屏旋转
- Web容器和Web应用程序介绍
- iOS_GCD_讲解一_基本概念和Dispatch Queue
- JQuery UI Layout
- 题目1510:替换空格
- uva 10177(数学)
- No.08 Xcode(5.1.x) 使用FFmpeg
- CSU 1259 跳跳
- 同步/异步与阻塞/非阻塞的区别
- *4-0. 求符合给定条件的整数集(15)
- 关于Set
- 杭电1232畅通工程
- 使用异步 I/O 大大提高应用程序的性能
- eclipse null 校验问题
- 利用 Console 来学习、调试JavaScript