Java Media Framework:To Compress AVI video.

M

Misterysword

Hi!! I have got a program that it make an AVI video without
compressing, with RGB format.

How can I compress the video with format MJPEG (for example)????

Regards!
 
A

Andrew Thompson

Hi!! I have got a program that it make an AVI video without
compressing, with RGB format.

How can I compress the video with format MJPEG (for example)????

The JMF Performance Pack supports MJPEG (422) for
AVI encoding on Win and *nix, so the code should only
need to call for that CODEC at the time of encoding.
 
M

Misterysword

The JMF Performance Pack supports MJPEG (422) for
AVI encoding on Win and *nix, so the code should only
need to call for that CODEC at the time of encoding.

Hi.

I do:

_______________________________________________________________

Format f[] = tcs[0].getSupportedFormats();

if (f == null || f.length <= 0) {
System.err.println("The mux does not support the input format: " +
tcs[0].getFormat());
return false;
}
else{
for( int i=0; i< f.length; i++ ){
if( f.getEncoding().equals("mjpg") ){
tcs[0].setFormat(f);
}
}
}

_______________________________________________________________

But I don't work... Can you give me an example code? Thanks
 
A

Andrew Thompson


<Snip code snippet>

Code that is not compilable is no use to me, I
will not look at it. If you want me to look at
code, post an SSCCE*.
But I don't work...

It does not work? Maybe it is just lazy.
Try giving it a flogging, that might 'motivate' it.
..Can you give me an example code?

Can you pay me? I am happy to churn out code, or
perform consultancy, for an appropriate fee. For free,
here (with the damnable JMF) you get my attention for
an SSCCE*.
...Thanks

No worries.

* An SSCCE is a very specific type of code..
<http://www.physci.org/codes/sscce.html>

--
Andrew Thompson
http://www.athompson.info/andrew/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200708/1
 
M

Misterysword

(e-mail address removed) wrote:

..


<Snip code snippet>

Code that is not compilable is no use to me, I
will not look at it. If you want me to look at
code, post an SSCCE*.


It does not work? Maybe it is just lazy.
Try giving it a flogging, that might 'motivate' it.


Can you pay me? I am happy to churn out code, or
perform consultancy, for an appropriate fee. For free,
here (with the damnable JMF) you get my attention for
an SSCCE*.


No worries.

* An SSCCE is a very specific type of code..
<http://www.physci.org/codes/sscce.html>

Ok, sorry for my stupidity...

For example, compilable code:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.media.*;
import javax.media.control.*;
import javax.media.datasink.*;
import javax.media.format.*;
import javax.media.protocol.*;

