[Q] Ermmm...is this good or bad? - HTC Wildfire S

In a previous forum post, we indicated that we would look into this request and, unfortunately we are not able to support video codecs for ARMv6 OMX IL libs for Qualcomm's QDSP5 on MSM7x27. The architecture of MSM7x27 cannot support OpenMax video codecs for ARMv6 OMX IL on QDSP5 running on Android Ice Cream Sandwich (ICS).
Click to expand...
Click to collapse
What does this mean? Does it relate to our phone?

Yes, it does relate to our phones. The Wildfire S has a Qualcomm MSM7227 chipset. Apparently, OpenMax is a set of open source libraries which are useful for video decoding, picture capturing, video recording and more on the hardware chip (The DSP Processor [GPU], in this case, the Adreno 200) directly and not on the CPU. In our case (From the message you posted), these libraries cannot work with the built-in hardware dsp processor so they can't use it to provide hardware decoding of videos on ICS.
Found the post at https://developer.qualcomm.com/forum/qdevnet-forums/multimedia-optimization-qdsp/13248
I'll try looking through it to see if I can understand any more details.
Okay. It says that gingerbread used the OMX IL libraries but the version which was provided was a lower version which is not completely compatible with ICS.
These drivers are not open source so they cannot be worked on by developers. They have to be released by Qualcomm directly. But according to the post, it would seem that the new OMX IL libraries which are required for ICS are not compatible with the armv6 instruction set and are only compatible with armv7 onwards.

Do we know the version that we have libraries for and the version we need ?
Okay. It says that gingerbread used the OMX IL libraries but the version which was provided was a lower version which is not completely compatible with ICS.
Do we know what version of the OMX IL libraries we have for gb and what version we need for ICS ? Thinking we might be able to write a compatibility layer to sit between them, if there isn't too much difference.

omx libraries.
scottrix said:
Okay. It says that gingerbread used the OMX IL libraries but the version which was provided was a lower version which is not completely compatible with ICS.
Do we know what version of the OMX IL libraries we have for gb and what version we need for ICS ? Thinking we might be able to write a compatibility layer to sit between them, if there isn't too much difference.
Click to expand...
Click to collapse
Don't know the versions yet, but the binaries are here....
vendor/htc/marvel/proprietary/lib/libOmxH264Dec.so
vendor/htc/marvel/proprietary/lib/libOmxMpeg4Dec.so
vendor/htc/marvel/proprietary/lib/libOmxVidEnc.so

