using X264 and librtmp to send live camera frame, but the flash can't show - rtmp

I am using X264 and librtmp to send my live camera frame, all the things seems right. but my web test flash can't show the correct video. Sometimes it seems correct, but when I re-click play button, it doesn't show any picture on the flash.
Here is my X264 config code
x264_param_default_preset(&x264param, "ultrafast", "zerolatency");
x264param.i_threads = 2;
x264param.i_width = width;
x264param.i_height = height;
x264param.i_log_level = X264_LOG_DEBUG;
x264param.i_fps_num = x264param.i_timebase_num= fps;
x264param.i_fps_den = x264param.i_timebase_den=1;
x264param.i_frame_total = 0;
x264param.i_frame_reference =1;
//x264param.i_frame_reference = 2;
x264param.i_keyint_min = 25;
x264param.i_keyint_max = fps*3;
x264param.i_scenecut_threshold = 40;
x264param.b_deblocking_filter = 1;
x264param.b_cabac = 0;
x264param.analyse.i_trellis = 0;
x264param.analyse.b_chroma_me = 1;
x264param.vui.i_sar_width = 0;
x264param.vui.i_sar_height = 0;
x264param.i_bframe_bias = 0;
x264param.b_interlaced= 0;
x264param.analyse.i_subpel_refine = 6; /* 0..5 -> 1..6 */
x264param.analyse.i_me_method = X264_ME_DIA;//X264_ME_HEX?X264_ME_DIA
x264param.analyse.i_me_range = 16;
x264param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
x264param.i_deblocking_filter_alphac0 = 0;
x264param.i_deblocking_filter_beta = 0;
//x264param.analyse.intra = X264_ANALYSE_I4x4;
x264param.analyse.intra = X264_ANALYSE_I4x4;// | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
x264param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
//edit 2014-7-28
x264param.analyse.b_transform_8x8 = 1;
//x264param.analyse.b_transform_8x8 = 0;
x264param.analyse.b_fast_pskip = 1;
x264param.i_bframe = 0;
//x264param.b_intra_refresh
x264param.analyse.b_weighted_bipred = 0;
//// Intra refres:
x264param.i_keyint_max = 250;
x264param.b_intra_refresh = 0;
////Rate control:
//x264param.rc.i_rc_method = X264_RC_CRF;
//Rate Control
x264param.rc.f_ip_factor = 1.4f;
x264param.rc.f_pb_factor = 1.3f;
x264param.rc.f_qcompress = 1.0;
x264param.rc.i_qp_min = 20;//20;
x264param.rc.i_qp_max = 32;
x264param.rc.i_qp_step = 1;
switch (0)
{
case 0: /* 1 PASS ABR */
x264param.rc.i_rc_method = X264_RC_ABR;
x264param.rc.i_bitrate = 300; // max = 5000
x264param.rc.b_mb_tree = 0;
break;
case 1: /* 1 PASS CQ */
x264param.rc.i_rc_method = X264_RC_CQP;
x264param.rc.i_qp_constant = 26;//10 - 51
break;
}
//For streaming:
x264param.b_repeat_headers = 1;
x264param.b_annexb = 1;
x264_param_apply_profile(&x264param, "baseline");
encoder = x264_encoder_open(&x264param);
x264_picture_init( &pic_in );
x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
pic_in.img.i_csp = X264_CSP_I420|X264_CSP_VFLIP;
pic_in.img.i_plane = 3;
pic_in.i_type = X264_TYPE_AUTO;
Sending To RTMP:
sws_scale(convertCtx,&a,&scribe,0,height, pic_in.img.plane, pic_in.img.i_stride);
int i_nal;
int i_frame_size = x264_encoder_encode( encoder, &nal, &i_nal, &pic_in, &pic_out );
if(i_frame_size <= 0){
printf("\t!!!FAILED encode frame \n");
}else{
for (int i = 0,last=0; i < i_nal;i++)
{
fwrite(nal[i].p_payload, 1, i_frame_size-last, fpw1);
if (nal[i].i_type == NAL_SPS) {
sps_len = nal[i].i_payload-4;
sps = new unsigned char[sps_len];
memcpy(sps,nal[i].p_payload+4,sps_len);
} else if (nal[i].i_type == NAL_PPS) {
pps_len = nal[i].i_payload-4;
pps = new unsigned char[sps_len];
memcpy(pps,nal[i].p_payload+4,pps_len);
send_video_sps_pps();
free(sps);
free(pps);
} else {
send_rtmp_video(nal[i].p_payload,i_frame_size-last);
break;
}
last += nal[i].i_payload;
}
}
Send PPS and SPS
void send_video_sps_pps(){
if(rtmp!= NULL){
RTMPPacket * packet;
unsigned char * body;
int i;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+1024);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
body = (unsigned char *)packet->m_body;
i = 0;
body[i++] = 0x17;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
/*AVCDecoderConfigurationRecord*/
body[i++] = 0x01;
body[i++] = sps[1];
body[i++] = sps[2];
body[i++] = sps[3];
body[i++] = 0xff;
/*sps*/
body[i++] = 0xe1;
body[i++] = (sps_len >> 8) & 0xff;
body[i++] = sps_len & 0xff;
memcpy(&body[i],sps,sps_len);
i += sps_len;
/*pps*/
body[i++] = 0x01;
body[i++] = (pps_len >> 8) & 0xff;
body[i++] = (pps_len) & 0xff;
memcpy(&body[i],pps,pps_len);
i += pps_len;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
packet->m_nBodySize = i;
packet->m_nChannel = 0x04;
packet->m_nTimeStamp = 0;
packet->m_hasAbsTimestamp = 0;
packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet->m_nInfoField2 = rtmp->m_stream_id;
RTMP_SendPacket(rtmp,packet,TRUE);
free(packet);
rtmp_start_time = GetTickCount();
}else{
std::cout<<"RTMP is not ready"<<std::endl;
}
}
Send video Frame
void send_rtmp_video(unsigned char * buf,int len){
RTMPPacket * packet;
long timeoffset = GetTickCount() - rtmp_start_time;
int type = buf[0]&0x1f;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+len+9);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
packet->m_nBodySize = len + 9;
/*send video packet*/
unsigned char *body = (unsigned char *)packet->m_body;
memset(body,0,len+9);
/*key frame*/
body[0] = 0x27;
if (type == NAL_SLICE_IDR) {
body[0] = 0x17;
}
body[1] = 0x01; /*nal unit*/
body[2] = 0x00;
body[3] = 0x00;
body[4] = 0x00;
body[5] = (len >> 24) & 0xff;
body[6] = (len >> 16) & 0xff;
body[7] = (len >> 8) & 0xff;
body[8] = (len ) & 0xff;
/*copy data*/
memcpy(&body[9],buf,len);
packet->m_hasAbsTimestamp = 0;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
if(rtmp != NULL){
packet->m_nInfoField2 = rtmp->m_stream_id;
}
packet->m_nChannel = 0x04;
packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
packet->m_nTimeStamp = timeoffset;
if(rtmp != NULL){
RTMP_SendPacket(rtmp,packet,TRUE);
}
free(packet);
}

