JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_FFmpeg_avcodec_1encode_1audio
    (JNIEnv *env, jclass clazz,
    jlong ctx,
    jbyteArray buf, jint buf_offset, jint buf_size,
    jbyteArray samples, jint samples_offset)
{
    jint ret;

    if (buf) {
        jbyte *buf_ptr = (*env)->GetByteArrayElements (env, buf, NULL);

        if (buf_ptr) {
            jbyte *samples_ptr
                = (*env)->GetByteArrayElements (env, samples, NULL);

            if (samples_ptr) {
                ret = (jint) avcodec_encode_audio(
                        (AVCodecContext *) (intptr_t) ctx,
                        (uint8_t *) (buf_ptr + buf_offset), (int) buf_size,
                        (const short *) (samples_ptr + samples_offset));
                (*env)->ReleaseByteArrayElements(
                        env,
                        samples, samples_ptr,
                        JNI_ABORT);
            } else
                ret = -1;
            (*env)->ReleaseByteArrayElements (env, buf, buf_ptr, 0);
        } else
            ret = -1;
    } else
        ret = -1;
    return ret;
}
Example #2
0
static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size)
{
	int n;
	n = avcodec_encode_audio(lavc_actx, dest, size, src);
        compressed_frame_size = n;
	return n;
}
Example #3
0
static hb_buffer_t * Flush( hb_work_object_t * w )
{
    hb_work_private_t * pv = w->private_data;
    hb_buffer_t *first, *buf, *last;

    first = last = buf = Encode( w );
    while( buf )
    {
        last = buf;
        buf->next = Encode( w );
        buf = buf->next;
    }

    if( last )
    {
        last->next = hb_buffer_init( pv->output_bytes );
        buf = last->next;
    }
    else
    {
        first = buf = hb_buffer_init( pv->output_bytes );
    }
    // Finalize with NULL input needed by FLAC to generate md5sum
    // in context extradata
    avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
    buf->size = 0;
    return first;
}
//*********************************
uint8_t	AUDMEncoder_Lavcodec::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples)
{
  uint32_t nbout;
  
  *samples = _chunk/_wavheader->channels; //FIXME
  *len = 0;

  if(!refillBuffer(_chunk ))
  {
    return 0; 
  }
        
  if(tmptail-tmphead<_chunk)
  {
    return 0; 
  }

  dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels);

  ADM_assert(tmptail>=tmphead);
  nbout = avcodec_encode_audio(CONTEXT, dest, 5000, (short *) &(tmpbuffer[tmphead]));

  tmphead+=_chunk;
  if (nbout < 0) 
  {
    printf("[Lavcodec] Error !!! : %ld\n", nbout);
    return 0;
  }
  *len=nbout;
  return 1;
}
Example #5
0
void audio_encode_example(const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int frame_size, i, j, out_size, outbuf_size;
    short *samples;
    float t, tincr;
    uint8_t *outbuf;

    codec = avcodec_find_encoder(CODEC_ID_ADPCM_IMA_WAV);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c= avcodec_alloc_context();
    
    /* put sample parameters */
    c->bit_rate = 64000;//64000;
    c->sample_rate = 8000;//44100;
    c->channels = 1;//2;

    /* open it */
    if (avcodec_open(c, codec) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }
    
    /* the codec gives us the frame size, in samples */
    frame_size = c->frame_size;
    samples = malloc(frame_size * 2 * c->channels);
    outbuf_size = 10000;
    outbuf = malloc(outbuf_size*2);
        
    /* encode a single tone sound */
    t = 0;
    tincr = 2 * M_PI * 440.0 / c->sample_rate;

    for(i=0;i<200;i++) 
	{
        for(j=0;j<frame_size;j++) 
		{
            samples[2*j] = (int)(sin(t) * 10000);
            samples[2*j+1] = samples[2*j];
            t += tincr;
        }
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
//        fwrite(outbuf, 1, out_size, f);

    }

    free(outbuf);
    free(samples);

    avcodec_close(c);
    free(c);
}
Example #6
0
extern int ffmpeg_encoder_encode_audio (ffmpeg_encoder_t * in_encoder, int num_samples, short * p_audio, uint8_t * * pp_enc_audio)
{
    internal_ffmpeg_encoder_t * aenc = (internal_ffmpeg_encoder_t *)in_encoder;
    if (!aenc)
    {
        return -1;
    }

    int size = 0;
    *pp_enc_audio = aenc->audio_outbuf;
    int nch = aenc->num_audio_channels;

    /* encode and write audio */
    if (p_audio)
    {
        /*
        Audio comes in in video frames (num_samples e.g. 1920) but may be encoded
        as MPEG frames (1152 samples) so we need to buffer.
        */
        /*
        NB. audio_inbuf_wroffset is in terms of 16-bit samples, hence the
        rather confusing pointer arithmetic.
        */

        // Copy input samples to audio_inbuf.
        memcpy (aenc->audio_inbuf + aenc->audio_inbuf_wroffset, p_audio, num_samples * 2 * nch);
        aenc->audio_inbuf_wroffset += (num_samples * nch);

        // If we have enough samples to code, code them.
        int diff;
        while ((diff = aenc->audio_inbuf_wroffset - (aenc->audio_samples_per_output_frame * nch)) >= 0)
        {
            //fprintf (stderr, "samples available to code = %d, i.e. %d per channel\n", aenc->audio_inbuf_wroffset, aenc->audio_inbuf_wroffset / nch);
            // You don't get any feedback from this function but it appears to consume audio_samples_per_output_frame
            // of input each time you call it.
            int s = avcodec_encode_audio(aenc->codec_context, aenc->audio_outbuf + size, aenc->audio_outbuf_size - size, aenc->audio_inbuf);
            if (s < 0)
            {
                fprintf(stderr, "error compressing audio!\n");
                return -1;
            }
            else
            {
                //fprintf (stderr, "produced %d bytes of encoded audio\n", s);
            }
            size += s;

            /* Shift samples in input buffer.
               The number to shift is diff, i.e. those exceeding what we can code at the moment. */
            memmove (aenc->audio_inbuf, aenc->audio_inbuf + (aenc->audio_samples_per_output_frame * nch), diff * 2);
            aenc->audio_inbuf_wroffset -= (aenc->audio_samples_per_output_frame * nch);
        }
    }

    //fprintf (stderr, "returning size=%d\n", size);
    return size;
}
Example #7
0
int FFMpegEncoder::encodeAudioFrame(short* audioBufIn,int audioBufInSize)
{
	audioEncodedSize = avcodec_encode_audio(pAudioCodecCtx,audioEncodeBuf,audioEncodeBufSize,audioBufIn);

	if (audioEncodedSize > 0)
		audioClock += ((double)audioEncodedSize / getAudioFrameSize());

	return audioEncodedSize;
}
static void write_audio_frame(EncoderJob &jobSpec, MediaFrame &frame, AVFormatContext *oc, AVStream *st)
{
	AVCodecContext *c;
	c = st->codec;

	double fs = c->frame_size;
	long as = frame.AudioSize;
	long runs = (as / fs);

	double pts_val = frame.AudioSampleTime * 90000.0; // mpeg ticks at start

	double _asr = frame.AudioSampleRate;
	long pts_incr = (fs / _asr) * 90000.0; // mpeg ticks per encoder frame.

	frame.AudioSamplesConsumed = 0;

	int bft = 0;
	while (
		((pts_val <= jobSpec.v_pts) || frame.ForceAudioConsumption)// (don't overtake video) unless forced
		&& (bft < runs)) { // (don't overrun buffer)
			int outsize = avcodec_encode_audio(c, jobSpec.audio_outbuf, fs, frame.AudioBuffer); // context, byte buffer, sample count, sample buffer

			AVPacket pkt;
			av_init_packet(&pkt);
			
			pkt.pts = pts_val;
			pkt.dts = pkt.pts;
			jobSpec.a_pts = pts_val;
			pkt.flags |= AV_PKT_FLAG_KEY;
			pts_val += pts_incr;

			pkt.stream_index= st->index;
			pkt.data = jobSpec.audio_outbuf;
			pkt.size = outsize;

			// write the compressed frame in the media file
			if (outsize > 0) {
				if (frame.ForceAudioConsumption) {
					advance_fragment(jobSpec); // advance if needed.
				}
#ifdef NEW_M2TS
				jobSpec.p->PushStream(121, Pests::TT_MpegAudio, pkt.data, pkt.size, pkt.pts);
#else
				av_interleaved_write_frame(oc, &pkt);
				put_flush_packet(jobSpec.oc->pb);
#endif
			}
			av_free_packet(&pkt);

			bft++;
			
			frame.AudioBuffer += (int)fs; // update positions
			frame.AudioSamplesConsumed += fs;
	}

}
Example #9
0
// Some encoders (e.g. flac) require a final NULL encode in order to
// finalize things.
static void Finalize( hb_work_object_t * w )
{
    hb_work_private_t * pv = w->private_data;
    hb_buffer_t * buf = hb_buffer_init( pv->output_bytes );

    // Finalize with NULL input needed by FLAC to generate md5sum
    // in context extradata
    avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
    hb_buffer_close( &buf );
}
Example #10
0
MediaRet MediaRecorder::AddFrame(const u16 *aud)
{
    if(!oc || !aud_st)
	return MRET_OK;
    // aud == NULL means just flush out last frame
    if(!aud && !in_audio_buf2)
	return MRET_OK;
    AVCodecContext *ctx = aud_st->codec;
    AVPacket pkt;

    int len = sample_len;
    if(in_audio_buf2) {
	int ncpy = frame_len - in_audio_buf2;
	if(ncpy > len)
	    ncpy = len;
	if(aud) {
	    memcpy(audio_buf2 + in_audio_buf2/2, aud, ncpy);
	    len -= ncpy;
	    aud += ncpy / 2;
	} else {
	    memset(audio_buf2 + in_audio_buf2/2, 0, ncpy);
	    len = 0;
	}
	in_audio_buf2 += ncpy;
    }
    while(len + in_audio_buf2 >= frame_len) {
	av_init_packet(&pkt);
	pkt.size = avcodec_encode_audio(ctx, audio_buf, frame_len,
					(const short *)(in_audio_buf2 ? audio_buf2 : aud));
	if(ctx->coded_frame && ctx->coded_frame->pts != AV_NOPTS_VALUE)
	    pkt.pts = av_rescale_q(ctx->coded_frame->pts, ctx->time_base, aud_st->time_base);
	pkt.flags |= AV_PKT_FLAG_KEY;
	pkt.stream_index = aud_st->index;
	pkt.data = audio_buf;
	if(av_interleaved_write_frame(oc, &pkt) < 0) {
	    avformat_free_context(oc);
	    oc = NULL;
	    // yeah, err might not be a file error, but if it isn't, it's a
	    // coding error rather than a user-controllable error
	    // and better resolved using debugging
	    return MRET_ERR_FERR;
	}
	if(in_audio_buf2)
	    in_audio_buf2 = 0;
	else {
	    aud += frame_len / 2;
	    len -= frame_len;
	}
    }
    if(len > 0) {
	memcpy(audio_buf2, aud, len);
	in_audio_buf2 = len;
    }
    return MRET_OK;
}
Example #11
0
// private method
int FFmpegEncoder::encodeAudioData(short *frameData, int dataSize)
{
	// the output size of the buffer which stores the encoded data
	int audioSize = this->audioBufferSize;

	if (this->audioStream->codec->frame_size <=1 && dataSize > 0)
	{
		// For PCM related codecs, the output size of the encoded data is
		// calculated from the size of the input audio frame.
		audioSize = dataSize;

		// The following codes are used for calculating "short" size from original "sample" size.
		// The codes are not needed any more because now the input size is already in "short" unit.

		// calculated the PCM size from input data size
		//switch(this->audioStream->codec->codec_id)
		//{
		//    case CODEC_ID_PCM_S32LE:
		//    case CODEC_ID_PCM_S32BE:
		//    case CODEC_ID_PCM_U32LE:
		//    case CODEC_ID_PCM_U32BE:
		//        audioSize <<= 1;
		//        break;
		//    case CODEC_ID_PCM_S24LE:
		//    case CODEC_ID_PCM_S24BE:
		//    case CODEC_ID_PCM_U24LE:
		//    case CODEC_ID_PCM_U24BE:
		//    case CODEC_ID_PCM_S24DAUD:
		//        audioSize = audioSize / 2 * 3;
		//        break;
		//    case CODEC_ID_PCM_S16LE:
		//    case CODEC_ID_PCM_S16BE:
		//    case CODEC_ID_PCM_U16LE:
		//    case CODEC_ID_PCM_U16BE:
		//        break;
		//    default:
		//        audioSize >>= 1;
		//        break;
		//}
	}

	// encode the frame
	int encodedSize = avcodec_encode_audio(this->audioStream->codec, this->audioBuffer, audioSize, frameData);

	if (encodedSize < 0)
	{
		return -1;
	}
	else
	{
		return encodedSize;
	}
}
Example #12
0
// returns non-zero if there is more sound, -1 in case of error
static int WriteAudioFrame()
{
    if (!g_pAStream)
        return 0;

    AVPacket Packet;
    av_init_packet(&Packet);
    Packet.data = NULL;
    Packet.size = 0;

    int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);

