GStreamer in Qt quick - qml

I am trying to create a GStreamer pipeline for mp4 video in Qt quick, but I can't seem to figure out how to do so. I think that I'm missing some elements since the code compiles but wont play the video.
int main(int argc, char *argv[])
{
int ret;
gst_init (&argc, &argv);
{
QGuiApplication app(argc, argv);
GstElement *pipeline = gst_pipeline_new (NULL);
GstElement *src = gst_element_factory_make ("filesrc", "source");
GstElement *dec= gst_element_factory_make ("decodebin", "decoder");
GstElement *col = gst_element_factory_make("glcolorconvert", "color_convert");
GstElement *glupload = gst_element_factory_make("glupload",NULL);
/* the plugin must be loaded before loading the qml file to register the
* GstGLVideoItem qml item */
GstElement *sink = gst_element_factory_make ("qmlglsink", NULL);
g_assert (src && dec && glupload && col && sink);
g_object_set (G_OBJECT (src), "location", "file: path-to-file", NULL);
gst_bin_add_many (GST_BIN (pipeline), src, glupload, dec, col, sink, NULL);
gst_element_link_many (src, glupload, dec, sink, NULL);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickItem *videoItem;
QQuickWindow *rootObject;
/* find and set the videoItem on the sink */
rootObject = static_cast<QQuickWindow *> (engine.rootObjects().first());
videoItem = rootObject->findChild<QQuickItem *> ("videoItem");
g_assert (videoItem);
g_object_set(sink, "widget", videoItem, NULL);
rootObject->scheduleRenderJob (new SetPlaying (pipeline),
QQuickWindow::BeforeSynchronizingStage);
ret = app.exec();
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
}
gst_deinit ();
return ret;
}

Related

How to send signal to a child process created via fork and execl?

Assume I have a program foo that simply prints forever but is stopped before then,
int main(int argc, char * argv[])
{
kill(getpid(), SIGSTOP);
while(1) {
printf("foo\n");
}
return 0;
}
And then I have a program bar that forks and runs foo:
int main(int argc, char * argv[])
{
pid_t pid = fork();
if (pid == 0)
{
execl("foo", "foo", NULL);
}
return 0;
}
Now, I want bar to be able to send SIGCONT to foo so it can go on its printing duties, and then later send SIGSTOP again, and even later send SIGCONT again, and so on.
I couldn't figure out how to do that. Any help?
EDIT: I figured out my problem. Apparently, the foo program isn't ready to accept signals immediately when it runs. When I did
sleep(5);
int rc = kill(pid, SIGCONT);
it worked.
pid_t pid = fork();
if (pid == 0)
{
execl("foo", "foo", NULL);
}
int rc = kill(pid, 18);
return 0;
Suggest: don't forget to handle errors codes from system calls! Work without handling of error codes is worse style! This two actions you can do in one program. In this case it's will be more effective:
#include <errno.h>
int main(int argc, char * argv[])
{
int rc = 0;
pid_t pid = fork();
if (pid == 0) /* child */
{
kill(getpid(), SIGSTOP);
if (rc == -1) {
perror("Something wrong while kill() in child");
}
while (1) {
printf("foo\n");
}
} else if (pid > 0) { /* father */
rc = kill(pid, SIGCONT);
if (rc == -1) {
perror("Something wrong while kill() in parent");
}
} else if (pid < 0) {
perror("Something wrong while fork()");
return -1;
}
return 0;
}

How to change this app to disable input from command line?

