I have a problem with textures in Jogl. I draw a bookshelf and when the shelf is detected as marked the texture should change. Here is my code so far:
Texture book;
if (Library.touchTime != 0 && Library.marked.equals(name)){
long actTime = System.currentTimeMillis();
if (actTime - Library.touchTime <= 2000){
this.book = books_marked;
}
else{
Library.touchTime = 0;
Library.marked = "";
this.book = books;
}
}
book.enable();
book.bind();
//---- front --------------------------------------------------
gl.glBegin(GL.GL_QUADS);
normVector = front.getNorm();
gl.glNormal3f(normVector.getX(), normVector.getY(), normVector.getZ());
drawRect(gl, 0, 1, 2, 3);
gl.glEnd();
The Objects books and books_marked are parameters of the constructor and are created like this:
// ---- Load Book Texture -----------------------------------------------
try {
InputStream stream = getClass().getResourceAsStream("books.jpg");
data = TextureIO.newTextureData(stream, false, "jpg");
books = TextureIO.newTexture(data);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
// -------------------------------------------------------------
// ---- Load Book_marked Texture -------------------------------------
try {
InputStream stream = getClass().getResourceAsStream("books_marked.jpg");
data = TextureIO.newTextureData(stream, false, "jpg");
books_marked = TextureIO.newTexture(data);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
// -------------------------------------------------------------------------
My intent was to instanciate the book Texture-Object within the if condition so that the bind() command would automatically bind the correct Picture. But the Texture doesn't change. Has anybody an idea what I got wrong here?
Call Texture.bind(GL) or glBindTexture.
Related
In my app I sync some data at the end of day to the app server.For this I wrap all my data as a JSONArray of JSONObjects.The data mainly includes about 50 pictures each with a size of approx 50kb(along with some text data).All these pictures are encoded using base64 encoding.Everthing works fine when the pictures uploaded(along with some text data) are few in number,but when I upload a large no of pictures ,say around 50 then I see in the logs that all the data is properly formed into the JSONArray,however when I try to display the JSONArray using 'array.toString()' method I encounter an out of memory exception.This I believe is due to the heap getting full(however,when I try making android:largeHeap="true" in the manifest everything is working fine,however I want to avoid using this approach,since this is not a good practice).My intention is just to write this JSONArray value into a file and then break this file into small chunks and send it across to the server.
Please guide me of the best approach of writing the JSONAray value to the file which won't lead to OOM issues.Thanks !
Following is the format of the JSONArray:
[{"pid":"000027058451111","popup_time":"2014-01-13 23:36:01","picture":"...base64encoded string......","punching_time":"Absent","status":"Absent"},{"pid":"000027058451111","popup_time":"2014-01-13 23:36:21","picture":"...base64encoded string......","punching_time":"Absent","status":"Absent"}]
Following are the main snippets of my code:
JSONObject aux;
JSONArray array = new JSONArray();
.
.
// Looping through each record in the cursor
for (int i = 0; i < count; i++) {
aux = new JSONObject();
try {
aux.put("pid", c.getString(c.getColumnIndex("pid")));
aux.put("status", c.getString(c.getColumnIndex("status")));
aux.put("pop_time", c.getString(c.getColumnIndex("pop_time")));
aux.put("punching_time", c.getString(c.getColumnIndex("punching_time")));
aux.put("picture", c.getString(c.getColumnIndex("image_str"))); // stores base64encoded picture
} catch (Exception e) {
e.printStackTrace();
}
array.put(aux); // Inserting individual objects into the array , works perfectly fine,no error here
c.moveToNext(); // Moving the cursor to the next record
}
Log.d("Log", "length of json array - "+array.length()); // shows me the total no of JSONObjects in the JSONArray,works fine no error
// HAD GOT OOM HERE
//Log.d("Log", "JSONArray is - " + array.toString());
if (array.length() != 0){
try {
String responseCode = writeToFile(array); //Writing the JSONArray value to file,which will then send file to server.
if(responseCode.equals("200"))
Log.d("Log","Data sent successfully from app to app server");
else
Log.d("Log","Data NOT sent successfully from app to app server");
} catch (Exception e) {
e.printStackTrace();
}
}
.
.
private String writeToFile(JSONArray data) {
Log.d("Log", "Inside writeToFile");
File externalStorageDir = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/File");
if (!externalStorageDir.exists()) {
externalStorageDir.mkdirs();
}
String responseCode = "";
File dataFile = new File(externalStorageDir, "File");
/* FileWriter writer;
String responseCode = "";
try {
writer = new FileWriter(dataFile);
writer.append(data);
writer.flush();
writer.close();
responseCode = sendFileToServer(dataFile.getPath(), AppConstants.url_app_server); // Sends the file to server,worked fine for few pictures
} catch (IOException e) {
e.printStackTrace();
}*/
try {
FileWriter file = new FileWriter("storage/sdcard0/Pictures/File/File");
file.write(data.toString()); // GOT OOM here.
file.flush();
file.close();
Log.d("Log","data written from JSONArray to file");
responseCode = sendFileToServer(dataFile.getPath(), AppConstants.url_app_server); // Sends the file to server,worked fine for few pictures
} catch (IOException e) {
e.printStackTrace();
}
return responseCode;
}
public String sendFileToServer(String filename, String targetUrl) {
.
.
// Sends the file to server,worked fine for few pictures
.
.
return response;
}
Here's the issue. You're trying to load your entire dataset into memory. And you're running out of memory.
Android's JSON classes (and some other JSON libraries) are designed to take a Java object (in memory), serialize it to a parse tree of objects (e.g. JSONObject, JSONArray) (in memory), then convert that tree to a String (in memory) and write it out somewhere.
Specifically in your case (at the moment) it appears what when it converts the parse tree into a String it runs out of memory; That String is effectively doubling the amount of memory required at that point.
To solve your issue you have a few different choices, I'll offer 3:
Don't use JSON at all. Refactor to simply send files and information to your server.
Refactor things so that you only read X images into memory at a time and have multiple output files. Where X is some number of images. Note this is still problematic if your image sizes vary greatly / aren't predictable.
Switch to using Jackson as a JSON library. It supports streaming operations where you can stream the JSON to the output file as you create each object in the array.
Edit to add: for your code, it would look something like this using Jackson:
// Before you get here, have created your `File` object
JsonFactory jsonfactory = new JsonFactory();
JsonGenerator jsonGenerator =
jsonfactory.createJsonGenerator(file, JsonEncoding.UTF8);
jsonGenerator.writeStartArray();
// Note: I don't know what `c` is, but if it's a cursor of some sort it
// should have a "hasNext()" or similar you should be using instead of
// this for loop
for (int i = 0; i < count; i++) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("pid", c.getString(c.getColumnIndex("pid")));
jsonGenerator.writeStringField("status", c.getString(c.getColumnIndex("status")));
jsonGenerator.writeStringField("pop_time", c.getString(c.getColumnIndex("pop_time")));
jsonGenerator.writeStringField("punching_time", c.getString(c.getColumnIndex("punching_time")));
// stores base64encoded picture
jsonGenerator.writeStringField("picture", c.getString(c.getColumnIndex("image_str")));
jsonGenerator.writeEndObject();
c.moveToNext(); // Moving the cursor to the next record
}
jsonGenerator.writeEndArray();
jsonGenerator.close();
The above is untested, but it should work (or at least get you going in the right direction).
First and foremost.Thanks a Billion to Brian Roach for assisting me.His inputs helped me solve the problem.I am sharing my answer.
What was I trying to solve? - In my project I had some user data(name,age,picture_time) and some corresponding pictures for each of the user data.At the EOD I needed to sync all this data to the app server.However when I tried to sync a lot of pictures(say 50 of 50kb approx) I faced an OOM(Out of Memory) issue.Initially, I was trying to upload all the data using a conventional JSONArray approach,however soon I found that I was hitting OOM.This, I attribute to the heap getting full when I was trying to access the JSONArray(which had loads of values and why not ?, afterall I was encoding the pics by base64encoding,which trust me has a hell lot of string data in it !)
Inputs from Brian suggested that I write all my data into a file one by one.So,after the whole process is complete I get one single file that has all the data(name,age,picture_time,base64encoded pictures etc) in it,and then I stream this file to the server.
Following is the code snippet which takes the user data from app database,corresponding pictures from sd card,loops through all the records,creates a JSONArray of JSONObjects using Jackson Json Library(which you need to include in your libs folder,should you use this code) and stores them into a file.This file is then streamed to the server(this snippet not included).Hope this helps someone!
// Sync the values in DB to the server
Log.d("SyncData", "Opening db to read files");
SQLiteDatabase db = context.openOrCreateDatabase("data_monitor", Context.MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS user_data(device_id VARCHAR,name VARCHAR,age VARCHAR,picture_time VARCHAR);");
Cursor c = db.rawQuery("SELECT * FROM user_data", null);
int count = c.getCount();
if (count > 0) {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/UserFile/UserFile");
JsonFactory jsonfactory = new JsonFactory();
JsonGenerator jsonGenerator = null;
try {
jsonGenerator = jsonfactory.createJsonGenerator(file, JsonEncoding.UTF8);
jsonGenerator.writeStartObject();
jsonGenerator.writeArrayFieldStart("user_data"); //Name for the JSONArray
} catch (IOException e3) {
e3.printStackTrace();
}
c.moveToFirst();
// Looping through each record in the cursor
for (int i = 0; i < count; i++) {
try {
jsonGenerator.writeStartObject(); //Start of inner object '{'
jsonGenerator.writeStringField("device_id", c.getString(c.getColumnIndex("device_id")));
jsonGenerator.writeStringField("name", c.getString(c.getColumnIndex("name")));
jsonGenerator.writeStringField("age", c.getString(c.getColumnIndex("age")));
jsonGenerator.writeStringField("picture_time", c.getString(c.getColumnIndex("picture_time")));
} catch (Exception e) {
e.printStackTrace();
}
// creating a fourth column for the input of corresponding image from the sd card
Log.d("SyncData", "Name of image - " + c.getString(c.getColumnIndex("picture_time")));
image = c.getString(c.getColumnIndex("picture_time")).replaceAll("[^\\d]", ""); //Removing everything except digits
Log.d("SyncData", "imagename - " + image);
File f = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/UserPic/" + image + ".jpg");
Log.d("SyncData", "------------size of " + image + ".jpg" + "= " + f.length());
String image_str;
if (!f.exists() || f.length() == 0) {
Log.d("SyncData", "Image has either size of 0 or does not exist");
try {
jsonGenerator.writeStringField("picture", "Error Loading Image");
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
// Reusing bitmaps to avoid Out Of Memory
Log.d("SyncData", "Image exists,encoding underway...");
if (bitmap_reuse == 0) { //ps : bitmap reuse was initialized to 0 at the start of the code,not included in this snippet
// Create bitmap to be re-used, based on the size of one of the bitmaps
mBitmapOptions = new BitmapFactory.Options();
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
mCurrentBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth, mBitmapOptions.outHeight, Bitmap.Config.ARGB_8888);
mBitmapOptions.inJustDecodeBounds = false;
mBitmapOptions.inBitmap = mCurrentBitmap;
mBitmapOptions.inSampleSize = 1;
BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
bitmap_reuse = 1;
}
BitmapFactory.Options bitmapOptions = null;
// Re-use the bitmap by using BitmapOptions.inBitmap
bitmapOptions = mBitmapOptions;
bitmapOptions.inBitmap = mCurrentBitmap;
mCurrentBitmap = BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
if (mCurrentBitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
mCurrentBitmap.compress(Bitmap.CompressFormat.JPEG, 35, stream);
Log.d("SyncData", "------------size of " + "bitmap_compress" + "= " + mCurrentBitmap.getByteCount());
} catch (Exception e) {
e.printStackTrace();
}
byte[] byte_arr = stream.toByteArray();
Log.d("SyncData", "------------size of " + "image_str" + "= " + byte_arr.length);
stream.close();
stream = null;
image_str = Base64.encodeToString(byte_arr, Base64.DEFAULT);
jsonGenerator.writeStringField("picture", image_str);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
try {
jsonGenerator.writeEndObject(); //End of inner object '}'
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
c.moveToNext(); // Moving the cursor to the next record
}
try {
jsonGenerator.writeEndArray(); //close the array ']'
//jsonGenerator.writeStringField("file_size", "0"); // If need be, place another object here.
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
} catch (JsonGenerationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
c.close();
db.close();
}
I have been attempting to use Zxing 2.3.0 to read images of UPC barcodes with a +5 supplement in java however i cannot read the supplement portion of the barcode. The code successfully reads the first portion only. After searching multiple websites i cannot find any further indications of how to read the supplement other than my current method. Any help would greatly be appreciated.
public static void main(String[] args) {
decodeUPC5();
}
public static void decodeUPC5(){
InputStream barCodeInputStream = null;
try {
barCodeInputStream = new FileInputStream("C:/Users/apoclyps/git/zxing-barcoder/Zxing-Test/img/upc5.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedImage barCodeBufferedImage = null;
try {
barCodeBufferedImage = ImageIO.read(barCodeInputStream);
} catch (IOException e) {
e.printStackTrace();
}
LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Attempting to read UPC + 5 Supplement
GenericMultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(new MultiFormatReader());
try {
multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e1) {
e1.printStackTrace();
}
Result[] result = null;
try {
result = multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e) {
e.printStackTrace();
}
System.out.println("Results length "+result.length);
for(Result r : result ){
System.out.println("Barcode text is " + r.toString());
}
}
Barcode image!
Output
Results length 1
Barcode text is 9780735200449
Keep in mind that the content of the barcode is 9780735200449 and not 9780735200449 51299. It will always (correctly) return the 9780735200449 as the contents of the barcode.
The +5 extension is returned as ResultMetadata, under key ResultMetadatatype.UPC_EAN_EXTENSION.
Note that it will still return the UPC barcode even if it doesn't see a +5 extension, obviously. So it's possible you would see it return without a +5 extension on this image. However it works for me with the app and so would imagine it easily detects the +5. (If you scan with the app, look at the left for "Metadata $12.99")
I was able to make a connection with a PLC to read data from it. Now there's one problem and it is that I have to write a method to modify the data from the PLC. To achieve this, I have to send two values to the PLC: an int value and a boolean value. I got the int value solved via the classes from the net.wimpi.modbus package. But when it comes to the boolean value I have no clue what to do.
If someone had the same problem as I do now, could you please send me a reference where I can find a solution or a link of a really good tutorial to solve my problem? Someone posted a couple of links in this question but it sends me to tutorials that doesn't have much to do with the communication with the PLC's and how to treat the data of the PLC.
EDIT
I made the connection with a Modicon M340 PLC, and for the connection I use the classes of the net.wimpi.modbus package. I made the connection in my code through the classes ModbusTCPTransaction and TCPMasterConnection, and I read the values through the classes ReadMultipleRegistersRequest and ReadMultipleRegistersResponse.
The code I made for the connection:
private InetAddress m_Address;
private ModbusTCPTransaction m_Transaction = null;
private TCPMasterConnection m_Connection = null;
int port = Modbus.DEFAULT_PORT;
private Activity activity;
public ModbusConnection(Activity activity, String ip)
{
this.activity = activity;
try {
m_Address = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // the slave'saddress
}
public void getTransaction(InetAddress inet) throws Exception
{
/*Variables for the reading of the PLC data*/
int port = Modbus.DEFAULT_PORT;
/*Data initialization for the reading of the PLC data*/
m_Connection = new TCPMasterConnection(inet);
m_Connection.setPort(port);
m_Connection.connect();
m_Transaction = new ModbusTCPTransaction(m_Connection);
}
And to read the values, I call the next code all the time. I accomplished only reading and writing int, String and float values through words that I read from an offset declared on the PLC:
private ReadMultipleRegistersResponse readValues(int offset, int count)
{
ReadMultipleRegistersRequest rReq = null; // the request
ReadMultipleRegistersResponse rRes = null; // the response
try {
rReq = new ReadMultipleRegistersRequest(offset, count);
m_Transaction.setRequest(rReq);
m_Transaction.execute();
rRes = (ReadMultipleRegistersResponse) m_Transaction.getResponse();
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
}
return rRes;
}
EDIT 2
I think I accomplished what I wanted. There are 4 classes that I use to read the coils:
ReadCoilsRequest
ReadCoilsResponse
WriteMultipleCoilsRequest
WriteMultileCoilsResponse
What I did is two methods to read and write coils into the PLC:
private ReadCoilsResponse readBytes(int offset, int count)
{
ReadCoilsRequest rReq = null; // the request
ReadCoilsResponse rRes = null; // the response
try {
rReq = new ReadCoilsRequest(offset, count);
m_Transaction.setRequest(rReq);
m_Transaction.execute();
rRes = (ReadCoilsResponse) m_Transaction.getResponse();
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
}
return rRes;
}
public void writeBytes(int wordNumber, BitVector b) {
try {
WriteMultipleCoilsRequest wReq = null; //
WriteMultipleCoilsResponse wRes = null; //
wReq = new WriteMultipleCoilsRequest(211, b);
m_Transaction.setRequest(wReq);
m_Transaction.execute();
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
}
}
Also, I made a method to read BitVector variables using the Coils classes:
public BitVector readBitVector(int offset, int count)
{
BitVector myBitVector;
ReadCoilsResponse rRes = readBytes(offset, count);
rRes = (ReadCoilsResponse) m_Transaction.getResponse();
myBitVector = rRes.getCoils();
return myBitVector;
}
After this, what I used to set the bit to 1 or 0 is using a native function from the BitVector class from the net.wimpi.modbus.util package in my code:
test.setBit(2, true);
NOTE: It is important to remember that everytime that you want to read or write values to the plc, the best way to do it is opening a closing the connection to the PLC.
My definitive answer is: you have to treat the registers as bits. So if you want to write the second bit of a register represented in an int value in your code, you will have to do something like this:
intValue = m_Data[1].getValue();
intValue = intValue | 2;
m_Data[1].setValue(intValue);
The second line modifies the bit I want to write in my PLC.
Previously I was working with JMF, but JMF need to be installed, but I don't want to add this overhead. That's why I want be moved to FMJ. And FMJ is opensource. :)
There is some sample example given with FMJ source. And there is a FMJStudio, from where I can run and transmit RTP audio captured from microphone.
But when I want to Transmit RTP, using the source below, it couldn't find any capture device.
The complete source can be found on: fmj-20070928-0938_2.zip in FMJ
And the class name of this source class is SimpleVoiceTransmiter.
//final String urlStr = URLUtils.createUrlStr(new File("samplemedia/gulp2.wav"));//"file://samplemedia/gulp2.wav";
Format format;
format = new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1);
//format = new AudioFormat(AudioFormat.ULAW_RTP, 8000.0, 8, 1, AudioFormat.LITTLE_ENDIAN, AudioFormat.SIGNED);
//format = new AudioFormat(BonusAudioFormatEncodings.ALAW_RTP, 8000, 8, 1);
//format = new AudioFormat(BonusAudioFormatEncodings.SPEEX_RTP, 8000, 8, 1, -1, AudioFormat.SIGNED);
//format = new AudioFormat(BonusAudioFormatEncodings.ILBC_RTP, 8000.0, 16, 1, AudioFormat.LITTLE_ENDIAN, AudioFormat.SIGNED);
CaptureDeviceInfo di = null;
//Set to true if you want to transmit audio from capture device, like microphone.
if (true)
{
// First find a capture device that will capture linear audio
// data at 8bit 8Khz
AudioFormat captureFormat = new AudioFormat(AudioFormat.LINEAR, 8000, 8, 1);
Vector devices = CaptureDeviceManager.getDeviceList(captureFormat);
if (devices.size() > 0)
{
di = (CaptureDeviceInfo) devices.elementAt(0);
} else
{
System.err.println("No capture devices");
// exit if we could not find the relevant capturedevice.
System.exit(-1);
}
}
// Create a processor for this capturedevice & exit if we
// cannot create it
Processor processor = null;
try
{
//processor = Manager.createProcessor(new MediaLocator(urlStr));
processor = Manager.createProcessor(di.getLocator());
} catch (IOException e)
{
e.printStackTrace();
System.exit(-1);
} catch (NoProcessorException e)
{
e.printStackTrace();
System.exit(-1);
}
// configure the processor
processor.configure();
while (processor.getState() != Processor.Configured)
{
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
processor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));
TrackControl track[] = processor.getTrackControls();
boolean encodingOk = false;
// Go through the tracks and try to program one of them to
// output g.711 data.
for (int i = 0; i < track.length; i++)
{
if (!encodingOk && track[i] instanceof FormatControl)
{
if (((FormatControl) track[i]).setFormat(format) == null)
{
track[i].setEnabled(false);
} else
{
encodingOk = true;
}
} else
{
// we could not set this track to g.711, so disable it
track[i].setEnabled(false);
}
}
// At this point, we have determined where we can send out
// g.711 data or not.
// realize the processor
if (encodingOk)
{
if (!new net.sf.fmj.ejmf.toolkit.util.StateWaiter(processor).blockingRealize())
{
System.err.println("Failed to realize");
return;
}
// get the output datasource of the processor and exit
// if we fail
DataSource ds = null;
try
{
ds = processor.getDataOutput();
} catch (NotRealizedError e)
{
e.printStackTrace();
System.exit(-1);
}
// hand this datasource to manager for creating an RTP
// datasink our RTP datasink will multicast the audio
try
{
String url = "rtp://192.168.1.99:49150/audio/1";
MediaLocator m = new MediaLocator(url);
DataSink d = Manager.createDataSink(ds, m);
d.open();
d.start();
System.out.println("Starting processor");
processor.start();
Thread.sleep(30000);
} catch (Exception e)
{
e.printStackTrace();
System.exit(-1);
}
}
When I run this source, The output is: No capture devices
What may be the problem? :-(
Edit: I uninstalled the JMF from my system.
Ok, after two and half days, stuck in the middle of nowhere, I pointed out the problem myself.
The problem was, when I uninstalled JMF it wasn't removed from the CLASSPATH user variable. There was somethinng like:
"C:\PROGRA~1\JMF21~1.1E\lib\sound.jar;C:\PROGRA~1\JMF21~1.1E\lib\jmf.jar;C:\PROGRA~1\JMF21~1.1E\lib;"
and when I removed them, and restarted my computer. Then bingo. The code run without any problem. :)
I have the next class, which is used to transmit RTP via audio or video files in Java.
So far so good.
What I want is to modify the UnicastRtp class to enable the transfer the screen, that is, you can use a medialocator like this:
MediaLocator new ("screen://0,0,1280,800/25")
I searched a lot on Internet and think the solution is to change the way you create and configure the processor.
In order to transmit the contents of the screen, it must be supported in StreamPantalla and DataSourcePantalla classes.
I developed a program that is able to display content in a player from an area of the screen (using the same StreamPantalla and DataSourcePantalla classes ), so I know they work well.
Now what I need is change the UnicastRtp class to be able to configure a processor for transmitting the contents of the screen.
Would appreciate any help or clues.
Thank you very much for the help.
Greetings!
This is my solution:
MediaLocator ml=new MediaLocator("screen://0,0,1280,800/25");
DataSource clone=null;
try {
ds = new DataSourcePantalla();
ds.setLocator(ml);
clone = javax.media.Manager.createCloneableDataSource(ds);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
ds.connect();
clone.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Format[] outputFormat=new Format[1];
FileTypeDescriptor outputType = new FileTypeDescriptor(FileTypeDescriptor.RAW_RTP);
outputFormat[0]=new VideoFormat(VideoFormat.JPEG_RTP);
ProcessorModel processorModel = new ProcessorModel(clone, outputFormat, outputType);
// Try to create a processor to handle the input media locator
try {
processor = Manager.createRealizedProcessor(processorModel);
} catch (NoProcessorException npe) {
System.out.println(npe.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
catch (CannotRealizeException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
boolean result = waitForState(processor, Processor.Configured);
if (result == false){
System.out.println("Error, No se pudo configurar el processor en UnicastRtpPantalla::createMyProcessor");
return false;
}
TrackControl[] tracks = processor.getTrackControls();
// Search through the tracks for a video track
for (int i = 0; i < tracks.length; i++) {
Format format = tracks[i].getFormat();
if (tracks[i].isEnabled() && format instanceof VideoFormat) {
System.out.println("Pista "+i+" de video tiene formato: "+tracks[i].getFormat());
// Found a video track. Try to program it to output JPEG/RTP
// Make sure the sizes are multiple of 8's.
float frameRate = 25;//((VideoFormat) format).getFrameRate();
Dimension size = new Dimension(1280, 800);//((VideoFormat) format).getSize();
int w = (size.width % 8 == 0 ? size.width: (int) (size.width / 8) * 8);
int h = (size.height % 8 == 0 ? size.height: (int) (size.height / 8) * 8);
VideoFormat jpegFormat = new VideoFormat(VideoFormat.JPEG_RTP,
new Dimension(w, h), Format.NOT_SPECIFIED,
Format.byteArray, frameRate);
tracks[i].setFormat(jpegFormat);
System.out.println("Pista "+i+" de video se cambiĆ³ a formato: "+tracks[i].getFormat());
} else
tracks[i].setEnabled(false);
}
// // Set the output content descriptor to RAW_RTP
ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
processor.setContentDescriptor(cd);
ds = processor.getDataOutput();
Regards!