00001 package org.hfbk.vid;
00002
00003 import java.util.LinkedList;
00004 import java.util.List;
00005
00006 import net.sf.ffmpeg_java.AVCodecLibrary.AVCodec;
00007 import net.sf.ffmpeg_java.AVCodecLibrary.AVCodecContext;
00008 import net.sf.ffmpeg_java.AVFormatLibrary.AVPacket;
00009
00010 import org.hfbk.util.Sleeper;
00011
00012 import com.sun.jna.Native;
00013
00022 public abstract class AVStreamThread extends Thread {
00023
00025 protected boolean running=true;
00027 protected boolean playing=true;
00028
00031 boolean finished=false;
00032
00033 AVCodecContext ctx;
00034
00035 int bytes, limit;
00036
00037 private List<AVPacket> queue=new LinkedList<AVPacket>();
00038 private List<AVPacket> free=new LinkedList<AVPacket>();
00039
00047 public AVStreamThread(String name, AVCodecContext ctx, int bufferlimit) {
00048 super(name);
00049 setDaemon(true);
00050 setPriority(Thread.MIN_PRIORITY + 3);
00051
00052 this.limit=bufferlimit;
00053 this.ctx=ctx;
00054
00055 String codecName=Native.toString(ctx.codec_name);
00056 if (ctx.codec_id == 0){
00057 throw new RuntimeException("Codec not available.");
00058 }
00059 synchronized(AV.CODEC){
00060
00061 AVCodec codec = AV.CODEC.avcodec_find_decoder(ctx.codec_id);
00062
00063
00064 if (AV.CODEC.avcodec_open(ctx, codec) < 0)
00065 throw new RuntimeException("Could not open codec.");
00066 }
00067 }
00068
00070 void setPlaying(boolean playing){this.playing=playing;}
00073 void setRunning(boolean running){this.running=running;}
00074
00075 protected void close() {
00076 flush();
00077 synchronized(AV.CODEC){
00078 AV.CODEC.avcodec_close(ctx);
00079 }
00080 }
00081
00085 void tick(int time){}
00086
00087
00088
00093 void add(AVPacket p) {
00094 while(bytes>limit) Sleeper.sleep(2);
00095 synchronized(this){
00096 bytes+=p.size;
00097 AV.FORMAT.av_dup_packet(p);
00098
00099 queue.add(p);
00100 }
00101 }
00102
00109 synchronized AVPacket poll() {
00110 if (queue.size()>0){
00111 AVPacket e=queue.get(0);
00112 queue.remove(0);
00113 bytes-=e.size;
00114 return e;
00115 }
00116 return null;
00117 }
00118
00120 void free(AVPacket p){
00121 p.destruct.callback(p);
00122 synchronized(free){
00123 free.add(p);
00124 }
00125 }
00126
00128 synchronized AVPacket getFree(){
00129 synchronized(free){
00130 if (free.size()>0){
00131 AVPacket e=free.get(0);
00132 free.remove(0);
00133 return e;
00134 }else{
00135 return new AVPacket();
00136 }
00137 }
00138 }
00139
00141 synchronized void flush() {
00142 AVPacket packet;
00143 while ((packet=poll())!=null)
00144 packet.destruct.callback(packet);
00145 }
00146 }