scottrix said:
Don't know the versions yet, but the binaries are here....
vendor/htc/marvel/proprietary/lib/libOmxH264Dec.so
vendor/htc/marvel/proprietary/lib/libOmxMpeg4Dec.so
vendor/htc/marvel/proprietary/lib/libOmxVidEnc.so
Click to expand...
Click to collapse
More information in these posts:
http://www.modaco.com/topic/354020-zte-n880e-first-zte-ics-update/page__st__20
http://forum.xda-developers.com/archive/index.php/t-1588599-p-2.html
http://newsandeducationblog.blogspot.com/2012/05/android-developers-video-videoview.html
http://forum.xda-developers.com/archive/index.php/t-1664335.html
---------- Post added at 09:01 PM ---------- Previous post was at 08:53 PM ----------
scottrix said:
More information in these posts:
http://www.modaco.com/topic/354020-zte-n880e-first-zte-ics-update/page__st__20
http://forum.xda-developers.com/archive/index.php/t-1588599-p-2.html
http://newsandeducationblog.blogspot.com/2012/05/android-developers-video-videoview.html
http://forum.xda-developers.com/archive/index.php/t-1664335.html
Click to expand...
Click to collapse
For get_config the debug output:
W/QCvdec ( 2751): get_config: unknown param 117440527
117440527 is 0x700000F, which from frameworks/base/include/media/stagefright/openmax/OMX_Index.h
/* Image & Video common Configurations */
OMX_IndexCommonStartUnused = 0x07000000,
OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */
OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */
OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */
OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */
OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */
OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */
OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */
OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */
OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */
OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */
OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */
OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */
OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */
OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */
OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
Is OMX_IndexConfigCommonOutputCrop, so the hardware mpeg4 decoder doesn't understand this index. Going from the source code that calls this, if the call fails then it does something else and carries on
./frameworks/base/media/libstagefright/ACodec.cpp:
if (mOMX->getConfig(
mNode, OMX_IndexConfigCommonOutputCrop,
&rect, sizeof(rect)) != OK) {
rect.nLeft = 0;
rect.nTop = 0;
rect.nWidth = videoDef->nFrameWidth;
rect.nHeight = videoDef->nFrameHeight;
}
CHECK_GE(rect.nLeft, 0);
CHECK_GE(rect.nTop, 0);
CHECK_GE(rect.nWidth, 0u);
CHECK_GE(rect.nHeight, 0u);
CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
./frameworks/base/media/libstagefright/OMXCodec.cpp:
status_t err =
mOMX->getConfig(
mNode, OMX_IndexConfigCommonOutputCrop,
&rect, sizeof(rect));
CODEC_LOGI(
"video dimensions are %ld x %ld",
video_def->nFrameWidth, video_def->nFrameHeight);
if (err == OK) {
#ifdef SAMSUNG_CODEC_SUPPORT
/* Hack GetConfig */
rect.nLeft = 0;
rect.nTop = 0;
rect.nWidth = video_def->nFrameWidth;
rect.nHeight = video_def->nFrameHeight;
#endif
CHECK_GE(rect.nLeft, 0);
CHECK_GE(rect.nTop, 0);
CHECK_GE(rect.nWidth, 0u);
CHECK_GE(rect.nHeight, 0u);
CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
mOutputFormat->setRect(
kKeyCropRect,
rect.nLeft,
rect.nTop,
rect.nLeft + rect.nWidth - 1,
rect.nTop + rect.nHeight - 1);
CODEC_LOGI(
"Crop rect is %ld x %ld @ (%ld, %ld)",
rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
} else {
mOutputFormat->setRect(
kKeyCropRect,
0, 0,
video_def->nFrameWidth - 1,
video_def->nFrameHeight - 1);
}
I think we can safely ignore this failure for now.
---------- Post added at 09:30 PM ---------- Previous post was at 09:01 PM ----------
get_extension_index might be a little more tricky. The file vendor/qcom/opensource/omx/mm-video/vidc/vdec/src/omx_vdec.cpp is a video decoder and the code for the get_extension_index is:
OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
OMX_IN OMX_STRING paramName,
OMX_OUT OMX_INDEXTYPE* indexType)
{
if(m_state == OMX_StateInvalid)
{
DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
return OMX_ErrorInvalidState;
}
else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
*indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
}
#ifdef MAX_RES_1080P
else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
{
*indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
}
#endif
#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
*indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
}
else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
*indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
}
else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
*indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
}
else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
*indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
}
#endif
else {
DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
return OMX_ErrorNotImplemented;
}
return OMX_ErrorNone;
}
In the debug output the message "OMX_GetExtensionIndex failed" comes from frameworks/base/media/libstagefright/omx/OMXNodeInstance.cpp:
status_t OMXNodeInstance::enableGraphicBuffers(
OMX_U32 portIndex, OMX_BOOL enable) {
Mutex::Autolock autoLock(mLock);
OMX_INDEXTYPE index;
OMX_ERRORTYPE err = OMX_GetExtensionIndex(
mHandle,
const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
&index);
if (err != OMX_ErrorNone) {
LOGE("OMX_GetExtensionIndex failed");
return StatusFromOMXError(err);
}
OMX_VERSIONTYPE ver;
ver.s.nVersionMajor = 1;
ver.s.nVersionMinor = 0;
ver.s.nRevision = 0;
ver.s.nStep = 0;
EnableAndroidNativeBuffersParams params = {
sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
};
err = OMX_SetParameter(mHandle, index, &params);
if (err != OMX_ErrorNone) {
LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
err, err);
return UNKNOWN_ERROR;
}
return OK;
}
So the OMX.google.android.index.enableAndroidNativeBuffers extension is the one we are missing, from the code snippet above this, we can see an
#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
#endif
around the check for this extension, so it has been added since Gingerbread, a diff with the cm7 source tells us that the enableGraphicsBuffers has also been added since gingerbread. The header file /frameworks/base/include/media/stagefright/HardwareAPI.h contains the following:
// A pointer to this struct is passed to the OMX_SetParameter when the extension
// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension
// is given.
//
// When Android native buffer use is disabled for a port (the default state),
// the OMX node should operate as normal, and expect UseBuffer calls to set its
// buffers. This is the mode that will be used when CPU access to the buffer is
// required.
//
// When Android native buffer use has been enabled for a given port, the video
// color format for the port is to be interpreted as an Android pixel format
// rather than an OMX color format. The node should then expect to receive
// UseAndroidNativeBuffer calls (via OMX_SetParameter) rather than UseBuffer
// calls for that port.
struct EnableAndroidNativeBuffersParams {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL enable;
};
I doubt the gb codec that we do have has support for the Android pixel format.
Question is can we change the stagefright sources to support both, i.e. if the extension OMX.google.android.index.enableAndroidNativeBuffers isn't supported then do what was done in gb. I'm sure it is possible and it might still be possible to get a codec wrapper working, however, it will take a lot more digging in the code.

