示例#1
0
static int
ogg_close (SF_PRIVATE *psf)
{
	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
	VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;

	if (odata == NULL || vdata == NULL)
		return 0 ;

	/*	Clean up this logical bitstream ; before exit we shuld see if we're
	**	followed by another [chained]. */

	if (psf->file.mode == SFM_WRITE)
	{
		if (psf->write_current <= 0)
			ogg_write_header (psf, 0) ;

		vorbis_analysis_wrote (&vdata->vd, 0) ;
		while (vorbis_analysis_blockout (&vdata->vd, &vdata->vb) == 1)
		{

		/* analysis, assume we want to use bitrate management */
			vorbis_analysis (&vdata->vb, NULL) ;
			vorbis_bitrate_addblock (&vdata->vb) ;

			while (vorbis_bitrate_flushpacket (&vdata->vd, &odata->op))
			{	/* weld the packet into the bitstream */
				ogg_stream_packetin (&odata->os, &odata->op) ;

				/* write out pages (if any) */
				while (!odata->eos)
				{	int result = ogg_stream_pageout (&odata->os, &odata->og) ;
					if (result == 0) break ;
					psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
					psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;

		/* this could be set above, but for illustrative purposes, I do
		   it here (to show that vorbis does know where the stream ends) */

					if (ogg_page_eos (&odata->og)) odata->eos = 1 ;
				}
			}
		}
	}

	/* ogg_page and ogg_packet structs always point to storage in
	   libvorbis.  They are never freed or manipulated directly */

	vorbis_block_clear (&vdata->vb) ;
	vorbis_dsp_clear (&vdata->vd) ;
	vorbis_comment_clear (&vdata->vc) ;
	vorbis_info_clear (&vdata->vi) ;	 /* must be called last */
	/* should look here to reopen if chained */

	/* OK, clean up the framer */
	ogg_sync_clear (&odata->oy) ;
	ogg_stream_clear (&odata->os) ;

	return 0 ;
} /* ogg_close */
示例#2
0
/*------------------------------------------------------------------------------
 *  Send pending Vorbis blocks to the underlying stream
 *----------------------------------------------------------------------------*/
void
VorbisLibEncoder :: vorbisBlocksOut ( void )                throw ()
{
    while ( 1 == vorbis_analysis_blockout( &vorbisDspState, &vorbisBlock) ) {
        ogg_packet      oggPacket;
        ogg_page        oggPage;

        vorbis_analysis( &vorbisBlock, &oggPacket);
#ifdef VORBIS_LIB_RC3
        vorbis_bitrate_addblock( &vorbisBlock);

        while ( vorbis_bitrate_flushpacket( &vorbisDspState, &oggPacket) ) {
#endif

            ogg_stream_packetin( &oggStreamState, &oggPacket);

            while ( ogg_stream_pageout( &oggStreamState, &oggPage) ) {
                int    written;
                
                written  = sink->write( oggPage.header, oggPage.header_len);
                written += sink->write( oggPage.body, oggPage.body_len);

                if ( written < oggPage.header_len + oggPage.body_len ) {
                    // just let go data that could not be written
                    reportEvent( 2,
                           "couldn't write full vorbis data to underlying sink",
                           oggPage.header_len + oggPage.body_len - written);
                }
            }
#ifdef VORBIS_LIB_RC3
        }
#endif
    }
}
示例#3
0
/*!
 * \brief Write out any pending encoded data.
 * \param s An OGG/Vorbis filestream.
 * \param f The file to write to.
 */