This is the Original code:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#else
#include <sys/select.h>
#endif
#include <sphinxbase/err.h>
#include <sphinxbase/ad.h>
#include "pocketsphinx.h"
static const arg_t cont_args_def[] = {
POCKETSPHINX_OPTIONS,
/* Argument file. */
{"-argfile",
ARG_STRING,
NULL,
"Argument file giving extra arguments."},
{"-adcdev",
ARG_STRING,
NULL,
"Name of audio device to use for input."},
{"-infile",
ARG_STRING,
NULL,
"Audio file to transcribe."},
{"-inmic",
ARG_BOOLEAN,
"no",
"Transcribe audio from microphone."},
{"-time",
ARG_BOOLEAN,
"no",
"Print word times in file transcription."},
CMDLN_EMPTY_OPTION
};
static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;
static void
print_word_times()
{
int frame_rate = cmd_ln_int32_r(config, "-frate");
ps_seg_t *iter = ps_seg_iter(ps);
while (iter != NULL) {
int32 sf, ef, pprob;
float conf;
ps_seg_frames(iter, &sf, &ef);
pprob = ps_seg_prob(iter, NULL, NULL, NULL);
conf = logmath_exp(ps_get_logmath(ps), pprob);
printf("%s %.3f %.3f %f\n", ps_seg_word(iter), ((float)sf / frame_rate),
((float) ef / frame_rate), conf);
iter = ps_seg_next(iter);
}
}
static int
check_wav_header(char *header, int expected_sr)
{
int sr;
if (header[34] != 0x10) {
E_ERROR("Input audio file has [%d] bits per sample instead of 16\n", header[34]);
return 0;
}
if (header[20] != 0x1) {
E_ERROR("Input audio file has compression [%d] and not required PCM\n", header[20]);
return 0;
}
if (header[22] != 0x1) {
E_ERROR("Input audio file has [%d] channels, expected single channel mono\n", header[22]);
return 0;
}
sr = ((header[24] & 0xFF) | ((header[25] & 0xFF) << 8) | ((header[26] & 0xFF) << 16) | ((header[27] & 0xFF) << 24));
if (sr != expected_sr) {
E_ERROR("Input audio file has sample rate [%d], but decoder expects [%d]\n", sr, expected_sr);
return 0;
}
return 1;
}
/*
* Continuous recognition from a file
*/
static void
recognize_from_file()
{
int16 adbuf[2048];
const char *fname;
const char *hyp;
int32 k;
uint8 utt_started, in_speech;
int32 print_times = cmd_ln_boolean_r(config, "-time");
fname = cmd_ln_str_r(config, "-infile");
if ((rawfd = fopen(fname, "rb")) == NULL) {
E_FATAL_SYSTEM("Failed to open file '%s' for reading",
fname);
}
if (strlen(fname) > 4 && strcmp(fname + strlen(fname) - 4, ".wav") == 0) {
char waveheader[44];
fread(waveheader, 1, 44, rawfd);
if (!check_wav_header(waveheader, (int)cmd_ln_float32_r(config, "-samprate")))
E_FATAL("Failed to process file '%s' due to format mismatch.\n", fname);
}
if (strlen(fname) > 4 && strcmp(fname + strlen(fname) - 4, ".mp3") == 0) {
E_FATAL("Can not decode mp3 files, convert input file to WAV 16kHz 16-bit mono before decoding.\n");
}
ps_start_utt(ps);
utt_started = FALSE;
while ((k = fread(adbuf, sizeof(int16), 2048, rawfd)) > 0) {
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
in_speech = ps_get_in_speech(ps);
if (in_speech && !utt_started) {
utt_started = TRUE;
}
if (!in_speech && utt_started) {
ps_end_utt(ps);
hyp = ps_get_hyp(ps, NULL);
if (hyp != NULL)
printf("%s\n", hyp);
if (print_times)
print_word_times();
fflush(stdout);
ps_start_utt(ps);
utt_started = FALSE;
}
}
ps_end_utt(ps);
if (utt_started) {
hyp = ps_get_hyp(ps, NULL);
if (hyp != NULL) {
printf("%s\n", hyp);
if (print_times) {
print_word_times();
}
}
}
fclose(rawfd);
}
/* Sleep for specified msec */
static void
sleep_msec(int32 ms)
{
#if (defined(_WIN32) && !defined(GNUWINCE)) || defined(_WIN32_WCE)
Sleep(ms);
#else
/* ------------------- Unix ------------------ */
struct timeval tmo;
tmo.tv_sec = 0;
tmo.tv_usec = ms * 1000;
select(0, NULL, NULL, NULL, &tmo);
#endif
}
/*
* Main utterance processing loop:
* for (;;) {
* start utterance and wait for speech to process
* decoding till end-of-utterance silence will be detected
* print utterance result;
* }
*/
static void
recognize_from_microphone()
{
ad_rec_t *ad;
int16 adbuf[2048];
uint8 utt_started, in_speech;
int32 k;
char const *hyp;
if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),
(int) cmd_ln_float32_r(config,
"-samprate"))) == NULL)
E_FATAL("Failed to open audio device\n");
if (ad_start_rec(ad) < 0)
E_FATAL("Failed to start recording\n");
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
for (;;) {
if ((k = ad_read(ad, adbuf, 2048)) < 0)
E_FATAL("Failed to read audio\n");
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
in_speech = ps_get_in_speech(ps);
if (in_speech && !utt_started) {
utt_started = TRUE;
E_INFO("Listening...\n");
}
if (!in_speech && utt_started) {
/* speech -> silence transition, time to start new utterance */
ps_end_utt(ps);
hyp = ps_get_hyp(ps, NULL );
if (hyp != NULL) {
printf("%s\n", hyp);
fflush(stdout);
}
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
}
sleep_msec(100);
}
ad_close(ad);
}
int
main(int argc, char *argv[])
{
char const *cfg;
config = cmd_ln_parse_r(NULL, cont_args_def, argc, argv, TRUE);
/* Handle argument file as -argfile. */
if (config && (cfg = cmd_ln_str_r(config, "-argfile")) != NULL) {
config = cmd_ln_parse_file_r(config, cont_args_def, cfg, FALSE);
}
if (config == NULL || (cmd_ln_str_r(config, "-infile") == NULL && cmd_ln_boolean_r(config, "-inmic") == FALSE)) {
E_INFO("Specify '-infile <file.wav>' to recognize from file or '-inmic yes' to recognize from microphone.\n");
cmd_ln_free_r(config);
return 1;
}
ps_default_search_args(config);
ps = ps_init(config);
if (ps == NULL) {
cmd_ln_free_r(config);
return 1;
}
E_INFO("%s COMPILED ON: %s, AT: %s\n\n", argv[0], __DATE__, __TIME__);
if (cmd_ln_str_r(config, "-infile") != NULL) {
recognize_from_file();
} else if (cmd_ln_boolean_r(config, "-inmic")) {
recognize_from_microphone();
}
ps_free(ps);
cmd_ln_free_r(config);
return 0;
}
#if defined(_WIN32_WCE)
#pragma comment(linker,"/entry:mainWCRTStartup")
#include <windows.h>
//Windows Mobile has the Unicode main only
int
wmain(int32 argc, wchar_t * wargv[])
{
char **argv;
size_t wlen;
size_t len;
int i;
argv = malloc(argc * sizeof(char *));
for (i = 0; i < argc; i++) {
wlen = lstrlenW(wargv[i]);
len = wcstombs(NULL, wargv[i], wlen);
argv[i] = malloc(len + 1);
wcstombs(argv[i], wargv[i], wlen);
}
//assuming ASCII parameters
return main(argc, argv);
}
#endif
I can compile it by this command:
g++ -o output continuous.cpp -DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\" `pkg-config --cflags --libs pocketsphinx sphinxbase`
And run it by this command : output -inmic yes .
But I like to convert the code as it has no need to get inmic yes and it automatically starts the program from microphone. But I got segmentation fault(core dumped) error when I changed these parts:
static const arg_t cont_args_def= {"-inmic",
ARG_BOOLEAN,
"no",
"Transcribe audio from microphone."};
int main(int argc, char *argv[])
{
config = cmd_ln_parse_r(NULL, cont_args_def, argc, argv, TRUE);
if (cmd_ln_boolean_r(config, "-inmic")) {
recognize_from_microphone();
}
// recognize_from_microphone();
ps_free(ps);
cmd_ln_free_r(config);
return 0;
}
I searched a lot and red the documentation but couldn't understand what's the problem?
Change the last argument passed to cmd_ln_parse_r from TRUE to FALSE.
It has something to do with strict checking.
I figured this out by reading the source code for cmd_ln.c in the sphinxbase code.
I also changed the boolean value for -inmic in cont_args_def from "no" to "yes".