Try changing:
pps = new unsigned char[sps_len];
to:
pps = new unsigned char[pps_len];

Related

Vulkan: Loading floating point cubemap textures distorted

I am using vulkan-tutorial codes and i made modify for cubemap.
when i use VK_FORMAT_R8G8B8A8_UNORM is working with this code:
unsigned char* pixelsArray[6];
for (int i = 0; i < 6; ++i)
{
pixelsArray[i] = stbi_load(imageFileArray[i].c_str(), &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
}
VkDeviceSize allSize = texWidth * texHeight * 4 * 6;
VkDeviceSize size = texWidth * texHeight * 4 ;
VkBufferCreateInfo bufferInfo{};
...
bufferInfo.size = allSize ;
vkMapMemory(device, stagingBufferMemory, 0, AllSize, 0, &data);
for(int i = 0; i < 6; ++i)
{
memcpy( (char*) data + (size*i) , pixelsArray[i], static_cast<size_t>(size));
}
vkUnmapMemory(device, stagingBufferMemory);
VkImageCreateInfo imageInfo{};
...
imageInfo.arrayLayers = 6;
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
VkImageViewCreateInfo viewInfo{};
...
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
viewInfo.subresourceRange.layerCount = 6;
but when i try VK_FORMAT_R16G16B16A16_SFLOAT is giving distorted display and no validation error with this code:
float* pixelsArray[6];
for (int i = 0; i < 6; ++i)
{
pixelsArray[i] = stbi_loadf(imageFileArray[i].c_str(), &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
}
VkDeviceSize allSize = texWidth * texHeight * 4 * 6 * 2;// I added *2
VkDeviceSize size = texWidth * texHeight * 4 * 2;// I added *2
VkBufferCreateInfo bufferInfo{};
...
bufferInfo.size = allSize ;
vkMapMemory(device, stagingBufferMemory, 0, AllSize, 0, &data);
for(int i = 0; i < 6; ++i)
{
memcpy( (char*) data + (size*i) , pixelsArray[i], static_cast<size_t>(size));
}
vkUnmapMemory(device, stagingBufferMemory);
VkImageCreateInfo imageInfo{};
...
imageInfo.arrayLayers = 6;
imageInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
VkImageViewCreateInfo viewInfo{};
...
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
viewInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
viewInfo.subresourceRange.layerCount = 6;
when VK_FORMAT_R8G8B8A8_UNORM :
when VK_FORMAT_R16G16B16A16_SFLOAT :
i fixed the problem. problem was that i want to use half float but i was sending float to memcpy function.i searched how can i use half float and i found a solution without using extra library.
what i did add helper functions :
typedef unsigned int uint;
typedef unsigned short ushort;
uint as_uint(const float x)
{
return *(uint*)&x;
}
ushort float_to_half(const float x)
{
// IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15, +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits
const uint b = as_uint(x)+0x00001000; // round-to-nearest-even: add last bit after truncated mantissa
const uint e = (b&0x7F800000)>>23; // exponent
const uint m = b&0x007FFFFF; // mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding
return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; // sign : normalized : denormalized : saturate
}
and fix problem with this helper functions :
VkDeviceSize size_2 = texWidth * texHeight * 4;// different from the above variables in question : allSize or size
//create half float for cubemap
void* half_pixelsArray[6];
half_pixelsArray[0] = new ushort[size_2];
half_pixelsArray[1] = new ushort[size_2];
half_pixelsArray[2] = new ushort[size_2];
half_pixelsArray[3] = new ushort[size_2];
half_pixelsArray[4] = new ushort[size_2];
half_pixelsArray[5] = new ushort[size_2];
//copy from float to half float
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < size_2; ++j)
{
((ushort*)half_pixelsArray[i])[j] = float_to_half( pixelsArray[i][j] );
}
}
// and change float to half flaot in memcpy
memcpy( (char*) data + (layerSize*i) , half_pixelsArray[i], static_cast<size_t>(layerSize));

Replacement for deprecated NXOpenEventStatus?

