I have been trying to follow the below example but using iOS/Xcode instead of VS2015 (which shows an example of an Android cross-platform project).
Youtube Link
I cannot get the code to display any of my texture at all. No matter what I try I only get a small white rectangle. What am I doing wrong?
This should be OpenGL ES1.x so no shaders should be required.
#import <Foundation/Foundation.h>
#include "SDL.h"
#include <time.h>
#include "SDL_opengles.h"
#define FALSE 0
#define TRUE 1
#ifndef BOOL
#define BOOL int
#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
GLuint g_Texture = 0;
BOOL g_Running = TRUE;
SDL_Window *g_SDLWindow = NULL;
SDL_Surface *g_SDLSurface = NULL;
SDL_Renderer *g_SDLRenderer = NULL;
SDL_Texture *g_SDLTexture = NULL;
int g_ScreenHeight = SCREEN_HEIGHT;
int g_ScreenWidth = SCREEN_WIDTH;
unsigned char treeData[420] = {
0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x10, 0x00, 0x20, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01,
0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x83, 0x16, 0x1D, 0x38,
0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x82, 0x16, 0x1D, 0x38, 0xFF, 0x82,
0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x81, 0x16, 0x1D,
0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x84, 0x16, 0x1D, 0x38, 0xFF,
0x83, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x16,
0x1D, 0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00,
0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x01, 0x16, 0x1D, 0x38, 0xFF, 0x10,
0x50, 0x6C, 0xFF, 0x81, 0x16, 0x1D, 0x38, 0xFF, 0x85, 0x00, 0x00, 0x00,
0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x83, 0x16, 0x1D, 0x38, 0xFF, 0x85,
0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x1D,
0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50,
0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
0x89, 0x24, 0xBA, 0x24, 0xFF, 0x82, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00,
0x00, 0x00, 0x00, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
0xFF, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87,
0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF,
0x86, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x24,
0xBA, 0x24, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF, 0x05, 0x1A, 0x87, 0x2F, 0xFF, 0x24,
0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x1A,
0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF,
0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x24,
0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF,
0x1A, 0x87, 0x2F, 0xFF, 0x8A, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x24, 0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF,
0x24, 0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x84,
0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x85, 0x24, 0xBA,
0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00,
0x87, 0x24, 0xBA, 0x24, 0xFF, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x52, 0x55, 0x45, 0x56, 0x49,
0x53, 0x49, 0x4F, 0x4E, 0x2D, 0x58, 0x46, 0x49, 0x4C, 0x45, 0x2E, 0x00
};
void LoadTree( void )
{
glGenTextures( 1, &g_Texture );
glBindTexture( GL_TEXTURE_2D, g_Texture );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, treeData+18 );
}
//--------------------------------------------------------------------------------------------
// InitSDL()
//--------------------------------------------------------------------------------------------
void InitSDL( void )
{
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
exit( -1 );
atexit( SDL_Quit );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
SDL_DisplayMode currentDisplay;
SDL_GetCurrentDisplayMode( 0, ¤tDisplay );
g_ScreenWidth = max( currentDisplay.w, currentDisplay.h );
g_ScreenHeight = min( currentDisplay.w, currentDisplay.h );
SDL_DisplayMode displayMode;
SDL_GetDesktopDisplayMode( 0, &displayMode );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
// PDS: GLES 2 will require shaders etc..
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 1 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
g_SDLWindow = SDL_CreateWindow( "Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
g_ScreenWidth,
g_ScreenHeight,
/* SDL_WINDOW_FULLSCFREEN | */ SDL_WINDOW_OPENGL );
if( g_SDLWindow == NULL )
exit( -1 );
SDL_GL_CreateContext( g_SDLWindow );
glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight ); // Reset The Current Viewport
glMatrixMode( GL_PROJECTION ); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glRotatef( -90, 0, 0, 1 );
glOrthof( 0.0f, g_ScreenWidth, g_ScreenHeight, 0.0f, -1.0f, 1.0f );
glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glTranslatef(0.5, 0.5, 0);
glClearColor( 0.9f, 0.9f, 0.9f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
LoadTree();
glShadeModel(GL_SMOOTH);
}
float sq[] =
{
-7, 7, 0,
7, 7, 0,
-7, -7, 0,
7, -7, 0
};
float tri[] =
{
sq[ 0 ], sq[ 1 ], sq[ 2 ],
sq[ 3 ], sq[ 4 ], sq[ 5 ],
sq[ 6 ], sq[ 7 ], sq[ 8 ],
sq[ 6 ], sq[ 7 ], sq[ 8 ],
sq[ 3 ], sq[ 4 ], sq[ 5 ],
sq[ 9 ], sq[ 10], sq[ 11]
};
float texCoords[]=
{
0, 1,
1, 1,
0, 0,
0, 0,
1, 1,
1, 0
};
//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( int x, int y )
{
glEnable( GL_TEXTURE_2D );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBindTexture( GL_TEXTURE_2D, g_Texture );
glPushMatrix();
glDisable( GL_BLEND );
glDisable( GL_CULL_FACE );
glEnable( GL_TEXTURE_2D );
GLfloat tX = (GLfloat) 10.0f;
GLfloat tY = (GLfloat) 10.0f;
GLfloat xOffset = 0;
GLfloat yOffset = 0;
// PDS: Offset the drawing by half character width since all placement will be done from quad centre..
xOffset = tX;
yOffset = tY;
glTranslatef( xOffset + x, yOffset + y, 0.0f);
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glFrontFace( GL_CW );
glVertexPointer( 3, GL_FLOAT, 0, tri );
glTexCoordPointer( 2, GL_FLOAT, 0, texCoords );
glDrawArrays( GL_TRIANGLES, 0, 6 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glPopMatrix();
glBindTexture( GL_TEXTURE_2D, 0 );
glEnable( GL_BLEND );
}
//--------------------------------------------------------------------------------------------
// main()
//--------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
InitSDL();
SDL_Event event;
while( g_Running )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
g_Running = false;
break;
}
}
Draw( 100, 100 );
SDL_GL_SwapWindow( g_SDLWindow );
}
SDL_Quit();
return EXIT_SUCCESS;
}
I figured this out.. The ordering of setting the Projection and ModelView uniforms was wrong - it had to be done after the shader program was in use.. and I had some crazy vertice values for the triangles making up the destination rectangle.
The raw TGA loading didn't work very well either so I went back to my original code for loading TGA files.
The below link contains a working example.
Working Example
I am trying to conver the following code to swift:
static unsigned char rsa2048Asn1Header[] = {
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
};
static unsigned char rsa4096Asn1Header[] = {
0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00
};
static unsigned char ecDsaSecp256r1Asn1Header[] = {
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00
};
static unsigned char *asn1HeaderBytes[3] = { rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header };
static unsigned int asn1HeaderSizes[3] = { sizeof(rsa2048Asn1Header), sizeof(rsa4096Asn1Header), sizeof(ecDsaSecp256r1Asn1Header) };
My swift code looks like this:
let rsa2048Asn1Header:[CUnsignedChar] = [0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00]
let rsa4096Asn1Header:[CUnsignedChar] = [0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00]
let ecDsaSecp256r1Asn1Header:[CUnsignedChar] = [0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00]
let asn1HeaderBytes:[[CUnsignedChar]] = [rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header]
let asn1HeaderSizes:[UInt] = [sizeof(rsa2048Asn1Header.dynamicType).toUInt, sizeof(rsa4096Asn1Header.dynamicType).toUInt, sizeof(ecDsaSecp256r1Asn1Header.dynamicType).toUInt]
However i failing at his badly, per example using rsa2048Asn1Header and converting it to NSData:
let data:NSData = NSData(bytes: rsa2048Asn1Header, length:strideofValue(rsa2048Asn1Header))
swift prints with length 8:
<30820122 300d0609>
objc for the following code:
[NSData dataWithBytes:rsa2048Asn1Header length:sizeof(rsa2048Asn1Header)];
prints
<30820122 300d0609 2a864886 f70d0101 01050003 82010f00> size: 24
looking at apple documentation, strideOfvalue should return the right size for each one of those [CUnsignedChar] but that doesnt seem to be the case, my question is shouldnt a [CUnsignedChar] have same size as usigned char [] in objc, if not what could i use to change?
also [[CUnsignedChar]] makes no sense whatsoever in my head, how would the code below convert to swift, should i convert those arrays to an NSString and extract the CString when required, if so what encoding should I use?
static unsigned char *asn1HeaderBytes[3] = { rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header };
I don't think strideofValue is the function you are looking for. I haven't heard of it before, but the documentation states:
Returns the least possible interval between distinct instances of T in memory. The result is always positive.
If this is returning 8, that means that the minimum distance between [CUnsignedChar]s in memory is 8 bytes.
To use NSData(data:length:) properly, the second parameter needs to be the size of the array. You can use the count property for this:
let data: NSData = NSData(bytes: rsa2048Asn1Header, length:rsa2048Asn1Header.count)
[[CUnsignedChar]] is an array of arrays (two-dimensional array) of CUnsignedChar.
Your headers are raw bytes, so technically no encoding is 'correct' to convert to NSString. The cryptographic headers you have don't appear to be strings, and contain unprintable characters.
You should not use strideofValue function. 'strideofValue' it's not a replacement for 'sizeof'. Just go for ".count" property.
I'm having issues where the decoded audio sounds punchy/garbled simply can't tell what is being heard when decoded on an iPhone/iPad device. However, when decoding the audio on simulator the audio is perfect.
I do realize emulator runs on a different CPU architecture i386 while actual device is ARMv7 so the issue could be something around that.
I have printed the compressed data on device and simulator before being decoded and it matches. Then I printed the decoded data for device and simulator and they are different. That leads me to think something is happening with the decoder. I can see that it is not a byte swap issue since the data is just completely different.
Any ideas on what I could or look into? I don't have this issue on Android...
First decoded audio frame.
DEVICE:
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xda, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
EMULATOR:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
UPDATE 1
I was able to resolve the issue by disabling asm with --disable-asm. Something must not be working correctly with the ARM asm files.
I have a security DVR that uses h264 streams. I have been trying to get this to work with zoneminder. I have successfully logged into the dvr and recieved some form of data streams. The data stream is dumped to a fifo/pipe, and then zoneminder uses ffmpeg to read this in.
Note: i know very very little about h.264 streams. just enough to be stupid.
The video only updates about every 15 seconds in ZM. I can dump the stream to a file with ffmpeg or avconv (avconv -i /tmp/mypipe cam.mp4) but it is still not right. However, the file created by avconv is WAY WAY better than the one created by ffmpeg.
I've included a link to the wireshark dump (I did change the PW and login info, etc...). From the data, It appears that the dvr is adding a header to the h264 data streams. I understand that the h264 stream starts with a (0x00 00 01 67) or (0x00 00 01 61). Here is an example of the header plus start of stream:
0x33, 0x30, 0x64, 0x63, 0x48, 0x32, 0x36, 0x34,
0x3f, 0x55, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00,
0xa2, 0x7a, 0xea, 0xdc, 0xcf, 0x08, 0x00, 0x00,
0x0d, 0x0a, 0x11, 0x07, 0x13, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xe0, 0x14,
0xdb, 0x05, 0x87, 0xc4, 0x00, 0x00, 0x00, 0x01,
0x68, 0xce, 0x30, 0xa4, 0x80, 0x00, 0x00, 0x00,
0x01, 0x06, 0xe5, 0x01, 0x51, 0x80, 0x00, 0x00,
0x00, 0x01, 0x65, 0xb8, 0x00, 0x01, 0xa8, 0xac,
I can see that there are a few frame indicators in this message. The DVR's header appears to be 32 bytes long in this case, and in some other messages in the dump, it appears to be 24 bytes long. I am striping the header off before I dump the stream to the pipe. (I have verified the output doesn't include the dvr's headers in any way.
What I would like help with is determining what I should be sending to the pipe. should I start with the first h.264 key? Is there something out of order? I'm very surprised that ffmpeg is only getting 15 second updates, but avconv is much better (lots of dropped frames, and playback is "sped up".
using ffmpeg to read the pipe produces a file that shows it's codec as: H264 - MPEG-4 AVC (part 10) (avc1) with a Decoded format: Planar 4:2:0 YUV using vlc.
Appreciate any help you can provide!
Wireshark h264 dump
edit: on Ubuntu 13.04
ffmpeg version: 6:0.8.6-1ubuntu2
avconv 0.8.6-6:0.8.6-1ubuntu2