#if LIBAVCODEC_VERSION_MAJOR >= 53
    AVFrame* pFrame = NULL;
    if (NumSamples > 0)
    {
        g_pAFrame->nb_samples = NumSamples;
        avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16,
                                 (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1);
        pFrame = g_pAFrame;
    }
    // when NumSamples == 0 we still need to call encode_audio2 to flush
    int got_packet;
    if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0)
        return FatalError("avcodec_encode_audio2 failed");
    if (!got_packet)
        return 0;

    av_packet_rescale_ts(&Packet, g_pAudio->time_base, g_pAStream->time_base);
#else
    if (NumSamples == 0)
        return 0;
    int BufferSize = OUTBUFFER_SIZE;
    if (g_pAudio->frame_size == 0)
        BufferSize = NumSamples*g_Channels*2;
    Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples);
    if (Packet.size == 0)
        return 1;
    if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE)
        Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base);
    Packet.flags |= AV_PKT_FLAG_KEY;
    Packet.data = g_OutBuffer;
#endif

    // Write the compressed frame to the media file.
    Packet.stream_index = g_pAStream->index;
    if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
        return FatalError("Error while writing audio frame");
    return 1;
}
Example #13
0
bool AVFormatWriter::WriteAudioFrame(unsigned char *buf, int fnum, int timecode)
{
    int csize = 0;

#if HAVE_BIGENDIAN
    int sample_cnt = m_audioFrameSize / m_audioBytesPerSample;
    bswap_16_buf((short int*) buf, sample_cnt, m_audioChannels);
#endif

    {
        QMutexLocker locker(avcodeclock);
        csize = avcodec_encode_audio(m_audioStream->codec, m_audioOutBuf,
                                     m_audioOutBufSize, (short int *)buf);
    }

    if (!csize)
    {
        // LOG(VB_RECORD, LOG_ERR, QString("WriteAudioFrame(): cs: %1, mfw: %2, tc: %3, fn: %4").arg(csize).arg(m_framesWritten).arg(timecode).arg(fnum));
        return false;
    }

    av_init_packet(m_pkt);

    long long tc = timecode;
    if (m_startingTimecodeOffset == -1)
        m_startingTimecodeOffset = tc;
    tc -= m_startingTimecodeOffset;

    if (m_avVideoCodec)
        m_pkt->pts = tc * m_videoStream->time_base.den / m_videoStream->time_base.num / 1000;
    else
        m_pkt->pts = tc * m_audioStream->time_base.den / m_audioStream->time_base.num / 1000;

    m_pkt->dts = AV_NOPTS_VALUE;
    m_pkt->flags |= AV_PKT_FLAG_KEY;
    m_pkt->data = (uint8_t*)m_audioOutBuf;
    m_pkt->size = csize;
    m_pkt->stream_index = m_audioStream->index;

    // LOG(VB_RECORD, LOG_ERR, QString("WriteAudioFrame(): cs: %1, mfw: %2, pkt->pts: %3, tc: %4, fn: %5").arg(csize).arg(m_framesWritten).arg(m_pkt->pts).arg(timecode).arg(fnum));

    int ret = av_interleaved_write_frame(m_ctx, m_pkt);
    if (ret != 0)
        LOG(VB_RECORD, LOG_ERR, LOC + "WriteAudioFrame(): "
                "av_interleaved_write_frame couldn't write Audio");

    return true;
}
Example #14
0
// Some encoders (e.g. flac) require a final NULL encode in order to
// finalize things.
static void Finalize( hb_work_object_t * w )
{
    hb_work_private_t * pv = w->private_data;
    hb_buffer_t * buf = hb_buffer_init( pv->output_bytes );

    // Finalize with NULL input needed by FLAC to generate md5sum
    // in context extradata
    avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
    hb_buffer_close( &buf );

    // Then we need to recopy the header since it was modified
    if ( pv->context->extradata )
    {
        memcpy( w->config->extradata.bytes, pv->context->extradata, pv->context->extradata_size );
        w->config->extradata.length = pv->context->extradata_size;
    }
}
Example #15
0
static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size)
{
	int n;
	if ((encoder->params.channels == 6 || encoder->params.channels == 5) &&
			(!strcmp(lavc_acodec->name,"ac3") ||
			!strcmp(lavc_acodec->name,"libfaac"))) {
		int isac3 = !strcmp(lavc_acodec->name,"ac3");
		reorder_channel_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
		                    isac3 ? AF_CHANNEL_LAYOUT_LAVC_DEFAULT
		                          : AF_CHANNEL_LAYOUT_AAC_DEFAULT,
		                    encoder->params.channels,
		                    size / 2, 2);
	}
	n = avcodec_encode_audio(lavc_actx, dest, size, src);
        compressed_frame_size = n;
	return n;
}
Example #16
0
	void encode_audio_frame(core::read_frame& frame)
	{			
		auto c = audio_st_->codec;

		boost::range::push_back(audio_buf_, convert_audio(frame, c));
		
		std::size_t frame_size = c->frame_size;
		auto input_audio_size = frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels;
		
		while(audio_buf_.size() >= input_audio_size)
		{
			safe_ptr<AVPacket> pkt(new AVPacket, [](AVPacket* p)
			{
				av_free_packet(p);
				delete p;
			});
			av_init_packet(pkt.get());

			if(frame_size > 1)
			{								
				pkt->size = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), reinterpret_cast<short*>(audio_buf_.data()));
				audio_buf_.erase(audio_buf_.begin(), audio_buf_.begin() + input_audio_size);
			}
			else
			{
				audio_outbuf_ = std::move(audio_buf_);		
				audio_buf_.clear();
				pkt->size = audio_outbuf_.size();
				pkt->data = audio_outbuf_.data();
			}
		
			if(pkt->size == 0)
				return;

			if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
				pkt->pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st_->time_base);

			pkt->flags		 |= AV_PKT_FLAG_KEY;
			pkt->stream_index = audio_st_->index;
			pkt->data		  = reinterpret_cast<uint8_t*>(audio_outbuf_.data());
		
			av_interleaved_write_frame(oc_.get(), pkt.get());
		}
	}