Related

[Q] root_plug

Not sure if this means anything, just throwing it out there, but i was going through file for froyo on the evo, original file name "supersonic-2.6.32.15-g746f4f0.tar" and found a file named root_plug-notepad, now i'm only guessing, but is this how they are blocking us from being able to root our device, or am i just guessing outta my arse.
on the notepad the full content is:
/*
* Root Plug sample LSM module
*
* Originally written for a Linux Journal.
*
* Copyright (C) 2002 Greg Kroah-Hartman
*
* Prevents any programs running with egid == 0 if a specific USB device
* is not present in the system. Yes, it can be gotten around, but is a
* nice starting point for people to play with, and learn the LSM
* interface.
*
* If you want to turn this into something with a semblance of security,
* you need to hook the task_* functions also.
*
* See for more information
* about this code.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
/* default is a generic type of usb to serial converter */
static int vendor_id = 0x0557;
static int product_id = 0x2008;
module_param(vendor_id, uint, 0400);
module_param(product_id, uint, 0400);
/* should we print out debug messages */
static int debug = 0;
module_param(debug, bool, 0600);
#define MY_NAME "root_plug"
#define root_dbg(fmt, arg...) \
do { \
if (debug) \
printk(KERN_DEBUG "%s: %s: " fmt , \
MY_NAME , __func__ , \
## arg); \
} while (0)
static int rootplug_bprm_check_security (struct linux_binprm *bprm)
{
struct usb_device *dev;
root_dbg("file %s, e_uid = %d, e_gid = %d\n",
bprm->filename, bprm->cred->euid, bprm->cred->egid);
if (bprm->cred->egid == 0) {
dev = usb_find_device(vendor_id, product_id);
if (!dev) {
root_dbg("e_gid = 0, and device not found, "
"task not allowed to run...\n");
return -EPERM;
}
usb_put_dev(dev);
}
return 0;
}
static struct security_operations rootplug_security_ops = {
.bprm_check_security = rootplug_bprm_check_security,
};
static int __init rootplug_init (void)
{
/* register ourselves with the security framework */
if (register_security (&rootplug_security_ops)) {
printk (KERN_INFO
"Failure registering Root Plug module with the kernel\n");
return -EINVAL;
}
printk (KERN_INFO "Root Plug module initialized, "
"vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id);
return 0;
}
security_initcall (rootplug_init);
nobody, nothing, someone has to have some sort of input, lol.
pubbs.net/200910/kernel/36760-patchrfc-security-remove-rootplug.html
Uncle jimmy says hello

LG Optimus S Source

I'm not sure how this might help all of you V developers. But the official Gingerbread source was just posted a bit ago on the LG Open Source Code Distribution site for the Optimus S. It is not available in the LG Updater tool yet. I thought this might be useful for anyone developing for the V still.
Can you provide a link please?
Whyzor said:
Can you provide a link please?
Click to expand...
Click to collapse
http://www.lg.com/global/support/opensource/opensource.jsp
in the drop down box select mobile phones
in the other box type ls670
I was getting ready to compile this and give it a go and two questions came up
1) how do you change the keylayout from the kernel
2) the lg optimus v 2.2.2 kernel had some funny business going on if you used the kernel. If you type adb remount without changing the ramdisk you get
an error stating it's not allowed. But if you edit the default prop in the ramdisk to allow this then adb shell would mess up. Any one know how to fix
Asadullah said:
I was getting ready to compile this and give it a go and two questions came up
1) how do you change the keylayout from the kernel
2) the lg optimus v 2.2.2 kernel had some funny business going on if you used the kernel. If you type adb remount without changing the ramdisk you get
an error stating it's not allowed. But if you edit the default prop in the ramdisk to allow this then adb shell would mess up. Any one know how to fix
Click to expand...
Click to collapse
picasticks posted a diff between sprint vd and vm kernels.
diff
original blog post
here's the bit of the diff with the keycodes
Code:
diff -urP vd/kernel/arch/arm/mach-msm/lge/board-thunderc-input.c vm670/kernel/arch/arm/mach-msm/lge/board-thunderc-input.c
--- vd/kernel/arch/arm/mach-msm/lge/board-thunderc-input.c 2011-02-04 19:00:38.000000000 -0500
+++ vm670/kernel/arch/arm/mach-msm/lge/board-thunderc-input.c 2011-04-12 06:00:32.000000000 -0400
@@ -23,7 +23,6 @@
#include <mach/board.h>
#include <mach/board_lge.h>
#include <mach/rpc_server_handset.h>
-// LGE_CHANGE [[email protected]] 2010-07-18, check the pcb revision
#include <mach/board_lge.h>
#include "board-thunderc.h"
@@ -44,12 +43,6 @@
},
};
-/* None qwerty keypad device
- * For Thunder CDMA Keypad [ [email protected] ]
- * gpio key pad device - from keypad-surf-ffa */
-/* LGE_CHANGE [LS670:FW:[email protected]] 2010-05-05, add keys.
- * CAM_SHOT, CAM_AF, VOICE
- */
#if defined(CONFIG_MACH_MSM7X27_THUNDERC_SPRINT)
static unsigned int keypad_row_gpios[] = {
32, 33, 34
@@ -64,16 +57,10 @@
#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(keypad_col_gpios) + (col))
-/* LGE_CHANGE [LS670:FW:[email protected]] 2010-05-05, add keys.
- * CAM_SHOT, CAM_AF, VOICE
- */
-/* LGE_CHANGE [[email protected]] 2010--05-15, modified the keymap
- * BACK <-> HOME
- */
#if defined(CONFIG_MACH_MSM7X27_THUNDERC_SPRINT)
static const unsigned short keypad_keymap_thunder[9] = {
- [KEYMAP_INDEX(0, 0)] = KEY_HOME,
- [KEYMAP_INDEX(0, 1)] = KEY_MENU,
+ [KEYMAP_INDEX(0, 0)] = KEY_MENU,
+ [KEYMAP_INDEX(0, 1)] = KEY_HOME,
[KEYMAP_INDEX(0, 2)] = KEY_VOLUMEUP,
[KEYMAP_INDEX(1, 0)] = KEY_SEARCH,
[KEYMAP_INDEX(1, 1)] = KEY_BACK,
I cut it short of the whole section it patches but you can see which file and the changes made.
also, I believe this bit here covers ADB shell, but I could be wrong:
Code:
diff -urP vd/kernel/arch/arm/mach-msm/lge/board-thunderc.c vm670/kernel/arch/arm/mach-msm/lge/board-thunderc.c
--- vd/kernel/arch/arm/mach-msm/lge/board-thunderc.c 2011-02-04 19:00:38.000000000 -0500
+++ vm670/kernel/arch/arm/mach-msm/lge/board-thunderc.c 2011-04-12 06:00:32.000000000 -0400
@@ -136,18 +136,39 @@
{
.product_id = 0x6003,
- .functions = 0x0F /* 001111 Modem,diag,NMEA,Mass*/
+ .functions = 0x0F /* 001111 Modem,diag,NMEA,Mass */
},
{
+ .product_id = 0x6004,
+ .functions = 0x1E /* 011110 diag,NMEA,Mass,ADB */
+ },
+
+ {
+ .product_id = 0x6005,
+ .functions = 0x19 /* 011001 Modem,Mass,ADB */
+ },
+
+ {
+ .product_id = 0x6006,
+ .functions = 0x09 /* 001001 Modem,ADB */
+ },
+
+ {
.product_id = 0x618E,
.functions = 0x1F /* 011111 Modem,diag,NMEA,Mass,ADB */
},
+
{
- // LGE_CHANGE [[email protected]] 2010-08-16, LS670 UMS PID: 0x61CC
- .product_id = 0x61CC,
+ .product_id = 0x61CE,
.functions = 0x08 /* 001000 Mass */
},
+
+ {
+ .product_id = 0x61A6,
+ .functions = 0x18 /* 011000 Mass,ADB */
+
+ },
};
#endif
@@ -157,9 +178,6 @@
.phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_65NM),
.vendor_id = 0x1004,
.product_name = "LG Android USB Device",
- /* LGE_CHANGE [[email protected]] 2010-05-22, change the serial_number
- * for LS670
- */
#ifdef CONFIG_MACH_MSM7X27_THUNDERC_SPRINT
.serial_number = "LGANDROIDLS670",
#else
@@ -194,7 +212,6 @@
},
};
-// LGE_CHANGE [[email protected]] 2010-09-28
static struct platform_device testmode_device = {
.name = "testmode",
.id = -1,
@@ -210,7 +227,6 @@
&msm_device_adspdec,
&lg_fw_diagcmd_device,
&lg_diag_cmd_device,
- // LGE_CHANGE [[email protected]] 2010-09-28
&testmode_device,
};
@@ -231,11 +247,6 @@
void msm_serial_debug_init(unsigned int base, int irq,
struct device *clk_device, int signal_irq);
-// LGE_CHANGE [[email protected]] 2010-07-22, merged from thunderg
-/* decrease FB pmem size because thunderg uses hvga
- * qualcomm's original value depends on wvga resolution
- * 2010-04-18, [email protected]
- */
unsigned pmem_fb_size = 0x96000;
unsigned pmem_adsp_size = 0xAE4000;
@@ -314,7 +325,6 @@
#endif
}
-/* LGE_CHANGE [[email protected]] 2010-06-02 [LS670] */
#ifdef CONFIG_MACH_MSM7X27_THUNDERC_SPRINT
MACHINE_START(MSM7X27_THUNDERC, "THUNDER Sprint board (LGE LS670)")
#else
hopefully that's what you're needing, but I'm not positive.
edit: looks like they changed the second bit quite a bit in 2.6.35, it'll take more work to patch in the changes for the v in the product id codes now.
FWIW in order to get USB tethering working, the IHO kernel does not use the stock VM670 USB code, so I wouldn't worry too much about patching anything or maintaining the USB IDs.