static void write_stream(struct vorbis_desc *s, FILE *f)
{
	while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
		vorbis_analysis(&s->vb, NULL);
		vorbis_bitrate_addblock(&s->vb);

		while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
			ogg_stream_packetin(&s->os, &s->op);
			while (!s->eos) {
				if (ogg_stream_pageout(&s->os, &s->og) == 0) {
					break;
				}
				if (!fwrite(s->og.header, 1, s->og.header_len, f)) {
				ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
				}
				if (!fwrite(s->og.body, 1, s->og.body_len, f)) {
					ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
				}
				if (ogg_page_eos(&s->og)) {
					s->eos = 1;
				}
			}
		}
	}
}
示例#4
0
int fetch_and_process_audio(FILE *audio,ogg_page *audiopage,
                            ogg_stream_state *vo,
                            vorbis_dsp_state *vd,
                            vorbis_block *vb,
                            int audioflag){
  ogg_packet op;
  int i,j;

  while(audio && !audioflag){
    /* process any audio already buffered */
    spinnit();
    if(ogg_stream_pageout(vo,audiopage)>0) return 1;
    if(ogg_stream_eos(vo))return 0;

    {
      /* read and process more audio */
      signed char readbuffer[4096];
      int toread=4096/2/audio_ch;
      int bytesread=fread(readbuffer,1,toread*2*audio_ch,audio);
      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{
        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]=((readbuffer[count+1]<<8)|
                                 (0x00ff&(int)readbuffer[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);
        
      }
    }
  }

  return audioflag;
}
示例#5
0
void SoundFileWriterOgg::flushBlocks()
{
    // Let the library divide uncompressed data into blocks, and process them
    vorbis_block block;
    vorbis_block_init(&m_state, &block);
    while (vorbis_analysis_blockout(&m_state, &block) == 1)
    {
        // Let the automatic bitrate management do its job
        vorbis_analysis(&block, NULL);
        vorbis_bitrate_addblock(&block);

        // Get new packets from the bitrate management engine
        ogg_packet packet;
        while (vorbis_bitrate_flushpacket(&m_state, &packet))
        {
            // Write the packet to the ogg stream
            ogg_stream_packetin(&m_ogg, &packet);

            // If the stream produced new pages, write them to the output file
            ogg_page page;
            while (ogg_stream_flush(&m_ogg, &page) > 0)
            {
                m_file.write(reinterpret_cast<const char*>(page.header), page.header_len);
                m_file.write(reinterpret_cast<const char*>(page.body), page.body_len);
            }
        }
    }

    // Clear the allocated block
    vorbis_block_clear(&block);
}
示例#6
0
static GstFlowReturn
gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
{
  GstFlowReturn ret;

  /* vorbis does some data preanalysis, then divides up blocks for
     more involved (potentially parallel) processing.  Get a single
     block for encoding now */
  while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
    ogg_packet op;

    GST_LOG_OBJECT (vorbisenc, "analysed to a block");

    /* analysis */
    vorbis_analysis (&vorbisenc->vb, NULL);
    vorbis_bitrate_addblock (&vorbisenc->vb);

    while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
      GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
      ret = gst_vorbis_enc_push_packet (vorbisenc, &op);

      if (ret != GST_FLOW_OK)
        return ret;
    }
  }

  return GST_FLOW_OK;
}
static int tc_vorbis_outframe(VorbisPrivateData *pd, TCFrameAudio *f)
{
    int has_block = TC_FALSE;
    ogg_packet op;

    tc_frame_audio_setup(f);
    
    do {
        has_block = vorbis_analysis_blockout(&pd->vd, &pd->vb);
        if (has_block == 1) {
            int has_pkt;

            /* FIXME: analysis, assume we want to use bitrate management */
            vorbis_analysis(&pd->vb, NULL);
            vorbis_bitrate_addblock(&pd->vb);
        
            do {
                has_pkt = vorbis_bitrate_flushpacket(&pd->vd, &op);
                if (has_pkt) {
                    tc_frame_audio_add_ogg_packet(pd, f, &op);
                    pd->packets++;
                }
            } while (has_pkt);
        }
    } while (has_block);
    pd->frames++;
    
    return TC_OK;
}
示例#8
0
    void encode_silent_samples(int n_samples)
        {
        float **buffer;
        int i;

        /* generate a silent buffer */
        buffer = vorbis_analysis_buffer(&vd, n_samples);
        for (i = 0; i < vi.channels; i++)
            memset(buffer[i], 0, n_samples * sizeof (float));
        vorbis_analysis_wrote(&vd, n_samples);

        /* encode it */
        while (vorbis_analysis_blockout(&vd, &vb) == 1)
            {
            vorbis_analysis(&vb, NULL);
            vorbis_bitrate_addblock(&vb);
            while (vorbis_bitrate_flushpacket(&vd, &op))
                {
                ogg_stream_packetin(&os, &op);
                while (ogg_stream_pageout(&os, &og))
                    {
                    write_out(&og);
                    if (ogg_page_eos(&og))
                        break;
                    }
                }
            }
        }
示例#9
0
/***********************************************************************
 * Flush
 ***********************************************************************
 *
 **********************************************************************/