status_t
AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
	int64 frameCount, media_encode_info* info)
{
	// Encode one audio chunk/frame. The bufferSize has already been adapted
	// to the needed size for fContext->frame_size, or we are writing raw
	// audio.
	int usedBytes = avcodec_encode_audio(fContext, fChunkBuffer,
		bufferSize, reinterpret_cast<const short*>(buffer));

	if (usedBytes < 0) {
		TRACE("  avcodec_encode_audio() failed: %d\n", usedBytes);
		return B_ERROR;
	}
	if (usedBytes == 0)
		return B_OK;

//	// Maybe we need to use this PTS to calculate start_time:
//	if (fContext->coded_frame->pts != kNoPTSValue) {
//		TRACE("  codec frame PTS: %lld (codec time_base: %d/%d)\n",
//			fContext->coded_frame->pts, fContext->time_base.num,
//			fContext->time_base.den);
//	} else {
//		TRACE("  codec frame PTS: N/A (codec time_base: %d/%d)\n",
//			fContext->time_base.num, fContext->time_base.den);
//	}

	// Setup media_encode_info, most important is the time stamp.
	info->start_time = (bigtime_t)(fFramesWritten * 1000000LL
		/ fInputFormat.u.raw_audio.frame_rate);
	info->flags = B_MEDIA_KEY_FRAME;

	// Write the chunk
	status_t ret = WriteChunk(fChunkBuffer, usedBytes, info);
	if (ret != B_OK) {
		TRACE("  error writing chunk: %s\n", strerror(ret));
		return ret;
	}

	fFramesWritten += frameCount;

	return B_OK;
}
Example #18
0
static GstFlowReturn
gst_ffmpegenc_encode_audio (GstFFMpegEnc * ffmpegenc, guint8 * audio_in,
    guint max_size, GstClockTime timestamp, GstClockTime duration,
    gboolean discont)
{
  GstBuffer *outbuf;
  AVCodecContext *ctx;
  guint8 *audio_out;
  gint res;
  GstFlowReturn ret;

  ctx = ffmpegenc->context;

  outbuf = gst_buffer_new_and_alloc (max_size);
  audio_out = GST_BUFFER_DATA (outbuf);

  GST_LOG_OBJECT (ffmpegenc, "encoding buffer of max size %d", max_size);
  if (ffmpegenc->buffer_size != max_size)
    ffmpegenc->buffer_size = max_size;

  res = avcodec_encode_audio (ctx, audio_out, max_size, (short *) audio_in);

  if (res < 0) {
    GST_ERROR_OBJECT (ffmpegenc, "Failed to encode buffer: %d", res);
    gst_buffer_unref (outbuf);
    return GST_FLOW_OK;
  }
  GST_LOG_OBJECT (ffmpegenc, "got output size %d", res);

  GST_BUFFER_SIZE (outbuf) = res;
  GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
  GST_BUFFER_DURATION (outbuf) = duration;
  if (discont)
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegenc->srcpad));

  GST_LOG_OBJECT (ffmpegenc, "pushing size %d, timestamp %" GST_TIME_FORMAT,
      res, GST_TIME_ARGS (timestamp));

  ret = gst_pad_push (ffmpegenc->srcpad, outbuf);

  return ret;
}
Example #19
0
static int write_audio_frame(void) 
{
	AVCodecContext* c = NULL;
	AVPacket pkt;

	c = audio_stream->codec;

	av_init_packet(&pkt);
	pkt.size = 0;

	AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_samples);
	audio_time += (double) audio_input_samples / (double) c->sample_rate;

	pkt.size = avcodec_encode_audio(c, audio_output_buffer,
					audio_outbuf_size,
					(short*) audio_input_buffer);

	if(pkt.size < 0)
	{
		// XXX error("Error writing audio packet");
		return -1;
	}

	pkt.data = audio_output_buffer;

	if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
	{
		pkt.pts = av_rescale_q(c->coded_frame->pts,
				       c->time_base, audio_stream->time_base);
		fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
	}

	pkt.stream_index = audio_stream->index;

	pkt.flags |= AV_PKT_FLAG_KEY;

	if (av_interleaved_write_frame(outfile, &pkt) != 0) {
		fprintf(stderr, "Error writing audio packet!\n");
		return -1;
	}
	return 0;
}
Example #20
0
File: Server.cpp Project: m1geo/UNV
void audio_encode_example(uint8_t *EncInpBuf, int iEncInpBufSize)
{
	// encode the samples

	int frameBytes = pCodecCtxAudEnc->frame_size * pCodecCtxAudEnc->channels * 2;

	while(iEncInpBufSize >= frameBytes) {
		iEncodeAudio = avcodec_encode_audio(pCodecCtxAudEnc, outbufEnc, iOutbufEncSize, (short *)EncInpBuf);
		
		if(iEncodeAudio > 0) {
			if(cliOpts.networkport > 0) {
				// if we requested networking, do it.
				addAudioFrame((char *)outbufEnc, iEncodeAudio, cliOpts.transport);
			}
			
			if(cliOpts.saveaudio ) {
				fwrite(outbufEnc, sizeof(uint8_t), iEncodeAudio, pOutputAudio);
			}
		}
		EncInpBuf += frameBytes;
		iEncInpBufSize -= frameBytes;
	}
}
Example #21
0
bool AudioEncoder::EncodeFrame(AVFrame* frame) {

	if(frame != NULL) {
#if SSR_USE_AVFRAME_NB_SAMPLES
		assert((unsigned int) frame->nb_samples == GetFrameSize());
#endif
#if SSR_USE_AVFRAME_CHANNELS
		assert(frame->channels == GetStream()->codec->channels);
#endif
#if SSR_USE_AVFRAME_SAMPLE_RATE
		assert(frame->sample_rate == GetStream()->codec->sample_rate);
#endif
#if SSR_USE_AVFRAME_FORMAT
		assert(frame->format == GetStream()->codec->sample_fmt);
#endif
	}

#if SSR_USE_AVCODEC_ENCODE_AUDIO2

	// allocate a packet
	std::unique_ptr<AVPacketWrapper> packet(new AVPacketWrapper());

	// encode the frame
	int got_packet;
	if(avcodec_encode_audio2(GetStream()->codec, packet->GetPacket(), frame, &got_packet) < 0) {
		Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Encoding of audio frame failed!"));
		throw LibavException();
	}

	// do we have a packet?
	if(got_packet) {

		// send the packet to the muxer
		GetMuxer()->AddPacket(GetStream()->index, std::move(packet));
		return true;

	} else {
		return false;
	}

#else

	// encode the frame
	short *data = (frame == NULL)? NULL : (short*) frame->data[0];
	int bytes_encoded = avcodec_encode_audio(GetStream()->codec, m_temp_buffer.data(), m_temp_buffer.size(), data);
	if(bytes_encoded < 0) {
		Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Encoding of audio frame failed!"));
		throw LibavException();
	}

	// do we have a packet?
	if(bytes_encoded > 0) {

		// allocate a packet
		std::unique_ptr<AVPacketWrapper> packet(new AVPacketWrapper(bytes_encoded));

		// copy the data
		memcpy(packet->GetPacket()->data, m_temp_buffer.data(), bytes_encoded);

		// set the timestamp
		// note: pts will be rescaled and stream_index will be set by Muxer
		if(GetStream()->codec->coded_frame != NULL && GetStream()->codec->coded_frame->pts != (int64_t) AV_NOPTS_VALUE)
			packet->GetPacket()->pts = GetStream()->codec->coded_frame->pts;

		// send the packet to the muxer
		GetMuxer()->AddPacket(GetStream()->index, std::move(packet));
		return true;

	} else {
		return false;
	}

#endif

}
Example #22
0
static bool encode_audio(ffemu_t *handle, AVPacket *pkt, bool dry)
{
   av_init_packet(pkt);
   pkt->data = handle->audio.outbuf;
   pkt->size = handle->audio.outbuf_size;

#ifdef HAVE_FFMPEG_AVCODEC_ENCODE_AUDIO2
   AVFrame frame;
   avcodec_get_frame_defaults(&frame);

   frame.nb_samples = handle->audio.frames_in_buffer;
   frame.pts = handle->audio.frame_cnt;

   int samples_size = frame.nb_samples *
      handle->audio.codec->channels *
      sizeof(int16_t);

   avcodec_fill_audio_frame(&frame, handle->audio.codec->channels,
         handle->audio.codec->sample_fmt, (const uint8_t*)handle->audio.buffer,
         samples_size, 1);

   int got_packet = 0;
   if (avcodec_encode_audio2(handle->audio.codec,
            pkt, dry ? NULL : &frame, &got_packet) < 0)
      return false;

   if (!got_packet)
   {
      pkt->size = 0;
      pkt->pts = AV_NOPTS_VALUE;
      pkt->dts = AV_NOPTS_VALUE;
      return true;
   }

   if (pkt->pts != (int64_t)AV_NOPTS_VALUE)
   {
      pkt->pts = av_rescale_q(pkt->pts,
            handle->audio.codec->time_base,
            handle->muxer.astream->time_base);
   }

   if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
   {
      pkt->dts = av_rescale_q(pkt->dts,
            handle->audio.codec->time_base,
            handle->muxer.astream->time_base);
   }

#else
   if (dry)
      return false;

   memset(handle->audio.buffer + handle->audio.frames_in_buffer * handle->audio.codec->channels, 0,
         (handle->audio.codec->frame_size - handle->audio.frames_in_buffer) *
         handle->audio.codec->channels * sizeof(int16_t));

   int out_size = avcodec_encode_audio(handle->audio.codec,
         handle->audio.outbuf, handle->audio.outbuf_size, handle->audio.buffer);

   if (out_size < 0)
      return false;

   if (out_size == 0)
   {
      pkt->size = 0;
      return true;
   }

   pkt->size = out_size;

   if (handle->audio.codec->coded_frame->pts != (int64_t)AV_NOPTS_VALUE)
   {
      pkt->pts = av_rescale_q(handle->audio.codec->coded_frame->pts,
            handle->audio.codec->time_base,
            handle->muxer.astream->time_base);
   }
   else
      pkt->pts = AV_NOPTS_VALUE;

   if (handle->audio.codec->coded_frame->key_frame)
      pkt->flags |= AV_PKT_FLAG_KEY;
#endif

   pkt->stream_index = handle->muxer.astream->index;
   return true;
}
Example #23
0
bool AudioEncoder::EncodeFrame(AVFrameWrapper* frame) {

	if(frame != NULL) {
#if SSR_USE_AVFRAME_NB_SAMPLES
		assert((unsigned int) frame->GetFrame()->nb_samples == GetFrameSize());
#endif
#if SSR_USE_AVFRAME_CHANNELS
		assert(frame->GetFrame()->channels == GetCodecContext()->channels);
#endif
#if SSR_USE_AVFRAME_SAMPLE_RATE
		assert(frame->GetFrame()->sample_rate == GetCodecContext()->sample_rate);
#endif
#if SSR_USE_AVFRAME_FORMAT
		assert(frame->GetFrame()->format == GetCodecContext()->sample_fmt);
#endif
	}

#if SSR_USE_AVCODEC_SEND_RECEIVE

	// send a frame
	AVFrame *avframe = (frame == NULL)? NULL : frame->Release();
	try {
		if(avcodec_send_frame(GetCodecContext(), avframe) < 0) {
			Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Sending of audio frame failed!"));
			throw LibavException();
		}
	} catch(...) {
		av_frame_free(&avframe);
		throw;
	}
	av_frame_free(&avframe);

	// try to receive a packet
	for( ; ; ) {
		std::unique_ptr<AVPacketWrapper> packet(new AVPacketWrapper());
		int res = avcodec_receive_packet(GetCodecContext(), packet->GetPacket());
		if(res == 0) { // we have a packet, send the packet to the muxer
			GetMuxer()->AddPacket(GetStream()->index, std::move(packet));
			IncrementPacketCounter();
		} else if(res == AVERROR(EAGAIN)) { // we have no packet
			return true;
		} else if(res == AVERROR_EOF) { // this is the end of the stream
			return false;
		} else {
			Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Receiving of audio packet failed!"));
			throw LibavException();
		}
	}

#elif SSR_USE_AVCODEC_ENCODE_AUDIO2

	// allocate a packet
	std::unique_ptr<AVPacketWrapper> packet(new AVPacketWrapper());

	// encode the frame
	int got_packet;
	if(avcodec_encode_audio2(GetCodecContext(), packet->GetPacket(), (frame == NULL)? NULL : frame->GetFrame(), &got_packet) < 0) {
		Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Encoding of audio frame failed!"));
		throw LibavException();
	}

	// do we have a packet?
	if(got_packet) {

		// send the packet to the muxer
		GetMuxer()->AddPacket(GetStream()->index, std::move(packet));
		IncrementPacketCounter();
		return true;

	} else {
		return false;
	}

#else

	// encode the frame
	short *data = (frame == NULL)? NULL : (short*) frame->GetFrame()->data[0];
	int bytes_encoded = avcodec_encode_audio(GetCodecContext(), m_temp_buffer.data(), m_temp_buffer.size(), data);
	if(bytes_encoded < 0) {
		Logger::LogError("[AudioEncoder::EncodeFrame] " + Logger::tr("Error: Encoding of audio frame failed!"));
		throw LibavException();
	}

	// do we have a packet?
	if(bytes_encoded > 0) {

		// allocate a packet
		std::unique_ptr<AVPacketWrapper> packet(new AVPacketWrapper(bytes_encoded));

		// copy the data
		memcpy(packet->GetPacket()->data, m_temp_buffer.data(), bytes_encoded);

		// set the timestamp
		// note: pts will be rescaled and stream_index will be set by Muxer
		if(GetCodecContext()->coded_frame != NULL && GetCodecContext()->coded_frame->pts != (int64_t) AV_NOPTS_VALUE)
			packet->GetPacket()->pts = GetCodecContext()->coded_frame->pts;

		// send the packet to the muxer
		GetMuxer()->AddPacket(GetStream()->index, std::move(packet));
		IncrementPacketCounter();
		return true;

	} else {
		return false;
	}

#endif

}
Example #24
0
int FileAC3::write_samples(double **buffer, int64_t len)
{
// Convert buffer to encoder format
	if(temp_raw_size + len > temp_raw_allocated)
	{
		int new_allocated = temp_raw_size + len;
		int16_t *new_raw = new int16_t[new_allocated * asset->channels];
		if(temp_raw)
		{
			memcpy(new_raw,
				temp_raw,
				sizeof(int16_t) * temp_raw_size * asset->channels);
			delete [] temp_raw;
		}
		temp_raw = new_raw;
		temp_raw_allocated = new_allocated;
	}

// Allocate compressed data buffer
	if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
	{
		compressed_allocated = temp_raw_allocated * asset->channels * 2;
		delete [] temp_compressed;
		temp_compressed = new unsigned char[compressed_allocated];
	}

// Append buffer to temp raw
	int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
	for(int i = 0; i < len; i++)
	{
		for(int j = 0; j < asset->channels; j++)
		{
			int sample = (int)(buffer[j][i] * 32767);
			CLAMP(sample, -32768, 32767);
			*out_ptr++ = sample;
		}
	}
	temp_raw_size += len;

	int frame_size = ((AVCodecContext*)codec_context)->frame_size;
	int output_size = 0;
	int current_sample = 0;
	for(current_sample = 0;
		current_sample + frame_size <= temp_raw_size;
		current_sample += frame_size)
	{
		int compressed_size = avcodec_encode_audio(
			((AVCodecContext*)codec_context),
			temp_compressed + output_size,
			compressed_allocated - output_size,
            temp_raw + current_sample * asset->channels);
		output_size += compressed_size;
	}

// Shift buffer back
	memcpy(temp_raw,
		temp_raw + current_sample * asset->channels,
		(temp_raw_size - current_sample) * sizeof(int16_t) * asset->channels);
	temp_raw_size -= current_sample;

	int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
	if(bytes_written < output_size)
	{
		eprintf("Error while writing samples. \n%m\n");
		return 1;
	}
	return 0;
}
Example #25
0
/****************************************************************************
 * EncodeAudio: the whole thing
 ****************************************************************************/
