aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/kvilib/ext/kvi_oggtheora.cpp505
-rw-r--r--src/kvilib/ext/kvi_oggtheora.h57
-rw-r--r--src/modules/dcc/codec.cpp2
3 files changed, 84 insertions, 480 deletions
diff --git a/src/kvilib/ext/kvi_oggtheora.cpp b/src/kvilib/ext/kvi_oggtheora.cpp
index a234dffaa..6ca193197 100644
--- a/src/kvilib/ext/kvi_oggtheora.cpp
+++ b/src/kvilib/ext/kvi_oggtheora.cpp
@@ -67,20 +67,11 @@ KviTheoraEncoder::KviTheoraEncoder(KviDataBuffer * stream, int iWidth, int iHeig
//used to check functions results
int ret;
videoflag=0;
- audioflag=0;
videoYuv=0;
frame_state=-1;
frames=0;
- //audio
- audio=false;
- audio_ch=1;
- audio_hz=8000;
- audio_q=.6f;
- samples_sofar=0;
-
//text
- text=true;
text_sofar=0;
//user settings
@@ -112,34 +103,14 @@ KviTheoraEncoder::KviTheoraEncoder(KviDataBuffer * stream, int iWidth, int iHeig
srand(time(NULL));
ogg_stream_init(&to,rand());
-
- // initialize Vorbis assuming we have audio to compress.
- if(audio)
+ ogg_stream_init(&zo,rand());
+ ret = KviOggIrcText::irct_encode_init();
+ if(ret)
{
- ogg_stream_init(&vo,rand());
- vorbis_info_init(&vi);
- ret = vorbis_encode_init_vbr(&vi,audio_ch,audio_hz,audio_q);
- if(ret)
- {
- qDebug("error initializing vorbis audio");
- return;
- }
- vorbis_comment_init(&vc);
- vorbis_analysis_init(&vd,&vi);
- vorbis_block_init(&vd,&vb);
+ qDebug("error initializing irctext");
+ return;
}
- // initialize out text codec
- if(text)
- {
- ogg_stream_init(&zo,rand());
- ret = KviOggIrcText::irct_encode_init();
- if(ret)
- {
- qDebug("error initializing irctext");
- return;
- }
- }
// Set up Theora encoder
// Theora has a divisible-by-sixteen restriction for the encoded frame size
@@ -212,36 +183,16 @@ KviTheoraEncoder::KviTheoraEncoder(KviDataBuffer * stream, int iWidth, int iHeig
ogg_stream_packetin(&to,&op);
}
- if(audio)
- {
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
- vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
- ogg_stream_packetin(&vo,&header); // automatically placed in its own page
- if(ogg_stream_pageout(&vo,&og)!=1){
- qDebug("Internal Ogg library error.");
- return;
- }
- m_pStream->append(og.header,og.header_len);
- m_pStream->append(og.body,og.body_len);
- // remaining vorbis header packets
- ogg_stream_packetin(&vo,&header_comm);
- ogg_stream_packetin(&vo,&header_code);
- }
-
- if(text)
- {
- ogg_packet header;
- KviOggIrcText::irct_encode_headerout(&header);
- ogg_stream_packetin(&zo,&header); // automatically placed in its own page
- if(ogg_stream_pageout(&zo,&og)!=1){
- qDebug("Internal Ogg library error (irct).");
- return;
- }
- m_pStream->append(og.header,og.header_len);
- m_pStream->append(og.body,og.body_len);
+ //irct
+ ogg_packet header;
+ KviOggIrcText::irct_encode_headerout(&header);
+ ogg_stream_packetin(&zo,&header); // automatically placed in its own page
+ if(ogg_stream_pageout(&zo,&og)!=1){
+ qDebug("Internal Ogg library error (irct).");
+ return;
}
+ m_pStream->append(og.header,og.header_len);
+ m_pStream->append(og.body,og.body_len);
// Flush the rest of our headers. This ensures the actual data in each stream
// will start on a new page, as per spec.
@@ -256,21 +207,6 @@ KviTheoraEncoder::KviTheoraEncoder(KviDataBuffer * stream, int iWidth, int iHeig
m_pStream->append(og.header,og.header_len);
m_pStream->append(og.body,og.body_len);
}
-
- if(audio)
- {
- for(;;){
- int result=ogg_stream_flush(&vo,&og);
- if(result<0){
- // can't get here
- qDebug("Internal Ogg library error.");
- return;
- }
- if(result==0)break;
- m_pStream->append(og.header,og.header_len);
- m_pStream->append(og.body,og.body_len);
- }
- }
}
KviTheoraEncoder::~KviTheoraEncoder()
@@ -280,15 +216,6 @@ KviTheoraEncoder::~KviTheoraEncoder()
// clear out state
- if(audio)
- {
- ogg_stream_clear(&vo);
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- }
-
ogg_stream_clear(&to);
th_comment_clear(&tc);
}
@@ -324,37 +251,8 @@ void KviTheoraEncoder::addVideoFrame(QRgb * rgb32, int)
videoflag=0;
}
-void KviTheoraEncoder::addAudioFrame(unsigned char* audioPkt, int audioSize)
-{
- /*
- * For each uncompressed frame:
- * o Submit the uncompressed frame via th_encode_ycbcr_in()
- * o Repeatedly call th_encode_packetout() to retrieve any video data packets that are ready.
- */
- if(!audio)
- return;
-
- double audiotime;
- ogg_page audiopage;
-
- // is there an audio page flushed? If not, fetch one if possible
- audioflag=fetch_and_process_audio(audioPkt, audioSize,&audiopage,&vo,&vd,&vb,audioflag);
-
- // no pages? Must be end of stream.
- if(!audioflag) return;
-
- audiotime=audioflag?vorbis_granule_time(&vd,ogg_page_granulepos(&audiopage)):-1;
-
- m_pStream->append(audiopage.header,audiopage.header_len);
- m_pStream->append(audiopage.body,audiopage.body_len);
- audioflag=0;
-}
-
void KviTheoraEncoder::addTextFrame(unsigned char* textPkt, int textSize)
{
- if(!text)
- return;
-
ogg_page textpage;
ogg_packet op;
@@ -365,10 +263,8 @@ void KviTheoraEncoder::addTextFrame(unsigned char* textPkt, int textSize)
ogg_stream_packetin(&zo, &op);
ogg_stream_pageout(&zo, &textpage);
-
-
// no pages? Must be end of stream.
- if(!textflag) return;
+// if(!textflag) return;
m_pStream->append(textpage.header,textpage.header_len);
m_pStream->append(textpage.body,textpage.body_len);
@@ -468,116 +364,33 @@ int KviTheoraEncoder::ilog(unsigned _v)
return ret;
}
-int KviTheoraEncoder::fetch_and_process_audio(quint8 * audio, int size, ogg_page *audiopage,
- ogg_stream_state *vo,
- vorbis_dsp_state *vd,
- vorbis_block *vb,
- int audioflag)
-{
- ogg_packet op;
- int i,j;
- qDebug("fetch_and_process_audio audioflag=%d",audioflag);
- signed char readbuffer[4096];
- int bytesread=qMin(size, 4096);
- memcpy(readbuffer,audio, bytesread);
-
- while(!audioflag)
- {
- /* process any audio already buffered */
- if(ogg_stream_pageout(vo,audiopage)>0) return 1;
- if(ogg_stream_eos(vo))return 0;
-
- {
- /* read and process more audio */
- qDebug("Processing audio frame size %d/4096",size);
- signed char *readptr=readbuffer;
- int sampread=bytesread/2/audio_ch;
- float **vorbis_buffer;
- int count=0;
-
- if(bytesread<=0)
- {
- /* end of file. this can be done implicitly, but it's
- easier to see here in non-clever fashion. Tell the
- library we're at end of stream so that it can handle the
- last frame and mark end of stream in the output properly */
- vorbis_analysis_wrote(vd,0);
- } else {
- samples_sofar += sampread;
-
- if(sampread>0)
- {
- vorbis_buffer=vorbis_analysis_buffer(vd,sampread);
- /* uninterleave samples */
- for(i=0;i<sampread;i++)
- {
- for(j=0;j<audio_ch;j++)
- {
- vorbis_buffer[j][i]=((readptr[count+1]<<8)|
- (0x00ff&(int)readptr[count]))/32768.f;
- count+=2;
- }
- }
- vorbis_analysis_wrote(vd,sampread);
- }
- }
-
- while(vorbis_analysis_blockout(vd,vb)==1)
- {
-
- /* analysis, assume we want to use bitrate management */
- vorbis_analysis(vb,NULL);
- vorbis_bitrate_addblock(vb);
-
- /* weld packets into the bitstream */
- while(vorbis_bitrate_flushpacket(vd,&op))
- ogg_stream_packetin(vo,&op);
- }
- }
- //FIXME remove this
- return 0;
- }
- return audioflag;
-}
-
//------------------------------------------------------------------------------
#define OC_CLAMP255(_x) ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255))))
-KviTheoraDecoder::KviTheoraDecoder(KviDataBuffer * signal)
+KviTheoraDecoder::KviTheoraDecoder(KviDataBuffer * videoSignal,KviDataBuffer * textSignal)
{
- m_pSignal=signal;
+ m_pVideoSignal=videoSignal;
+ m_pTextSignal=textSignal;
theora_p=0;
- vorbis_p=0;
stateflag=0;
ts=NULL;
thda=false;
thtic=false;
+ irct_p=0;
+
/* single frame video buffering */
videobuf_ready=0;
videobuf_granulepos=-1;
videobuf_time=0;
- /* single audio fragment audio buffering */
- audiobuf_fill=0;
- audiobuf_ready=0;
- audiobuf_granulepos=0; /* time position of last sample */
-
frames = 0;
dropped = 0;
- audiofd_totalsize=-1;
- audiofd=-1;
- audiofd_timer_calibrate=-1;
-
/* start up Ogg stream synchronization layer */
ogg_sync_init(&oy);
- /* init supporting Vorbis structures needed in header parsing */
- vorbis_info_init(&vi);
- vorbis_comment_init(&vc);
-
/* init supporting Theora structures needed in header parsing */
th_comment_init(&tc);
th_info_init(&ti);
@@ -594,13 +407,6 @@ KviTheoraDecoder::KviTheoraDecoder(KviDataBuffer * signal)
KviTheoraDecoder::~KviTheoraDecoder()
{
- if(vorbis_p){
- ogg_stream_clear(&vo);
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- }
if(theora_p){
ogg_stream_clear(&to);
th_decode_free(td);
@@ -608,28 +414,33 @@ KviTheoraDecoder::~KviTheoraDecoder()
th_info_clear(&ti);
}
+ if(irct_p)
+ ogg_stream_clear(&zo);
+
ogg_sync_clear(&oy);
}
void KviTheoraDecoder::addData(KviDataBuffer * stream)
{
-// qDebug("adddata signal %p stream size %d",m_pSignal, stream->size() );
+// qDebug("adddata signal %p stream size %d",m_pVideoSignal, stream->size() );
if(stream->size()==0)return;
/* Ogg file open; parse the headers */
- /* Only interested in Vorbis/Theora streams */
- if(!stateflag){
+ if(!stateflag)
+ {
char *buffer=ogg_sync_buffer(&oy,stream->size());
memcpy(buffer,stream->data(),stream->size());
ogg_sync_wrote(&oy,stream->size());
stream->clear();
- while(ogg_sync_pageout(&oy,&og)>0){
+ while(ogg_sync_pageout(&oy,&og)>0)
+ {
ogg_stream_state test;
/* is this a mandated initial header? If not, stop parsing */
- if(!ogg_page_bos(&og)){
+ if(!ogg_page_bos(&og))
+ {
/* don't leak the page; get it into the appropriate stream */
// qDebug("queue_page && return");
queue_page(&og);
@@ -648,11 +459,6 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
/* it is theora */
memcpy(&to,&test,sizeof(test));
theora_p=1;
- }else if(!vorbis_p && vorbis_synthesis_headerin(&vi,&vc,&op)>=0){
- qDebug("is vorbis");
- /* it is vorbis */
- memcpy(&vo,&test,sizeof(test));
- vorbis_p=1;
}else if(!irct_p && KviOggIrcText::irct_decode_headerin(&op)>=0){
qDebug("is irct");
/* it is irct */
@@ -667,9 +473,9 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
/* fall through to non-bos page parsing */
}
-// qDebug("checkpoint 2, theora_p=%d vorbis_p=%d",theora_p, vorbis_p);
+// qDebug("checkpoint 2, theora_p=%d ",theora_p);
/* we're expecting more header packets. */
- if((theora_p && theora_p<3) || (vorbis_p && vorbis_p<3))
+ if((theora_p && theora_p<3))
{
int ret;
@@ -687,28 +493,11 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
theora_p++;
}
- /* look for more vorbis header packets */
- while(vorbis_p && (vorbis_p<3) && (ret=ogg_stream_packetout(&vo,&op)))
- {
- if(ret<0)
- {
- qDebug("Error parsing Vorbis stream headers; corrupt stream?");
- return;
- }
- if(vorbis_synthesis_headerin(&vi,&vc,&op))
- {
- qDebug("Error parsing Vorbis stream headers; corrupt stream?");
- return;
- }
- vorbis_p++;
- if(vorbis_p==3)break;
- }
-
/* The header pages/packets will arrive before anything else we
care about, or the stream is not obeying spec */
if(ogg_sync_pageout(&oy,&og)>0)
{
-// qDebug("queue_page");
+ qDebug("queue_page");
queue_page(&og); /* demux into the appropriate stream */
} else {
qDebug("TheoraDecoder: need more data!");
@@ -719,7 +508,8 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
// qDebug("checkpoint 3");
/* and now we have it all. initialize decoders */
- if(theora_p && !thda){
+ if(theora_p && !thda)
+ {
thda=true;
td=th_decode_alloc(&ti,ts);
qDebug("Ogg logical stream %lx is Theora %dx%d %.02f fps",
@@ -734,7 +524,8 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
geometry.pic_y = ti.pic_y;
px_fmt=ti.pixel_fmt;
- switch(ti.pixel_fmt){
+ switch(ti.pixel_fmt)
+ {
case TH_PF_444: qDebug(" 4:4:4 video"); break;
default:
qDebug(" video (UNSUPPORTED Chroma sampling!)");
@@ -758,59 +549,26 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
th_setup_free(ts);
}
-
- if(vorbis_p){
- vorbis_synthesis_init(&vd,&vi);
- vorbis_block_init(&vd,&vb);
- qDebug("Ogg logical stream %lx is Vorbis %d channel %ld Hz audio.",
- vo.serialno,vi.channels,vi.rate);
- }else{
- /* tear down the partial vorbis setup */
- vorbis_info_clear(&vi);
- vorbis_comment_clear(&vc);
- }
-
+// qDebug("debug4");
// stateflag=0; /* playback has not begun */
- /* we want a video and audio frame ready to go at all times. If
- we have to buffer incoming, buffer the compressed data (ie, let
- ogg do the buffering) */
-
- while(vorbis_p && !audiobuf_ready){
- int ret;
- float **pcm;
-
- // if there's pending, decoded audio, grab it
- if((ret=vorbis_synthesis_pcmout(&vd,&pcm))>0){
- int count=audiobuf_fill/2;
- int maxsamples=(audiofd_fragsize-audiobuf_fill)/2/vi.channels;
- for(i=0;i<ret && i<maxsamples;i++)
- for(j=0;j<vi.channels;j++){
- int val=rint(pcm[j][i]*32767.f);
- if(val>32767)val=32767;
- if(val<-32768)val=-32768;
- audiobuf[count++]=val;
- }
- vorbis_synthesis_read(&vd,i);
- audiobuf_fill+=i*vi.channels*2;
- if(audiobuf_fill==audiofd_fragsize)audiobuf_ready=1;
- if(vd.granulepos>=0)
- audiobuf_granulepos=vd.granulepos-ret+i;
- else
- audiobuf_granulepos+=i;
-
- }else{
-
- // no pending audio; is there a pending packet to decode?
- if(ogg_stream_packetout(&vo,&op)>0){
- if(vorbis_synthesis(&vb,&op)==0) // test for success!
- vorbis_synthesis_blockin(&vd,&vb);
- }else // we need more data; break out to suck in another page
- break;
+ if(irct_p)
+ {
+ if(ogg_stream_packetout(&zo,&op)>0)
+ {
+ qDebug("irct::ogg_stream_packetout");
+ char * textPkt=0;
+ int textSize=0;
+ if(KviOggIrcText::irct_decode_packetin(textPkt, textSize, &op)==0)
+ {
+ qDebug("irct stream recv %d bytes", textSize);
+ m_pTextSignal->append((unsigned char *)textPkt, textSize);
+ }
}
}
- if(theora_p && !videobuf_ready){
+ if(theora_p && !videobuf_ready)
+ {
if(stream->size()>0)
{
char *buffer=ogg_sync_buffer(&oy,stream->size());
@@ -818,124 +576,34 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
ogg_sync_wrote(&oy,stream->size());
stream->clear();
- while(ogg_sync_pageout(&oy,&og)>0){
+ while(ogg_sync_pageout(&oy,&og)>0)
queue_page(&og);
- }
}
// qDebug("loop4 theora_p=%d videobuf_ready=%d",theora_p, videobuf_ready);
// theora is one in, one out...
- if(ogg_stream_packetout(&to,&op)>0){
-// qDebug("ogg_stream_packetout >0");
- if(pp_inc){
- pp_level+=pp_inc;
- th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,
- sizeof(pp_level));
- pp_inc=0;
- }
- /*HACK: This should be set after a seek or a gap, but we might not have
- a granulepos for the first packet (we only have them for the last
- packet on a page), so we just set it as often as we get it.
- To do this right, we should back-track from the last packet on the
- page and compute the correct granulepos for the first packet after
- a seek or a gap.*/
- if(op.granulepos>=0){
- th_decode_ctl(td,TH_DECCTL_SET_GRANPOS,&op.granulepos,sizeof(op.granulepos));
- }
- if(th_decode_packetin(td,&op,&videobuf_granulepos)==0){
-// qDebug("th_decode_packetin ==0");
- videobuf_time=th_granule_time(td,videobuf_granulepos);
- frames++;
-
- /* is it already too old to be useful? This is only actually
- useful cosmetically after a SIGSTOP. Note that we have to
- decode the frame even if we don't show it (for now) due to
- keyframing. Soon enough libtheora will be able to deal
- with non-keyframe seeks. */
-
- if(videobuf_time>=get_time())
- {
-// qDebug("videobuf_time>=get_time");
- videobuf_ready=1;
- }else{
-// qDebug("videobuf_time<get_time");
- /*If we are too slow, reduce the pp level.*/
- pp_inc=pp_level>0?-1:0;
- dropped++;
- }
- }
- }else {
-// qDebug("ogg_stream_packetout <=0");
+ if(ogg_stream_packetout(&to,&op)>0)
+ {
+ if(th_decode_packetin(td,&op,&videobuf_granulepos)==0)
+ videobuf_ready=1;
+ } else {
+// qDebug("ogg_stream_packetout <=0");
//need more data :)
return;
}
}
- if(!videobuf_ready && !audiobuf_ready)return;
-/*
- if(!videobuf_ready || !audiobuf_ready){
- // no data yet for somebody. Grab another page
- return;
- }
-*/
- /* If playback has begun, top audio buffer off immediately. */
-// if(stateflag) audio_write_nonblocking();
+ if(!videobuf_ready)return;
- /* are we at or past time for this video frame? */
- if(stateflag && videobuf_ready) {// && videobuf_time<=get_time()){
+
+ if(stateflag && videobuf_ready)
+ {
video_write();
videobuf_ready=0;
}
-/*
- if(stateflag &&
- (audiobuf_ready || !vorbis_p) &&
- (videobuf_ready || !theora_p) &&
- ){
- // we have an audio frame ready (which means the audio buffer is
- // full), it's not time to play video, so wait until one of the
- // audio buffer is ready or it's near time to play video
- // set up select wait on the audiobuffer and a timeout for video
- struct timeval timeout;
- fd_set writefs;
- fd_set empty;
- int n=0;
-
- FD_ZERO(&writefs);
- FD_ZERO(&empty);
- if(audiofd>=0){
- FD_SET(audiofd,&writefs);
- n=audiofd+1;
- }
-
- if(theora_p){
- double tdiff;
- long milliseconds;
- tdiff=videobuf_time-get_time();
- //If we have lots of extra time, increase the post-processing level.
- if(tdiff>ti.fps_denominator*0.25/ti.fps_numerator){
- pp_inc=pp_level<pp_level_max?1:0;
- }
- else if(tdiff<ti.fps_denominator*0.05/ti.fps_numerator){
- pp_inc=pp_level>0?-1:0;
- }
- milliseconds=tdiff*1000-5;
- if(milliseconds>500)milliseconds=500;
- if(milliseconds>0){
- timeout.tv_sec=milliseconds/1000;
- timeout.tv_usec=(milliseconds%1000)*1000;
-
- n=select(n,&empty,&writefs,&empty,&timeout);
- if(n)audio_calibrate_timer(0);
- }
- }else{
- select(n,&empty,&writefs,&empty,NULL);
- }
- }
-*/
// if our buffers either don't exist or are ready to go,we can begin playback
- if((!theora_p || videobuf_ready) &&
- (!vorbis_p || audiobuf_ready))stateflag=1;
+ if(!theora_p || videobuf_ready)stateflag=1;
}
/* helper: push a page into the appropriate steam */
@@ -944,49 +612,10 @@ void KviTheoraDecoder::addData(KviDataBuffer * stream)
int KviTheoraDecoder::queue_page(ogg_page *page)
{
if(theora_p)ogg_stream_pagein(&to,page);
- if(vorbis_p)ogg_stream_pagein(&vo,page);
if(irct_p)ogg_stream_pagein(&zo,page);
return 0;
}
-/* get relative time since beginning playback, compensating for A/V
- drift */
-double KviTheoraDecoder::get_time(){
- ogg_int64_t last=0;
- ogg_int64_t up=0;
- ogg_int64_t now;
- struct timeval tv;
-
- gettimeofday(&tv,0);
- now=tv.tv_sec*1000+tv.tv_usec/1000;
-
- if(audiofd_timer_calibrate==-1)audiofd_timer_calibrate=last=now;
-
- if(audiofd<0){
- /* no audio timer to worry about, we can just use the system clock */
- /* only one complication: If the process is suspended, we should
- reset timing to account for the gap in play time. Do it the
- easy/hack way */
- if(now-last>1000)audiofd_timer_calibrate+=(now-last);
- last=now;
- }
-
- if(now-up>200){
-/*
- double timebase=(now-audiofd_timer_calibrate)*.001;
- int hundredths=timebase*100-(long)timebase*100;
- int seconds=(long)timebase%60;
- int minutes=((long)timebase/60)%60;
- int hours=(long)timebase/3600;
-
- qDebug(" Playing: %d:%02d:%02d.%02d \r",hours,minutes,seconds,hundredths);
-*/
- up=now;
- }
-
- return (now-audiofd_timer_calibrate)*.001;
-}
-
void KviTheoraDecoder::video_write(void)
{
th_ycbcr_buffer yuv;
@@ -1018,9 +647,9 @@ void KviTheoraDecoder::video_write(void)
int size = sizeof(char) * geometry.pic_w * geometry.pic_h * ARGB32_BPP;
-// qDebug("VIDEO WRITE size=%d",size);
- m_pSignal->clear();
- m_pSignal->append(RGBbuffer, size);
+// qDebug("VIDEO WRITE size=%d",size);
+ m_pVideoSignal->clear();
+ m_pVideoSignal->append(RGBbuffer, size);
}
#endif // COMPILE_DISABLE_OGG_THEORA \ No newline at end of file
diff --git a/src/kvilib/ext/kvi_oggtheora.h b/src/kvilib/ext/kvi_oggtheora.h
index 751579cc7..4b02b46d3 100644
--- a/src/kvilib/ext/kvi_oggtheora.h
+++ b/src/kvilib/ext/kvi_oggtheora.h
@@ -31,8 +31,6 @@
#include "theora/theoradec.h"
#include "theora/theoraenc.h"
-#include "vorbis/codec.h"
-#include "vorbis/vorbisenc.h"
#include <QColor>
@@ -111,10 +109,12 @@ public:
oggpack_buffer ob;
oggpack_writeinit(&ob);
+
_tp_writebuffer(&ob, textPkt, textSize); //pre-encoded text
int bytes=oggpack_bytes(&ob);
op->packet= (unsigned char *)kvi_malloc(bytes);
memcpy(op->packet, oggpack_get_buffer(&ob), bytes);
+ qDebug("irct_encode_packetout bytes=%d |%s", bytes, textPkt);
op->bytes=bytes;
oggpack_writeclear(&ob);
op->b_o_s=0;
@@ -136,7 +136,15 @@ public:
if(strncmp(buf, "irct", 4)!=0) return 1;
version = oggpack_read(&ob,8);
subversion = oggpack_read(&ob,8);
- qDebug("irct stream version %d.%d", version, subversion);
+ return 0;
+ }
+ static int irct_decode_packetin(char* textPkt, int textSize, ogg_packet *op)
+ {
+ oggpack_buffer ob;
+ oggpack_readinit(&ob, op->packet, op->bytes);
+ textSize = op->bytes;
+ textPkt=(char*)kvi_malloc(textSize);
+ _tp_readbuffer(&ob, textPkt, textSize);
return 0;
}
};
@@ -147,24 +155,15 @@ public:
KviTheoraEncoder(KviDataBuffer * stream, int iWidth=320, int iHeight=240, int iFpsN=5, int iFpsD=1, int iParN=4, int iParD=3);
virtual ~KviTheoraEncoder();
void addVideoFrame(QRgb * rgb32, int videoSize);
- void addAudioFrame(unsigned char* audioPkt, int audioSize);
void addTextFrame(unsigned char* textPkt, int textSize);
private:
int fetch_and_process_video(quint8 * videoYuv,ogg_page *videopage,ogg_stream_state *to,th_enc_ctx *td,int videoflag);
int fetch_and_process_video_packet(quint8 * videoYuv,th_enc_ctx *td,ogg_packet *op);
- int fetch_and_process_audio(quint8 * audio, int size, ogg_page *audiopage, ogg_stream_state *vo, vorbis_dsp_state *vd, vorbis_block *vb, int audioflag);
private:
KviTheoraGeometry geometry;
KviDataBuffer * m_pStream;
quint8 * videoYuv;
- bool text;
-
- bool audio;
- int audio_ch;
- int audio_hz;
- float audio_q;
- ogg_int64_t samples_sofar;
ogg_int64_t text_sofar;
int frame_state;
@@ -182,7 +181,6 @@ private:
ogg_stream_state zo; // take physical pages, weld into a logical stream of packets
ogg_stream_state to; // take physical pages, weld into a logical stream of packets
- ogg_stream_state vo; // take physical pages, weld into a logical stream of packets
ogg_page og; // one Ogg bitstream page. Vorbis packets are inside
ogg_packet op; // one raw packet of data for decode
@@ -190,22 +188,17 @@ private:
th_info ti;
th_comment tc;
- vorbis_info vi; // struct that stores all the static vorbis bitstream settings
- vorbis_comment vc; // struct that stores all the user comments
- vorbis_dsp_state vd; // central working state for the packet->PCM decoder
- vorbis_block vb; // local working space for packet->PCM decode
-
int textflag;
- int audioflag;
int videoflag;
private:
static int ilog(unsigned _v);
};
-class KVILIB_API KviTheoraDecoder {
+class KVILIB_API KviTheoraDecoder
+{
public:
- KviTheoraDecoder(KviDataBuffer * signal);
+ KviTheoraDecoder(KviDataBuffer * videoSignal,KviDataBuffer * textSignal);
virtual ~KviTheoraDecoder();
void addData(KviDataBuffer * stream);
private:
@@ -213,28 +206,23 @@ private:
double get_time();
void video_write(void);
private:
- KviDataBuffer * m_pSignal;
+ KviDataBuffer * m_pVideoSignal;
+ KviDataBuffer * m_pTextSignal;
KviTheoraGeometry geometry;
unsigned char * RGBbuffer;
// Ogg and codec state for demux/decode
ogg_sync_state oy;
ogg_page og;
- ogg_stream_state vo;
ogg_stream_state to;
ogg_stream_state zo;
th_info ti;
th_comment tc;
th_dec_ctx *td;
th_setup_info *ts;
- vorbis_info vi;
- vorbis_dsp_state vd;
- vorbis_block vb;
- vorbis_comment vc;
th_pixel_fmt px_fmt;
int theora_p;
- int vorbis_p;
int irct_p;
int stateflag;
@@ -249,12 +237,6 @@ private:
ogg_int64_t videobuf_granulepos;
double videobuf_time;
- // single audio fragment audio buffering
- int audiobuf_fill;
- int audiobuf_ready;
- ogg_int16_t *audiobuf;
- ogg_int64_t audiobuf_granulepos; // time position of last sample
-
int pp_level_max;
int pp_level;
int pp_inc;
@@ -264,13 +246,6 @@ private:
int frames;
int dropped;
- long audiofd_totalsize;
- int audiofd_fragsize; /* read and write only complete fragments
- so that SNDCTL_DSP_GETOSPACE is
- accurate immediately after a bank
- switch */
- int audiofd;
- ogg_int64_t audiofd_timer_calibrate;
bool thda;
bool thtic;
diff --git a/src/modules/dcc/codec.cpp b/src/modules/dcc/codec.cpp
index 7e1433f1a..a124132a1 100644
--- a/src/modules/dcc/codec.cpp
+++ b/src/modules/dcc/codec.cpp
@@ -306,7 +306,7 @@ void KviDccVideoTheoraCodec::decode(KviDataBuffer * stream,KviDataBuffer * video
if(stream->size() < 1)return;
if(!m_pDecoder)
- m_pDecoder = new KviTheoraDecoder(videoSignal);
+ m_pDecoder = new KviTheoraDecoder(videoSignal, textSignal);
m_pDecoder->addData(stream);
}