What needs to be done in linux kernel to initialize broadcom L2 switch via PCI-E?

I have a custom board with Armada 370 SoC in which a Broadcom L2 switch is now being added via PCI-E to the Soc.
The board runs on linux. I want to just initialize the L2 switch registers.
I just want very minimal access so that I can access the registers of L2 switch(using a program which uses /dev/mem - I have the application).
Am new and I would like to know what needs to be done in PCI-E drivers and menuconfig and etc.
I would be happy if someone could point to a resource which explains all this stuff from scratch because I want to learn more.
Will I be able to access the registers if I just do the memory mapping correctly? Do I need to do anything more?
This should get you on your way. It sets up BAR0 for access. All you have to do is figure out how you want software to access the driver and implement those handlers: read/write/open/close/ioctl, etc.
#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/tty.h>
#include <linux/version.h>
void error_msg (const char *msg, ...); /* provide by calling possibly kprintf() */
static dev_t dev_num; /* major/minor device numbers */
static struct cdev c_dev, pci_dev; /* character device structure */
static const char DEVICE_NAME[] = "mydevice"; /* name for /dev/... */
static unsigned long bar0_len;
static unsigned char __iomem *bar0_mem;
static struct file_operations mydevice_fops = {
.owner = THIS_MODULE,
// .open = (function to handle open),
// .read = (function to handle read),
// .write = (function to handle write),
// .close = (function to handle close),
// .unlocked_ioctl = (function to handle ioctl),
};
static int mydevice_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
int ret;
char name[20];
dev_t unit_num;
struct device *dev_p;
ret = pci_enable_device (dev);
if (ret)
{
error_msg ("error %d enabling device");
return ret;
}
bar0_len = pci_resource_len (dev, 0);
bar0_mem = pci_iomap (dev, 0, bar0_len);
if (!bar0_len || !bar0_mem) /* device not there */
{
error_msg ("device bar0 missing");
return -1;
}
snprintf (name, sizeof name, "%s%d", DEVICE_NAME, 1); /* create device name */
unit_num = MKDEV(MAJOR(dev_num), 1);
dev_p = device_create (NULL, NULL, unit_num, NULL, name);
if (IS_ERR(dev_p))
{
error_msg ("error creating pci device %s", name);
return -1;
}
cdev_init (&pci_dev, &mydevice_fops);
mydevice_fops.owner = THIS_MODULE;
ret = cdev_add (&pci_dev, unit_num, 1);
if (ret < 0)
{
error_msg ("error adding pci device");
device_destroy (NULL, unit_num);
return ret;
}
pci_set_master (dev);
return 0;
}
static void mydevice_pci_remove (struct pci_dev *dev)
{
cdev_del (&c_dev);
device_destroy (NULL, dev_num);
pci_iounmap (dev, bar0_mem);
pci_disable_device (dev);
}
static struct pci_device_id mydevice_ids[] = {
{
0xabcd, /* vendor/manufacturer ID */
0x1234, /* device/vendor device ID */
PCI_ANY_ID, /* subvendor: don't care */
PCI_ANY_ID, /* subdevice: don't care */
0, /* class: don't care */
0, /* class_mask: don't care */
0, /* ulong_t driver_data: private driver data */
},
{} /* end of pci device IDs */
};
static struct pci_driver mydriver_ops = {
.name = DEVICE_NAME,
.id_table = mydevice_ids,
.probe = mydevice_pci_probe,
.remove = mydevice_pci_remove,
/*
* For pci bus error recovery, see
* https://www.kernel.org/doc/Documentation/PCI/pcieaer-howto.txt
*/
};
static struct file_operations mydriver_fops = {
.owner = THIS_MODULE,
};
static int __init mydriver_init (void)
{
struct device *mydriver_device;
int ret = alloc_chrdev_region (&dev_num, 0, 1, DEVICE_NAME);
if (ret)
{
error_msg ("unable to allocate major/minor device number");
return ret;
}
mydriver_device = device_create (NULL, NULL, dev_num, NULL, DEVICE_NAME);
if (IS_ERR(mydriver_device))
{
error_msg ("error creating device");
unregister_chrdev_region (dev_num, 1);
return -ENODEV;
}
cdev_init (&c_dev, &mydevice_fops);
c_dev.owner = THIS_MODULE;
ret = cdev_add (&c_dev, dev_num, 1);
if (ret < 0)
{
error_msg ("error adding device");
device_destroy (NULL, dev_num);
unregister_chrdev_region (dev_num, 1);
return ret;
}
ret = pci_register_driver (&mydriver_ops); // this is key to PCI devices
if (ret < 0)
{
error_msg ("error %d from pci_register_driver", ret);
cdev_del (&c_dev);
device_destroy (NULL, dev_num);
unregister_chrdev_region (dev_num, 1);
return ret;
}
return 0;
}
static void __exit mydriver_exit (void)
{
device_destroy (NULL, dev_num);
unregister_chrdev (MAJOR(dev_num), DEVICE_NAME);
unregister_chrdev_region (dev_num, 1);
}
module_init(mydriver_init);
module_exit(mydriver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your name <youremail#example.com>");

CFURL does not give full data when download

Iam trying to use CFHTTP to write a small downloader. Unfortunately I cannot use NSURL which is very easy. I basically want an async way to download the data and store it in a file. I have not yet found how to do async way but I have some code with Sync approach which not working as well. The problem is the downloader does not download the complete bytes. I see some data missing causing the final file to be corrupt. Here is the code I have so far.
#include <stdio.h>
#include <string.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CFNetwork/CFNetwork.h>
#include <CFNetwork/CFHTTPStream.h>
int main(int argc, const char * argv[])
{
// insert code here...
const char *data;
FILE *fp;
CFShow(CFSTR("Hello, World!\n"));
CFURLRef cfUrl = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip"), NULL);
CFHTTPMessageRef cfHttpReq = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), cfUrl, kCFHTTPVersion1_1);
CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, cfHttpReq);
CFReadStreamOpen(readStream);
CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
CFIndex numBytesRead;
do {
const int nBuffSize = 1024;
UInt8 buff[nBuffSize];
numBytesRead = CFReadStreamRead(readStream, buff, nBuffSize);
if( numBytesRead > 0 )
{
CFHTTPMessageAppendBytes(cfHttpResp, buff, numBytesRead);
}
else if( numBytesRead < 0 )
{
CFStreamError error = CFReadStreamGetError(readStream);
printf ("Error %d", error.error);
}
} while ( numBytesRead > 0 );
CFStringRef myStatusLine = CFHTTPMessageCopyResponseStatusLine(cfHttpReq);
CFReadStreamClose(readStream);
CFDataRef cfResp = CFHTTPMessageCopyBody(cfHttpResp);
CFIndex length = CFDataGetLength(cfResp);
printf ("%lu\n", length);
CFShow(myStatusLine);
data = (const char*)CFDataGetBytePtr(cfResp);
fp = fopen("/var/tmp/Update.zip", "w");
if (fp == NULL) {
printf("ACnnot be opened\n");
} else {
fwrite(data, length, 1, fp);
fclose(fp);
}
printf ("Download done\n");
CFRelease(cfUrl);
CFRelease(cfHttpReq);
CFRelease(readStream);
CFRelease(cfHttpResp);
CFRelease(cfResp);
return 0;
}
The length I get is less than my actual file download. I dont understand whats is wrong with this code. Can someone please help me with this?
I still dont know what went wrong in this code. But I fixed my problem by replacing
//CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
CFMutableDataRef cfResp = CFDataCreateMutable(kCFAllocatorDefault, 0);
I now use MutableDataRef instead of CFHTTPMessageRef. I will upadte the new code here.
int main(int argc, const char * argv[])
{
// insert code here...
const char *data;
FILE *fp;
CFShow(CFSTR("Hello, World!\n"));
CFURLRef cfUrl = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip"), NULL);
CFHTTPMessageRef cfHttpReq = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), cfUrl, kCFHTTPVersion1_1);
CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, cfHttpReq);
CFReadStreamOpen(readStream);
//CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
CFMutableDataRef cfResp = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFIndex numBytesRead;
do {
const int nBuffSize = 1024;
UInt8 buff[nBuffSize];
numBytesRead = CFReadStreamRead(readStream, buff, nBuffSize);
if( numBytesRead > 0 )
{
CFDataAppendBytes(cfResp, buff, numBytesRead);
//CFHTTPMessageAppendBytes(cfHttpResp, buff, numBytesRead);
}
else if( numBytesRead < 0 )
{
CFStreamError error = CFReadStreamGetError(readStream);
printf ("Error %d", error.error);
}
} while ( numBytesRead > 0 );
CFReadStreamClose(readStream);
//CFDataRef cfResp = CFHTTPMessageCopyBody(cfHttpResp);
CFIndex length = CFDataGetLength(cfResp);
printf ("%lu\n", length);
data = (const char*)CFDataGetBytePtr(cfResp);
fp = fopen("/var/tmp/Update.zip", "w");
if (fp == NULL) {
printf("ACnnot be opened\n");
} else {
fwrite(data, length, 1, fp);
fclose(fp);
}
printf ("Download done\n");
CFRelease(cfUrl);
CFRelease(cfHttpReq);
CFRelease(readStream);
CFRelease(cfResp);
return 0;
}
Hope this helps. It will still be useful if someone can point out what went wrong original code.
I know this late, but your code really helped me out (it is surprisingly hard to find straight forward, complete, examples of getting the response body bytes using CFNetworking API).
Anyway, I think the mistake was the last parameter should be FALSE (response message), and not TRUE (request message) in CFHTTPMessageCreateEmpty line.
CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE);