I need to get the tracking speed of the mouse on OSX 10.13. I found this code on the internet but NXOpenEventStatus is deprecated (as is IOHIDGetAccelerationWithKey), is there an alternative way?
#include <stdio.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDLib.h>
#include <IOKit/hidsystem/IOHIDParameter.h>
#include <IOKit/hidsystem/event_status_driver.h>
int main()
{
kern_return_t kr;
double trackpadAcceleration, mouseAcceleration;
NXEventHandle h = 0;
h = NXOpenEventStatus();
if (h == nil)
return -1;
kr = IOHIDGetAccelerationWithKey( h, CFSTR(kIOHIDMouseAccelerationType), &mouseAcceleration);
return 0;
}
Since NXOpenEventStatus and IOHIDGetAccelerationWithKey are both part of the open-source IOKit distribution, you can look at how they're implemented. It turns out we can do what those functions do, using only non-deprecated functions.
To boil it down to the bare minimum, you can get a dictionary of the HID system's properties like this:
#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault, kIOServicePlane ":/IOResources/IOHIDSystem");
CFDictionaryRef parameters = IORegistryEntryCreateCFProperty(service, CFSTR(kIOHIDParametersKey), kCFAllocatorDefault, kNilOptions);
NSLog(#"%#", parameters);
IOObjectRelease(service);
}
return 0;
}
Output (for me on macOS 10.13.4):
2018-04-05 17:06:55.560590-0500 accel[11924:131983] {
ActuateDetents = 1;
Clicking = 0;
DragLock = 0;
Dragging = 0;
EjectDelay = 0;
FirstClickThreshold = 1;
ForceSuppressed = 0;
HIDClickSpace = (
5,
5
);
HIDClickTime = 500000000;
HIDDefaultParameters = 1;
HIDF12EjectDelay = 250;
HIDFKeyMode = 1;
HIDInitialKeyRepeat = 250000000;
HIDKeyRepeat = 33333333;
HIDKeyboardModifierMappingPairs = (
);
HIDMouseAcceleration = 98304;
HIDMouseKeysOptionToggles = 0;
HIDPointerAcceleration = 45056;
HIDPointerButtonMode = 2;
HIDScrollAcceleration = 20480;
HIDScrollZoomModifierMask = 262144;
HIDSlowKeysDelay = 0;
HIDStickyKeysDisabled = 0;
HIDStickyKeysOn = 0;
HIDStickyKeysShiftToggles = 0;
HIDTrackpadAcceleration = 57344;
HIDWaitCursorFrameInterval = 16666667;
JitterNoClick = 1;
JitterNoMove = 1;
MouseButtonDivision = 55;
MouseButtonMode = TwoButton;
MouseHorizontalScroll = 1;
MouseMomentumScroll = 1;
MouseOneFingerDoubleTapGesture = 0;
MouseTwoFingerDoubleTapGesture = 0;
MouseTwoFingerHorizSwipeGesture = 0;
MouseVerticalScroll = 1;
"OutsidezoneNoAction When Typing" = 1;
"PalmNoAction Permanent" = 1;
"PalmNoAction When Typing" = 1;
SecondClickThreshold = 1;
"Trackpad Jitter Milliseconds" = 192;
TrackpadCornerSecondaryClick = 0;
TrackpadFiveFingerPinchGesture = 0;
TrackpadFourFingerHorizSwipeGesture = 2;
TrackpadFourFingerPinchGesture = 0;
TrackpadFourFingerVertSwipeGesture = 0;
TrackpadHandResting = 1;
TrackpadHorizScroll = 1;
TrackpadMomentumScroll = 1;
TrackpadPinch = 1;
TrackpadRightClick = 1;
TrackpadRotate = 1;
TrackpadScroll = 1;
TrackpadThreeFingerDrag = 0;
TrackpadThreeFingerHorizSwipeGesture = 2;
TrackpadThreeFingerTapGesture = 0;
TrackpadThreeFingerVertSwipeGesture = 0;
TrackpadThreeFingersRightClick = 0;
TrackpadTwoFingerDoubleTapGesture = 1;
TrackpadTwoFingerFromRightEdgeSwipeGesture = 0;
TwofingerNoAction = 1;
USBMouseStopsTrackpad = 0;
"Use Panther Settings for W" = 0;
UserPreferences = 1;
version = 1;
}
Program ended with exit code: 0
The kIOHIDMouseAccelerationType constant has value HIDMouseAcceleration. I also see HIDPointerAcceleration and HIDTrackpadAcceleration in there. There are kIOHID... constants for those too.
Note also that IOHIDGetAccelerationWithKey divides the registry value by 65536 before returning it. IOHIDSetAccelerationWithKey performs the opposite transformation.

Adding a custom chain to OUTPUT using libiptc

I'm trying to achieve the following iptable command using libiptc, but cannot find any examples of how to do this.
iptables -A OUTPUT -j my_outbound_rules
I've tried using the following code:
int addChainToBuiltin(const char *_pChain, const char *_pTarget)
{
/*iptables -A OUTPUT -j <chain>*/
const char *pTable = "filter";
struct xtc_handle *pHandle;
struct ipt_entry *pEntry;
struct xt_entry_target *pTarget;
size_t entrySize = XT_ALIGN(sizeof(struct ipt_entry));
size_t targetSize = XT_ALIGN(sizeof(struct xt_entry_target));
pHandle = iptc_init(pTable);
if (! pHandle)
return errno;
pEntry = calloc(1, entrySize + targetSize);
pTarget = (struct xt_entry_target *)((char*)pEntry + entrySize);
strncpy(pTarget->u.user.name, _pTarget, sizeof(pTarget->u.user.name));
pTarget->u.target_size = targetSize;
pTarget->u.user.target_size = targetSize;
pTarget->u.user.revision = 1;
pEntry->target_offset = entrySize;
pEntry->next_offset = entrySize + targetSize;
pEntry->ip.src.s_addr = INADDR_ANY;
pEntry->ip.smsk.s_addr = 0;
pEntry->ip.dst.s_addr = INADDR_ANY;
pEntry->ip.dmsk.s_addr = 0;
pEntry->ip.proto = 0; // any
pEntry->ip.flags = 0;
pEntry->ip.invflags = 0;
pEntry->nfcache = NFC_UNKNOWN;
int res = applyRule(Append, _pChain, pEntry, pHandle);
if (res == 0)
res = commitAndFree(pHandle);
printf("Result: %d %s\n", res, iptc_strerror(res));
free(pEntry);
return res;
}
But I get an error 'Invalid Argument' from iptc_strerror, but cannot see which argument is invalid.
Many thanks
Solved it with the following code:
int addChainToBuiltin(const char *_pChain, const char *_pTarget)
{
/*iptables -A OUTPUT -j <chain>*/
const char *pTable = "filter";
struct xtc_handle *pHandle;
struct ipt_entry *pEntry;
struct xt_standard_target *pTarget;
size_t entrySize = XT_ALIGN(sizeof(struct ipt_entry));
size_t targetSize = XT_ALIGN(sizeof(struct xt_standard_target));
pHandle = iptc_init(pTable);
if (! pHandle)
return errno;
pEntry = calloc(1, entrySize + targetSize);
pTarget = (struct xt_entry_target *)((char*)pEntry + entrySize);
strncpy(pTarget->target.u.user.name, _pTarget, sizeof(pTarget->target.u.user.name));
pTarget->target.u.target_size = targetSize;
pTarget->target.u.user.target_size = targetSize;
pTarget->target.u.user.revision = 0;
pEntry->target_offset = entrySize;
pEntry->next_offset = entrySize + targetSize;
pEntry->ip.src.s_addr = INADDR_ANY;
pEntry->ip.smsk.s_addr = 0;
pEntry->ip.dst.s_addr = INADDR_ANY;
pEntry->ip.dmsk.s_addr = 0;
pEntry->ip.proto = 0; // any
pEntry->ip.flags = 0;
pEntry->ip.invflags = 0;
pEntry->nfcache = NFC_UNKNOWN;
printf("Adding: %s to %s\n", pTarget->target.u.user.name, _pChain);
int res = applyRule(Append, _pChain, pEntry, pHandle);
if (res == 0)
res = commitAndFree(pHandle);
free(pEntry);
return res;
}