MAPIdotnet and binary message body

Best all,
A while ago I tried to make a simple application which can export all my smses and mmses to my local database server. It runs quite smoothly but I can't manage to get the correct mms body data. It seems that about 5% of the exported body data(for example a sent picture in jpeg format) is different from the original jpeg picture/body data: the exported picture data can't be viewed, it is corrupt.
I suspect the method of exporting the data must be changed from string to binary, but I don't know exactly how to proceed.
I'm using C# 2008 in combination with the MAPIdotnet library, and my target device is a HTC HD Mini with Windows Mobile 6.5 professional.
The part of my code where it's going wrong:
Code:
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(s);
bw.Write(ba);
bw.Close();
fs.Close();
if (messages[msgID].Body != null)
{
FileStream fs2 = File.Create("\\Opslagkaart\\Debug\\body_" + Convert.ToString(msgID) + ".dat");
BinaryWriter bw2 = new BinaryWriter(fs2);
System.Text.UnicodeEncoding enc = new System.Text.UnicodeEncoding();
byte[] file = enc.GetBytes(messages[msgID].Body);
//bw2.Write(messages[msgID].Body);
bw2.Write(file);
bw2.Close();
fs2.Close();
}
In combination with MAPIdotnet's code:
Code:
public string Body
{
get
{
IStreamChar s = (IStreamChar)this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0);
if (s == null)
return "";
IntPtr p = Marshal.AllocHGlobal(4);
char[] b = new char[3];
StringBuilder str = new StringBuilder();
int c, len = b.Length * 2;
do
{
s.Read(b, len, p);
c = Marshal.ReadInt32(p);
str.Append(new string(b, 0, c / 2));
}
while (c >= len);
Marshal.FreeHGlobal(p);
return str.ToString();
}
}
Can somebody give a hint of how to proceed?
Thanks,
I suddenly got some more inspiration and, with help from google, I've managed to correctly retrieve the binary jpeg attachments of two of my mmses.
The code part of my program:
Code:
//if (messages[msgID].BodyBinary.Length>0)
//{
FileStream fs2 = File.Create("\\Opslagkaart\\Debug\\body_" + Convert.ToString(msgID) + ".dat");
BinaryWriter bw2 = new BinaryWriter(fs2);
bw2.Write(messages[msgID].BodyBinary);
bw2.Close();
fs2.Close();
//}
The code part of the customized MAPIdotnet:
Code:
private static IntPtr ReadBuffer;
static int Read(OpenNETCF.Runtime.InteropServices.ComTypes.IStream strm, byte[] buffer)
{
if (ReadBuffer == IntPtr.Zero) ReadBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
try
{
strm.Read(buffer, buffer.Length, ReadBuffer);
}
catch (NullReferenceException e)
{
//do nothing
}
return Marshal.ReadInt32(ReadBuffer);
}
public byte[] BodyBinary
{
get
{
int buffsize = 1024*1024*2; /* If mms body is bigger than 2MB we have a problem here */
byte[] buffer = new byte[buffsize];
Read(this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0), buffer);
byte[] data = buffer;//ms.ToArray();
Marshal.FreeCoTaskMem(ReadBuffer);
return data;
}
}
But now ALL bodies are saved as 2MB files.. including the empty ones from for example a sms. And not all mms bodies are of the max size of 2mb. My carrier/phone supports up to 1MB. Perhaps I need to get some 'dynamic size' buffer instead of the fixed one. Does anyone have an idea on how to determine the size of the
this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0)
Click to expand...
Click to collapse
stream ?
I've solved all my problems by means of the following code (for mapidotnet):
Code:
private static IntPtr ReadBuffer;
static int Read(OpenNETCF.Runtime.InteropServices.ComTypes.IStream strm, byte[] buffer)
{
int returnvalue = 0;
if (ReadBuffer == IntPtr.Zero) ReadBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
try
{
strm.Read(buffer, buffer.Length, ReadBuffer);
returnvalue = Marshal.ReadInt32(ReadBuffer);
}
catch (NullReferenceException e)
{
returnvalue = 0;
}
return returnvalue;
}
public byte[] BodyBinary
{
get
{
int newdatasize = 0;
int buffsize = 1024*1024*3; /* If mms body is bigger than 3MB we have a problem here */
byte[] buffer = new byte[buffsize];
newdatasize = Read(this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0), buffer);
if (newdatasize < 0) { newdatasize = 0; }
byte[] data = new byte[newdatasize];
Buffer.BlockCopy(buffer, 0, data, 0, newdatasize);
Marshal.FreeCoTaskMem(ReadBuffer);
return data;
}
}
Now all is working fine and the exported files are of their own real size. I'm sure the above code can be optimized but it's working good now.

