AVAnimator Assertion failure in -[AVMvidFrameDecoder advanceToFrame:] 'framebuffer num bytes' - ios

I have dolwoaded the latest code from Github for AVAnimator library. I added the folders AVAnimator and LZMASDK in addition to AutoPropertyRelease.h and AutoPropertyRelease.m.
I am using the following code to play a video with alpha channel (adopted form another AVAnimator app examples):
CGRect iPhoneExplosionRect = CGRectMake(0, -2, 640/2, 480/2);
CGRect iPadExplosionRect = CGRectMake(0, -5, 840, 630);
NSString *rgbResourceName = #"ExplosionAdjusted_rgb_CRF_30_24BPP.m4v";
NSString *alphaResourceName = #"ExplosionAdjusted_alpha_CRF_30_24BPP.m4v";
// Output filename
NSString *tmpFilename;
NSString *tmpPath;
tmpFilename = #"Explosion.mvid";
tmpPath = [AVFileUtil getTmpDirPath:tmpFilename];
// Set to TRUE to always decode from H.264
BOOL alwaysDecode = FALSE;
if (alwaysDecode && [AVFileUtil fileExists:tmpPath]) {
BOOL worked = [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
NSAssert(worked, #"could not remove file %#", tmpPath);
}
// This loader will join 2 H.264 videos together into a single 32BPP .mvid
AVAssetJoinAlphaResourceLoader *resLoader = [AVAssetJoinAlphaResourceLoader aVAssetJoinAlphaResourceLoader];
resLoader.movieRGBFilename = rgbResourceName;
resLoader.movieAlphaFilename = alphaResourceName;
resLoader.outPath = tmpPath;
//resLoader.alwaysGenerateAdler = TRUE;
AVAnimatorMedia *media = [AVAnimatorMedia aVAnimatorMedia];
media.resourceLoader = resLoader;
self.expMedia = media;
// Frame decoder will read from generated .mvid file
AVMvidFrameDecoder *aVMvidFrameDecoder = [AVMvidFrameDecoder aVMvidFrameDecoder];
media.frameDecoder = aVMvidFrameDecoder;
// Create layer that video data will be directed into
CGRect expFrame;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
expFrame = iPhoneExplosionRect;
} else {
expFrame = iPadExplosionRect;
}
CALayer *layer = [CALayer layer];
layer.frame = expFrame;
}
if (FALSE) {
layer.backgroundColor = [UIColor orangeColor].CGColor;
}
[self.view.layer addSublayer:layer];
AVAnimatorLayer *animatorLayer = [AVAnimatorLayer aVAnimatorLayer:layer];
self.expAnimatorLayer = animatorLayer;
// Finally connect the media object to the layer so that rendering will be
// sent to the layer.
[animatorLayer attachMedia:media];
//media.animatorRepeatCount = 3;
//media.animatorRepeatCount = 30;
//media.animatorRepeatCount = INT_MAX;
[media prepareToAnimate];
Once prepareToAnimate is hit the application fails at an assertion as described below
** Assertion failure in -[AVMvidFrameDecoder advanceToFrame:], /Users/user/Documents/.../AVAnimator/AVMvidFrameDecoder.m:844
...*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'framebuffer num bytes'
Is it the architecture I am using (both 32 and 64 bit) causing it or something else?
I hope someone can put me on the right track
AF

I looked into this assert and different ways it might be reproduced. I tried improperly setting the arch flags to include only 32 bit or only 64 bit code in the executable and tested on a 64 bit device and the simulator. I was not able to reproduce the problem and it is not clear how it could happen. To gather more information, I added an extra check that is compiled in either DEBUG or OPT mode when the framebuffer is allocated, could you pull the most recent version of AVAnimator from the github or grab the patch from patch here. Please make sure that none of the defines were modified in your version of the code and that you are using the most recent version of Xcode.

Related

EXC_BAD_ACCESS when calling vuRenderControllerUpdateVideoBackgroundTexture

