fixed rendering

This commit is contained in:
Diego Waxemberg 2014-01-18 19:14:57 -05:00
parent 029d3b0a97
commit f97fe7fce2
9 changed files with 89 additions and 72 deletions

View File

@ -36,15 +36,11 @@
<true/> <true/>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array> </array>
<key>UISupportedInterfaceOrientations~ipad</key> <key>UISupportedInterfaceOrientations~ipad</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>

View File

@ -23,6 +23,7 @@
- (void)StreamButton:(UIButton *)sender - (void)StreamButton:(UIButton *)sender
{ {
NSLog(@"Stream Button Pressed!"); NSLog(@"Stream Button Pressed!");
[self performSegueWithIdentifier:@"createStreamFrame" sender:self];
} }
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

View File

@ -10,6 +10,5 @@
#import "StreamView.h" #import "StreamView.h"
@interface StreamFrameViewController : UIViewController @interface StreamFrameViewController : UIViewController
@property (strong, nonatomic) IBOutlet StreamView *renderView;
@end @end

View File

@ -18,15 +18,21 @@
- (void)viewDidLoad - (void)viewDidLoad
{ {
[super viewDidLoad]; [super viewDidLoad];
[self.renderView setNeedsDisplay]; StreamView* streamView = [[StreamView alloc] initWithFrame:self.view.frame];
streamView.backgroundColor = [UIColor blackColor];
[self.view addSubview:streamView];
[streamView setNeedsDisplay];
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
VideoDepacketizer* depacketizer = [[VideoDepacketizer alloc] init];
NSString* path = [[NSBundle mainBundle] pathForResource:@"notpadded" NSString* path = [[NSBundle mainBundle] pathForResource:@"notpadded"
ofType:@"h264"]; ofType:@"h264"];
NSLog(@"Path: %@", path); NSLog(@"Path: %@", path);
[depacketizer readFile:path]; VideoDepacketizer* depacketizer = [[VideoDepacketizer alloc] initWithFile:path renderTarget:streamView];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:depacketizer];
} }

View File

@ -18,19 +18,16 @@
CGColorSpaceRef colorSpace; CGColorSpaceRef colorSpace;
CGContextRef bitmapContext; CGContextRef bitmapContext;
CGImageRef image; CGImageRef image;
UIImage *uiImage;
unsigned char* pixelData; unsigned char* pixelData;
} }
static bool firstFrame = true;
-(id)init
{
NSLog(@"init");
return [super init];
}
- (void)awakeFromNib
- (id)initWithFrame:(CGRect)frame
{ {
NSLog(@"awakeFromNib"); self = [super initWithFrame:frame];
NSLog(@"initWithFrame");
// Initialization code // Initialization code
width = 1280; width = 1280;
height = 720; height = 720;
@ -38,21 +35,18 @@
bytesPerRow = (bitsPerComponent / 8) * width * 4; bytesPerRow = (bitsPerComponent / 8) * width * 4;
pixelData = malloc(width * height * 4); pixelData = malloc(width * height * 4);
colorSpace = CGColorSpaceCreateDeviceRGB(); colorSpace = CGColorSpaceCreateDeviceRGB();
bitmapContext = CGBitmapContextCreate(NULL, 1280, 720, 8, 5120, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipLast); //bitmapContext = CGBitmapContextCreate(pixelData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGBitmapByteOrderDefault);
image = CGBitmapContextCreateImage(bitmapContext); //image = CGBitmapContextCreateImage(bitmapContext);
uiImage = [UIImage imageWithCGImage:image];
//VideoRenderer* renderer = [[VideoRenderer alloc]initWithTarget:self]; return self;
//NSOperationQueue* opQueue = [[NSOperationQueue alloc]init];
//[opQueue addOperation:renderer];
[self setNeedsDisplay];
} }
// Only override drawRect: if you perform custom drawing. // Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation. // An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect - (void)drawRect:(CGRect)rect
{ {
NSLog(@"drawRect"); NSLog(@"drawRect");
if (!nv_avc_get_rgb_frame(pixelData, width*height*4)) if (!nv_avc_get_rgb_frame(pixelData, width*height*4))
@ -60,10 +54,31 @@
return; return;
} }
if (firstFrame) {
NSData *data = [[NSData alloc] initWithBytes:pixelData length:(width*height*4)];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"MyFile"];
[data writeToFile:appFile atomically:YES];
NSLog(@"writing data to: %@",documentsDirectory);
firstFrame = false;
}
bitmapContext = CGBitmapContextCreate(pixelData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
image = CGBitmapContextCreateImage(bitmapContext);
struct CGContext* context = UIGraphicsGetCurrentContext(); struct CGContext* context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, CGRectMake(0, 0, 1280, 720), image); CGContextTranslateCTM(context, 0, rect.size.width);
CGContextScaleCTM(context, (float)width / self.frame.size.width, (float)height / -self.frame.size.height);
CGContextDrawImage(context, rect, image);
CGImageRelease(image);
[super drawRect:rect]; [super drawRect:rect];
} }