static hb_buffer_t * Flush( hb_work_object_t * w )
{
    hb_work_private_t * pv = w->private_data;
    hb_buffer_t * buf;
    int64_t     blocksize = 0;

    if( vorbis_analysis_blockout( &pv->vd, &pv->vb ) == 1 )
    {
        ogg_packet op;

        vorbis_analysis( &pv->vb, NULL );
        vorbis_bitrate_addblock( &pv->vb );

        if( vorbis_bitrate_flushpacket( &pv->vd, &op ) )
        {
            buf = hb_buffer_init( sizeof( ogg_packet ) + op.bytes );
            memcpy( buf->data, &op, sizeof( ogg_packet ) );
            memcpy( buf->data + sizeof( ogg_packet ), op.packet,
                    op.bytes );
            blocksize = vorbis_packet_blocksize(&pv->vi, &op);
            buf->frametype   = HB_FRAME_AUDIO;
            buf->start = (int64_t)(vorbis_granule_time(&pv->vd, op.granulepos) * 90000);
            buf->stop  = (int64_t)(vorbis_granule_time(&pv->vd, (pv->prev_blocksize + blocksize)/4 + op.granulepos) * 90000);
            /* The stop time isn't accurate for the first ~3 packets, as the actual blocksize depends on the previous _and_ current packets. */
            pv->prev_blocksize = blocksize;
            return buf;
        }
    }

    return NULL;
}
示例#10
0
		void OggWriter::closeResource() {
			vorbis_analysis_wrote( this->dsp_.get(), 0 );

			while( vorbis_analysis_blockout( this->dsp_.get(), this->block_.get() ) == 1 ) {
				vorbis_analysis( this->block_.get(), NULL );
				vorbis_bitrate_addblock( this->block_.get() );

				ogg_packet op;
				while( vorbis_bitrate_flushpacket( this->dsp_.get(), &op ) ) {
					ogg_stream_packetin( this->muxer_.get(), &op );
				}

				for(;;) {
					ogg_page og;
					int ret = ogg_stream_pageout( this->muxer_.get(), &og );
					if( ret == 0 ) {
						break;
					}
					std::fwrite( og.header, 1, og.header_len, this->fout_.get() );
					std::fwrite( og.body, 1, og.body_len, this->fout_.get() );
				}
			}

			this->quality_ = -1.f;
			this->comments_.reset();
			this->block_.reset();
			this->dsp_.reset();
			this->muxer_.reset();
			this->encoder_.reset();
			this->fout_.reset();
		}