I receive a EXC_BAD_ACCESS (code=1, address = 0x0) when I call the function vuRenderControllerUpdateVideoBackgroundTexture in Vuforia 10.
None of the parameters I sent are NULL/nullptr though.
- (void)renderFrame {
if(![[self session]cameraIsStarted]) {
[[self view]setHidden:YES];
return;
}
[[self view]setHidden:NO];
CAMetalLayer* layer = (CAMetalLayer*) view.layer;
if(!_videoTexture) {
[self viewDidChangeSize:[layer drawableSize]];
}
id<CAMetalDrawable> drawable = [layer nextDrawable];
if(!drawable) {
return;
}
VuState* state = nullptr;
vuEngineAcquireLatestState([session engine], &state);
if(vuStateHasCameraFrame(state) == VU_FALSE) {
vuStateRelease(state);
return;
}
id<MTLCommandBuffer> commandBuffer = [[self commandQueue] commandBuffer];
MTLRenderPassDescriptor* backgroundPassDescriptor = [[MTLRenderPassDescriptor alloc] init];
MTLRenderPassColorAttachmentDescriptor* colorAttachment = [backgroundPassDescriptor colorAttachments][0];
[colorAttachment setTexture:[drawable texture]];
[colorAttachment setLoadAction:MTLLoadActionClear];
[colorAttachment setClearColor:MTLClearColorMake(0.0,0.0,0.0,1.0)];
[colorAttachment setStoreAction:MTLStoreActionStore];
[[backgroundPassDescriptor depthAttachment] setTexture:[self videoDepthTexture]];
[[backgroundPassDescriptor depthAttachment]setLoadAction:MTLLoadActionClear];
[[backgroundPassDescriptor depthAttachment]setStoreAction:MTLStoreActionStore];
[[backgroundPassDescriptor depthAttachment]setClearDepth:0.0f];
id<MTLRenderCommandEncoder> backgroundEncoder = [commandBuffer renderCommandEncoderWithDescriptor:backgroundPassDescriptor];
int textureUnitData = 0;
VuRenderVideoBackgroundData backgroundData;
backgroundData.renderData = &backgroundEncoder;
backgroundData.textureUnitData = &textureUnitData;
backgroundData.textureData = &_videoTexture;
VuResult result = vuRenderControllerUpdateVideoBackgroundTexture([session renderController], state, &backgroundData); // crash here
At the call site, the variables are like this:
Am I missing an undocumented precondition?
I am not familiar with Vuforia so I'm not sure if this will help.
The OxO is indeed likely to be a NULL pointer deference.
I dont see the contents of state on your image. Did you make sure state is not NULL anymore?
Else maybe check if there are methods to instantiate VuState and VuRenderVideoBackgroundData objects. Sometimes only declaring can be not enough.

iOS Core Foundation Memory Leak in External Library

I'm currently trying to write an application using an open-source, external library. I have the source code available to it, and can build myself a fresh copy whenever needed.
Anyway, while profiling my application - I noticed that some memory was leaking in the library. It's small - 128b a shot - but still, I'd prefer not to have memory leaks to begin with.
Here's the code. The modified code that I wrote is on top (that leaks), and the original code is on bottom (that leaks).
CFURLRef getURLFromPath(const char * path) {
//modified code to hopefully clean up after myself
CFStringRef cfTotalPath = CFStringCreateWithCString (NULL, path, kCFStringEncodingUTF8);
CFURLRef cURL = CFURLCreateWithFileSystemPath(NULL, cfTotalPath, kCFURLPOSIXPathStyle, false);
CFRelease(cfTotalPath);
return cURL;
//original code
/*CFStringRef cfTotalPath = CFStringCreateWithCString (kCFAllocatorDefault,
path, kCFStringEncodingUTF8);
return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfTotalPath,
kCFURLPOSIXPathStyle, false);*/
}
I'm relatively new to iOS programming; I'm debugging on an actual device, and I know that sometimes Instruments gives false-positives when it comes to leaks.
This is infuriating, because this one block of code is the last step in the stack trace for my leaks... and I honestly do not know how to fix it.
EDIT: From what I've read, Apple doesn't mind the occasional memory leak here and there; I'll continue programming, because this process only happens once per music file in my application - analyzing a track for the BPM (it gets saved once analyzed).
Edit2: Here's the referring code. I've added all of the CFRelease(fileURL), but it still leaks:
uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) {
if (s->samplerate == 0 || s->channels == 0) return AUBIO_FAIL;
AudioStreamBasicDescription clientFormat;
memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mSampleRate = (Float64)(s->samplerate);
clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
clientFormat.mChannelsPerFrame = s->channels;
clientFormat.mBitsPerChannel = sizeof(short) * 8;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
clientFormat.mReserved = 0;
AudioFileTypeID fileType = kAudioFileWAVEType;
CFURLRef fileURL = getURLFromPath(s->path);
bool overwrite = true;
OSStatus err = noErr;
err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile);
if (err) {
char_t errorstr[20];
AUBIO_ERR("sink_apple_audio: error when trying to create %s with "
"ExtAudioFileCreateWithURL (%s)\n", s->path,
getPrintableOSStatusError(errorstr, err));
goto beach;
}
if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, "
"out of memory? \n", s->path);
goto beach;
}
//added release code
CFRelease(fileURL);
return AUBIO_OK;
beach:
//added release code
CFRelease(fileURL);
return AUBIO_FAIL;
}
EDIT3: Here's a screenshot
EDIT4: The original solution actually works, XCode refused to load the new version of my framework even though I kept recompiling it. So, I had to purge all references of the framework - including scrubbing the Build info pages - and re-add the "fixed" version.
You are leaking the returned CFURLRef created with CFURLCreateWithFileSystemPath.
You should rename the function from getURLFromPath to createURLFromPath to indicate that ownership of the returned CFURLRef is being passed on to the caller. Then any code that calls the method is responsible for releasing the CFURLRef when done with it.

