I get
collect2: ld returned 1 exit status
usr/bin/g++4.2 failed with exit code 1
#import <stdio.h>
#import <string.h>
#import <mach/mach_host.h>
#import <sys/sysctl.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPSKeys.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
void printMemoryInfo()
{
size_t length;
int mib[6];
int result;
printf("Memory Info\n");
printf("-----------\n");
int pagesize;
mib[0] = CTL_HW;
mib[1] = HW_PAGESIZE;
length = sizeof(pagesize);
if (sysctl(mib, 2, &pagesize, &length, NULL, 0) < 0)
{
perror("getting page size");
}
printf("Page size = %d bytes\n", pagesize);
printf("\n");
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) != KERN_SUCCESS)
{
printf("Failed to get VM statistics.");
}
double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count;
double wired = vmstat.wire_count / total;
double active = vmstat.active_count / total;
double inactive = vmstat.inactive_count / total;
double free = vmstat.free_count / total;
printf("Total = %8d pages\n", vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count);
printf("\n");
printf("Wired = %8d bytes\n", vmstat.wire_count * pagesize);
printf("Active = %8d bytes\n", vmstat.active_count * pagesize);
printf("Inactive = %8d bytes\n", vmstat.inactive_count * pagesize);
printf("Free = %8d bytes\n", vmstat.free_count * pagesize);
printf("\n");
printf("Total = %8d bytes\n", (vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count) * pagesize);
printf("\n");
printf("Wired = %0.2f %%\n", wired * 100.0);
printf("Active = %0.2f %%\n", active * 100.0);
printf("Inactive = %0.2f %%\n", inactive * 100.0);
printf("Free = %0.2f %%\n", free * 100.0);
printf("\n");
mib[0] = CTL_HW;
mib[1] = HW_PHYSMEM;
length = sizeof(result);
if (sysctl(mib, 2, &result, &length, NULL, 0) < 0)
{
perror("getting physical memory");
}
printf("Physical memory = %8d bytes\n", result);
mib[0] = CTL_HW;
mib[1] = HW_USERMEM;
length = sizeof(result);
if (sysctl(mib, 2, &result, &length, NULL, 0) < 0)
{
perror("getting user memory");
}
printf("User memory = %8d bytes\n", result);
printf("\n");
}
void printProcessorInfo()
{
size_t length;
int mib[6];
int result;
printf("Processor Info\n");
printf("--------------\n");
mib[0] = CTL_HW;
mib[1] = HW_CPU_FREQ;
length = sizeof(result);
if (sysctl(mib, 2, &result, &length, NULL, 0) < 0)
{
perror("getting cpu frequency");
}
printf("CPU Frequency = %d hz\n", result);
mib[0] = CTL_HW;
mib[1] = HW_BUS_FREQ;
length = sizeof(result);
if (sysctl(mib, 2, &result, &length, NULL, 0) < 0)
{
perror("getting bus frequency");
}
printf("Bus Frequency = %d hz\n", result);
printf("\n");
}
int printBatteryInfo()
{
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
CFDictionaryRef pSource = NULL;
const void *psValue;
int numOfSources = CFArrayGetCount(sources);
if (numOfSources == 0) {
perror("Error getting battery info");
return 1;
}
printf("Battery Info\n");
printf("------------\n");
for (int i = 0 ; i < numOfSources ; i++)
{
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
if (!pSource) {
perror("Error getting battery info");
return 2;
}
psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
int curCapacity = 0;
int maxCapacity = 0;
int percent;
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
percent = (int)((double)curCapacity/(double)maxCapacity * 100);
printf ("powerSource %d of %d: percent: %d/%d = %d%%\n", i+1, CFArrayGetCount(sources), curCapacity, maxCapacity, percent);
printf("\n");
}
}
int printProcessInfo() {
int mib[5];
struct kinfo_proc *procs = NULL, *newprocs;
int i, st, nprocs;
size_t miblen, size;
/* Set up sysctl MIB */
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
mib[3] = 0;
miblen = 4;
/* Get initial sizing */
st = sysctl(mib, miblen, NULL, &size, NULL, 0);
/* Repeat until we get them all ... */
do {
/* Room to grow */
size += size / 10;
newprocs = realloc(procs, size);
if (!newprocs) {
if (procs) {
free(procs);
}
perror("Error: realloc failed.");
return (0);
}
procs = newprocs;
st = sysctl(mib, miblen, procs, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st != 0) {
perror("Error: sysctl(KERN_PROC) failed.");
return (0);
}
/* Do we match the kernel? */
assert(size % sizeof(struct kinfo_proc) == 0);
nprocs = size / sizeof(struct kinfo_proc);
if (!nprocs) {
perror("Error: printProcessInfo.");
return(0);
}
printf(" PID\tName\n");
printf("-----\t--------------\n");
for (i = nprocs-1; i >=0; i--) {
printf("%5d\t%s\n",(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm);
}
free(procs);
return (0);
}
int main(int argc, char **argv)
{
printf("iPhone Hardware Info\n");
printf("====================\n");
printf("\n");
printMemoryInfo();
printProcessorInfo();
printBatteryInfo();
printProcessInfo();
return (0);
}
No. The iPhone SDK does not include IOKit as part of the default header search path, so it's unlikely that an app that uses it would be approved for the App Store. (It works in the simulator if you find and link IOKit manually, but a 30 second attempt to compile it for a device failed)
Related
The problem is:
Memory is never released; potential leak of memory pointed to by 'p'
In Code it occurs on the return of this single line method:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}
base64_encode function:
char* base64_encode(const void* buf, size_t size)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* str = (char*) malloc((size+3)*4/3 + 1);
char* p = str;
unsigned char* q = (unsigned char*) buf;
size_t i = 0;
while(i < size) {
int c = q[i++];
c *= 256;
if (i < size) c += q[i];
i++;
c *= 256;
if (i < size) c += q[i];
i++;
*p++ = base64[(c & 0x00fc0000) >> 18];
*p++ = base64[(c & 0x0003f000) >> 12];
if (i > size + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000fc0) >> 6];
if (i > size)
*p++ = '=';
else
*p++ = base64[c & 0x0000003f];
}
*p = 0;
return str;
}
You should free(str) after converting the char * to NSString:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
char *base64 = base64_encode(input, length);
NSString *ret = [NSString stringWithUTF8String:base64];
free(base64);
return ret;
}
the memory allocated with the malloc function has to be released with free, you has to change the line
*p = 0;
to
free(p);
I am trying to implement the new VerificationController.m class that Apple released to fix the in-app purchase fraud problem.
As everything released by Apple, this is one more vague, incomplete and bad explained document with a lot of voids and unknowns that cannot be circumvented/understood by everyone.
I am trying to implement that, but at the end of the code we see these four methods:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
#warning Replace this method.
return nil;
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
#warning Replace this method.
return nil;
}
#warning Implement this function.
char* base64_encode(const void* buf, size_t size)
{ return NULL; }
#warning Implement this function.
void * base64_decode(const char* s, size_t * data_len)
{ return NULL; }
You can see that Apple was lazy to implement the C functions at the end of the code. As my C/C++ abilities stink, I see I need to implement these two functions in C/C++ and that they must return char and void (???). Other people have posted routines to do that on SO, but they are either in Objective-C or not returning chars and void (??).
NOTE: this is another problem I have: how can a method return void if it is used by Apple in this form?
uint8_t *purchase_info_bytes = base64_decode([purchase_info_string cStringUsingEncoding:NSASCIIStringEncoding], &purchase_info_length);
shouldn't it be returning uint8_t?
NOTE2: another problem I have is that apple says base64_encode is required but it is not being used on the code provided by them. I think they are smoking bad stuff or my C/C++ knowledge really stink.
So, returning to my first question. Can someone post/point a method that can do the job that follows the requirements of the declared methods base64_encode and base64_decode? Please refrain from posting objective-c methods that are not compatible with these requirements imposed by Apple.
Thanks.
This solution should be pretty straight forward, which includes all the methods to populate the missing information. Tested and functional within the sandbox.
// single base64 character conversion
static int POS(char c)
{
if (c>='A' && c<='Z') return c - 'A';
if (c>='a' && c<='z') return c - 'a' + 26;
if (c>='0' && c<='9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
if (c == '=') return -1;
[NSException raise:#"invalid BASE64 encoding" format:#"Invalid BASE64 encoding"];
return 0;
}
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
size_t retLen;
uint8_t *retStr = base64_decode([input UTF8String], &retLen);
if (length)
*length = (NSInteger)retLen;
NSString *st = [[[NSString alloc] initWithBytes:retStr
length:retLen
encoding:NSUTF8StringEncoding] autorelease];
free(retStr); // If base64_decode returns dynamically allocated memory
return st;
}
char* base64_encode(const void* buf, size_t size)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* str = (char*) malloc((size+3)*4/3 + 1);
char* p = str;
unsigned char* q = (unsigned char*) buf;
size_t i = 0;
while(i < size) {
int c = q[i++];
c *= 256;
if (i < size) c += q[i];
i++;
c *= 256;
if (i < size) c += q[i];
i++;
*p++ = base64[(c & 0x00fc0000) >> 18];
*p++ = base64[(c & 0x0003f000) >> 12];
if (i > size + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000fc0) >> 6];
if (i > size)
*p++ = '=';
else
*p++ = base64[c & 0x0000003f];
}
*p = 0;
return str;
}
void* base64_decode(const char* s, size_t* data_len_ptr)
{
size_t len = strlen(s);
if (len % 4)
[NSException raise:#"Invalid input in base64_decode" format:#"%d is an invalid length for an input string for BASE64 decoding", len];
unsigned char* data = (unsigned char*) malloc(len/4*3);
int n[4];
unsigned char* q = (unsigned char*) data;
for(const char*p=s; *p; )
{
n[0] = POS(*p++);
n[1] = POS(*p++);
n[2] = POS(*p++);
n[3] = POS(*p++);
if (n[0]==-1 || n[1]==-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
if (n[2]==-1 && n[3]!=-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
}
// make sure that data_len_ptr is not null
if (!data_len_ptr)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid destination for output string length"];
*data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1);
return data;
}
Here is a base 64 encode function for NSString to NSString:
+(NSString *) encodeString:(NSString *)inString
{
NSData *data = [inString dataUsingEncoding:NSUTF8StringEncoding];
//Point to start of the data and set buffer sizes
int inLength = [data length];
int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
const char *inputBuffer = [data bytes];
char *outputBuffer = malloc(outLength);
outputBuffer[outLength] = 0;
//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//start the count
int cycle = 0;
int inpos = 0;
int outpos = 0;
char temp;
outputBuffer[outLength-1] = '=';
outputBuffer[outLength-2] = '=';
while (inpos < inLength){
switch (cycle) {
case 0:
outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
cycle = 1;
break;
case 1:
temp = (inputBuffer[inpos++]&0x03)<<4;
outputBuffer[outpos] = Encode[temp];
cycle = 2;
break;
case 2:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
temp = (inputBuffer[inpos++]&0x0F)<<2;
outputBuffer[outpos] = Encode[temp];
cycle = 3;
break;
case 3:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
cycle = 4;
break;
case 4:
outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
cycle = 0;
break;
default:
cycle = 0;
break;
}
}
NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
free(outputBuffer);
return pictemp;
}
and Here is a base 64 decode function for NSString to NSString:
+(NSString *) decodeString:(NSString *)inString
{
const char* string = [inString cStringUsingEncoding:NSASCIIStringEncoding];
NSInteger inputLength = inString.length;
static char decodingTable[128];
static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (NSInteger i = 0; i < 128; i++) {
decodingTable[encodingTable[i]] = i;
}
if ((string == NULL) || (inputLength % 4 != 0)) {
return nil;
}
while (inputLength > 0 && string[inputLength - 1] == '=') {
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}
NSLog(#"%#",data);
NSString *finalString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return finalString;
}
These were pieced together from examples I found in various places on the internet when I was searching for them a while ago. They, may be easier for you to implement. I just created a Base64 class and placed these methods in it.
Here are the C wrappers around Justin's answer:
char* base64_encode(const void* buf, size_t size)
{
NSData* data = [NSData dataWithBytesNoCopy:(void*)buf length:size];
NSString* string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return [[_Class_ encode:string] UTF8String];
}
void* base64_Decode (const char* s, size_t* data_len)
{
NSString* result = [_Class_ decode:[NSString stringWithCString:s encoding:NSASCIIStringEncoding]];
*data_len = result.length;
return [result UTF8String];
}
Where Class is the class that contains Justin's functions.
I've got an app where I use Core Audio for sound recording. Sound is made from some parts and then must be saved to the device. It was working fine but in some new ios versions I have a noise, something like distortion, in output files. What is the possible reason? ExtAudioFileCreateWithURL is used to create output file and ExtAudioFileSetProperty to set its properties.
Any help will be appreciated.
This code was created by another programmer who is currently unavailable, so I don't have any idea why such hack was implemented.
The way sound buffer is created for different versions of ios:
static BOOL shouldFixData = NO;
static int checkOnce = 1;
if (checkOnce) {
checkOnce = 0;
if (inNumberFrames * 8 == ioData->mBuffers[0].mDataByteSize) {
shouldFixData = YES;
}
}
if (shouldFixData) {
AudioBufferList cutData = {0};
cutData.mNumberBuffers = 1;
cutData.mBuffers[0].mNumberChannels = ioData->mBuffers[0].mNumberChannels;
cutData.mBuffers[0].mDataByteSize = ioData->mBuffers[0].mDataByteSize / 2;
cutData.mBuffers[0].mData = malloc(cutData.mBuffers[0].mDataByteSize);
SInt32* oldData = (SInt32*)ioData->mBuffers[0].mData;
SInt32* newData = (SInt32*)cutData.mBuffers[0].mData;
int count = cutData.mBuffers[0].mDataByteSize/4;
for (int i = 0; i < count; ++i) {
newData[i] = oldData[i*2];
}
ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, &cutData);
free(cutData.mBuffers[0].mData);
} else {
ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, ioData);
}
}
Saving the record:
CAStreamBasicDescription dstFormat;
dstFormat.mSampleRate = mOutputFormat.mSampleRate;
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mChannelsPerFrame = 2;
dstFormat.mBitsPerChannel = 16;
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mFramesPerPacket = 1;
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
//recordInfo.output file is ExtAudioFileRef
err = ExtAudioFileCreateWithURL((CFURLRef)recordFileURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordInfo.outputFile);
if (err) { printf("ExtAudioFileCreateWithURL result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
NSComparisonResult versionCompareRes = [currSysVer compare:#"4.3" options:NSNumericSearch];
if (versionCompareRes == NSOrderedSame || versionCompareRes == NSOrderedDescending) {
//for new versions
err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(mOutputFormat), &mOutputFormat);
if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
} else {
//for old versions
err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(dstFormat), &dstFormat);
if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; }
}
sample output file:
output.mp3
You could use SPEEX to do denoising, include speex_preprocess.h first:
SpeexPreprocessState *_spt = speex_preprocess_state_init(NN, 16000);/NN is 320 for sampleRate 16000.
int i=1;
speex_preprocess_ctl(_spt, SPEEX_PREPROCESS_SET_DENOISE, &i);
-(BOOL)doConvert:(void *)data SampleLength:(SInt64)length
{
AudioBufferList *dataBuffer = (AudioBufferList*)data;
AudioSampleType *samples = (AudioSampleType*)dataBuffer->mBuffers[0].mData;
SInt64 count = length / NN;
//short sample_ground[count][NN];
short **sample_group;
sample_group = (short**)malloc(sizeof(short*)*count);
for (int i=0; i<count; i++)
sample_group[i] = (short*)malloc(sizeof(short)*NN);
for (int i = 0; i < count; i++) {
for (int j = 0 ; j < NN; j++) {
short value = samples[i*NN+j];
sample_group[i][j] = value;
}
}
for (int i = 0; i < count; i++) {
speex_preprocess_run(_spt, sample_group[i]);
}
for (int i = 0; i < count; i++) {
for (int j = 0 ; j < NN; j++) {
samples[i*NN+j] = sample_group[i][j];
}
}
for (int i=0; i<count; i++)
free(sample_group[i]);
free(sample_group);
return YES;
}
oops.. should have been feedback. Sorry..
The main difference in the code you posted is the format setup
sizeof(mOutputFormat), &mOutputFormat
where mOutputFormat not specified how its set.
compared to the dst format for older version which is set.
Setting "wrong" format usually gives bad sound :-)
I'm working on a program that monitors your iPhone's charging statues while plugged into your PC. How can I do this in either VB, BAT or C++?
You can set the following on a timer (in ObjC):
-(NSString *)getBatteryPercent
{
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
CFDictionaryRef pSource = NULL;
const void *psValue;
int i;
int curCapacity = 0;
int maxCapacity = 0;
int percent = 0;
int numOfSources = CFArrayGetCount(sources);
//if (numOfSources == 0) return 1;
for (i = 0 ; i < numOfSources ; i++)
{
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
percent = (int)((double)curCapacity/(double)maxCapacity * 100);
}
return [NSString stringWithFormat:#"%d",percent];
}
To get the state of the battery:
-(NSString*)batteryStateStatus:(UIDeviceBatteryState)state
{
switch ( state )
{
case UIDeviceBatteryStateUnknown:
return #"Unknown";
break;
case UIDeviceBatteryStateUnplugged:
return #"Unplugged";
break;
case UIDeviceBatteryStateCharging:
return #"Charging";
break;
case UIDeviceBatteryStateFull:
return #"Charged";
break;
}
return nil;
}
EDIT:
Requires the IOKit.framework
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPSKeys.h>
I'd like to convert NSImage/UIImage to AVFrame(ffmpeg).
I found a example code.
http://lists.mplayerhq.hu/pipermail/libav-user/2010-April/004550.html
but this code doesn't work.
I tried another approach.
AVFrame *frame = avcodec_alloc_frame();
int numBytes = avpicture_get_size(PIX_FMT_YUV420P, outputWidth, outputHeight);
uint8_t *buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)frame, buffer, PIX_FMT_YUV420P, outputWidth, outputHeight);
//UIImage *image = … smothing … ;
NSImage *image = … smothing … ;
//CGImageRef newCgImage = image.CGImage;
CGImageRef newCgImage = [image CGImageForProposedRect:nil context:nil hints:nil];
//NSBitmapImageRep* bm = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
//CGImageRef newCgImage = [bm CGImage];
size_t w = CGImageGetWidth(newCgImage);
size_t h = CGImageGetHeight(cgImage);
CGDataProviderRef dataProvider = CGImageGetDataProvider(newCgImage);
CFDataRef bitmapData = CGDataProviderCopyData(dataProvider);
uint8_t *buffer = (uint8_t *)CFDataGetBytePtr(bitmapData);
frame->linesize[0] = w;
int y, x;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
int z = y * w + x;
frame->data[0][z] = buffer[z];
}
}
but this AVFrame give me green picture.
Please let me know how can i get it.
Thanks.
following is additional.
I tried again with paying attention color format.
I found example to conver RGB to YUM.
How to perform RGB->YUV conversion in C/C++?
new code is like this.but,still doesn't work…
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <libavutil/avstring.h>
#import <libavcodec/avcodec.h>
#import <libavformat/avformat.h>
#import <libswscale/swscale.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
int i;
int outputWidth = 480; //size must be same size of arg
int outputHeight = 360; //size must be same size of arg
av_register_all();
AVOutputFormat *format = av_guess_format("mp4", NULL, NULL);
if(!format) return -1;
AVFormatContext *outFormatCtx = avformat_alloc_context();
if(!outFormatCtx) return -1;
outFormatCtx->oformat = format;
av_strlcpy(outFormatCtx->filename, "test.mov", sizeof(outFormatCtx->filename));
AVStream *vstream = av_new_stream(outFormatCtx, 0);
if(!vstream) return -1;
enum CodecID codec_id = av_guess_codec(outFormatCtx->oformat,
NULL,
outFormatCtx->filename,
NULL, CODEC_TYPE_VIDEO);
AVCodec *ovCodec = avcodec_find_encoder(codec_id);
if(!ovCodec) return -1;
AVCodecContext *ovCodecCtx = vstream->codec;
ovCodecCtx->codec_id = ovCodec->id;
ovCodecCtx->codec_type = CODEC_TYPE_VIDEO;
ovCodecCtx->width = outputWidth;
ovCodecCtx->height = outputHeight;
ovCodecCtx->pix_fmt = PIX_FMT_NONE;
if(ovCodec && ovCodec->pix_fmts){
const enum PixelFormat *p = ovCodec->pix_fmts;
while(*p++ != -1){
if(*p == ovCodecCtx->pix_fmt) break;
}
if(*p == -1) ovCodecCtx->pix_fmt = ovCodec->pix_fmts[0];
}
ovCodecCtx->time_base.num = 1;
ovCodecCtx->time_base.den = 30;
if(format->flags & AVFMT_GLOBALHEADER)
ovCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
if(avcodec_open(ovCodecCtx, ovCodec) != 0) return -1;
if (! ( format->flags & AVFMT_NOFILE )) {
if(url_fopen(&outFormatCtx->pb, outFormatCtx->filename, URL_WRONLY) < 0) return NO;
}
av_write_header(outFormatCtx);
int buf_size = ovCodecCtx->width * ovCodecCtx->height * 4;
uint8_t *buf = av_malloc(buf_size);
AVFrame *buffer_frame = avcodec_alloc_frame();
if(!buffer_frame) return -1;
AVFrame *frame = avcodec_alloc_frame();
if(!frame) return -1;
int numBytes = avpicture_get_size(PIX_FMT_YUV420P, outputWidth, outputHeight);
uint8_t *buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)frame, buffer, PIX_FMT_YUV420P, outputWidth, outputHeight);
for(i=1;i<argc;i++){
NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[NSString stringWithCString: argv[i] encoding: NSUTF8StringEncoding]];
CGImageRef imageRef = [image CGImageForProposedRect:nil context:nil hints:nil];
size_t w = CGImageGetWidth(imageRef);
size_t h = CGImageGetHeight(imageRef);
size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);
CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef);
CFDataRef bitmapData = CGDataProviderCopyData(dataProvider);
uint8_t *buff = (uint8_t *)CFDataGetBytePtr(bitmapData);
uint8_t R,G,B,Y,U,V;
int x,y;
for(y=0;y<h;y++){
for(x=0;x<w;x++){
uint8_t *tmp = buff + y * bytesPerRow + x * 4;
R = *(tmp + 3);
G = *(tmp + 2);
B = *(tmp + 1);
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16;
U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128;
V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128;
//printf("y:%d x:%d R:%d,G:%d,B:%d Y:%d,U:%d,V:%d \n",y,x,R,G,B,Y,U,V);
frame->data[0][y*frame->linesize[0]+x]= Y;
//frame->data[1][y*frame->linesize[1]+x]= U; //if coment out "Bus error"
//frame->data[2][y*frame->linesize[2]+x]= V; //if coment out "Bus error"
}
}
CGImageRelease(imageRef);
CFRelease(bitmapData);
int out_size = avcodec_encode_video (ovCodecCtx, buf, buf_size, frame);
AVPacket outPacket;
av_init_packet(&outPacket);
outPacket.stream_index= vstream->index;
outPacket.data= buf;
outPacket.size= out_size;
//outPacket.pts = ?;
//outPacket.dts = ?;
if(ovCodecCtx->coded_frame->key_frame)
outPacket.flags |= PKT_FLAG_KEY;
if(av_interleaved_write_frame(outFormatCtx, &outPacket) != 0) return -1;
[image release];
[innerPool release];
}
av_write_trailer(outFormatCtx);
if (! ( format->flags & AVFMT_NOFILE ))
if(url_fclose(outFormatCtx->pb) < 0) return -1;
avcodec_close(vstream->codec);
for(i = 0; i < outFormatCtx->nb_streams; i++) {
av_freep(&outFormatCtx->streams[i]->codec);
av_freep(&outFormatCtx->streams[i]);
}
av_freep(&outFormatCtx);
av_free(buffer);
av_free(frame);
av_free(buffer_frame);
[pool release];
return 0;
}
and mekefile is like this.
CC = /usr/bin/gcc
CFLAGS = -O4 -Wall -I/usr/local/include
LDFLAGS =
LDLIBS = -L/usr/local/bin -lavutil -lavformat -lavcodec -lswscale
FRAMEWORK = -framework Foundation -framework AppKit #-framework CoreGraphics
OBJS = test.o
test: $(OBJS)
$(CC) -o $# $(LDFLAGS) $(OBJS) $(LDLIBS) $(FRAMEWORK) -lz -lbz2 -arch x86_64
Please somebody help me.
There is a colorspace mismatch between the data of the CGImage and the destination AVFrame. In order to fix that, you need to convert the CGImage data (probably in ARGB) into the YUV420 format (FFMpeg has built-in format converter). You can get information on the colorspace of a CGImage with the CGImageGetBitsPerComponent, CGImageGetBitsPerPixel and CGImageGetBytesPerRow functions.