示例#11
0
static GstBuffer *
_create_audio_buffer (void)
{
  GstBuffer *buffer;
  ogg_packet packet;
  float **vorbis_buffer;
  gint i;

  vorbis_buffer = vorbis_analysis_buffer (&vd, 44100);
  for (i = 0; i < 44100 * 1; ++i)
    vorbis_buffer[0][i] = 0.0;
  vorbis_analysis_wrote (&vd, 44100);
  vorbis_analysis_blockout (&vd, &vb);
  vorbis_analysis (&vb, NULL);
  vorbis_bitrate_addblock (&vb);
  vorbis_bitrate_flushpacket (&vd, &packet);
  buffer = gst_buffer_new_and_alloc (packet.bytes);
  gst_buffer_fill (buffer, 0, packet.packet, packet.bytes);

  vorbis_comment_clear (&vc);
  vorbis_block_clear (&vb);
  vorbis_dsp_clear (&vd);
  vorbis_info_clear (&vi);

  return buffer;
}
bool VorbisWriter::write(QByteArray &left, QByteArray &right, long samples, bool flush) {
	const long maxChunkSize = 4096;

	const qint16 *leftData = (const qint16 *)left.constData();
	const qint16 *rightData = stereo ? (const qint16 *)right.constData() : NULL;

	long todoSamples = samples;
	int eos = 0;

	while (!eos) {
		long chunkSize = todoSamples > maxChunkSize ? maxChunkSize : todoSamples;
		todoSamples -= chunkSize;

		if (chunkSize == 0) {
			if (!flush)
				break;
			hasFlushed = true;
			vorbis_analysis_wrote(&pd->vd, 0);
		} else {
			float **buffer = vorbis_analysis_buffer(&pd->vd, chunkSize);

			for (long i = 0; i < chunkSize; i++)
				buffer[0][i] = (float)leftData[i] / 32768.0f;
			leftData += chunkSize;

			if (stereo) {
				for (long i = 0; i < chunkSize; i++)
					buffer[1][i] = (float)rightData[i] / 32768.0f;
				rightData += chunkSize;
			}

			vorbis_analysis_wrote(&pd->vd, chunkSize);
		}

		while (vorbis_analysis_blockout(&pd->vd, &pd->vb) == 1) {
			vorbis_analysis(&pd->vb, NULL);
			vorbis_bitrate_addblock(&pd->vb);

			while (vorbis_bitrate_flushpacket(&pd->vd, &pd->op)) {
				ogg_stream_packetin(&pd->os, &pd->op);

				while (!eos && ogg_stream_pageout(&pd->os, &pd->og) != 0) {
					file.write((const char *)pd->og.header, pd->og.header_len);
					file.write((const char *)pd->og.body, pd->og.body_len);

					if (ogg_page_eos(&pd->og))
						eos = 1;
				}
			}
		}
	}

	samplesWritten += samples;

	left.remove(0, samples * 2);
	if (stereo)
		right.remove(0, samples * 2);

	return true;
}
示例#13
0
void
MediaRecorder::WriteAudio()
{
    int ret;
    nsresult rv;
    PRUint32 wr;

    while (vorbis_analysis_blockout(&aState->vd, &aState->vb) == 1) {
        vorbis_analysis(&aState->vb, NULL);
        vorbis_bitrate_addblock(&aState->vb);
        while (vorbis_bitrate_flushpacket(
                &aState->vd, &aState->op)) {
            ogg_stream_packetin(&aState->os, &aState->op);

            for (;;) {
                ret = ogg_stream_pageout(&aState->os, &aState->og);
                if (ret == 0)
                    break;

                rv = WriteData(aState->og.header, aState->og.header_len, &wr);
                rv = WriteData(aState->og.body, aState->og.body_len, &wr);

                if (ogg_page_eos(&aState->og))
                    break;
            }
        }
    }
}
static GstFlowReturn
gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
{
  GstFlowReturn ret;

  /* vorbis does some data preanalysis, then divides up blocks for
     more involved (potentially parallel) processing.  Get a single
     block for encoding now */
  while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
    ogg_packet op;

    GST_LOG_OBJECT (vorbisenc, "analysed to a block");

    /* analysis */
    vorbis_analysis (&vorbisenc->vb, NULL);
    vorbis_bitrate_addblock (&vorbisenc->vb);

    while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
      GstBuffer *buf;

      if (op.e_o_s) {
        GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
        GstClockTime duration;

        GST_DEBUG_OBJECT (vorbisenc, "Got EOS packet from libvorbis");
        GST_AUDIO_ENCODER_STREAM_LOCK (enc);
        if (!GST_CLOCK_TIME_IS_VALID (enc->output_segment.stop)) {
          GST_DEBUG_OBJECT (vorbisenc,
              "Output segment has no end time, setting");
          duration =
              gst_util_uint64_scale (op.granulepos, GST_SECOND,
              vorbisenc->frequency);
          enc->output_segment.stop = enc->output_segment.start + duration;
          GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT,
              &enc->output_segment);
          gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc),
              gst_event_new_segment (&enc->output_segment));
        }
        GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
      }

      GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
      buf =
          gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER
          (vorbisenc), op.bytes);
      gst_buffer_fill (buf, 0, op.packet, op.bytes);
      /* tracking granulepos should tell us samples accounted for */
      ret =
          gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER
          (vorbisenc), buf, op.granulepos - vorbisenc->samples_out);
      vorbisenc->samples_out = op.granulepos;

      if (ret != GST_FLOW_OK)
        return ret;
    }
  }

  return GST_FLOW_OK;
}
示例#15
0
static int oggvorbis_encode_frame(AVCodecContext *avccontext,
                                  unsigned char *packets,
                           int buf_size, void *data)
{
    OggVorbisContext *context = avccontext->priv_data ;
    float **buffer ;
    ogg_packet op ;
    signed short *audio = data ;
    int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0;

    buffer = vorbis_analysis_buffer(&context->vd, samples) ;

    if(context->vi.channels == 1) {
        for(l = 0 ; l < samples ; l++)
            buffer[0][l]=audio[l]/32768.f;
    } else {
        for(l = 0 ; l < samples ; l++){
            buffer[0][l]=audio[l*2]/32768.f;
            buffer[1][l]=audio[l*2+1]/32768.f;
        }
    }

    vorbis_analysis_wrote(&context->vd, samples) ;

    while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
        vorbis_analysis(&context->vb, NULL);
        vorbis_bitrate_addblock(&context->vb) ;

        while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
            /* i'd love to say the following line is a hack, but sadly it's
             * not, apparently the end of stream decision is in libogg. */
            if(op.bytes==1)
                continue;
            memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
            context->buffer_index += sizeof(ogg_packet);
            memcpy(context->buffer + context->buffer_index, op.packet, op.bytes);
            context->buffer_index += op.bytes;
//            av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes);
        }
    }

    l=0;
    if(context->buffer_index){
        ogg_packet *op2= (ogg_packet*)context->buffer;
        op2->packet = context->buffer + sizeof(ogg_packet);

        l=  op2->bytes;
        avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base);
        //FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate

        memcpy(packets, op2->packet, l);
        context->buffer_index -= l + sizeof(ogg_packet);
        memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