Unblocking thread safe queue - check code, please (and use, if right for you)

Hi friends.
I must solve big problem to finish HaRET (and other native applications) managed wrapper and UI (i. e. for example managed Silverlight UI controlled from unmanaged code), safe WP7 FTP client, interprocess cooperation on WP7, etc.
I know it is a basic issue, which is probably solved many time in operating systems (windows messages etc.) and many other examples.
But, I could find no any source code for queue, which is:
1. safe for more writers (threads from more processes) and for one reader,
2. unblocking for all writers,
3. unblocking for reader.
I found only very much unblocking ringbuffers or blocking queues, no one unblocking unlimited queue. Please, send corrections if I am bad looking.
Then, I tried code it...
First I want use std::queue with Thread Local Storage identifications (one subqueue for all writer and one abqueue for reader). But, TLS is very limited on CE based systems and I am not sure, if it solve interprocess safety too.
Finally, I tried to write the following code. It is designed for interthread queue only still, but interprocess can be added by safe named filemapping probably. Tell your opinion, it will be the basis for many complex applications here. For many years I have not worked with low-level synchronisation, I could make a fundamental mistake. So far I've missed templates and any wrapper, it's just the basic idea, usable in both C/C++ with very little changes:
PHP:
// This queue is unblocking and thread safe, when:
// 1. more writers are allowed,
// 2. one reader is allowed only.
// Motto: Pointers queue is both-directional, but frontal direction is changed by writers, backward direction by reader only!
#ifndef InterlockedExchangePointer
#define InterlockedExchangePointer(Target, Value) ((PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)))
#endif
#ifndef InterlockedCompareExchangePointer
#define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) ((PVOID)InterlockedCompareExchange((PLONG)(Destination), (LONG)(ExChange), (LONG)(Comperand)))
#endif
typedef struct SQItem
{
SQItem * pNext;
SQItem * pPrev;
void * pValue;
} * PItem;
SQItem EmptyItem = {NULL, NULL, NULL};
PItem pFront = &EmptyItem;
PItem pBack = &EmptyItem;
// Empty queue contains one item with both directions pointers nulled.
bool push_front(void * pNewValue) // nonblocking push, but theoretically forever cycle is possible for low priority thread! Practically improbable.
{
if (!pNewValue)
{
return false;
}
PItem pNewFront = new SQItem;
if (pNewFront)
{
PItem pProbablyFront;
InterlockedExchangePointer(&pProbablyFront, pFront);
pNewFront->pNext = pProbablyFront;
pNewFront->pPrev = NULL;
pNewFront->pValue = pNewValue;
while (InterlockedCompareExchangePointer(&pFront, pNewFront, pProbablyFront) != pProbablyFront)
{ // Another writer changed front pointer, active writer must try it again.
InterlockedExchangePointer(&pProbablyFront, pFront);
pNewFront->pNext = pProbablyFront;
}
return true; // Success allways.
}
return false; // Insufficient memory.
}
void * pop_back() // one reader allowed only!!!
{
PItem pBackward;
InterlockedExchangePointer(&pBackward, pFront); // Safe copy of actual front pointer
if (pBackward == pBack) // Queue is empty in time of interlocked attempt.
{
return NULL;
}
if (!pBack->pPrev)
{ // If backward queue is not continued here, reconstruct it from safe front pointer.
while (pBackward != pBack && !pBackward->pNext->pPrev)
{
pBackward->pNext->pPrev = pBackward;
pBackward = pBackward->pNext;
}
}
// One reader can safe read from back and manipulate with backward queue.
PItem pDelete = pBack;
pBack->pPrev->pNext = NULL;
pBack = pBack->pPrev;
delete pDelete;
return pBack->pValue;
/* // This is not necessary, but it is more clean:
void * pResult = pBack->pValue;
pBack->pValue = NULL;
return pResult;
*/
}
I am not sure, if heap allocation is not more "blocking" operation due to swapping and mm priorities, then object/signal waiting. What do you mean about it?
Mirror principle can be used to OneToMore queue making. Thanks unblocking, MoreToOne and OneToMore can be immeditelly piped to MoreToMore one.
But, when CE systems do not support two coupled pointers interlocked functions, there is no possibility to identify allowed reader safely, then this has not great significance.
As well, MoreToOne is much more needed now.
Template version
Using (simple example, the same way will be used between native threads and managed Silverlight UI):
Code:
#include "..\Templates\STQueue.h"
STQueue<tstring> qMessages(L"");
Code:
... // Called by [B]any thread[/B]:
void SafeMessage(tstring sMessage)
{
qMessages.push_front(sMessage);
PostMessage(hUnsafe, WM_FTP_MESSAGE, 0 , 0);
}
...
Code:
... // In UI thread:
LRESULT OnMsgMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
bool bChange = false;
tstring szMessage = L"";
while ((szMessage = qMessages.pop_back()) != L"")
{
szMessages += szMessage;
szMessages += L"\r\n";
bChange = true;
}
if (bChange)
{
SetDlgItemText(hMainDlg, IDC_EDITMessage, szMessages.c_str());
}
return TRUE;
}
...
STQueue.h:
PHP:
template <class _Type> class STQItem
{
public:
STQItem<_Type> * pNext;
STQItem<_Type> * pPrev;
_Type Value;
STQItem(_Type & rV, STQItem<_Type> * pN = NULL, STQItem<_Type> * pP = NULL);
};
template <class _Type> class STQueue
{
protected:
STQItem<_Type> * pFront;
STQItem<_Type> * pBack;
_Type EmptyValue;
public:
STQueue(_Type EmptyV);
~STQueue();
bool push_front(const _Type & rNewValue);
const _Type & pop_back();
bool empty();
};
template <class _Type> STQItem<_Type>::STQItem(_Type & rV, STQItem<_Type> * pN, STQItem<_Type> * pP)
{
Value = rV;
pNext = pN;
pPrev = pP;
}
template <class _Type> STQueue<_Type>::STQueue(_Type EmptyV)
{
EmptyValue = EmptyV;
STQItem<_Type> * EmtyItem = new STQItem<_Type>(EmptyValue);
pFront = EmtyItem;
pBack = EmtyItem;
}
template <class _Type> STQueue<_Type>::~STQueue()
{
while (pop_back() != EmptyValue)
{
}
delete pBack;
}
template <class _Type> bool STQueue<_Type>::push_front(const _Type & rNewValue)
{ // nonblocking push, but theoretically forever cycle is possible for low priority thread!
STQItem<_Type> * pNewFront = new STQItem<_Type>(EmptyValue);
if (pNewFront)
{
STQItem<_Type> * pProbablyFront;
InterlockedExchangePointer(&pProbablyFront, pFront);
pNewFront->pNext = pProbablyFront;
pNewFront->pPrev = NULL;
pNewFront->Value = rNewValue;
while (InterlockedCompareExchangePointer(&pFront, pNewFront, pProbablyFront) != pProbablyFront)
{ // Another writer changed front pointer, active writer must try it again.
InterlockedExchangePointer(&pProbablyFront, pFront);
pNewFront->pNext = pProbablyFront;
}
return true; // Success allways.
}
return false; // Insufficient memory.
}
template <class _Type> const _Type & STQueue<_Type>::pop_back()
{ // one reader allowed only!!!
STQItem<_Type> * pBackward;
InterlockedExchangePointer(&pBackward, pFront); // Safe copy of actual front pointer
if (pBackward == pBack) // Queue is empty in time of interlocked attempt.
{
return EmptyValue;
}
if (!pBack->pPrev)
{ // If backward queue is not beginned, reconstruct it from safe front pointer.
while (pBackward != pBack && !pBackward->pNext->pPrev)
{
pBackward->pNext->pPrev = pBackward;
pBackward = pBackward->pNext;
}
}
// One reader can safe read from back and manipulate with backward queue.
STQItem<_Type> * pDelete = pBack;
pBack->pPrev->pNext = NULL;
pBack = pBack->pPrev;
delete pDelete;
return pBack->Value;
/* // This is not necessary, but it is more clean:
void * pResult = pBack->pValue;
pBack->pValue = NULL;
return pResult;
*/
}
template <class _Type> bool STQueue<_Type>::empty()
{
if(last==NULL)
return TRUE;
else
return FALSE;
}

