2014年1月23日星期四

opengl 红蓝切换 上下翻转

opengl  红蓝切换   上下翻转


  1. #pragma mark -
  2. #pragma mark Capture Video Methods
  3. - (void) testVideoWriter {
  4.     
  5.     //initialize global info
  6.     MOVIE_NAME = @"Documents/Movie.mov";
  7.     CGSize size = CGSizeMake(1024, 768);
  8.     frameLength = CMTimeMake(1, 30);
  9.     currentTime = kCMTimeZero;
  10.     currentFrame = 0;
  11.     
  12.     NSString *MOVIE_PATH = [NSHomeDirectory() stringByAppendingPathComponent:MOVIE_NAME];
  13.     NSError *error = nil;
  14.     
  15.     unlink([MOVIE_PATH UTF8String]);
  16.     
  17.     videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:MOVIE_PATH] fileType:AVFileTypeQuickTimeMovie error:&error];
  18.     
  19.     NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
  20.                                    [NSNumber numberWithInt:size.width], AVVideoWidthKey,
  21.                                    [NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
  22.     writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
  23.     
  24.     //writerInput.expectsMediaDataInRealTime = NO;
  25.     
  26.     NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil];
  27.     
  28.     adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput                                                                          sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
  29.     [adaptor retain];
  30.     
  31.     [videoWriter addInput:writerInput];
  32.     
  33.     [videoWriter startWriting];
  34.     [videoWriter startSessionAtSourceTime:kCMTimeZero];
  35.     
  36.     VIDEO_WRITER_IS_READY = true;
  37. }
  38. - (void) captureScreenVideo {
  39.     
  40.     if (!writerInput.readyForMoreMediaData) {
  41.         return;
  42.     }
  43.     
  44.     CGSize esize = CGSizeMake(1024, 768);
  45.     NSInteger myDataLength = esize.width * esize.height * 4;
  46.     GLubyte *buffer = (GLubyte *) malloc(myDataLength);
  47.     glReadPixels(0, 0, esize.width, esize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  48.     // swap red and blue
  49.     for (int i=0; i
  50.         GLubyte b_red = buffer[i];
  51.         buffer[i] = buffer[i+2];
  52.         buffer[i+2] = b_red;
  53.     }
  54.     // flip the buffer data
  55.     GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
  56.     NSInteger myDataLineLength = esize.width * 4;
  57.     for (int i=0; i
  58.         memcpy(buffer2+i*myDataLineLength, buffer+((GLuint)esize.height-i-1)*myDataLineLength, myDataLineLength);
  59.     }
  60.     // copy back flipped data
  61.     memcpy(buffer, buffer2, myDataLength);
  62.     free(buffer2);
  63.     
  64.     CVPixelBufferRef pixel_buffer = NULL;
  65.     CVPixelBufferCreateWithBytes (NULL, esize.width, esize.height, kCVPixelFormatType_32BGRA, buffer, 4 * esize.width, NULL, 0, NULL, &pixel_buffer);
  66.     
  67.     if(![adaptor appendPixelBuffer:pixel_buffer withPresentationTime:currentTime]) {
  68.         NSLog(@"FAIL");
  69.     } else {
  70.         NSLog(@"Success:%d", currentFrame);
  71.         currentTime = CMTimeAdd(currentTime, frameLength);
  72.     }
  73.     
  74.     free(buffer);
  75.     CVPixelBufferRelease(pixel_buffer);
  76.     currentFrame++;
  77.     
  78.     if (currentFrame > MAX_FRAMES) {
  79.         VIDEO_WRITER_IS_READY = false;
  80.         [writerInput markAsFinished];
  81.         [videoWriter finishWriting];
  82.         [videoWriter release];
  83.         
  84.         [self moveVideoToSavedPhotos];
  85.     }
  86. }
  87. - (void) moveVideoToSavedPhotos {
  88.     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
  89.     NSString *localVid = [NSHomeDirectory() stringByAppendingPathComponent:MOVIE_NAME];    
  90.     NSURL* fileURL = [NSURL fileURLWithPath:localVid];
  91.     
  92.     [library writeVideoAtPathToSavedPhotosAlbum:fileURL
  93.                                 completionBlock:^(NSURL *assetURL, NSError *error) {
  94.                                     if (error) {  
  95.                                         NSLog(@"%@: Error saving context: %@", [self class], [error localizedDescription]);
  96.                                     }
  97.                                 }];
  98.     [library release];
  99. }

2014年1月16日星期四

Epoll vs IOCP

http://liuxun.org/blog/epoll-vs-iocp/

1 Epoll vs. IOCP Epoll 和 IOCP 都是为高性能网络服务器而设计的高效 I/O 模型;都是基于事件驱动的。事件驱动有个著名的好莱坞原则(“不要打电话给我们,我们会打电话给你”)。
不同之处在于: 1. Epoll 用于 Linux 系统;而 IOCP 则是用于 Windows; 2. Epoll 是当事件资源满足时发出可处理通知消息;而 IOCP 则是当事件完成时发出完成通知消息。 3. 从应用程序的角度来看, Epoll 本质上来讲是同步非阻塞的,而 IOCP 本质上来讲则是异步操作;这是才二者最大的不同。 就第 3 点来讲,还需要简单说说系统的 IO 模型。
2 系统的 IO 模型 系统 IO 可以分成三种模型:阻塞 (blocking) ,同步非阻塞 (non-blocking synchronous) 和异步非阻塞 (non-blocking asynchronous) 。
先举个打印室的例子: 你有个文档需要拿到打印室打印,这时候正巧你的一个同事正在打印一本 800 页的书; 看看这三种模型下你和打印室的反应。
  1. 阻塞模型 调用者必须阻塞等待操作的完成,如果资源不可用,只能阻塞等待。可见这是一种相当低效的模型。 对应于打印室的例子:你把文档给打印室,打印室不会告诉你,现在前面有个兄弟 800 页呢,你的等半天了。你只能等在那里,直到打印室打完文档后给你;在打那 800 页时你也只能白等着。
  2. 同步非阻塞 本质上依然是同步的,但是当资源不可用时,调用将会立即返回,并得到通知指示资源部可用;否则可以立即完成。 对应于打印室的例子:你把文档给打印室,打印室马上就会告诉你,忙着呢,现在前面有个兄弟 800 页呢。得到打印室的通知后,随你怎么处理了;如果你去的时候打印机正好空闲,打印室就会立即开始打印,把打印好的文档给你。
  3. 异步非阻塞 异步肯定不会阻塞,异步就是你告诉操作系统说,我要给你什么事情,好了,如果操作立即完成,系统会立即返回给你操作结果;否则就告诉你说执行中,完成了再通知你,你接着干自己的事情去吧,不用等在这里。 当然这个时候系统必须提供一种机制,以期能在完成时让应用程序得到通知。 对应于打印室的例子:你把文档给打印室,如果这时候打印机正好空闲,打印室就会立即开始打印,把打印好的文档给你;否则打印室会对你说,兄弟你忙去吧,文档打印好了马上通知你。 从理论上来讲异步肯定是最优的方案了,你把处理扔给操作系统就行了。

2014年1月15日星期三

产品设计:核心要做到极致

1.核心能力
任何产品都有核心功能,其宗旨就是能帮助到用户,解决用户某一方面的需求,如节省时间、解决问题、提升效率等。
很多产品经理对核心能力的关注不够,不是说完全没有关注,而是没有关注到位。核心能力不仅仅是功能,也包括性能。对于技术出身的产品经理,特别 是做后台出来的,如果自己有能力、有信心做到对核心能力的关注,肯定会渴望将速度、后台做到极限。但是现在的问题是产品还没做好。比如前段时间的网页速度 优化,优化之后速度提高很多,真不知道之前都做什么去了?让用户忍受了这么久,既浪费时间又浪费我们的资源。不抓,都没人理,很说不过去。所以说我们要在 性能方面放入更多精力。
谈到核心的能力,首先就要有技术突破点。比如做QQ影音,我们不能做人家有我也有的东西,否则总是排在第二第三,虽然也有机会,但缺乏第一次出 来时的惊喜,会失去用户的认同感。这时候,你第一要关注的就是你的产品的硬指标。在设计和开发的时候你就要考虑到外界会将它与竞争对手做比较,如播放能 力、占用内存等。就像QQ影音,它的核心性能和速度都超越了暴风影音,所以推出之后发展的势头将会很好。
硬指标选择上其实也有很多选择,如网络播放、交流、分享,这都是很好的思路。但是最后都砍掉了,我们就是要做播放器,因为这是用户的需求。并不 是所有人都需要高清,但是高端用户需要(这个后面口碑创造会再提到)。只有硬指标满足了,用户说,我这个破机器,暴风影音不能放,QQ影音能放。就这一句 话,口碑就出来了,用户知道你行,口碑要有差异性。
核心能力要做到极致。要多想如何通过技术实现差异化,让人家做不到,或通过一年半载才能追上。
很多用户评论QQ时说用QQ唯一的理由是传文件快,有群。那这就是我们的优势,我们要将这样的优势发挥到极致。比如离线传文件,以邮件方式体现 就是一个中转站,即使是超大的文件也不困难,关键是要去做。虽然真正使用的用户并不一定多,但用户会说,我要传大文件,找了半天找不到可以传的地方,万般 无奈之下用了很烂的QQmail,居然行了,于是我们的口碑就来了。
要做大,你首先要考虑的就是如何让人家想到也追不上。这么多年在IDC(互联网数据中心)上的积累我们不能浪费,高速上传、城域网中转站,支持 高速地上传 ⋯⋯可能又会发现新的问题,如果不是邮件,在IM(即时通讯软件)上又该怎么实现。我们的目的是要让用户感到超快、飞快,让用户体验非常好,这些都需要大 量技术和后台来配合。
产品的更新和升级需要产品经理来配合,但我们产品经理做研发出身的不多。而产品和服务是需要大量技术背景的,我们希望的产品经理是非常资深的, 做过前端、后端开发的技术研发人员晋升而来。好的产品最好交到一个有技术能力、有经验的人员手上,这样会让大家更加放心。如果产品经理不合格,让很多兄弟 陪着干,结果就会发现方向错误是非常浪费和挫伤团队士气的。
2.口碑
做产品要做口碑就要关注高端用户、意见领袖关注的方向。以前,我们的思路是抓大放小,满足大部分“小白”用户的需求。但是现在来看,高端用户的感受才是真正可以拿口碑的。
如何提升高端用户的关注,这是在基础功能比较好的情况下需要考虑的问题。如邮件搜索、RSS聚合等,这些只有“很炫”的用户在博客和论坛里面会 提及,在有能力的情况下我们要保证。在产品已经成型的情况下,对待高端用户的心态也要不一样。比如允许用户在我们的QQmail上使用别的邮箱。之前我们 自己心里打着小九九,让别人不方便使用外部邮箱地址,好使用我们的,但是这些小九九,高端用户是看得出来的,所以要改掉,只有这样才能做到真正的方便用 户。
个性化服务,并不是大众化服务,也是要取得口碑的。
一个产品在没有口碑的时候,不要滥用平台。如像IM(即时通讯)部门要求支持,投入营销资源、要marketing(市场部门)联系公关公司投放广 告,提广告位要求⋯⋯等着人家砍,其实心里想着有一半也够了。我们的产品经理精力好像分配得很好,50% 产品、30%营销⋯⋯当然,如果你在基础环节控制得好,这样当然可以。但多数情况下我们的人第一点都做不好。如果你的实力和胜算不到70%〜80%,那么 就把精力放在最核心的地方。当你的产品已经获得良好口碑,处于上升期后再考虑这些。
产品经理要关注最最核心、能够获得用户口碑的战略点,如果这块没做透,结果只能是用户过来,失望,再花更多的精力弥补,这是得不偿失的。当用户 在自动增长(用户会主动推荐朋友来使用我们的产品),就不要去打扰用户,否则可能是好心办坏事。这时,每做一件事情,每加一个东西都要很慎重的考虑,真的 是有建设性地去增加产品的一个口碑。当用户口碑坏掉后,再将用户拉回来很难。
增加功能,在管理控制功能上也要有技巧。在核心功能做好后,常用功能是要逐步补齐的。产品在局部、细小之处的创新需要永不满足。作为一个有良好 口碑的产品,每加一个功能都要考虑清楚,这个功能给10%的用户带来好感的时候是否会给90%的用户带来困惑。有冲突的时候要聪明,分情况避免。每个功能 不一定要用得多才是好,而是用了的人都觉得好才是真正的好。
做产品开发的时候需要有较强的研发机制保证,这样可以让产品开发更加敏捷和快速。就算是大项目也要灵活。不能说等3个月后再给你东西看,这个时候竞争对手已经跑出去已经不知道有多远了。
开发人员要用心来思考产品,而不是公事公办的态度。你要知道用户、同行会关注你的产品,在这种驱动下开发人员要有责任心去主动完成。不能说等到 产品都做好了,流水线一样送到面前再做。40-50%左右的产品最终体验应是由开发人员决定的。产品人员不要嫉妒有些工作是是开发人员设计的,只有这样才 是团队共同参与的。否则出来的产品一定会慢半拍。
运营式管理:敏感才能找到不足
关键词:天天用
我们的产品不是单机版,不仅需要很强的用户感和技术功底,更重要的是服务。我们要关注一些很复杂的内容,如架构、应用等,产品需要有更好的架 构,这需要花很多精力,常态下可能看不出来,所以需要我们高层更多的从KPI(重要绩效指标)上考虑。这很考验功力,谁做的好,总办领导是看得到的,好的 设计架构不会手乱脚乱。如把核心的东西做成组件模块分发。
发现产品的不足,最简单的方法就是天天用你的产品。产品经理只有更敏感才能找出你产品的不足之处。我经常感到很奇怪,有的产品经理说找不出问 题,我相信如果产品上线的时候你坚持使用三个月,问题是有限的,一天发现一个,解决掉,你就会慢慢逼近那个“很有口碑”的点。不要因为工作没有技术含量就 不去做,很多好的产品都是靠这个方法做出来的。我们的领导不仅仅要安排下面的人去做,一定要自己做。这些都不难,关键要坚持,心里一定要想着,这个周末不 试,肯定出事,直到一个产品基本成型。
从哪个地方找问题呢?论坛、博客、RSS订阅啊。高端用户不屑于去论坛提出问题,我们的产品经理就要主动追出来,去查、去搜,然后主动和用户接 触,解决,有些确实是用户搞错了,有些是我们自己的问题。产品经理心态要很好,希望用户能找出问题我们再解决掉。哪怕再小的问题解决了也是完成一件大事。 有些事情做了,见效很快。产品经理要关注多个方面,经常去看看运营,比如说你的产品慢,用户不会管你的IDC(互联网数据中心)差或者其他原因,只知道你 的速度慢。
交互设计:做最挑剔的用户
关键词:细致
产品经理要把自己当一个挑剔的用户。我们做产品的精力是有限的,交互内容很多,所以要抓最常见的一块。流量、用量最大的地方都要考虑。规范到要让用户使用的舒服。要在感觉、触觉上都有琢磨,有困惑要想到去改善。如鼠标少移动、可快速点到等等。
像邮箱的“返回”按钮放在哪儿,放右边还是左边,大家要多琢磨,怎么放更好,想好了再上线测试。对同一个用户发信,在此用户有多个邮箱的情况下如何默认选最近用的一个账号。这些需求都小,但你真正做出来了,用户就会说好,虽然他未必能说出好在哪里。
产品的使用要符合用户的习惯,如写邮件的时候拷贝东西,更多人习惯用键盘来操作。虽然有些技术难度,但也可以解决,交互,对鼠标反馈的灵敏性,便捷性。
在设计上我们应该坚持几点:
不强迫用户。如点亮图标,如QQmail,不为1%的需求骚扰99%的用户。
操作便利。如QQ音乐,新旧列表,两者都要兼顾到,如QQ影音的快捷播放,从圆形到方形,最后因为影响性能而放弃。
淡淡的美术,点到即止。如QQmail,QQmail在UI界面上的启发,不用太重也能做得很好。图案和简洁并不是一对矛盾体。
重点要突出,不能刻意地迎合低龄化。

1、为产品订立优先级和先后次序。
2、不强迫用户。不为1%的需求骚扰99%的用户。
3、研发机制保证,产品换代要快,快速实现、快速响应。
4、图案和简洁并不是一对矛盾体。
5、要丰富自己的角色,做最挑剔的用户、笨用户。
6、产品经理第一要关注产品的硬指标。
7、技术核心能力非可复制性要强,让极致核心能力产生口碑。
8、在局部、细小之处的创新要永不满足。