/**For AVI files, each frame must have a time stamp set.See the
following message from the jmf - interest archives for details :
http : //archives.java.sun.com/cgi-bin/wa?A2=ind0107&L=jmf-
interest&P=R34660
*/
public class AviCreator implements ControllerListener,
DataSinkListener {

private boolean doIt(int width, int height, int frameRate,
MediaLocator outML) {

ImageDataSource ids = new ImageDataSource(width, height, frameRate);
Processor p;
try {
System.err.println("- create processor for the image datasource ...");
p = Manager.createProcessor(ids);
}
catch (Exception e) {
System.err.println("Yikes! Cannot create a processor from the data
source.");
return false;
}
p.addControllerListener(this);
// Put the Processor into configured state so we can set some
processing options on the processor.
p.configure();
if (!waitForState(p, Processor.Configured)) {
System.err.println("Failed to configure the processor.");
return false;
}
// Set the output content descriptor to QuickTime.
p.setContentDescriptor(new
ContentDescriptor(FileTypeDescriptor.MSVIDEO));
//p.setContentDescriptor(new
ContentDescriptor(FileTypeDescriptor.QUICKTIME));
// Query for the processor for supported formats.
// Then set it on the processor.
TrackControl tcs[] = p.getTrackControls();
Format f[] = tcs[0].getSupportedFormats();
if (f == null || f.length <= 0) {
System.err.println("The mux does not support the input format: " +
tcs[0].getFormat());
return false;
}
tcs[0].setFormat(f[0]);
System.err.println("Setting the track format to: " + f[0]);
// We are done with programming the processor. Let's just realize it.
p.realize();
if (!waitForState(p, Processor.Realized)) {
System.err.println("Failed to realize the processor.");
return false;
}
// Now, we'll need to create a DataSink.
DataSink dsink;
if ((dsink = createDataSink(p, outML)) == null) {
System.err.println("Failed to create a DataSink for the given output
MediaLocator: " + outML);
return false;
}
dsink.addDataSinkListener(this);
fileDone = false;
System.err.println("start processing...");
// OK, we can now start the actual transcoding.
try {

p.start();
dsink.start();

}
catch (IOException e) {
System.err.println("IO error during processing");
return false;
}
// Wait for EndOfStream event.
waitForFileDone();
// Cleanup.
try {
dsink.close();
}
catch (Exception e) {
}
p.removeControllerListener(this);
System.err.println("...done processing.");
return true;
}

/** Create the DataSink.
*/
private DataSink createDataSink(Processor p, MediaLocator outML) {
DataSource ds;
if ((ds = p.getDataOutput()) == null) {
System.err.println("Something is really wrong: the processor does not
have an output DataSource");
return null;
}
DataSink dsink;
try {
System.err.println("- create DataSink for: " + outML);
dsink = Manager.createDataSink(ds, outML);
dsink.open();
}
catch (Exception e) {
System.err.println("Cannot create the DataSink: " + e);
return null;
}
return dsink;
}

private Object waitSync = new Object();

private boolean stateTransitionOK = true;

/** Block until the processor has transitioned to the given state.
* Return false if the transition failed.
*/
private boolean waitForState(Processor p, int state) {
synchronized (waitSync) {
try {
while (p.getState() < state && stateTransitionOK) {
waitSync.wait();
}
}
catch (Exception e) {
}
}
return stateTransitionOK;
}

/** Controller Listener.
*/
public void controllerUpdate(ControllerEvent evt) {

if (evt instanceof ConfigureCompleteEvent || evt instanceof
RealizeCompleteEvent || evt instanceof PrefetchCompleteEvent) {
synchronized (waitSync) {
stateTransitionOK = true;
waitSync.notifyAll();
}
}
else if (evt instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
stateTransitionOK = false;
waitSync.notifyAll();
}
}
else if (evt instanceof EndOfMediaEvent) {
evt.getSourceController().stop();
evt.getSourceController().close();
System.out.println("Se procue CONTROLLER-END");
}
}

private Object waitFileSync = new Object();

private boolean fileDone = false;

private boolean fileSuccess = true;

/** Block until file writing is done.
*/
private boolean waitForFileDone() {
synchronized (waitFileSync) {
try {
while (!fileDone) {
waitFileSync.wait();
}
}
catch (Exception e) {
}
}
return fileSuccess;
}

/**
* Event handler for the file writer.
*/
public void dataSinkUpdate(DataSinkEvent evt) {
if (evt instanceof EndOfStreamEvent) {
synchronized (waitFileSync) {
fileDone = true;
waitFileSync.notifyAll();
System.out.println("Se procue DATASINKEVENT-END");
}
}
else if (evt instanceof DataSinkErrorEvent) {
synchronized (waitFileSync) {
fileDone = true;
fileSuccess = false;
waitFileSync.notifyAll();
}
}
}

/** Self-test main.
* @param args Arguments from the command-line.
* @exception java.lang.Exception case of errors.
*/
public static void main(String args[]) throws Exception {
//jpegCreator.main(null);
//if (args.length == 0)
// prUsage();
// Parse the arguments.
int i = 0;
int width = -1, height = -1, frameRate = 1;
//Vector inputFiles = new Vector();
String outputURL = null;
//width = 658;
//height = 573;
width = 1280;//657;
height = 800;//573;
outputURL = "test.avi";
//outputURL = "test.mov";
// Generate the output media locators.
MediaLocator oml;
if ((oml = createMediaLocator(outputURL)) == null) {
System.err.println("Cannot build media locator from: " + outputURL);
System.exit(1);
}
AviCreator imageToMovie = new AviCreator();
imageToMovie.doIt(width, height, frameRate, oml);
System.exit(0);
}

/*
static void prUsage() {
System.err.println("Usage: java JpegImagesToMovie -w <width> -h
<height> -f <frame rate> -o <output URL> <input JPEG file 1> <input
JPEG file 2> ...");
System.exit( -1);
}
*/

/** Create a media locator from the given string.
*/
// Allows JMF to locate output file.
private static MediaLocator createMediaLocator(String url) {
MediaLocator ml;
if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null) {
return ml;
}
if (url.startsWith(File.separator)) {
if ((ml = new MediaLocator("file:" + url)) != null) {
return ml;
}
}
else {
String file = "file:" + System.getProperty("user.dir") +
File.separator + url;
if ((ml = new MediaLocator(file)) != null) {
return ml;
}
}
return null;
}

///////////////////////////////////////////////
//
// Inner classes.
///////////////////////////////////////////////

/** A DataSource to read from a list of JPEG image files and turn that
into a stream of JMF buffers.
* The DataSource is not seekable or positionable.
*/
private class ImageDataSource extends PullBufferDataSource {

private ImageSourceStream[] streams;

ImageDataSource(int width, int height, int frameRate) {
streams = new ImageSourceStream[1];
streams[0] = new ImageSourceStream(width, height, frameRate);
}

public void setLocator(MediaLocator source) {
}

public MediaLocator getLocator() {
return null;
}

/** Content type is of RAW since we are sending buffers of video
frames without a container format.
*/
public String getContentType() {
return ContentDescriptor.RAW;
}

public void connect() {
}

public void disconnect() {
}

public void start() {
}

public void stop() {
}

/** Return the ImageSourceStreams.
*/
public PullBufferStream[] getStreams() {
return streams;
}

/** We could have derived the duration from the number of frames and
frame rate. But for the purpose of this program, it's not necessary.
*/
public Time getDuration() {
System.out.println("dur is " + streams[0].nextImage);
//return new Time(1000000000);
return DURATION_UNKNOWN;
}

public Object[] getControls() {
return new Object[0];
}

public Object getControl(String type) {
return null;
}
}


/** The source stream to go along with ImageDataSource.
*/
class ImageSourceStream implements PullBufferStream {

private final int width, height;

private final VideoFormat format;

private BufferedImage frame = null;

// Bug fix from Forums - next two lines
private float frameRate;
private long seqNo = 0;

private int nextImage = 0; // index of the next image to be read.
private boolean ended = false;

public ImageSourceStream(int width, int height, int frameRate) {
this.width = width;
this.height = height;

// Bug fix from Forums (next line)
this.frameRate = (float) frameRate;

final int rMask = 0x00ff0000;
final int gMask = 0x0000FF00;
final int bMask = 0x000000ff;

format = new javax.media.format.RGBFormat(new Dimension(width,
height), Format.NOT_SPECIFIED, Format.intArray, frameRate, 32, bMask,
gMask, rMask);

}

/**
* We should never need to block assuming data are read from files.
*/
public boolean willReadBlock() {
return false;
}

/** This is called from the Processor to read a frame worth of video
data.
*/
public void read(Buffer buf) throws IOException {
// Check if we've finished all the frames.
if (nextImage >= 5) {
// We are done. Set EndOfMedia.
System.err.println("Done reading all images.");
buf.setEOM(true);
buf.setOffset(0);
buf.setLength(0);
ended = true;
return;
}
int max = (int) Math.log10(252);
int current = (nextImage != 0) ? (int) Math.log10(nextImage) : 0;
StringBuilder b = new StringBuilder("image");
for (int i = current; i < max; i++) {
b.append(0);
}
b.append(nextImage).append(".png");
System.out.println(b.toString());
BufferedImage image = ImageIO.read(new File(b.toString()));
if ((image.getWidth() != width) || (image.getHeight() != height)) {
// Lazily create frame of the correct size.
if (frame == null) {
frame = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
Graphics2D graphics = frame.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.drawImage(image, 0, 0, width, height, null);
graphics.dispose();
}
else {
frame = image;
}
nextImage++;
int[] data = null;
if (buf.getData() instanceof int[]) {
data = (int[]) buf.getData();
}
// Check to see the given buffer is big enough for the frame.
if (data == null || data.length < width * height) {
data = new int[width * height];
buf.setData(data);
}
data = frame.getRGB(0, 0, width, height, data, 0, width);
// Bug fix from Forums ( next 3 lines).
long time = (long) (seqNo * (1000 / frameRate) * 1000000);
buf.setTimeStamp(time);
buf.setSequenceNumber(seqNo++);
buf.setData(data);
buf.setOffset(0);
buf.setLength(width * height);
buf.setFormat(format);
buf.setFlags(buf.getFlags() | Buffer.FLAG_KEY_FRAME);
}



/**
* Return the format of each video frame. That will be JPEG.
*/
public Format getFormat() {
return format;
}

public ContentDescriptor getContentDescriptor() {
return new ContentDescriptor(ContentDescriptor.RAW);
}

public long getContentLength() {
return 0;
}

public boolean endOfStream() {
return ended;
}

public Object[] getControls() {
return new Object[0];
}

public Object getControl(String type) {
return null;
}
}
}

______________________________________________________________________________________________________________

Notes:

- This program makes a AVI video (with name "test.avi") from a
sequence of images (PNG).
- You must put images with this type of name: "image000.png",
"image001.png", "image002.png"....In this case, you must put five
images (from 000 to 004). You can change the number of images in the
line: 359 (method: read( Buffer buf ) ).

PROBLEM:

The size of video is fairly big since I don't use compression. Frames
are RGB. This video should be compressed with MJPEG, but I don't know
to use compression.
I thing that the key is in the lines 39-45. I changed this part and I
put:

__________________________________________________________________________-

Format f[] = tcs[0].getSupportedFormats();

if (f == null || f.length <= 0) {
System.err.println("The mux does not support the input format: " +
tcs[0].getFormat());
return false;
}
/*else{
for( int i=0; i< f.length; i++ ){
System.err.println("PASA="+f.getEncoding());
if( f.getEncoding().equals("mjpg") ){
tcs[0].setFormat(f);
System.err.println("Lo coge en="+i);
}
}
}*/

tcs[0].setFormat(f[0]);

______________________________________________________________________________________________________________________

BUT I didn't work...

Please, help me with any idea.

Regards.
 
L

Lew

/**For AVI files, each frame must have a time stamp set.See the
following message from the jmf - interest archives for details :
http : //archives.java.sun.com/cgi-bin/wa?A2=ind0107&L=jmf-
interest&P=R34660
*/
public class AviCreator implements ControllerListener,
DataSinkListener {

private boolean doIt(int width, int height, int frameRate,
MediaLocator outML) {

ImageDataSource ids = new ImageDataSource(width, height, frameRate);
Processor p;
try {
System.err.println("- create processor for the image datasource ...");
p = Manager.createProcessor(ids);
}
catch (Exception e) {
System.err.println("Yikes! Cannot create a processor from the data
source.");
return false;
}
....

Dude, indent your code (with spaces, not TABs) in the future. This is very
hard to read.
 
A

Andrew Thompson

Lew said:
/**For AVI files, each frame must have a time stamp set.See the
following message from the jmf - interest archives for details :
[quoted text clipped - 18 lines]
return false;
}
...

Dude, indent your code (with spaces, not TABs) in the future. This is very
hard to read.

1) I'll start by agreeing with that, then go on to point out that
it is mentioned in the SSCCE document to which I first
linked.

2) Also, over 500 lines of code? That is *not* an SSCCE!
(hint: what does the first 'S' stand for?)
Without even looking closely at that mess, I can guess this
problem could be expressed in under 200 lines of code, and
for those experienced with making SSCCE's, maybe less than 50.

So, my advice would be to revisit that code, and progressively
remove *every* line that can be removed, yet still display the
basic problem.

3) Short lines only! Many long lines in that code were
'line-wrapped' and therefore were broken when I went to
compile it. A couple of notes about breaking up lines..

System.out.println("A very, extremely, unnecessarily, long and obtuse
series of words");

..can be broken into short lines like this..

System.out.println("A very, " +
"extremely, unnecessarily, " +
"long and obtuse series of " +
"words");

Most other type of lines can be broken on any 'dot, comma or brace'. E.G.

System.out.println("Hi!");

..can actually be broken into separate lines like this..

System
.
out
.
println
(
"Hi!");

(That is of course, a ridiculous extent to take it to - I am just
making a point that there are lots of places where most code
lines can be safely wrapped onto a new line).

4) Then, (and this is *not* covered in the SSCCE document
but..) media projects are tricky to make SSCCE's for.

In particular, the problem *might* be with the source media, and
even if not, we are unable to run it, lacking an appropriate
animation file to start with.

In this case, perhaps you can use a little animation I made, as
the 'test source'. It is here..
<http://www.javasaver.com/testjs/jmf/anim/lunarphases.mov>
That is a mov of around 210Kb. I am not sure that a mov is suitable
for this test, but if not, have a look at
<http://www.javasaver.com/testjs/jmf/#media>
for other possiblilities.

If you change the code to refer to that lunar phases mov (directly
by URL), not only can anybody run it, but the clever ones can
download the mov and use the local copy.

So - I hear that you are not confident with English, & the fine
details of the SSCCE document may not have been clear to you,
but if you do not understand anything I say, please ask, rather
than dumping 500+ lines of unformatted, uncompilable code
on us!
 
M

Misterysword

Lew said:
/**For AVI files, each frame must have a time stamp set.See the
following message from the jmf - interest archives for details :
[quoted text clipped - 18 lines]
return false;
} ...

Dude, indent your code (with spaces, not TABs) in the future. This is very
hard to read.

1) I'll start by agreeing with that, then go on to point out that
it is mentioned in the SSCCE document to which I first
linked.

2) Also, over 500 lines of code? That is *not* an SSCCE!
(hint: what does the first 'S' stand for?)
Without even looking closely at that mess, I can guess this
problem could be expressed in under 200 lines of code, and
for those experienced with making SSCCE's, maybe less than 50.

So, my advice would be to revisit that code, and progressively
remove *every* line that can be removed, yet still display the
basic problem.

3) Short lines only! Many long lines in that code were
'line-wrapped' and therefore were broken when I went to
compile it. A couple of notes about breaking up lines..

System.out.println("A very, extremely, unnecessarily, long and obtuse
series of words");

.can be broken into short lines like this..

System.out.println("A very, " +
"extremely, unnecessarily, " +
"long and obtuse series of " +
"words");

Most other type of lines can be broken on any 'dot, comma or brace'. E.G.

System.out.println("Hi!");

.can actually be broken into separate lines like this..

System
.
out
.
println
(
"Hi!");

(That is of course, a ridiculous extent to take it to - I am just
making a point that there are lots of places where most code
lines can be safely wrapped onto a new line).

4) Then, (and this is *not* covered in the SSCCE document
but..) media projects are tricky to make SSCCE's for.

In particular, the problem *might* be with the source media, and
even if not, we are unable to run it, lacking an appropriate
animation file to start with.

In this case, perhaps you can use a little animation I made, as
the 'test source'. It is here..
<http://www.javasaver.com/testjs/jmf/anim/lunarphases.mov>
That is a mov of around 210Kb. I am not sure that a mov is suitable
for this test, but if not, have a look at
<http://www.javasaver.com/testjs/jmf/#media>
for other possiblilities.

If you change the code to refer to that lunar phases mov (directly
by URL), not only can anybody run it, but the clever ones can
download the mov and use the local copy.

So - I hear that you are not confident with English, & the fine
details of the SSCCE document may not have been clear to you,
but if you do not understand anything I say, please ask, rather
than dumping 500+ lines of unformatted, uncompilable code
on us!

Thank you for his advices. I do not want that you lose any more time
with me, so that I only ask you one thing:

In JMF, how do you add a codec? I need to compress the information
(with cinepak or mjpg format...) and I think that a codec is the only
way.

Thank you for everything.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top