How to view complete contents of NSUserDefaults [duplicate]

This question already has answers here:
See NSUserDefaults file content
(4 answers)
Closed 8 years ago.
I have an app where I store all of the user preferences in NSUserDefaults. I would like to be able to see (for debugging purposes) the complete contents of the NSUserDefaults file.
Can it be done without providing each of the keys?
Can it be done without providing each of the keys?
You can use dictionaryRepresentation of NSUserDefaults like that below example:-
NSUserDefaults *def=[NSUserDefaults standardUserDefaults];
[def setObject:#"test1" forKey:#"test1"];
[def setObject:#"test2" forKey:#"test2"];
NSLog(#"%#",[[NSUserDefaults standardUserDefaults]dictionaryRepresentation]);
EDIT:-
When use dictionaryRepresentation it will print the complete information of user default, including extra value which is added in the defaults.
Below is the output of above code. Also you can see the value in the last which is extra included in the user defaults :-
AppleAntiAliasingThreshold = 4;
AppleGCIdleTimeInterval = "1.0";
AppleLanguages = (
en,
fr,
de,
"zh-Hans",
"zh-Hant",
ja,
es,
it,
nl,
ko,
pt,
"pt-PT",
da,
fi,
nb,
sv,
ru,
pl,
tr,
ar,
th,
cs,
hu,
ca,
hr,
el,
he,
ro,
sk,
uk,
id,
ms,
vi
);
AppleLocale = "en_US";
AppleMeasurementUnits = Inches;
AppleMetricUnits = 0;
AppleMiniaturizeOnDoubleClick = 0;
AppleShowScrollBars = Always;
AppleTextDirection = 0;
AppleUserLanguages = 1;
Country = US;
MultipleSessionEnabled = 1;
NSBoldSystemFont = ".LucidaGrandeUI-Bold";
NSButtonDelay = "0.4";
NSButtonPeriod = "0.075";
NSDocumentRevisionsDebugMode = YES;
NSDragAutoscrollAreaWidth = "5.0";
NSDragCancelLimit = "100000.0";
NSDraggingAutoscrollDelay = "0.4";
NSEnableAutoCollapseOutlineDuringDragsDefault = NO;
NSEnableAutoExpandOutlineDuringDragsDefault = YES;
NSFixedPitchFont = "Menlo-Regular";
NSFixedPitchFontSize = 11;
NSFont = Helvetica;
NSFontSize = 12;
NSInputServerLaunchTimeout = 60;
NSInterfaceStyle = macintosh;
NSLanguages = (
en,
fr,
de,
"zh-Hans",
"zh-Hant",
ja,
es,
it,
nl,
ko,
pt,
"pt-PT",
da,
fi,
nb,
sv,
ru,
pl,
tr,
ar,
th,
cs,
hu,
ca,
hr,
el,
he,
ro,
sk,
uk,
id,
ms,
vi
);
NSMargins = "72 72 90 90";
NSMenuFlashCount = 3;
NSMenuScrollingOffset = 3;
NSMenuScrollingSpeed = 5;
NSNavPanelFileLastListModeForOpenModeKey = 1;
NSNavPanelFileListModeForOpenMode2 = 1;
NSNavPanelSidebarKeyForOpen = (
);
NSNavPanelSidebarKeyForSave = (
);
NSNavRecentPlaces = (
"~/Documents",
"~/Documents/sample Project/learning_iOS",
"~/Desktop/firstPage",
"~/Desktop/SoftwareDepotIssue",
"~/Desktop"
);
NSPreferredSpellServerVendors = {
English = "NeXT-OpenStep";
};
NSPreferredWebServices = {
NSWebServicesProviderWebSearch = {
NSDefaultDisplayName = Google;
NSProviderIdentifier = "com.google.www";
};
};
NSQuotedKeystrokeBinding = "^q";
NSRequireAutoCollapseOutlineAfterDropsDefault = NO;
NSResetIncrementalSearchOnFailure = YES;
NSScrollAnimationEnabled = YES;
NSScrollerButtonAcceleration = 8;
NSScrollerButtonDelay = "0.5";
NSScrollerButtonPeriod = "0.05";
NSScrollerHasSeparateArrows = YES;
NSScrollerKnobCount = 2;
NSScrollerKnobDelay = "0.001";
NSSmartCMYKColorConversion = YES;
NSSystemFont = ".LucidaGrandeUI";
NSSystemFontSize = 13;
NSUIHeartBeatCycle = "0.03";
NSUseCocoaInputServers = YES;
NSUserDictionaryReplacementItems = (
);
NSWindowResizeTime = ".20";
NavPanelFileListModeForOpenMode = 1;
SGTRecentFileSearches = (
{
attributes = (
kMDItemDisplayName
);
enforceStrictMatch = 0;
exactMatch = 0;
name = istsu;
scope = 4;
type = "com.apple.finder";
values = (
istsu
);
}
);
WebKitAVFoundationEnabled = 1;
WebKitAccelerated2dCanvasEnabled = 0;
WebKitAcceleratedCompositingEnabled = 1;
WebKitAcceleratedDrawingEnabled = 0;
WebKitAllowAnimatedImageLoopingPreferenceKey = 1;
WebKitAllowAnimatedImagesPreferenceKey = 1;
WebKitAllowFileAccessFromFileURLs = 1;
WebKitAllowUniversalAccessFromFileURLs = 1;
WebKitApplicationCacheDefaultOriginQuota = 9223372036854775807;
WebKitApplicationCacheTotalQuota = 9223372036854775807;
WebKitApplicationChromeModeEnabledPreferenceKey = 0;
WebKitAsynchronousSpellCheckingEnabled = 0;
WebKitAuthorAndUserStylesEnabledPreferenceKey = 1;
WebKitBackForwardCacheExpirationIntervalKey = 1800;
WebKitBackspaceKeyNavigationEnabled = 1;
WebKitCSSCompositingEnabled = 1;
WebKitCSSCustomFilterEnabled = 1;
WebKitCSSGridLayoutEnabled = 0;
WebKitCSSRegionsEnabled = 1;
WebKitCacheModelPreferenceKey = 0;
WebKitCanvasUsesAcceleratedDrawing = 0;
WebKitCursiveFont = "Apple Chancery";
WebKitDNSPrefetchingEnabled = 0;
WebKitDOMPasteAllowedPreferenceKey = 0;
WebKitDatabasesEnabledPreferenceKey = 1;
WebKitDefaultFixedFontSize = 13;
WebKitDefaultFontSize = 16;
WebKitDefaultTextEncodingName = "ISO-8859-1";
WebKitDeveloperExtrasEnabledPreferenceKey = 0;
WebKitDiagnosticLoggingEnabled = 0;
WebKitDisplayImagesKey = 1;
WebKitEditableLinkBehavior = 0;
WebKitEnableInheritURIQueryComponent = 0;
WebKitExperimentalNotificationsEnabledPreferenceKey = 0;
WebKitFantasyFont = Papyrus;
WebKitFixedFont = Courier;
WebKitFrameFlatteningEnabled = 0;
WebKitFullScreenEnabled = 0;
WebKitHiddenPageCSSAnimationSuspensionEnabled = 0;
WebKitHiddenPageDOMTimerThrottlingEnabled = 0;
WebKitHyperlinkAuditingEnabled = 1;
WebKitJavaEnabled = 1;
WebKitJavaScriptCanAccessClipboard = 0;
WebKitJavaScriptCanOpenWindowsAutomatically = 1;
WebKitJavaScriptEnabled = 1;
WebKitJavaScriptExperimentsEnabledPreferenceKey = 0;
WebKitKerningAndLigaturesEnabledByDefault = 1;
WebKitLoadSiteIconsKey = 0;
WebKitLocalFileContentSniffingEnabledPreferenceKey = 0;
WebKitLocalStorageEnabledPreferenceKey = 1;
WebKitLowPowerVideoAudioBufferSizeEnabled = 0;
WebKitMediaPlaybackAllowsInline = 1;
WebKitMediaPlaybackRequiresUserGesture = 0;
WebKitMinimumFontSize = 0;
WebKitMinimumLogicalFontSize = 9;
WebKitNotificationsEnabled = 1;
WebKitOfflineWebApplicationCacheEnabled = 0;
WebKitPDFDisplayMode = 1;
WebKitPDFScaleFactor = 0;
WebKitPageCacheSupportsPluginsPreferenceKey = 1;
WebKitPictographFont = "Apple Color Emoji";
WebKitPlugInSnapshottingEnabled = 0;
WebKitPluginsEnabled = 1;
WebKitPrivateBrowsingEnabled = 0;
WebKitQTKitEnabled = 1;
WebKitRegionBasedColumnsEnabled = 0;
WebKitRequestAnimationFrameEnabled = 1;
WebKitRespectStandardStyleKeyEquivalents = 0;
WebKitSansSerifFont = Helvetica;
WebKitScreenFontSubstitutionEnabled = 0;
WebKitSerifFont = Times;
WebKitShouldDisplayCaptions = 0;
WebKitShouldDisplaySubtitles = 0;
WebKitShouldDisplayTextDescriptions = 0;
WebKitShouldPrintBackgroundsPreferenceKey = 0;
WebKitShouldRespectImageOrientation = 0;
WebKitShowDebugBorders = 0;
WebKitShowRepaintCounter = 0;
WebKitShowsToolTipOverTruncatedText = 0;
WebKitShowsURLsInToolTips = 0;
WebKitShrinksStandaloneImagesToFit = 0;
WebKitSpatialNavigationEnabled = 0;
WebKitStandardFont = Times;
WebKitStorageBlockingPolicy = 0;
WebKitSuppressesIncrementalRendering = 0;
WebKitTabToLinksPreferenceKey = 0;
WebKitTextAreasAreResizable = 0;
WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey = 1;
WebKitUseLegacyTextAlignPositionedElementBehavior = 0;
WebKitUsePreHTML5ParserQuirks = 0;
WebKitUseSiteSpecificSpoofing = 0;
WebKitUserStyleSheetEnabledPreferenceKey = 0;
WebKitUserStyleSheetLocationPreferenceKey = "";
WebKitUsesEncodingDetector = 0;
WebKitUsesPageCachePreferenceKey = 1;
WebKitWantsBalancedSetDefersLoadingBehavior = 0;
WebKitWebArchiveDebugModeEnabledPreferenceKey = 0;
WebKitWebAudioEnabled = 0;
WebKitWebGLEnabled = 0;
WebKitWebSecurityEnabled = 1;
WebKitXSSAuditorEnabled = 1;
WebKitZoomsTextOnly = 1;
"com.apple.AppleModemSettingTool.LastCountryCode" = US;
"com.apple.ColorSync.Devices" = {
"Device.cmra.00000000-0000-0000-0000-000000533630" = {
DeviceDescriptions = {
"en_US" = "NO NAME";
};
FactoryProfiles = {
555810816 = {
DeviceModeDescriptions = {
"en_US" = Default;
};
DeviceProfileURL = "/System/Library/Frameworks/ICADevices.framework/Versions/A/Resources/Camera RGB Profile.icc";
};
DeviceDefaultProfileID = 555810816;
};
};
"Device.cmra.30303441-3030-3930-4637-393830304637" = {
DeviceDescriptions = {
"en_US" = "Lumia 520";
};
FactoryProfiles = {
555810816 = {
DeviceModeDescriptions = {
"en_US" = Default;
};
DeviceProfileURL = "/System/Library/Frameworks/ICADevices.framework/Versions/A/Resources/Camera RGB Profile.icc";
};
DeviceDefaultProfileID = 555810816;
};
};
"Device.cmra.37616133-3566-6339-6362-303662336639" = {
DeviceDescriptions = {
"en_US" = iPhone;
};
FactoryProfiles = {
555810816 = {
DeviceModeDescriptions = {
"en_US" = Default;
};
DeviceProfileURL = "/System/Library/Frameworks/ICADevices.framework/Versions/A/Resources/Camera RGB Profile.icc";
};
DeviceDefaultProfileID = 555810816;
};
};
};
"com.apple.TimeZonePref.Last_Selected_City" = (
"37.36883",
"-122.0363",
0,
"America/Los_Angeles",
US,
Sunnyvale,
"U.S.A.",
Sunnyvale,
"U.S.A.",
"DEPRECATED IN 10.6"
);
"com.apple.preferences.timezone.selected_city" = {
CountryCode = US;
GeonameID = 5400075;
Latitude = "37.36883";
LocalizedNames = {
ar = "\U0633\U0627\U0646\U064a\U0641\U064a\U0644";
ca = Sunnyvale;
cs = Sunnyvale;
da = Sunnyvale;
de = Sunnyvale;
el = Sunnyvale;
en = Sunnyvale;
es = Sunnyvale;
fi = Sunnyvale;
fr = Sunnyvale;
he = "\U05e1\U05d0\U05e0\U05d9\U05d5\U05d5\U05dc";
hr = Sunnyvale;
hu = Sunnyvale;
id = Sunnyvale;
it = Sunnyvale;
ja = "\U30b5\U30cb\U30fc\U30d9\U30fc\U30eb";
ko = "\Uc11c\Ub2c8\Ubca0\Uc77c";
ms = Sunnyvale;
nb = Sunnyvale;
nl = Sunnyvale;
pl = Sunnyvale;
pt = Sunnyvale;
"pt-PT" = Sunnyvale;
ro = Sunnyvale;
ru = "\U0421\U0430\U043d\U043d\U0438\U0432\U0435\U0439\U043b";
sk = Sunnyvale;
sv = Sunnyvale;
th = Sunnyvale;
tr = Sunnyvale;
uk = "\U0421\U0430\U043d\U043d\U0456\U0432\U0435\U0439\U043b";
vi = Sunnyvale;
"zh-Hans" = "\U6851\U5c3c\U7ef4\U5c14";
"zh-Hant" = "\U6851\U5c3c\U7dad\U723e";
};
Longitude = "-122.0363";
Name = Sunnyvale;
Population = 140081;
RegionalCode = CA;
TimeZoneName = "America/Los_Angeles";
Version = 1;
};
"com.apple.springing.delay" = "0.5";
"com.apple.springing.enabled" = 1;
"com.apple.trackpad.enableSecondaryClick" = 1;
"com.apple.trackpad.fiveFingerPinchSwipeGesture" = 2;
"com.apple.trackpad.fourFingerHorizSwipeGesture" = 2;
"com.apple.trackpad.fourFingerPinchSwipeGesture" = 2;
"com.apple.trackpad.fourFingerVertSwipeGesture" = 2;
"com.apple.trackpad.momentumScroll" = 1;
"com.apple.trackpad.pinchGesture" = 1;
"com.apple.trackpad.rotateGesture" = 1;
"com.apple.trackpad.scrollBehavior" = 2;
"com.apple.trackpad.threeFingerDragGesture" = 0;
"com.apple.trackpad.threeFingerHorizSwipeGesture" = 2;
"com.apple.trackpad.threeFingerTapGesture" = 2;
"com.apple.trackpad.threeFingerVertSwipeGesture" = 2;
"com.apple.trackpad.twoFingerDoubleTapGesture" = 1;
"com.apple.trackpad.twoFingerFromRightEdgeSwipeGesture" = 3;
"com.apple.trackpad.version" = 5;
"com.apple.updatesettings_did_disable_ftp" = 1;
test1 = test1;
test2 = test2;

mupdf render jpeg2000 lose color?

I am working on an android project, which use vudroid, which in turn use mupdf version 0.5.
Vudroid remove the original openjpeg support of mupdf, I have ported the mupdf version 1.5's openjpeg support.
But I encounter a new problem, color information in jpx image gone, the desired effect:
my effect:
the ported load-jpx code:
#include "fitz.h"
#include "mupdf.h"
/* Without the definition of OPJ_STATIC, compilation fails on windows
* due to the use of __stdcall. We believe it is required on some
* linux toolchains too. */
#define OPJ_STATIC
#ifndef _MSC_VER
#define OPJ_HAVE_STDINT_H
#endif
#include <openjpeg.h>
static void fz_opj_error_callback(const char *msg, void *client_data)
{
//fz_context *ctx = (fz_context *)client_data;
//fz_warn(ctx, "openjpeg error: %s", msg);
}
static void fz_opj_warning_callback(const char *msg, void *client_data)
{
//fz_context *ctx = (fz_context *)client_data;
//fz_warn(ctx, "openjpeg warning: %s", msg);
}
static void fz_opj_info_callback(const char *msg, void *client_data)
{
/* fz_warn("openjpeg info: %s", msg); */
}
typedef struct stream_block_s
{
unsigned char *data;
int size;
int pos;
} stream_block;
static OPJ_SIZE_T fz_opj_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
int len;
len = sb->size - sb->pos;
if (len < 0)
len = 0;
if (len == 0)
return (OPJ_SIZE_T)-1; /* End of file! */
if ((OPJ_SIZE_T)len > p_nb_bytes)
len = p_nb_bytes;
memcpy(p_buffer, sb->data + sb->pos, len);
sb->pos += len;
return len;
}
static OPJ_OFF_T fz_opj_stream_skip(OPJ_OFF_T skip, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
if (skip > sb->size - sb->pos)
skip = sb->size - sb->pos;
sb->pos += skip;
return sb->pos;
}
static OPJ_BOOL fz_opj_stream_seek(OPJ_OFF_T seek_pos, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
if (seek_pos > sb->size)
return OPJ_FALSE;
sb->pos = seek_pos;
return OPJ_TRUE;
}
fz_error
fz_load_jpx(pdf_image* img, unsigned char *data, int size, fz_colorspace *defcs, int indexed)
{
//fz_pixmap *img;
opj_dparameters_t params;
opj_codec_t *codec;
opj_image_t *jpx;
opj_stream_t *stream;
fz_colorspace *colorspace;
unsigned char *p;
OPJ_CODEC_FORMAT format;
int a, n, w, h, depth, sgnd;
int x, y, k, v;
stream_block sb;
if (size < 2)
fz_throw("not enough data to determine image format");
/* Check for SOC marker -- if found we have a bare J2K stream */
if (data[0] == 0xFF && data[1] == 0x4F)
format = OPJ_CODEC_J2K;
else
format = OPJ_CODEC_JP2;
opj_set_default_decoder_parameters(&params);
if (indexed)
params.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
codec = opj_create_decompress(format);
opj_set_info_handler(codec, fz_opj_info_callback, 0);
opj_set_warning_handler(codec, fz_opj_warning_callback, 0);
opj_set_error_handler(codec, fz_opj_error_callback, 0);
if (!opj_setup_decoder(codec, &params))
{
fz_throw("j2k decode failed");
}
stream = opj_stream_default_create(OPJ_TRUE);
sb.data = data;
sb.pos = 0;
sb.size = size;
opj_stream_set_read_function(stream, fz_opj_stream_read);
opj_stream_set_skip_function(stream, fz_opj_stream_skip);
opj_stream_set_seek_function(stream, fz_opj_stream_seek);
opj_stream_set_user_data(stream, &sb);
/* Set the length to avoid an assert */
opj_stream_set_user_data_length(stream, size);
if (!opj_read_header(stream, codec, &jpx))
{
opj_stream_destroy(stream);
opj_destroy_codec(codec);
fz_throw("Failed to read JPX header");
}
if (!opj_decode(codec, stream, jpx))
{
opj_stream_destroy(stream);
opj_destroy_codec(codec);
opj_image_destroy(jpx);
fz_throw("Failed to decode JPX image");
}
opj_stream_destroy(stream);
opj_destroy_codec(codec);
/* jpx should never be NULL here, but check anyway */
if (!jpx)
fz_throw("opj_decode failed");
pdf_logimage("opj_decode succeeded");
for (k = 1; k < (int)jpx->numcomps; k++)
{
if (!jpx->comps[k].data)
{
opj_image_destroy(jpx);
fz_throw("image components are missing data");
}
if (jpx->comps[k].w != jpx->comps[0].w)
{
opj_image_destroy(jpx);
fz_throw("image components have different width");
}
if (jpx->comps[k].h != jpx->comps[0].h)
{
opj_image_destroy(jpx);
fz_throw("image components have different height");
}
if (jpx->comps[k].prec != jpx->comps[0].prec)
{
opj_image_destroy(jpx);
fz_throw("image components have different precision");
}
}
n = jpx->numcomps;
w = jpx->comps[0].w;
h = jpx->comps[0].h;
depth = jpx->comps[0].prec;
sgnd = jpx->comps[0].sgnd;
if (jpx->color_space == OPJ_CLRSPC_SRGB && n == 4) { n = 3; a = 1; }
else if (jpx->color_space == OPJ_CLRSPC_SYCC && n == 4) { n = 3; a = 1; }
else if (n == 2) { n = 1; a = 1; }
else if (n > 4) { n = 4; a = 1; }
else { a = 0; }
if (defcs)
{
if (defcs->n == n)
{
colorspace = defcs;
}
else
{
fz_warn("jpx file and dict colorspaces do not match");
defcs = NULL;
}
}
if (!defcs)
{
switch (n)
{
case 1: colorspace = pdf_devicegray; break;
case 3: colorspace = pdf_devicergb; break;
case 4: colorspace = pdf_devicecmyk; break;
}
}
//error = fz_new_pixmap(&img, colorspace, w, h);
//if (error)
// return error;
pdf_logimage("colorspace handled\n");
int bpc = 1;
if (colorspace) {
bpc = 1 + colorspace->n;
};
pdf_logimage("w = %d, bpc = %d, h = %d\n", w, bpc, h);
img->samples = fz_newbuffer(w * bpc * h);
//opj_image_destroy(jpx);
//fz_throw("out of memory loading jpx");
p = (char*)img->samples->bp;
pdf_logimage("start to deal with samples");
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
for (k = 0; k < n + a; k++)
{
v = jpx->comps[k].data[y * w + x];
if (sgnd)
v = v + (1 << (depth - 1));
if (depth > 8)
v = v >> (depth - 8);
*p++ = v;
}
if (!a)
*p++ = 255;
}
}
img->samples->wp = p;
pdf_logimage("start to deal with samples succeeded");
opj_image_destroy(jpx);
// if (a)
// {
// if (n == 4)
// {
// fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb(ctx), w, h);
// fz_convert_pixmap(ctx, tmp, img);
// fz_drop_pixmap(ctx, img);
// img = tmp;
// }
// fz_premultiply_pixmap(ctx, img);
// }
return fz_okay;
}
The render code:
JNIEXPORT jbyteArray JNICALL Java_org_vudroid_pdfdroid_codec_PdfPage_drawPage
(JNIEnv *env, jclass clazz, jlong dochandle, jlong pagehandle)
{
renderdocument_t *doc = (renderdocument_t*) dochandle;
renderpage_t *page = (renderpage_t*) pagehandle;
//DEBUG("PdfView(%p).drawpage(%p, %p)", this, doc, page);
fz_error error;
fz_matrix ctm;
fz_irect viewbox;
fz_pixmap *pixmap;
jfloat *matrix;
jint *viewboxarr;
jint *dimen;
jint *buffer;
int length, val;
pixmap = nil;
/* initialize parameter arrays for MuPDF */
ctm.a = 1;
ctm.b = 0;
ctm.c = 0;
ctm.d = 1;
ctm.e = 0;
ctm.f = 0;
// matrix = (*env)->GetPrimitiveArrayCritical(env, matrixarray, 0);
// ctm.a = matrix[0];
// ctm.b = matrix[1];
// ctm.c = matrix[2];
// ctm.d = matrix[3];
// ctm.e = matrix[4];
// ctm.f = matrix[5];
// (*env)->ReleasePrimitiveArrayCritical(env, matrixarray, matrix, 0);
// DEBUG("Matrix: %f %f %f %f %f %f",
// ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
// viewboxarr = (*env)->GetPrimitiveArrayCritical(env, viewboxarray, 0);
// viewbox.x0 = viewboxarr[0];
// viewbox.y0 = viewboxarr[1];
// viewbox.x1 = viewboxarr[2];
// viewbox.y1 = viewboxarr[3];
// (*env)->ReleasePrimitiveArrayCritical(env, viewboxarray, viewboxarr, 0);
// DEBUG("Viewbox: %d %d %d %d",
// viewbox.x0, viewbox.y0, viewbox.x1, viewbox.y1);
viewbox.x0 = 0;
viewbox.y0 = 0;
viewbox.x1 = 595;
viewbox.y1 = 841;
/* do the rendering */
DEBUG("doing the rendering...");
//buffer = (*env)->GetPrimitiveArrayCritical(env, bufferarray, 0);
// do the actual rendering:
error = fz_rendertree(&pixmap, doc->rast, page->page->tree,
ctm, viewbox, 1);
/* evil magic: we transform the rendered image's byte order
*/
int x, y;
if (bmpdata)
fz_free(bmpdata);
bmpstride = ((pixmap->w * 3 + 3) / 4) * 4;
bmpdata = fz_malloc(pixmap->h * bmpstride);
DEBUG("inside drawpage, bmpstride = %d, pixmap->w = %d, pixmap->h = %d\n", bmpstride, pixmap->w, pixmap->h);
if (!bmpdata)
return;
for (y = 0; y < pixmap->h; y++)
{
unsigned char *p = bmpdata + y * bmpstride;
unsigned char *s = pixmap->samples + y * pixmap->w * 4;
for (x = 0; x < pixmap->w; x++)
{
p[x * 3 + 0] = s[x * 4 + 3];
p[x * 3 + 1] = s[x * 4 + 2];
p[x * 3 + 2] = s[x * 4 + 1];
}
}
FILE* fp = fopen("/sdcard/drawpage", "wb");
fwrite(bmpdata, pixmap->h * bmpstride, 1, fp);
fclose(fp);
jbyteArray array = (*env)->NewByteArray(env, pixmap->h * bmpstride);
(*env)->SetByteArrayRegion(env, array, 0, pixmap->h * bmpstride, bmpdata);
// if(!error) {
// DEBUG("Converting image buffer pixel order");
// length = pixmap->w * pixmap->h;
// unsigned int *col = pixmap->samples;
// int c = 0;
// for(val = 0; val < length; val++) {
// col[val] = ((col[val] & 0xFF000000) >> 24) |
// ((col[val] & 0x00FF0000) >> 8) |
// ((col[val] & 0x0000FF00) << 8);
// }
// winconvert(pixmap);
// }
// (*env)->ReleasePrimitiveArrayCritical(env, bufferarray, buffer, 0);
fz_free(pixmap);
if (error) {
DEBUG("error!");
throw_exception(env, "error rendering page");
}
DEBUG("PdfView.drawPage() done");
return array;
}
I have compare the jpx output samples to the mupdf-1.5 windows, it is the same, but the colorspace of original jpx have gone.
Could help me to get the colorspace back?
It seems you are trying to use an old version of MuPDF with some bits pulled in from a more recent version. TO be honest that's hardly likely to work. I would also guess that its not the OpenJPEG library causing your problem, since the image appears, but converted to grayscale.
Have you tried opening the file in the current version of MuPDF ? Does it work ?
If so then it seems to me your correct approach should be to use the current code, not try and bolt pieces onto an older version.