//        av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l);
    }

    return l;
}
示例#16
0
static double encode_vorbis( FILE *f, vorbis_dsp_state *vd, ogg_stream_state *vo, vorbis_block *vb, 
			     unsigned int audio_rate, double audiopos, signed char *buf, int n_samples )
{
   float **vorbis_buffer;
   const int audio_ch = 2;
   int i,j;
   int count = 0;
   ogg_page og;
   int got_page = 0;

   vorbis_buffer = vorbis_analysis_buffer( vd, n_samples );
   
   for( i = 0; i < n_samples; i++ )
   {
      for( j = 0; j < audio_ch; j++ )
      {
	 vorbis_buffer[j][i] = ( ( buf[count+1] << 8 ) | ( buf[count] & 0xff ) ) / 32768.0f;
	 count += 2;
      }
   }
   
   vorbis_analysis_wrote( vd, n_samples );

   while( vorbis_analysis_blockout( vd, vb ) == 1 )
   {
      ogg_packet op;
      
      vorbis_analysis( vb, NULL );
      vorbis_bitrate_addblock( vb );
      
      while( vorbis_bitrate_flushpacket( vd, &op ) )
      {
	 ogg_stream_packetin( vo, &op );
      }
   }
   
   while( ogg_stream_pageout( vo, &og ) )
   {
      got_page = 1;
      audiopos = vorbis_granule_time( vd, ogg_page_granulepos( &og ) );
/*       printf( "VORBIS: %f\n", audiopos ); */
      fwrite( og.header, og.header_len, 1, f );
      fwrite( og.body, og.body_len, 1, f );
   }

   if( !got_page )
   {
      double t;
      
      t = ( ( 1.0 * n_samples ) / audio_rate );
      
      audiopos += t;
   }

   return audiopos;
}
示例#17
0
static int oggvorbis_encode_frame(AVCodecContext *avccontext,
				  unsigned char *packets,
			   int buf_size, void *data)
{
    OggVorbisContext *context = avccontext->priv_data ;
    float **buffer ;
    ogg_packet op ;
    signed char *audio = data ;
    int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0;

    buffer = vorbis_analysis_buffer(&context->vd, samples) ;

    if(context->vi.channels == 1) {
	for(l = 0 ; l < samples ; l++)
	    buffer[0][l]=((audio[l*2+1]<<8)|(0x00ff&(int)audio[l*2]))/32768.f;
    } else {
	for(l = 0 ; l < samples ; l++){
	    buffer[0][l]=((audio[l*4+1]<<8)|(0x00ff&(int)audio[l*4]))/32768.f;
	    buffer[1][l]=((audio[l*4+3]<<8)|(0x00ff&(int)audio[l*4+2]))/32768.f;
	}
    }
    
    vorbis_analysis_wrote(&context->vd, samples) ; 

    while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
	vorbis_analysis(&context->vb, NULL);
	vorbis_bitrate_addblock(&context->vb) ;

	while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
            if(op.bytes==1) //id love to say this is a hack, bad sadly its not, appearently the end of stream decission is in libogg
                continue;
            memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
            context->buffer_index += sizeof(ogg_packet);
            memcpy(context->buffer + context->buffer_index, op.packet, op.bytes);
            context->buffer_index += op.bytes;
//            av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes);
	}
    }

    l=0;
    if(context->buffer_index){
        ogg_packet *op2= (ogg_packet*)context->buffer;
        op2->packet = context->buffer + sizeof(ogg_packet);

        l=  op2->bytes;
        avccontext->coded_frame->pts= av_rescale(op2->granulepos, AV_TIME_BASE, avccontext->sample_rate);

        memcpy(packets, op2->packet, l);
        context->buffer_index -= l + sizeof(ogg_packet);
        memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
//        av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l);
    }

    return l;
}
示例#18
0
tbool CVorbisEncoder::Finalize_Descendant()
{
	if (miOutputSamplesTotal > 0) {
		// Actually done any processing?
		
		// 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);
		
		while(vorbis_analysis_blockout(&vd,&vb)==1){
			
			/* analysis, assume we want to use bitrate management */
			vorbis_analysis(&vb,NULL);
			vorbis_bitrate_addblock(&vb);
			
			while(vorbis_bitrate_flushpacket(&vd,&op)){
				
				/* weld the packet into the bitstream */
				ogg_stream_packetin(&os,&op);
				
				/* write out pages (if any) */
				tbool bEOS = false;
				while(!bEOS){
					int result=ogg_stream_pageout(&os,&og);
					if(result==0)break;
					//fwrite(og.header,1,og.header_len,stdout);
					//fwrite(og.body,1,og.body_len,stdout);
					WriteOutput((char*)og.header, og.header_len);
					WriteOutput((char*)og.body, og.body_len);
					
					/* this could be set above, but for illustrative purposes, I do
						it here (to show that vorbis does know where the stream ends) */
					
					if(ogg_page_eos(&og))bEOS=1;
				}
			}
		}

		/* clean up and exit.  vorbis_info_clear() must be called last */
		ogg_stream_clear(&os);
		vorbis_block_clear(&vb);
		vorbis_dsp_clear(&vd);
		vorbis_comment_clear(&vc);
		vorbis_info_clear(&vi);
		
		/* ogg_page and ogg_packet structs always point to storage in
			libvorbis.  They're never freed or manipulated directly */
	}

	tfloat fSecs = ((tfloat)miOutputSamplesTotal) / miOutputSampleFreq;
	tfloat fKbps = muiBytesTotalOutput * 8.0f / (fSecs * 1000);
	std::cout << "Done (wrote " << muiBytesTotalOutput << " bytes, " << fSecs << " secs, avg rate " << fKbps << " kbps)\n\n";
	
	return true;
}
示例#19
0
文件: encode.c 项目: miksago/icecast
/* Returns:
 *   0     No output at this time
 *   >0    Page produced
 *
 * Caller should loop over this to ensure that we don't end up with
 * excessive buffering in libvorbis.
 */
