Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: JMF: Unable to add custom codec when processor's content descriptor is set

  1. #1
    Junior Member
    Join Date
    Dec 2010
    Posts
    7
    My Mood
    Stressed
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default JMF: Unable to add custom codec when processor's content descriptor is set

    Hi ,


    I'm trying to create a video conferencing application using JMF. I need to access the frames before it is transmitted to the remote end, so I have a custom codec class. Below is the code:


    public void startMedia(String peerIP, int peerPort, int recvPort, int fmt) {
     
            try {
                /* initialization start */
     
                InetAddress inLocalAddr = InetAddress.getLocalHost();
                InetAddress destAddr = InetAddress.getByName(peerIP);
                SessionAddress localAddr =
                        new SessionAddress(inLocalAddr, recvPort, inLocalAddr, recvPort + 1);
                SessionAddress remoteAddr = new SessionAddress(destAddr, peerPort, destAddr, peerPort + 1);
                myVideoSessionManager.startSession(localAddr, localAddr, remoteAddr, null);
                /* initialization complete */
     
                int m = 0;
                if (inputSource == null) {
                    MediaLocator ml = new MediaLocator("vfw://0");
                    myDS = Manager.createDataSource(ml);
                } else {
     
                    myDS = ((SourceCloneable) inputSource).createClone();
                }
                myProcessor = Manager.createProcessor(myDS);
                myProcessor.addControllerListener(this);
                myProcessor.configure();
                while (myProcessor.getState() != Processor.Configured) {
                }
                myProcessor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));
     
                TrackControl track[] = myProcessor.getTrackControls();
     
     
                String videoFormat = track[0].getFormat().toString();
                Dimension videoSize = parseVideoSize(videoFormat);
     
                // Instantiate and set the frame access codec to the data flow path.
                try {
                    Codec codec[] = {new PostAccessCodec(videoSize)};
                    track[0].setCodecChain(codec);
                } catch (UnsupportedPlugInException e) {
                    System.err.println("The process does not support effects.");
                }
     
                myProcessor.prefetch();
                if (!waitForState(Processor.Prefetched)) {
                    System.err.println("Failed to realise the processor.");
                    //  return false;
                }
                ds = myProcessor.getDataOutput();
                try {
                    ss = myVideoSessionManager.createSendStream(ds, 0);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //We start capture and transmission
                myProcessor.start();
                ss.start();
     
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }




     public class PreAccessCodec implements Codec {
     
            /**
             * Callback to access individual video frames.
             */
            void accessFrame(Buffer frame) {
     
    // For demo, we'll just print out the frame #, time &
    // data length.
     
                long t = (long) (frame.getTimeStamp() / 10000000f);
     
                System.err.println(
                        "Pre: frame #: "
                        + frame.getSequenceNumber()
                        + ", time: "
                        + ((float) t) / 100f
                        + ", len: "
                        + frame.getLength());
     
            }
            /**
             * The code for a pass through codec.
             */
            protected Format supportedIns[] = new Format[]{new VideoFormat(null)};
            protected Format supportedOuts[] = new Format[]{new VideoFormat(null)};
            Format input = null, output = null;
     
            public String getName() {
                return "Pre-Access Codec";
            }
     
    //these dont do anything
            public void open() {
            }
     
            public void close() {
            }
     
            public void reset() {
            }
     
            public Format[] getSupportedInputFormats() {
                return supportedIns;
            }
     
            public Format[] getSupportedOutputFormats(Format in) {
                if (in == null) {
                    return supportedOuts;
                } else {
                    Format outs[] = new Format[1];
                    outs[0] = in;
                    return outs;
                }
            }
     
            public Format setInputFormat(Format format) {
                input = format;
                return input;
            }
     
            public Format setOutputFormat(Format format) {
                output = format;
                return output;
            }
     
            public int process(Buffer in, Buffer out) {
     
    // This is the "Callback" to access individual frames.
                accessFrame(in);
     
    // Swap the data between the input & output.
                Object data = in.getData();
                in.setData(out.getData());
                out.setData(data);
     
    // Copy the input attributes to the output
                out.setFlags(Buffer.FLAG_NO_SYNC);
                out.setFormat(in.getFormat());
                out.setLength(in.getLength());
                out.setOffset(in.getOffset());
     
                return BUFFER_PROCESSED_OK;
            }
     
            public Object[] getControls() {
                return new Object[0];
            }
     
            public Object getControl(String type) {
                return null;
            }
        }
     
        public class PostAccessCodec extends PreAccessCodec {
     
            long count = 0;
    // We'll advertize as supporting all video formats.
     
            public PostAccessCodec(Dimension size) {
                supportedIns = new Format[]{new RGBFormat()};
                this.size = size;
            }
     
            /**
             * Callback to access individual video frames.
             */
            void accessFrame(Buffer frame) {
     
                count = count + 1;
                long t = (long) (frame.getTimeStamp() / 10000000f);
                System.err.println(
                        "Post: frame #: "
                        + frame.getSequenceNumber()
                        + ", time: "
                        + ((float) t) / 100f
                        + ", len: "
                        + frame.getLength());
                       }
     
            public String getName() {
                return "Post-Access Codec";
            }
            private Dimension size;
        }
     
        /**
         * Block until the processor has transitioned to the given state.
         * Return false if the transition failed.
         */
        boolean waitForState(int state) {
            synchronized (waitSync) {
                try {
                    while (myProcessor.getState() != state && stateTransitionOK) {
                        waitSync.wait();
                    }
                } catch (Exception e) {
                }
            }
            return stateTransitionOK;
        }
     
      public Dimension parseVideoSize(String videoSize) {
            int x = 352, y = 288;
            StringTokenizer strtok = new StringTokenizer(videoSize, ", ");
            strtok.nextToken();
            String size = strtok.nextToken();
            StringTokenizer sizeStrtok = new StringTokenizer(size, "x");
            try {
                x = Integer.parseInt(sizeStrtok.nextToken());
                y = Integer.parseInt(sizeStrtok.nextToken());
            } catch (NumberFormatException e) {
                System.out.println("unable to find video size, assuming default of 352*288");
            }
            System.out.println("Image width = " + String.valueOf(x) + "\nImage height = " + String.valueOf(y));
            return new Dimension(x, y);
        }


    Below is the exception I got while executing the code:

    HTML Code:
    Class: com.ibm.media.codec.video.h263.NativeEncoder@1b7ae22
      can only encode in sizes: 128x96, 176x144, 352x288.
    Failed to realize: com.sun.media.ProcessEngine@9903f4
      Cannot build a flow graph with the customized options:
        Unable to add customed codecs: 
          splibraries.VideoTool$PostAccessCodec@1926e90
    Error: Unable to realize com.sun.media.ProcessEngine@9903f4
    Failed to realise the processor.
    javax.media.NotRealizedError: getDataOutput cannot be called before realized
            at com.sun.media.ProcessEngine.getDataOutput(ProcessEngine.java:379)
    I was able to access the frame when I set the content descriptor for processor to null as below:
    myProcessor.setContentDescriptor(null);

    But this will not allow me to get the data output from processor . Kindly help me to resolve the issue.


  2. #2
    Junior Member
    Join Date
    Jan 2013
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default cghmwhbcc tpskcoood rcowaqlca bbozkmkus xysjmdxvj

    Excellent site you have here but I was wondering if you knew of any forums that cover the same topics talked about here? I'd really love to be a part of community where I can get responses from other knowledgeable individuals that share the same interest. If you have any suggestions, please let me know. Thanks a lot 2013fakeoakleys.webs.com!

Similar Threads

  1. Custom Log level help
    By seanman in forum Java SE APIs
    Replies: 1
    Last Post: September 25th, 2011, 09:55 PM
  2. can i use custom buttons ?
    By Gaurav18 in forum Member Introductions
    Replies: 3
    Last Post: September 12th, 2011, 10:56 AM
  3. Replies: 1
    Last Post: September 9th, 2011, 03:30 PM
  4. Creating a custom panel:
    By xterradaniel in forum AWT / Java Swing
    Replies: 19
    Last Post: October 3rd, 2010, 08:15 PM
  5. My Custom Layout (VERY EASY TO USE)
    By aussiemcgr in forum AWT / Java Swing
    Replies: 10
    Last Post: August 5th, 2010, 02:37 PM