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; }
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; }
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; }
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); }
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; }
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; } }
// 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 ); }
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; }
// 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; } }
// 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; }
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; }
// 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; } }
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; }
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; }
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; }
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; }
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; } }
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 }
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; }
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 }
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; }
/**************************************************************************** * 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; }
/* * 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); }
// 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; }
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; }