Revision: 9179
Author: [email protected]
Date: Wed Dec 30 04:56:54 2009
Log: completed evolve for Audio and Video Player for AVPlayer
http://code.google.com/p/mobicents/source/detail?r=9179
Modified:
/trunk/servers/media/core/server-impl/src/main/java/org/mobicents/media/server/impl/resource/video/AVPlayer.java
=======================================
---
/trunk/servers/media/core/server-impl/src/main/java/org/mobicents/media/server/impl/resource/video/AVPlayer.java
Wed Dec 30 03:07:44 2009
+++
/trunk/servers/media/core/server-impl/src/main/java/org/mobicents/media/server/impl/resource/video/AVPlayer.java
Wed Dec 30 04:56:54 2009
@@ -45,7 +45,7 @@
import org.mobicents.media.server.impl.resource.ss7.Mtp2;
import org.mobicents.media.server.impl.rtp.sdp.AVProfile;
import org.mobicents.media.server.spi.MultimediaSource;
-import org.mobicents.media.server.spi.ResourceGroup;
+import org.mobicents.media.server.spi.events.NotifyEvent;
import org.mobicents.media.server.spi.resource.AudioPlayer;
import org.mobicents.media.server.spi.resource.video.VideoPlayer;
@@ -56,305 +56,386 @@
*/
public class AVPlayer extends BaseComponent implements MultimediaSource {
- private final static Format[] AUDIO_FORMATS = new
Format[]{AVProfile.MPEG4_GENERIC};
- private final static Format[] VIDEO_FORMATS = new
Format[]{AVProfile.MP4V};
-
- private final static Logger logger = Logger.getLogger(AVPlayer.class);
- private volatile boolean eom = false;
- private String fileName;
- private FileInputStream fin;
- private FileTypeBox fileTypeBox;
- private MovieBox movieBox;
- private MediaDataBox mediaDataBox;
- private AudioWrapper audioWrapper;
- private VideoWrapper videoWrapper;
- private File file;
-
- private AudioSource audioSource;
- private VideoSource videoSource;
-
- private static ArrayList<String> mediaTypes = new ArrayList();
- static {
- mediaTypes.add("audio");
- mediaTypes.add("video");
- }
- public AVPlayer(String name) {
- super(name);
- }
-
- public void setFile(String fileName) {
- this.fileName = fileName;
- }
-
- public MediaSource getMediaSource(String media) {
- if (media.equals("audio")) {
- return audioSource;
- } else return videoSource;
- }
-
- private byte[] read(DataInputStream in) throws IOException {
- byte[] buff = new byte[4];
- for (int i = 0; i < buff.length; i++) {
- buff[i] = in.readByte();
- }
- return buff;
- }
-
- public void prepareTracks() throws Exception {
- closeStream();
- fin = new FileInputStream(fileName);
-
- parse();
-
- TrackBox audioTrackBox = null;
- TrackBox audioHintTrackBox = null;
- TrackBox videoTrackBox = null;
- TrackBox videoHintTrackBox = null;
-
- for (TrackBox tBox : this.movieBox.getTrackBoxes()) {
- String type =
tBox.getMediaBox().getHandlerReferenceBox().getHandlerType();
- if (type.equalsIgnoreCase("soun")) {
- audioTrackBox = tBox;
- } else if (type.equalsIgnoreCase("vide")) {
- videoTrackBox = tBox;
- } else if (type.equalsIgnoreCase("hint")) {
- TrackReferenceBox trackReferenceBox =
tBox.getTrackReferenceBox();
- List<TrackReferenceTypeBox> trackRefTypList =
trackReferenceBox.getTrackReferenceTypeBoxes();
-
- for (TrackReferenceTypeBox trkRefTypBox : trackRefTypList)
{
- if
(trkRefTypBox.getType().equals(HintTrackReferenceTypeBox.TYPE_S)) {
- long[] trackIds = trkRefTypBox.getTrackIDs();
- // FIXME we are assuming here there is always 1
track that this hint track is referencing but
- // there could be more than 1
- long trackId = trackIds[0];
-
- // FIXME audioTrackBox can be still null if hint
track is placed before audioTrack
- if (audioTrackBox.getTrackHeaderBox().getTrackID()
== trackId) {
- audioHintTrackBox = tBox;
- audioWrapper = new AudioWrapper(audioTrackBox,
audioHintTrackBox, this.file);
- } else if
(videoTrackBox.getTrackHeaderBox().getTrackID() == trackId) {
- videoHintTrackBox = tBox;
- videoWrapper = new VideoWrapper(videoTrackBox,
videoHintTrackBox, this.file);
- }
- }
- }
- }
- }// for
- if (audioWrapper == null || videoWrapper == null) {
- throw new IOException("The file neither have Hint Audio track
nor Hint Video track");
- }
- }
-
- public void afterStop() {
- closeStream();
- }
-
- private void closeStream() {
- try {
- if (fin != null) {
- fin.close();
- fin = null;
- }
-
- this.file = null;
-
- fileTypeBox = null;
- movieBox = null;
- mediaDataBox = null;
-
- if (this.audioWrapper != null) {
- this.audioWrapper.close();
- }
-
- if (this.videoWrapper != null) {
- this.videoWrapper.close();
- }
- this.audioWrapper = null;
- this.videoWrapper = null;
-
- } catch (IOException e) {
- if (logger.isDebugEnabled()) {
- logger.debug("Closing resources of Videolayer failed ", e);
- }
- }
- }
-
- private void parse() throws IOException {
- DataInputStream ds = new DataInputStream(fin);
- long count = 0;
-
- while (ds.available() > 0) {
- long len = readU32(ds);
- byte[] type = read(ds);
-
- if (comparebytes(type, FileTypeBox.TYPE)) {
- fileTypeBox = new FileTypeBox(len);
- count += fileTypeBox.load(ds);
-
- if (logger.isDebugEnabled()) {
- logger.debug(this.fileTypeBox.toString());
- }
- } else if (comparebytes(type, MovieBox.TYPE)) {
- movieBox = new MovieBox(len);
- count += movieBox.load(ds);
- } else if (comparebytes(type, FreeSpaceBox.TYPE_FREE)) {
- FreeSpaceBox free = new FreeSpaceBox(len,
FreeSpaceBox.TYPE_FREE_S);
- count += free.load(ds);
- } else if (comparebytes(type, FreeSpaceBox.TYPE_SKIP)) {
- FreeSpaceBox skip = new FreeSpaceBox(len,
FreeSpaceBox.TYPE_SKIP_S);
- count += skip.load(ds);
- } else if (comparebytes(type, MediaDataBox.TYPE)) {
- // TODO : How should we handle multiple MediaDataBox?
- mediaDataBox = new MediaDataBox(len);
- count += mediaDataBox.load(ds);
-
- if (file == null) {
- file = new File(this.fileName);
- }
- } else {
- // TODO : Do we care for other boxes?
- if (len - 8 > 0) {
- ds.skipBytes((int) len - 8);
- }
- }
- }
- }
-
- private boolean comparebytes(byte[] arg1, byte[] arg2) {
- if (arg1.length != arg2.length) {
- return false;
- }
- for (int i = 0; i < arg1.length; i++) {
- if (arg1[i] != arg2[i]) {
- return false;
- }
- }
- return true;
- }
-
- private long readU32(DataInputStream in) throws IOException {
- return ((long) (in.read() << 24 | in.read() << 16 | in.read() << 8
| in.read())) & 0xFFFFFFFFL;
- }
-
- public static void main(String[] args) throws Exception {
-
- BasicConfigurator.configure();
-
- AVPlayer vp = new AVPlayer("PlayerTest");
- // vp.setFile("/home/abhayani/Desktop/tones/multiTrack.3gp");
- vp.setFile("c:\\video\\001.mp4");
- vp.prepareTracks();
-
- System.out.println("AUDIO SDP = " + vp.audioWrapper.getSdpText());
- System.out.println("VIDEO SDP = " + vp.videoWrapper.getSdpText());
-
- // Audio
- for (int i = 0; i < 10; i++) {
- List<RTPPacket> rtpPktList = vp.audioWrapper.process();
- for (RTPPacket rtpPacket : rtpPktList) {
- System.out.println("\nrtpSequenceSeed = " +
rtpPacket.getRtpSequenceSeed() + " payloadType = " +
rtpPacket.getPayloadType() + " RtpTimeStamp = " +
rtpPacket.getRtpTimestamp() + " TimeStamp in ms = " +
rtpPacket.getTimestamp() + " PacketPeriod in ms = " +
rtpPacket.getPacketPeriod() + " PBit = " + rtpPacket.getPbit() + " X Bit
= " + rtpPacket.getXbit() + " Marker = " + rtpPacket.getMbit());
-
- System.out.println("The Payload Data ");
- System.out.print(Mtp2.dump(rtpPacket.getPayload(),
rtpPacket.getPayload().length, false));
- }
- }
-
- // Video
- // for (int i = 0; i < 10; i++) {
- // List<RTPPacket> rtpPktList = vp.videoWrapper.process();
- // for (RTPPacket rtpPacket : rtpPktList) {
- //
- // System.out.println("\nrtpSequenceSeed = " +
rtpPacket.getRtpSequenceSeed() + " payloadType = "
- // + rtpPacket.getPayloadType() + " TimeStamp = " +
rtpPacket.getTimestamp() + " PBit = "
- // + rtpPacket.getPbit() + " X Bit = " + rtpPacket.getXbit()+ " Marker
= "+ rtpPacket.getMbit() );
- //
- // System.out.println("The Payload Data ");
- // System.out.print(Mtp2.dump(rtpPacket.getPayload(),
rtpPacket.getPayload().length, false));
- // }
- // }
- }
-
-
- public Format[] getFormats() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public void start() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public void stop() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Collection<String> getMediaTypes() {
- return mediaTypes;
- }
-
- public MediaSink getSink(String media) {
- return null;
- }
-
- public MediaSource getSource(String media) {
- if (media.equals("audio")) {
- return audioSource;
- } else if (media.equals("video")) {
- return videoSource;
- }
- return null;
- }
-
- private class AudioSource extends AbstractSource implements
AudioPlayer {
-
- private String url;
-
- public AudioSource(String name) {
- super(name);
- }
-
- @Override
- public void evolve(Buffer buffer, long timestamp, long
sequenceNumber) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Format[] getFormats() {
- return AUDIO_FORMATS;
- }
-
- public void setURL(String url) {
- this.url = url;
- }
-
- public String getURL() {
- return url;
- }
- }
-
- private class VideoSource extends AbstractSource implements
VideoPlayer {
-
- private String url;
-
- public VideoSource(String name) {
- super(name);
- }
-
- @Override
- public void evolve(Buffer buffer, long timestamp, long
sequenceNumber) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- public Format[] getFormats() {
- return VIDEO_FORMATS;
- }
-
- public void setURL(String url) {
- this.url = url;
- }
-
- public String getURL() {
- return url;
- }
- }
+ private final static Format[] AUDIO_FORMATS = new Format[] {
AVProfile.MPEG4_GENERIC };
+ private final static Format[] VIDEO_FORMATS = new Format[] {
AVProfile.MP4V };
+
+ private final static Logger logger = Logger.getLogger(AVPlayer.class);
+ private volatile boolean eom = false;
+ private String fileName;
+ private FileInputStream fin;
+ private FileTypeBox fileTypeBox;
+ private MovieBox movieBox;
+ private MediaDataBox mediaDataBox;
+ private AudioWrapper audioWrapper;
+ private VideoWrapper videoWrapper;
+ private File file;
+
+ private AudioSource audioSource;
+ private VideoSource videoSource;
+
+ private volatile boolean started = false;
+
+ private static ArrayList<String> mediaTypes = new ArrayList();
+ static {
+ mediaTypes.add("audio");
+ mediaTypes.add("video");
+ }
+
+ public AVPlayer(String name) {
+ super(name);
+ this.audioSource = new AudioSource(name, this);
+ this.videoSource = new VideoSource(name, this);
+ }
+
+ public void setFile(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public MediaSource getMediaSource(String media) {
+ if (media.equals("audio")) {
+ return audioSource;
+ } else
+ return videoSource;
+ }
+
+ private byte[] read(DataInputStream in) throws IOException {
+ byte[] buff = new byte[4];
+ for (int i = 0; i < buff.length; i++) {
+ buff[i] = in.readByte();
+ }
+ return buff;
+ }
+
+ public void prepareTracks() throws Exception {
+ closeStream();
+ fin = new FileInputStream(fileName);
+
+ parse();
+
+ TrackBox audioTrackBox = null;
+ TrackBox audioHintTrackBox = null;
+ TrackBox videoTrackBox = null;
+ TrackBox videoHintTrackBox = null;
+
+ for (TrackBox tBox : this.movieBox.getTrackBoxes()) {
+ String type =
tBox.getMediaBox().getHandlerReferenceBox().getHandlerType();
+ if (type.equalsIgnoreCase("soun")) {
+ audioTrackBox = tBox;
+ } else if (type.equalsIgnoreCase("vide")) {
+ videoTrackBox = tBox;
+ } else if (type.equalsIgnoreCase("hint")) {
+ TrackReferenceBox trackReferenceBox =
tBox.getTrackReferenceBox();
+ List<TrackReferenceTypeBox> trackRefTypList =
trackReferenceBox.getTrackReferenceTypeBoxes();
+
+ for (TrackReferenceTypeBox trkRefTypBox :
trackRefTypList) {
+ if
(trkRefTypBox.getType().equals(HintTrackReferenceTypeBox.TYPE_S)) {
+ long[] trackIds =
trkRefTypBox.getTrackIDs();
+ // FIXME we are assuming here there is always 1 track that this hint
track is referencing but
+ // there could be more than 1
+ long trackId = trackIds[0];
+
+ // FIXME audioTrackBox can be still null if hint track is placed
before audioTrack
+ if
(audioTrackBox.getTrackHeaderBox().getTrackID() == trackId) {
+ audioHintTrackBox =
tBox;
+ audioWrapper = new AudioWrapper(audioTrackBox, audioHintTrackBox,
this.file);
+ } else if (videoTrackBox.getTrackHeaderBox().getTrackID() ==
trackId) {
+ videoHintTrackBox =
tBox;
+ videoWrapper = new VideoWrapper(videoTrackBox, videoHintTrackBox,
this.file);
+ }
+ }
+ }
+ }
+ }// for
+ if (audioWrapper == null || videoWrapper == null) {
+ throw new IOException("The file neither have Hint Audio track nor Hint
Video track");
+ }
+ }
+
+ public void afterStop() {
+ closeStream();
+ }
+
+ private void closeStream() {
+ try {
+ if (fin != null) {
+ fin.close();
+ fin = null;
+ }
+
+ this.file = null;
+
+ fileTypeBox = null;
+ movieBox = null;
+ mediaDataBox = null;
+
+ if (this.audioWrapper != null) {
+ this.audioWrapper.close();
+ }
+
+ if (this.videoWrapper != null) {
+ this.videoWrapper.close();
+ }
+ this.audioWrapper = null;
+ this.videoWrapper = null;
+
+ } catch (IOException e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing resources of Videolayer failed
", e);
+ }
+ }
+ }
+
+ private void parse() throws IOException {
+ DataInputStream ds = new DataInputStream(fin);
+ long count = 0;
+
+ while (ds.available() > 0) {
+ long len = readU32(ds);
+ byte[] type = read(ds);
+
+ if (comparebytes(type, FileTypeBox.TYPE)) {
+ fileTypeBox = new FileTypeBox(len);
+ count += fileTypeBox.load(ds);
+
+ if (logger.isDebugEnabled()) {
+
logger.debug(this.fileTypeBox.toString());
+ }
+ } else if (comparebytes(type, MovieBox.TYPE)) {
+ movieBox = new MovieBox(len);
+ count += movieBox.load(ds);
+ } else if (comparebytes(type, FreeSpaceBox.TYPE_FREE)) {
+ FreeSpaceBox free = new FreeSpaceBox(len,
FreeSpaceBox.TYPE_FREE_S);
+ count += free.load(ds);
+ } else if (comparebytes(type, FreeSpaceBox.TYPE_SKIP)) {
+ FreeSpaceBox skip = new FreeSpaceBox(len,
FreeSpaceBox.TYPE_SKIP_S);
+ count += skip.load(ds);
+ } else if (comparebytes(type, MediaDataBox.TYPE)) {
+ // TODO : How should we handle multiple
MediaDataBox?
+ mediaDataBox = new MediaDataBox(len);
+ count += mediaDataBox.load(ds);
+
+ if (file == null) {
+ file = new File(this.fileName);
+ }
+ } else {
+ // TODO : Do we care for other boxes?
+ if (len - 8 > 0) {
+ ds.skipBytes((int) len - 8);
+ }
+ }
+ }
+ }
+
+ private boolean comparebytes(byte[] arg1, byte[] arg2) {
+ if (arg1.length != arg2.length) {
+ return false;
+ }
+ for (int i = 0; i < arg1.length; i++) {
+ if (arg1[i] != arg2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private long readU32(DataInputStream in) throws IOException {
+ return ((long) (in.read() << 24 | in.read() << 16 | in.read() << 8 |
in.read())) & 0xFFFFFFFFL;
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ BasicConfigurator.configure();
+
+ AVPlayer vp = new AVPlayer("PlayerTest");
+ // vp.setFile("/home/abhayani/Desktop/tones/multiTrack.3gp");
+ vp.setFile("c:\\video\\001.mp4");
+ vp.prepareTracks();
+
+ System.out.println("AUDIO SDP = " +
vp.audioWrapper.getSdpText());
+ System.out.println("VIDEO SDP = " +
vp.videoWrapper.getSdpText());
+
+ // Audio
+ for (int i = 0; i < 10; i++) {
+ List<RTPPacket> rtpPktList = vp.audioWrapper.process();
+ for (RTPPacket rtpPacket : rtpPktList) {
+ System.out.println("\nrtpSequenceSeed = " +
rtpPacket.getRtpSequenceSeed() + " payloadType = "
+ + rtpPacket.getPayloadType() + " RtpTimeStamp = " +
rtpPacket.getRtpTimestamp()
+ + " TimeStamp in ms = " + rtpPacket.getTimestamp() + " PacketPeriod
in ms = "
+ + rtpPacket.getPacketPeriod() + " PBit = " + rtpPacket.getPbit() + "
X Bit = "
+ + rtpPacket.getXbit() + " Marker =
" + rtpPacket.getMbit());
+
+ System.out.println("The Payload Data ");
+ System.out.print(Mtp2.dump(rtpPacket.getPayload(),
rtpPacket.getPayload().length, false));
+ }
+ }
+
+ // Video
+ // for (int i = 0; i < 10; i++) {
+ // List<RTPPacket> rtpPktList = vp.videoWrapper.process();
+ // for (RTPPacket rtpPacket : rtpPktList) {
+ //
+ // System.out.println("\nrtpSequenceSeed = " +
rtpPacket.getRtpSequenceSeed() + " payloadType = "
+ // + rtpPacket.getPayloadType() + " TimeStamp = " +
rtpPacket.getTimestamp() + " PBit = "
+ // + rtpPacket.getPbit() + " X Bit = " + rtpPacket.getXbit()+ " Marker
= "+ rtpPacket.getMbit() );
+ //
+ // System.out.println("The Payload Data ");
+ // System.out.print(Mtp2.dump(rtpPacket.getPayload(),
rtpPacket.getPayload().length, false));
+ // }
+ // }
+ }
+
+ public Format[] getFormats() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void start() {
+ try {
+
+ this.prepareTracks();
+
+ this.started = true;
+
+ this.audioSource.start();
+ this.videoSource.start();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ this.started = false;
+
+ // TODO notify the Listener about error
+ }
+ }
+
+ public void stop() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Collection<String> getMediaTypes() {
+ return mediaTypes;
+ }
+
+ public MediaSink getSink(String media) {
+ return null;
+ }
+
+ public MediaSource getSource(String media) {
+ if (media.equals("audio")) {
+ return audioSource;
+ } else if (media.equals("video")) {
+ return videoSource;
+ }
+ return null;
+ }
+
+ private class AudioSource extends AbstractSource implements AudioPlayer
{
+
+ private String url;
+ private AVPlayer avPlayer;
+
+ public AudioSource(String name, AVPlayer avPlayer) {
+ super(name);
+ this.avPlayer = avPlayer;
+ }
+
+ @Override
+ public void start() {
+ if (this.avPlayer.started) {
+ super.start();
+ }
+ }
+
+ @Override
+ public void evolve(Buffer buffer, long timestamp, long
sequenceNumber) {
+
+ try {
+ List<RTPPacket> rtpPackets =
this.avPlayer.audioWrapper.process();
+ //TODO : handle more than one RTPPackets
+
+ RTPPacket rtpPacket = rtpPackets.get(0);
+
+ byte[] data = rtpPacket.getPayload();
+ buffer.setData(data);
+
buffer.setTimeStamp(rtpPacket.getRtpTimestamp());
+ buffer.setOffset(0);
+ buffer.setLength(data.length);
+ buffer.setEOM(eom);
+
buffer.setSequenceNumber(rtpPacket.getRtpSequenceSeed());
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ failed(NotifyEvent.TX_FAILED, e);
+ }
+ }
+
+ public Format[] getFormats() {
+ return AUDIO_FORMATS;
+ }
+
+ public void setURL(String url) {
+ this.url = url;
+ }
+
+ public String getURL() {
+ return url;
+ }
+ }
+
+ private class VideoSource extends AbstractSource implements VideoPlayer
{
+
+ private String url;
+ private AVPlayer avPlayer;
+
+ public VideoSource(String name, AVPlayer avPlayer) {
+ super(name);
+ this.avPlayer = avPlayer;
+ }
+
+ @Override
+ public void start() {
+ if (this.avPlayer.started) {
+ super.start();
+ }
+ }
+
+ @Override
+ public void evolve(Buffer buffer, long timestamp, long
sequenceNumber) {
+ try {
+ List<RTPPacket> rtpPackets =
this.avPlayer.audioWrapper.process();
+ //TODO : handle more than one RTPPackets
+
+ RTPPacket rtpPacket = rtpPackets.get(0);
+
+ byte[] data = rtpPacket.getPayload();
+ buffer.setData(data);
+
buffer.setTimeStamp(rtpPacket.getRtpTimestamp());
+ buffer.setOffset(0);
+ buffer.setLength(data.length);
+ buffer.setEOM(eom);
+
buffer.setSequenceNumber(rtpPacket.getRtpSequenceSeed());
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ failed(NotifyEvent.TX_FAILED, e);
+ }
+
+ }
+
+ public Format[] getFormats() {
+ return VIDEO_FORMATS;
+ }
+
+ public void setURL(String url) {
+ this.url = url;
+ }
+
+ public String getURL() {
+ return url;
+ }
+ }
}