static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    block_t *p_block, *p_chain = NULL;

    char *p_buffer = p_aout_buf->p_buffer;
    int i_samples = p_aout_buf->i_nb_samples;
    int i_samples_delay = p_sys->i_samples_delay;

    p_sys->i_pts = p_aout_buf->start_date -
                (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
                (mtime_t)p_enc->fmt_in.audio.i_rate;

    p_sys->i_samples_delay += i_samples;

    while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
    {
        int16_t *p_samples;
        int i_out;

        if( i_samples_delay )
        {
            /* Take care of the left-over from last time */
            int i_delay_size = i_samples_delay * 2 *
                                 p_sys->p_context->channels;
            int i_size = p_sys->i_frame_size - i_delay_size;

            p_samples = (int16_t *)p_sys->p_buffer;
            memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
            p_buffer -= i_delay_size;
            i_samples += i_samples_delay;
            i_samples_delay = 0;
        }
        else
        {
            p_samples = (int16_t *)p_buffer;
        }

        i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
                                      2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
                                      p_samples );

#if 0
        msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
#endif
        if( i_out < 0 ) break;

        p_buffer += p_sys->i_frame_size;
        p_sys->i_samples_delay -= p_sys->p_context->frame_size;
        i_samples -= p_sys->p_context->frame_size;

        if( i_out == 0 ) continue;

        p_block = block_New( p_enc, i_out );
        memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );

        p_block->i_length = (mtime_t)1000000 *
            (mtime_t)p_sys->p_context->frame_size /
            (mtime_t)p_sys->p_context->sample_rate;

        p_block->i_dts = p_block->i_pts = p_sys->i_pts;

        /* Update pts */
        p_sys->i_pts += p_block->i_length;
        block_ChainAppend( &p_chain, p_block );
    }

    /* Backup the remaining raw samples */
    if( i_samples )
    {
        memcpy( p_sys->p_buffer + i_samples_delay * 2 *
                p_sys->p_context->channels, p_buffer,
                i_samples * 2 * p_sys->p_context->channels );
    }

    return p_chain;
}
Example #26
0
/*
 * Audio encoding example
 */