IOMobileFramebufferGetLayerDefaultSurface function failed on iOS 9

I created a app to capture screenshot in background. It works well on iOS 7.x & 8.x, but failed to execute on iOS 9 beta. Here's my code:
CFMutableDictionaryRef sm = IOServiceMatching("AppleH1CLCD");
io_service_t ioService = IOServiceGetMatchingService(kIOMasterPortDefault, sm);
if (!ioService)
{
sm = IOServiceMatching("AppleM2CLCD");
ioService = IOServiceGetMatchingService(kIOMasterPortDefault, sm);
}
if (!ioService)
{
sm = IOServiceMatching("AppleCLCD");
ioService = IOServiceGetMatchingService(kIOMasterPortDefault, sm);
}
IOMobileFramebufferConnection connection = 0;
IOSurfaceRef ptr = nil;
IOMobileFramebufferReturn openMobileFrameBufferResult = IOMobileFramebufferOpen(ioService, mach_task_self(), 0, &connection);
if (openMobileFrameBufferResult)
{
return;
}
IOMobileFramebufferReturn getLayerDefaultSurfaceResult = IOMobileFramebufferGetLayerDefaultSurface(connection, 0, (CoreSurfaceBufferRef*)&ptr);
if (getLayerDefaultSurfaceResult)
{
return; // Here, the getLayerDefaultSurfaceResult is -536870201, not 0!
}
.......
When debugging it step by step, I found that the function IOMobileFramebufferGetLayerDefaultSurface failed to execute with a returning value -536870201 and the value expected was 0.
Who can tell me why this happened and how to resolve it ? thhhhhhhhhhhhhhhx!!
Another user asked a similar question. I did some digging into IOMobileFramebufferGetLayerDefaultSurface on iOS8 vs iOS9 (GM). And the results of what I found are summarized in this answer.
Given these results, I believe it is no longer possible, as of iOS9, to use IOMFB to capture the screen.

Waiting time Epson T88V