int encode_dataout(encoder_state *s, ogg_page *og)
{
    ogg_packet op;
    int result;

    if(s->in_header)
    {
        result = ogg_stream_flush(&s->os, og);
        if(result==0) 
        {
            s->in_header = 0;
            return encode_dataout(s,og);
        }
        else
            return 1;
    }
    else
    {
        while(vorbis_analysis_blockout(&s->vd, &s->vb)==1)
        {
            vorbis_analysis(&s->vb, NULL);
            vorbis_bitrate_addblock(&s->vb);

            while(vorbis_bitrate_flushpacket(&s->vd, &op)) 
                ogg_stream_packetin(&s->os, &op);
        }

        /* FIXME: Make this threshold configurable.
         * We don't want to buffer too many samples in one page when doing
         * live encoding - that's fine for non-live encoding, but breaks
         * badly when doing things live. 
         * So, we flush the stream if we have too many samples buffered
         */
        if(s->samples_in_current_page > s->samplerate * 2)
        {
            /*LOG_DEBUG1("Forcing flush: Too many samples in current page (%d)",
                    s->samples_in_current_page); */
            result = ogg_stream_flush(&s->os, og);
        }
        else
            result = ogg_stream_pageout(&s->os, og);

        if(result==0)
            return 0;
        else /* Page found! */
        {
            s->samples_in_current_page -= ogg_page_granulepos(og) - 
                    s->prevgranulepos;
            s->prevgranulepos = ogg_page_granulepos(og);
            return 1;
        }
    }
}
示例#20
0
/* Returns TRUE if an ogg page was output, FALSE if there is nothing
 * left to do.
 */
gboolean xmms_ices_encoder_output (encoder_state *s, ogg_page *og)
{
	ogg_packet op;

	/* As long as we're still in the header, we still have the header
	 * packets to output. Loop over those before going to the actual
	 * vorbis data. */
	if (s->in_header) {
		if (ogg_stream_flush (&s->os, og))
			return TRUE;
		else
			s->in_header = FALSE;
	}

	/* If we're flushing the end of the stream, just output. */
	if (s->flushing) {
		if (ogg_stream_flush (&s->os, og))
			return TRUE;
		else
			return FALSE;
	}

	/* Flush the vorbis analysis stream into ogg packets, and add
	 * those to the ogg packet stream. */
	while (vorbis_analysis_blockout (&s->vd, &s->vb) == 1) {
		vorbis_analysis (&s->vb, NULL);
		vorbis_bitrate_addblock (&s->vb);

		while (vorbis_bitrate_flushpacket (&s->vd, &op))
			ogg_stream_packetin (&s->os, &op);
	}

	/* For live encoding, we want to stream pages regularly, rather
	 * than burst huge pages. Therefore, we periodically manually
	 * flush the stream. */
	if (s->samples_in_current_page > s->rate * 2) {
		if (!ogg_stream_flush (&s->os, og))
			return FALSE;
	} else {
		if (!ogg_stream_pageout (&s->os, og))
			return FALSE;
	}

	/* At this point, we have an ogg page in og. Keep bookkeeping
	 * accurate regarding the number of samples still in the page
	 * buffer, and return. */
	s->samples_in_current_page -= (ogg_page_granulepos (og)
	                               - s->previous_granulepos);
	s->previous_granulepos = ogg_page_granulepos (og);

	return TRUE;
}
示例#21
0
static void
vorbis_encoder_blockout(struct vorbis_encoder *encoder)
{
	while (vorbis_analysis_blockout(&encoder->vd, &encoder->vb) == 1) {
		ogg_packet packet;

		vorbis_analysis(&encoder->vb, NULL);
		vorbis_bitrate_addblock(&encoder->vb);

		while (vorbis_bitrate_flushpacket(&encoder->vd, &packet))
			ogg_stream_packetin(&encoder->os, &packet);
	}
}
示例#22
0
void WebMEncoder::encodeAudioInterleaved(const short* samples,int samplesToEncode) {

	//cout << "AUDIO TIME: " << (lastAudioTime+samplesToEncode-audioSampleRate/2)/double(audioSampleRate) << " VIDEO TIME " << curFrame/30.0 << endl;
    if( (lastAudioTime+samplesToEncode)>audioSampleRate/2 && (lastAudioTime+samplesToEncode-24000)/double(audioSampleRate) > curFrame/30.0)
	    return; // Skip this frame

    float **buffer = vorbis_analysis_buffer(&vd,samplesToEncode);
    
    const short* curSample = samples;
    for(int a=0;a<samplesToEncode;a++) {
        for(int b=0;b<2;b++) {
            buffer[b][a] = (*curSample)/32768.0f;
            curSample++;
        }
    }
    
    vorbis_analysis_wrote(&vd,samplesToEncode);

    /* vorbis does some data preanalysis, then divvies up blocks for
       more involved (potentially parallel) processing.  Get a single
       block for encoding now */
    while(vorbis_analysis_blockout(&vd,&vb)==1){
        
        /* analysis, assume we want to use bitrate management */
        vorbis_analysis(&vb,NULL);
        vorbis_bitrate_addblock(&vb);
        
        while(true){
            ogg_packet opNotMine;
            if(!vorbis_bitrate_flushpacket(&vd,&opNotMine)) {
                break;
            }
            ogg_packet* op = new ogg_packet();
            op->packet = (unsigned char*)malloc(opNotMine.bytes);
            memcpy(op->packet, opNotMine.packet, opNotMine.bytes);
            op->bytes = opNotMine.bytes;
            op->granulepos = opNotMine.granulepos;
            
            lastAudioTime = op->granulepos;
            boost::mutex::scoped_lock scoped_lock(muxerMutex);
            long long audioTimeNS = ((long long)(double(op->granulepos)*1000000000.0/audioSampleRate));
            //printf("GOT AUDIO FRAME: %lld\n", audioTimeNS/1000000);
            packetsToWrite[audioTimeNS] = op;
            //cout << "CURRENT AUDIO TIME IN SAMPLES: " << lastAudioTime << " IN SECONDS: " << (double(lastAudioTime)/audioSampleRate) << endl;
            
            
        }
    }

}
示例#23
0
文件: encode.c 项目: miksago/icecast
void encode_finish(encoder_state *s)
{
    ogg_packet op;
    vorbis_analysis_wrote(&s->vd, 0);

    while(vorbis_analysis_blockout(&s->vd, &s->vb)==1)
    {
        vorbis_analysis(&s->vb, NULL);
        vorbis_bitrate_addblock(&s->vb);
        while(vorbis_bitrate_flushpacket(&s->vd, &op))
            ogg_stream_packetin(&s->os, &op);
    }

}
/*
 * Class:     org_tritonus_lowlevel_pvorbis_DspState
 * Method:    flushPacket_native
 * Signature: (Lorg/tritonus/lowlevel/ogg/Packet;)I
 */