static void audio_encode_example(const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int frame_size, i, j, out_size, outbuf_size;
    FILE *f;
    short *samples;
    float t, tincr;
    uint8_t *outbuf;

    printf("Audio encoding\n");

    /* find the MP2 encoder */
    codec = avcodec_find_encoder(CODEC_ID_MP2);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);

    /* put sample parameters */
    c->bit_rate = 64000;
    c->sample_rate = 44100;
    c->channels = 2;
    c->sample_fmt = AV_SAMPLE_FMT_S16;

    /* open it */
    if (avcodec_open(c, codec) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    /* the codec gives us the frame size, in samples */
    frame_size = c->frame_size;
    samples = malloc(frame_size * 2 * c->channels);
    outbuf_size = 10000;
    outbuf = malloc(outbuf_size);

    f = fopen(filename, "wb");
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }

    /* encode a single tone sound */
    t = 0;
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
    for(i=0;i<200;i++) {
        for(j=0;j<frame_size;j++) {
            samples[2*j] = (int)(sin(t) * 10000);
            samples[2*j+1] = samples[2*j];
            t += tincr;
        }
        /* encode the samples */
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
        fwrite(outbuf, 1, out_size, f);
    }
    fclose(f);
    free(outbuf);
    free(samples);

    avcodec_close(c);
    av_free(c);
}
Example #27
0
// Filter data through filter
static af_data_t* play(struct af_instance_s* af, af_data_t* data)
{
    af_ac3enc_t *s = af->setup;
    af_data_t *c = data;    // Current working data
    af_data_t *l;
    int len, left, outsize = 0, destsize;
    char *buf, *src, *dest;
    int max_output_len;
    int frame_num = (data->len + s->pending_len) / s->expect_len;

    if (s->add_iec61937_header)
        max_output_len = AC3_FRAME_SIZE * 2 * 2 * frame_num;
    else
        max_output_len = AC3_MAX_CODED_FRAME_SIZE * frame_num;

    if (af->data->len < max_output_len) {
        mp_msg(MSGT_AFILTER, MSGL_V, "[libaf] Reallocating memory in module %s, "
               "old len = %i, new len = %i\n", af->info->name, af->data->len,
                max_output_len);
        free(af->data->audio);
        af->data->audio = malloc(max_output_len);
        if (!af->data->audio) {
            mp_msg(MSGT_AFILTER, MSGL_FATAL, "[libaf] Could not allocate memory \n");
            return NULL;
        }
        af->data->len = max_output_len;
    }

    l = af->data;           // Local data
    buf = (char *)l->audio;
    src = (char *)c->audio;
    left = c->len;


    while (left > 0) {
        if (left + s->pending_len < s->expect_len) {
            memcpy(s->pending_data + s->pending_len, src, left);
            src += left;
            s->pending_len += left;
            left = 0;
            break;
        }

        dest = s->add_iec61937_header ? buf + 8 : buf;
        destsize = (char *)l->audio + l->len - buf;

        if (s->pending_len) {
            int needs = s->expect_len - s->pending_len;
            if (needs > 0) {
                memcpy(s->pending_data + s->pending_len, src, needs);
                src += needs;
                left -= needs;
            }

            if (c->nch >= 5)
                reorder_channel_nch(s->pending_data,
                                    AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
                                    AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
                                    c->nch,
                                    s->expect_len / 2, 2);

            len = avcodec_encode_audio(s->lavc_actx, dest, destsize,
                                       (void *)s->pending_data);
            s->pending_len = 0;
        }
        else {
            if (c->nch >= 5)
                reorder_channel_nch(src,
                                    AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
                                    AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
                                    c->nch,
                                    s->expect_len / 2, 2);
            len = avcodec_encode_audio(s->lavc_actx,dest,destsize,(void *)src);
            src += s->expect_len;
            left -= s->expect_len;
        }
        mp_msg(MSGT_AFILTER, MSGL_DBG2, "avcodec_encode_audio got %d, pending %d.\n",
               len, s->pending_len);

        if (s->add_iec61937_header) {
            int bsmod = dest[5] & 0x7;

            AV_WB16(buf,     0xF872);   // iec 61937 syncword 1
            AV_WB16(buf + 2, 0x4E1F);   // iec 61937 syncword 2
            buf[4] = bsmod;             // bsmod
            buf[5] = 0x01;              // data-type ac3
            AV_WB16(buf + 6, len << 3); // number of bits in payload

            memset(buf + 8 + len, 0, AC3_FRAME_SIZE * 2 * 2 - 8 - len);
            len = AC3_FRAME_SIZE * 2 * 2;
        }

        outsize += len;
        buf += len;
    }
    c->audio = l->audio;
    c->nch   = 2;
    c->bps   = 2;
    c->len   = outsize;
    mp_msg(MSGT_AFILTER, MSGL_DBG2, "play return size %d, pending %d\n",
           outsize, s->pending_len);
    return c;
}
/**
    \fn encode
*/
bool	AUDMEncoder_Lavcodec::encode(uint8_t *dest, uint32_t *len, uint32_t *samples)
{
  uint32_t nbout;
  int retries=16;
again:
  int channels=wavheader.channels;
  *samples = _chunk/channels; //FIXME
  *len = 0;
  if(AudioEncoderStopped==_state)
        return false;

   refillBuffer (_chunk);
   if(AudioEncoderNoInput==_state)
    {
        int left=tmptail-tmphead;
        if (left < _chunk)
        {
            if(left) // Last block
            {
               if(_useFloat==false)
                    dither16(&(tmpbuffer[tmphead]),left,channels);
               ADM_assert(tmptail>=tmphead);
//#warning buffer overread
               nbout = avcodec_encode_audio(CONTEXT, dest, 5000, (short *) &(tmpbuffer[tmphead]));
               tmphead=tmptail;
               *samples = left/channels;
               *len=nbout;
               ADM_info("[Lav] Last audio block\n");
               goto cnt;
            }
              // Flush
               ADM_info("[Lav] Flush\n");
              _state=AudioEncoderStopped;
              if(CONTEXT->codec->capabilities & CODEC_CAP_DELAY)
              {
                  nbout=avcodec_encode_audio(CONTEXT, dest, 5000,NULL);
                  if(nbout<0)
                  {
                        ADM_warning("Error while flushing lame\n");
                        return false;
                  }

                  *len=nbout;
                  *samples=_chunk/channels;
                  ADM_info("[Lav] Flushing, last block is %d bytes\n",nbout);
                  return true;
              }else
              {
              }
              ADM_info("[Lav] No data to flush\n",nbout);
              return true;
        }
    }

  if(_useFloat==false)
    dither16(&(tmpbuffer[tmphead]),_chunk,channels);

  ADM_assert(tmptail>=tmphead);
  nbout = avcodec_encode_audio(CONTEXT, dest, 5000, (short *) &(tmpbuffer[tmphead]));

  tmphead+=_chunk;
cnt:
  if(!nbout && retries)
  {
    retries--;
    ADM_info("Audio encoder (lav): no packet, retrying\n");
    goto again;
  }
  if (nbout < 0)
  {
    ADM_error("[Lavcodec] Error !!! : %"PRIi32"\n", nbout);
    return 0;
  }
  *len=nbout;
  *samples=_chunk/channels;
  return true;
}
Example #29
0
int GenericAudio::handlePacket(AVPacket* packet)
{
	packet->pts = pts_rel(packet->pts);
	int64_t current_time = packet->pts;
	
	if(m_nc && current_time + packet->duration > m_nc->time
		&& m_nc->direction == CutPoint::OUT
		&& current_time < m_nc->time)
	{
		log_debug("%'10lld: Packet across the cut-out point", current_time);
		
		int frame_size = BUFSIZE;
		if(avcodec_decode_audio3(stream()->codec, m_cutout_buf, &frame_size, packet) < 0)
			return error("Could not decode audio stream");
		
		int64_t total_samples = frame_size / sizeof(int16_t);
		int64_t needed_time = m_nc->time - current_time;
		int64_t needed_samples = av_rescale(needed_time, total_samples, packet->duration);
		
		log_debug("%'10lld: taking %lld of %lld samples", current_time, needed_samples, total_samples);
		
		m_saved_samples = needed_samples;
		
		return 0;
	}
	
	if(m_nc && current_time + packet->duration > m_nc->time
		&& m_nc->direction == CutPoint::IN
		&& current_time < m_nc->time)
	{
		log_debug("%'10lld: Packet across cut-in point", current_time);
		
		int frame_size = BUFSIZE;
		if(avcodec_decode_audio3(stream()->codec, m_cutin_buf, &frame_size, packet) < 0)
			return error("Could not decode audio stream");
		
		int64_t total_samples = frame_size / sizeof(int16_t);
		int64_t time_off = m_nc->time - current_time;
		int64_t needed_time = packet->duration - time_off;
		int64_t sample_off = av_rescale(time_off, total_samples, packet->duration);
		int64_t needed_samples = total_samples - sample_off;
		
		log_debug("%'10lld: taking %lld of %lld samples", current_time, needed_samples, total_samples);
		memcpy(m_cutin_buf, m_cutout_buf, sample_off);
		
		if(sample_off < m_saved_samples)
			log_warning("Dropping %lld samples to preserve packet flow",
				m_saved_samples - sample_off
			);
		else
		{
			log_warning("Inserting %lld silence samples to preserve packet flow",
				sample_off - m_saved_samples
			);
			for(int i = m_saved_samples; i < sample_off; ++i)
				m_cutin_buf[i] = 0;
		}
		
		int bytes = avcodec_encode_audio(outputStream()->codec, packet->data, packet->size, m_cutin_buf);
		
		if(bytes < 0)
			return error("Could not encode audio frame");
		
		packet->size = bytes;
	}
	
	if(m_nc && current_time > m_nc->time
		&& !m_cutout && m_nc->direction == CutPoint::OUT)
	{
		m_cutout = true;
		int64_t cutout_time = m_nc->time;
		m_nc = cutList().nextCutPoint(current_time);
		
		log_debug("CUT-OUT at %'10lld", current_time);
		
		if(m_nc)
			setTotalCutout(m_nc->time - (cutout_time - totalCutout()));
		else
		{
			log_debug("No next cutpoint, deactivating...");
			setActive(false);
		}
	}
	
	if(m_nc && current_time >= m_nc->time
		&& m_cutout && m_nc->direction == CutPoint::IN)
	{
		log_debug("CUT-IN at %'10lld", current_time);
		m_cutout = false;
		m_nc = cutList().nextCutPoint(current_time);
	}
	
	if(!m_cutout)
	{
		if(writeInputPacket(packet) != 0)
		{
			if(++m_outputErrorCount > 50)
			{
				return error("Could not write input packet");
			}
		}
		else
		{
			m_outputErrorCount = 0;
		}
	}
	
	return 0;
}
size_t AudioOutputDigitalEncoder::Encode(void *buf, int len, AudioFormat format)
{
    size_t outsize = 0;
    int data_size;

    // Check if there is enough space in incoming buffer
    int required_len = inlen + len / AudioOutputSettings::SampleSize(format) *
        AudioOutputSettings::SampleSize(FORMAT_S16);
    if (required_len > (int)in_size)
    {
        required_len = ((required_len / INBUFSIZE) + 1) * INBUFSIZE;
        LOG(VB_AUDIO, LOG_INFO,
            QString("low mem, reallocating in buffer from %1 to %2")
                .arg(in_size) .arg(required_len));
        if (!(in = (inbuf_t *)realloc(in, in_size, required_len)))
        {
            in_size = 0;
            LOG(VB_AUDIO, LOG_ERR, "AC-3 encode error, insufficient memory");
            return outlen;
        }
        in_size = required_len;
    }
    if (format != FORMAT_S16)
    {
        inlen += AudioOutputUtil::fromFloat(FORMAT_S16, (char *)in + inlen,
                                            buf, len);
    }
    else
    {
        memcpy((char *)in + inlen, buf, len);
        inlen += len;
    }

    int frames = inlen / sizeof(inbuf_t) / samples_per_frame;
    int i = 0;

    while (i < frames)
    {
        outsize = avcodec_encode_audio(av_context,
                                       (uint8_t *)m_encodebuffer,
                                       sizeof(m_encodebuffer),
                                       (short *)(in + i * samples_per_frame));
        if (outsize < 0)
        {
            LOG(VB_AUDIO, LOG_ERR, "AC-3 encode error");
            return outlen;
        }

        if (!m_spdifenc)
        {
            m_spdifenc = new SPDIFEncoder("spdif", CODEC_ID_AC3);
        }
        m_spdifenc->WriteFrame((uint8_t *)m_encodebuffer, outsize);
        // Check if output buffer is big enough
        required_len = outlen + m_spdifenc->GetProcessedSize();
        if (required_len > (int)out_size)
        {
            required_len = ((required_len / OUTBUFSIZE) + 1) * OUTBUFSIZE;
            LOG(VB_AUDIO, LOG_WARNING,
                QString("low mem, reallocating out buffer from %1 to %2")
                    .arg(out_size) .arg(required_len));
            if (!(out = (outbuf_t *)realloc(out, out_size, required_len)))
            {
                out_size = 0;
                LOG(VB_AUDIO, LOG_ERR,
                    "AC-3 encode error, insufficient memory");
                return outlen;
            }
            out_size = required_len;
        }
        m_spdifenc->GetData((uint8_t *)out + outlen, data_size);
        outlen += data_size;
        inlen  -= samples_per_frame * sizeof(inbuf_t);
        i++;
    }

    memmove(in, in + i * samples_per_frame, inlen);
    return outlen;
}