PROBLEM:
How to print (multiple) receipts without any delay?
As far as I know, there are at least 3 options to print with a T88V on OSX or iOS device. Unfortunately, all 3 of those options has a flaw.
OPTION 1:
I've been playing around with the official OSX driver (latest version 1.2a) and have no problems printing with it. However, between every print command, there's 1 sec delay.
- (IBAction)button1:(id)sender
{
[self TMAppPrint];
}
- (OSStatus)TMAppPrint
{
TMTextView *textWindow = [[TMTextView alloc] init];
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
OSStatus err = noErr;
err = [TMPrintSupport TMSetJobTicket:printInfo printerName:#"TM-T88V" documentSize:NSMakeSize(204.0, 841.8) resolution:#"180x180dpi" speed:#"1" blank:#"Off" paperCut:#"DocFeedCut" chashDrwr1:#"Off" chashDrwr2:#"Off" buzzerControl:#"Off" buzzerPattern:#"Internal" buzzerRepeat:#"1"];
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:textWindow printInfo:printInfo];
[printOperation setCanSpawnSeparateThread:YES];
[printOperation setShowsPrintPanel:NO];
[printOperation runOperation];
return err;
}
OPTION 2:
Using the iOS SDK (latest version 1.3.0) I can also print without problems but it's even worse. After sending the print command, there will be 1 sec delay till it prints.
- (IBAction)button2:(id)sender
{
if (printer != nil)
{
errorStatus = EPOS_OC_SUCCESS;
if (builder != nil)
{
int printStatus = EPOS_OC_SUCCESS;
// create a print document
printStatus = [builder addTextLang: EPOS_OC_LANG_EN];
printStatus = [builder addTextSmooth: EPOS_OC_TRUE];
printStatus = [builder addTextFont: EPOS_OC_FONT_A];
printStatus = [builder addTextSize: 1 Height: 1];
printStatus = [builder addTextStyle: EPOS_OC_FALSE Ul: EPOS_OC_FALSE Em: EPOS_OC_TRUE Color: EPOS_OC_PARAM_UNSPECIFIED];
// specify the print data>
printStatus = [builder addText: #"hello!\n"];
printStatus = [builder addCut: EPOS_OC_CUT_FEED];
// send data>
errorStatus = [printer sendData:builder Timeout:1000 Status: &status];
// end communication with the printer>
errorStatus = [printer closePrinter];
}
}
}
OPTION 3:
The last option is using the ESC/POS commands. I managed to get it to print some basic lines but I still don't understand most of it. There's no delay in printing though.
- (IBAction)button3:(id)sender
{
printer = [[EposPrint alloc] init];
errorStatus = [printer openPrinter:EPOS_OC_DEVTYPE_TCP DeviceName:#"192.168.1.168"];
builder = [[EposBuilder alloc] initWithPrinterModel:#"TM-T88V" Lang:EPOS_OC_MODEL_ANK];
}
I already directly asked Epson about this, but they couldn't give me any answer except it's working as intended... Which means I have to dive into the ESC/POS commands and learn it or are there still other options?

How can I use the PoDoFo library for annotating PDFs on iOS?

I would like to annotate PDFs within an iOS application. I came across the PoDoFo library, but I'm not sure how to use this in an iOS application.
Is it possible to use this library to annotate PDFs on iOS? If so, how?
Please do something like this.
+ (void)createUTFAnnotationTextOnPage:(NSInteger)pageIndex
doc:(PdfDocument*)doc // PdfMemDocument instance
rect:(PdfRect)rect
title:(NSString*)title
content:(NSString*)content
bOpen:(Boolean)bOpen
colorR:(double)r
colorG:(double)g
colorB:(double)b {
PdfPage* pPage = doc->GetPage(pageIndex);
if (! pPage) {
// couldn't get that page
return;
}
PdfAnnotation* anno;
anno = pPage->CreateAnnotation(ePdfAnnotation_Text, rect);
PdfString sTitle(reinterpret_cast<const pdf_utf8*>([title UTF8String]));
PdfString sContent(reinterpret_cast<const pdf_utf8*>([content UTF8String]));
anno->SetTitle(sTitle);
anno->SetContents(sContent);
anno->SetColor(r, g, b);
anno->SetOpen(bOpen);
}
// -----------
PdfError::EnableDebug(false); // or true
NSString* inFile = [[NSBundle mainBundle] pathForResource:#"forTesting.pdf" ofType:nil];
PoDoFo::PdfMemDocument doc( [inFile UTF8String] );
[YourPodofoObj createUTFAnnotationTextOnPage:0 doc:&doc rect:PdfRect(50, 50, 50, 50) title:#"author by XX" content:#"I use it for test" bOpen:true colorR:1.0 colorG:.0 colorB:.0];
doc.Write(OUT_PUT_PATH);
The Above answer only provides you way to add Annotations (of Type FreeText etc). Generally you would want to create/Modify Fields. I normally use PdfTextFields, PdfCheckboxes, PdfSignature Field for this purpose. Hope that helps
PdfMemDocument memDoc;
PdfFileInputStream fileInputStream(filePath);
char *srcBuffer = new char[fileInputStream.GetFileLength()];
size_t srcLen = fileInputStream.GetFileLength();
fileInputStream.Read(srcBuffer,srcLen);
PdfOutputDevice outputDevice(filePath);
outputDevice.Write(srcBuffer,srcLen);
memDoc.Load(srcBuffer,srcLen);
PdfTextField txtField = PdfTextField( pPage,PdfRect(50, 50, 50, 50),&memDoc);
txtField.SetFieldName(#"SomeUniqueName");
memDoc.Write(&outputDevice);
outputDevice.Flush();

Resources