JNIEXPORT jint JNICALL
Java_org_tritonus_lowlevel_pvorbis_DspState_flushPacket_1native
(JNIEnv* env, jobject obj, jobject packet)
{
	vorbis_dsp_state*	handle;
	ogg_packet*		packetHandle;
	int			nReturn;

	if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_pvorbis_DspState_flushPacket(): begin\n"); }
	handle = getHandle(env, obj);
	packetHandle = getPacketNativeHandle(env, packet);
	nReturn = vorbis_bitrate_flushpacket(handle, packetHandle);
	if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_pvorbis_DspState_flushPacket(): end\n"); }
	return nReturn;
}
示例#25
0
void TargetFileOggVorbis::processAndWriteVorbisBlocks()
{
	while ( vorbis_analysis_blockout( &mVorbisDspState, &mVorbisBlock ) == 1 ) {
		vorbis_analysis( &mVorbisBlock, NULL );
		vorbis_bitrate_addblock( &mVorbisBlock );

		while ( vorbis_bitrate_flushpacket( &mVorbisDspState, &mOggPacket ) == 1 ) {
			ogg_stream_packetin( &mOggStream, &mOggPacket );

			while ( ogg_stream_pageout( &mOggStream, &mOggPage ) != 0 ) {
				mStream->writeData( mOggPage.header, mOggPage.header_len );
				mStream->writeData( mOggPage.body, mOggPage.body_len );
			}
		}
	}
}
示例#26
0
bool ShoutVSTEncoderOGG::Process( float **inputs, long sampleFrames )
{
  if (!bInitialized) return false;

  float **buffer=vorbis_analysis_buffer(&vd,sampleFrames);

  /* uninterleave samples */
  for(int i=0;i<sampleFrames;i++){
    buffer[0][i] = inputs[0][i];
    buffer[1][i] = inputs[1][i];
  }

  /* tell the library how much we actually submitted */
  vorbis_analysis_wrote(&vd,sampleFrames);

  /* vorbis does some data preanalysis, then divvies up blocks for
  more involved (potentially parallel) processing.  Get a single
  block for encoding now */
  int eos = 0;

  while(vorbis_analysis_blockout(&vd,&vb)==1){

    /* analysis, assume we want to use bitrate management */
    vorbis_analysis(&vb,NULL);
    vorbis_bitrate_addblock(&vb);

    while(vorbis_bitrate_flushpacket(&vd,&op)){

      /* weld the packet into the bitstream */
      ogg_stream_packetin(&os,&op);

      /* write out pages (if any) */
      while(!eos){
        int result=ogg_stream_pageout(&os,&og);
        if(result==0)break;
        if (!SendOGGPageToICE(&og)) return false;

        /* this could be set above, but for illustrative purposes, I do
        it here (to show that vorbis does know where the stream ends) */

        if(ogg_page_eos(&og))eos=1;
      }
    }
  } 

  return true;
}
void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){
    float **vorbis_buffer;
    int count=0,i,j;
    int sampread=(buff!=NULL)?pdata->periodsize:0;

    vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread);

    if(!pdata->args.use_jack){
        for(i=0;i<sampread;i++){
            for(j=0;j<pdata->args.channels;j++){
                vorbis_buffer[j][i]=((buff[count+1]<<8)|
                                        (0x00ff&(int)buff[count]))/
                                    32768.f;
                count+=2;
            }
        }
    }
    else{
        for(j=0;j<pdata->args.channels;j++){
            for(i=0;i<sampread;i++){
                vorbis_buffer[j][i]=((float*)buff)[count];
                count++;
            }
        }
    }

    vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);

    pthread_mutex_lock(&pdata->libogg_mutex);
    while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,
                                   &pdata->enc_data->m_vo_block)==1){

        vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
        vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);

        while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp,
                                         &pdata->enc_data->m_ogg_pckt2)){
            ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,
                                &pdata->enc_data->m_ogg_pckt2);
        }
    }
    pthread_mutex_unlock(&pdata->libogg_mutex);

    if(!pdata->running)pdata->enc_data->m_ogg_vs.e_o_s=1;

    pdata->avd-=pdata->periodtime;
}
示例#28
0
void encoder_encode_work(encoder_instance state) {
  ogg_page og;
  
  while (vorbis_analysis_blockout(&state->vd, &state->vb) == 1) {
    vorbis_analysis(&state->vb, NULL);
    vorbis_bitrate_addblock(&state->vb);
    
    while (vorbis_bitrate_flushpacket(&state->vd, &state->op)) {
      
      ogg_stream_packetin(&state->os, &state->op);
      
      while (ogg_stream_pageout(&state->os, &og) != 0) {
        encoder_write_page(state, &og);
      }
    }
  }
}
示例#29
0
void EncoderVorbis::writePage() {

    /*
     * Vorbis streams begin with three headers; the initial header (with
     * most of the codec setup parameters) which is mandated by the Ogg
     * bitstream spec.  The second header holds any comment fields.  The
     * third header holds the bitstream codebook.  We merely need to
     * make the headers, then pass them to libvorbis one at a time;
     * libvorbis handles the additional Ogg bitstream constraints
         */


    //Write header only once after stream has been initalized
    int result;
    if (m_header_write) {
        while (true) {
            result = ogg_stream_flush(&m_oggs, &m_oggpage);
            if (result == 0)
                break;
            m_pCallback->write(m_oggpage.header, m_oggpage.body, m_oggpage.header_len, m_oggpage.body_len);
        }
        m_header_write = false;
    }

    while (vorbis_analysis_blockout(&m_vdsp, &m_vblock) == 1) {
        vorbis_analysis(&m_vblock, 0);
        vorbis_bitrate_addblock(&m_vblock);
        while (vorbis_bitrate_flushpacket(&m_vdsp, &m_oggpacket)) {
            // weld packet into bitstream
            ogg_stream_packetin(&m_oggs, &m_oggpacket);
            // write out pages
            bool eos = false;
            while (!eos) {
                int result = ogg_stream_pageout(&m_oggs, &m_oggpage);
                if (result == 0)
                    break;
                m_pCallback->write(m_oggpage.header, m_oggpage.body,
                                   m_oggpage.header_len, m_oggpage.body_len);
                if (ogg_page_eos(&m_oggpage))
                    eos = true;
            }
        }
    }
}
示例#30
0
void ogg_encoder_write_blocks(guac_audio_stream* audio) {

    /* Get state */
    ogg_encoder_state* state = (ogg_encoder_state*) audio->data;

    while (vorbis_analysis_blockout(&(state->vorbis_state),
                &(state->vorbis_block)) == 1) {

        /* Analyze */
        vorbis_analysis(&(state->vorbis_block), NULL);
        vorbis_bitrate_addblock(&(state->vorbis_block));

        /* Flush Ogg pages */
        while (vorbis_bitrate_flushpacket(&(state->vorbis_state),
                    &(state->ogg_packet))) {

            /* Weld packet into bitstream */
            ogg_stream_packetin(&(state->ogg_state), &(state->ogg_packet));

            /* Write out pages */
            while (ogg_stream_pageout(&(state->ogg_state),
                        &(state->ogg_page)) != 0) {

                /* Write packet header */
                guac_audio_stream_write_encoded(audio,
                        state->ogg_page.header,
                        state->ogg_page.header_len);

                /* Write packet body */
                guac_audio_stream_write_encoded(audio,
                        state->ogg_page.body,
                        state->ogg_page.body_len);

                if (ogg_page_eos(&(state->ogg_page)))
                    break;

            }

        }

    }

}