Programmatically get GPU percent usage in OS X

Is there a standard way of getting GPU percent usage in Cocoa/Objective-C on OS X (10.6 and 10.7)?
Enjoy it, GPU and RAM usage , doesn't work on the discreet GPU btw because it does not expose the performances monitoring dictionary. My MBP has an NVIDIA gpu, should work on ATI too but I'm not sure 100%
#include <CoreFoundation/CoreFoundation.h>
#include <Cocoa/Cocoa.h>
#include <IOKit/IOKitLib.h>
int main(int argc, const char * argv[])
{
while (1) {
// Get dictionary of all the PCI Devicces
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName);
// Create an iterator
io_iterator_t iterator;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,matchDict,
&iterator) == kIOReturnSuccess)
{
// Iterator for devices found
io_registry_entry_t regEntry;
while ((regEntry = IOIteratorNext(iterator))) {
// Put this services object into a dictionary object.
CFMutableDictionaryRef serviceDictionary;
if (IORegistryEntryCreateCFProperties(regEntry,
&serviceDictionary,
kCFAllocatorDefault,
kNilOptions) != kIOReturnSuccess)
{
// Service dictionary creation failed.
IOObjectRelease(regEntry);
continue;
}
CFMutableDictionaryRef perf_properties = (CFMutableDictionaryRef) CFDictionaryGetValue( serviceDictionary, CFSTR("PerformanceStatistics") );
if (perf_properties) {
static ssize_t gpuCoreUse=0;
static ssize_t freeVramCount=0;
static ssize_t usedVramCount=0;
const void* gpuCoreUtilization = CFDictionaryGetValue(perf_properties, CFSTR("GPU Core Utilization"));
const void* freeVram = CFDictionaryGetValue(perf_properties, CFSTR("vramFreeBytes"));
const void* usedVram = CFDictionaryGetValue(perf_properties, CFSTR("vramUsedBytes"));
if (gpuCoreUtilization && freeVram && usedVram)
{
CFNumberGetValue( (CFNumberRef) gpuCoreUtilization, kCFNumberSInt64Type, &gpuCoreUse);
CFNumberGetValue( (CFNumberRef) freeVram, kCFNumberSInt64Type, &freeVramCount);
CFNumberGetValue( (CFNumberRef) usedVram, kCFNumberSInt64Type, &usedVramCount);
NSLog(#"GPU: %.3f%% VRAM: %.3f%%",gpuCoreUse/(double)10000000,usedVramCount/(double)(freeVramCount+usedVramCount)*100.0);
}
}
CFRelease(serviceDictionary);
IOObjectRelease(regEntry);
}
IOObjectRelease(iterator);
}
sleep(1);
}
return 0;
}