[Q] How to get the PERF_COUNT_HW_INSTRUCTION event with perf_event on Nexus 7 2013?

I'm trying to get hardware performance counter events on Nexus 7 2013.
I've tested on ASOP 4.3, 4.4, CyanogenMod 11, google original kernel 3.4, and codeaurora msm-3.4 kernel.
I already tested that CPU_CYCLE(PERF_COUNT_HW_CPU_CYCLES) and L2 Cache related events are working.
However, I couldn't get an executed instrunction event (PERF_COUNT_HW_INSTRUCTION) which is one of the default HPC events.
It always returns zero!
I'm stuck for 2 weeks.:crying:
Please somebody help me!
Thanks in advance.
My test code is as follow.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
static long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
int
main(int argc, char **argv)
{
struct perf_event_attr pe;
long long count;
int fd;
int i=0;
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS; //PERF_COUNT_HW_CPU_CYCLES;
pe.disabled = 1;
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
fd = perf_event_open(&pe, 0, 0, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
for (i=0; i< 10000; i++)
printf("%d = %d * %d\n", i*(i+1), i, i+1);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
read(fd, &count, sizeof(long long));
printf("%lld events\n", count);
close(fd);
}
Same here
I've also had no luck I'm actually not able to get any hardware counters (they are all zero or errno 2). I only got some software counters like the clock. Did you need cygenomod to get cycles/cache counters working? I figured this should work even without custom builds. Did you need to run as root while querying them?

Categories

Resources