View File

@ -9,11 +9,13 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "VideoDecoder.h" #import "VideoDecoder.h"
@interface VideoDepacketizer : NSObject <NSStreamDelegate> @interface VideoDepacketizer : NSOperation <NSStreamDelegate>
@property uint8_t* byteBuffer; @property uint8_t* byteBuffer;
@property unsigned int offset; @property unsigned int offset;
@property VideoDecoder* decoder; @property VideoDecoder* decoder;
@property NSString* file;
@property UIView* target;
- (void) readFile:(NSString*) file; - (id) initWithFile:(NSString*) file renderTarget:(UIView*)renderTarget;
@end @end

View File

@ -11,10 +11,18 @@
@implementation VideoDepacketizer @implementation VideoDepacketizer
static int BUFFER_LENGTH = 131072; static int BUFFER_LENGTH = 131072;
- (void) readFile:(NSString*) file - (id)initWithFile:(NSString *)file renderTarget:(UIView*)renderTarget
{
self = [super init];
self.file = file;
self.target = renderTarget;
return self;
}
- (void)main
{ {
NSLog(@"Allocating input stream\n"); NSLog(@"Allocating input stream\n");
NSInputStream* inStream = [[NSInputStream alloc] initWithFileAtPath:file]; NSInputStream* inStream = [[NSInputStream alloc] initWithFileAtPath:self.file];
NSLog(@"Allocating byteBuffer"); NSLog(@"Allocating byteBuffer");
self.byteBuffer = malloc(BUFFER_LENGTH); self.byteBuffer = malloc(BUFFER_LENGTH);
NSLog(@"byte pointer: %p", self.byteBuffer); NSLog(@"byte pointer: %p", self.byteBuffer);
@ -39,21 +47,20 @@ static int BUFFER_LENGTH = 131072;
len = [(NSInputStream *)inStream read:self.byteBuffer maxLength:BUFFER_LENGTH]; len = [(NSInputStream *)inStream read:self.byteBuffer maxLength:BUFFER_LENGTH];
if (len) if (len)
{ {
NSLog(@"len: %u\n", len);
BOOL firstStart = false; BOOL firstStart = false;
for (int i = 0; i < len - 4; i++) { for (int i = 0; i < len - 4; i++) {
self.offset++; self.offset++;
if (self.byteBuffer[i] == 0 && self.byteBuffer[i+1] == 0 if (self.byteBuffer[i] == 0 && self.byteBuffer[i+1] == 0
&& self.byteBuffer[i+2] == 0 && self.byteBuffer[i+3] == 1) && self.byteBuffer[i+2] == 0 && self.byteBuffer[i+3] == 1)
{ {
NSLog(@"i: %d", i);
if (firstStart) if (firstStart)
{ {
// decode the first i-1 bytes // decode the first i-1 bytes
[self.decoder decode:self.byteBuffer length:i-1]; [self.decoder decode:self.byteBuffer length:i];
[self renderFrame];
[inStream setProperty:[[NSNumber alloc] initWithInt:self.offset-4] forKey:NSStreamFileCurrentOffsetKey]; [inStream setProperty:[[NSNumber alloc] initWithInt:self.offset-4] forKey:NSStreamFileCurrentOffsetKey];
self.offset -= 4; self.offset -= 1;
break; break;
} else } else
{ {
@ -67,6 +74,12 @@ static int BUFFER_LENGTH = 131072;
NSLog(@"No Buffer!"); NSLog(@"No Buffer!");
} }
} }
}
- (void) renderFrame
{
[self.target performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:NULL waitUntilDone:FALSE];
} }
@end @end

View File

@ -21,8 +21,6 @@
} }
}*/ }*/
int decStat = nv_avc_decode(buffer, length); int decStat = nv_avc_decode(buffer, length);
NSLog(@"Decode Status: %d", decStat);
} }
- (id) init - (id) init
@ -125,23 +123,7 @@ int nv_avc_init(int width, int height, int perf_lvl, int thread_count) {
decoder_ctx->height = height; decoder_ctx->height = height;
decoder_ctx->pix_fmt = PIX_FMT_YUV420P; decoder_ctx->pix_fmt = PIX_FMT_YUV420P;
// Little-endian makes the AV_PIX_FMT constants look wierd render_pix_fmt = AV_PIX_FMT_RGBA;
if (perf_lvl & NATIVE_COLOR_RGB0) {
render_pix_fmt = AV_PIX_FMT_0BGR;
}
else if (perf_lvl & NATIVE_COLOR_0RGB) {
render_pix_fmt = AV_PIX_FMT_BGR0;
}
else if (perf_lvl & NATIVE_COLOR_RGBA) {
render_pix_fmt = AV_PIX_FMT_ABGR;
}
else if (perf_lvl & NATIVE_COLOR_ARGB) {
render_pix_fmt = AV_PIX_FMT_BGRA;
}
else {
// Default
render_pix_fmt = AV_PIX_FMT_ABGR;
}
err = avcodec_open2(decoder_ctx, decoder, NULL); err = avcodec_open2(decoder_ctx, decoder, NULL);
if (err < 0) { if (err < 0) {

View File

@ -12,18 +12,18 @@
<viewControllerLayoutGuide type="top" id="9ZL-gP-cfY"/> <viewControllerLayoutGuide type="top" id="9ZL-gP-cfY"/>
<viewControllerLayoutGuide type="bottom" id="Shd-7C-CVq"/> <viewControllerLayoutGuide type="bottom" id="Shd-7C-CVq"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="ugc-rC-3gm"> <view key="view" contentMode="scaleToFill" horizontalHuggingPriority="222" id="ugc-rC-3gm">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/> <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Geforce PC Host" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iC2-gT-zgS"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Geforce PC Host" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iC2-gT-zgS">
<rect key="frame" x="20" y="107" width="728" height="30"/> <rect key="frame" x="20" y="107" width="984" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="22"/> <fontDescription key="fontDescription" type="system" pointSize="22"/>
<textInputTraits key="textInputTraits"/> <textInputTraits key="textInputTraits"/>
</textField> </textField>
<pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rnA-uG-hAA"> <pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rnA-uG-hAA">
<rect key="frame" x="0.0" y="211" width="768" height="216"/> <rect key="frame" x="0.0" y="211" width="1024" height="216"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<connections> <connections>
<outlet property="dataSource" destination="wb7-af-jn8" id="25E-op-oh6"/> <outlet property="dataSource" destination="wb7-af-jn8" id="25E-op-oh6"/>
@ -31,7 +31,7 @@
</connections> </connections>
</pickerView> </pickerView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="taW-Um-zc6" userLabel="Start Stream Btn"> <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="taW-Um-zc6" userLabel="Start Stream Btn">
<rect key="frame" x="189" y="435" width="391" height="141"/> <rect key="frame" x="317" y="421" width="391" height="141"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="26"/> <fontDescription key="fontDescription" type="system" pointSize="26"/>
<state key="normal" title="Start Streaming Steam!"> <state key="normal" title="Start Streaming Steam!">
@ -39,13 +39,10 @@
</state> </state>
<connections> <connections>
<action selector="StreamButton:" destination="wb7-af-jn8" eventType="touchUpInside" id="u2m-8A-Tor"/> <action selector="StreamButton:" destination="wb7-af-jn8" eventType="touchUpInside" id="u2m-8A-Tor"/>
<segue destination="OIm-0n-i9v" kind="popover" popoverAnchorView="taW-Um-zc6" id="RqQ-bq-Vkc">
<popoverArrowDirection key="popoverArrowDirection" up="YES" down="YES" left="YES" right="YES"/>
</segue>
</connections> </connections>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Nz-KX-Du4" userLabel="Pair Btn"> <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Nz-KX-Du4" userLabel="Pair Btn">
<rect key="frame" x="311" y="604" width="147" height="36"/> <rect key="frame" x="439" y="595" width="147" height="36"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="26"/> <fontDescription key="fontDescription" type="system" pointSize="26"/>
<state key="normal" title="Pair with PC"> <state key="normal" title="Pair with PC">
@ -57,14 +54,17 @@
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view> </view>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<connections> <connections>
<outlet property="StreamConfigs" destination="rnA-uG-hAA" id="LPP-jQ-5eW"/> <outlet property="StreamConfigs" destination="rnA-uG-hAA" id="LPP-jQ-5eW"/>
<segue destination="OIm-0n-i9v" kind="modal" identifier="createStreamFrame" modalPresentationStyle="fullScreen" id="MOD-9A-3Sk"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="109" y="-320"/> <point key="canvasLocation" x="179" y="-318"/>
</scene> </scene>
<!--Stream Frame View Controller--> <!--Stream Frame View Controller-->
<scene sceneID="RuD-qk-7nb"> <scene sceneID="RuD-qk-7nb">
@ -74,15 +74,18 @@
<viewControllerLayoutGuide type="top" id="NG3-N1-D4k"/> <viewControllerLayoutGuide type="top" id="NG3-N1-D4k"/>
<viewControllerLayoutGuide type="bottom" id="3MH-n6-BSR"/> <viewControllerLayoutGuide type="bottom" id="3MH-n6-BSR"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView"> <view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/> <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view> </view>
<navigationItem key="navigationItem" id="aB9-My-tz5"/> <navigationItem key="navigationItem" id="G20-tf-3L9"/>
<connections> <nil key="simulatedStatusBarMetrics"/>
<outlet property="renderView" destination="VPm-Ae-rc4" id="Xf2-AW-9Cg"/> <nil key="simulatedTopBarMetrics"/>
</connections> <nil key="simulatedBottomBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>