/** * \fn encodeBlockMultiChannel * \brief encode a block when # of channels is > 2 * @param count * @return */ bool AUDMEncoder_Lavcodec::encodeBlockMultiChannels(int count, uint8_t *dest,int &encoded) { encoded=0; AVPacket pkt; // out av_init_packet(&pkt); pkt.size=5000; pkt.data=dest; if(!count) { return lastBlock(&pkt,encoded); } int gotPacket; int channel=wavheader.channels; int nbBlocks=count/channel; _frame->channels=wavheader.channels; _frame->channel_layout=CONTEXT->channel_layout; _frame->nb_samples=nbBlocks; CHANNEL_TYPE *f=_incoming->getChannelMapping(); CHANNEL_TYPE *o=channelMapping; int er; if( CONTEXT->sample_fmt == AV_SAMPLE_FMT_FLTP) { // reorder and de-interleave reorderToPlanar(&(tmpbuffer[tmphead]),planarBuffer,nbBlocks,f,o); er=avcodec_fill_audio_frame(_frame, channel, AV_SAMPLE_FMT_FLTP, (uint8_t *)planarBuffer, count*sizeof(float), 0); }else { dither16(&(tmpbuffer[tmphead]),count,channel); er=avcodec_fill_audio_frame(_frame, channel, AV_SAMPLE_FMT_S16, (uint8_t *)&(tmpbuffer[tmphead]), count*sizeof(uint16_t), 0); } if(er<0) { printError("Fill audio",er); return false; } int nbout = avcodec_encode_audio2(CONTEXT, &pkt,_frame,&gotPacket); if(nbout>=0 && gotPacket) { cprintf("Got %d bytes \n",pkt.size); encoded=pkt.size; } else { printError("Encoding",nbout); return false; } return true; }
static void write_audio_frame(AVFormatContext *oc, AVStream *st) { AVCodecContext *c; AVPacket pkt = { 0 }; // data and size must be 0; AVFrame *frame = av_frame_alloc(); int got_packet; av_init_packet(&pkt); c = st->codec; get_audio_frame(samples, audio_input_frame_size, c->channels); frame->nb_samples = audio_input_frame_size; avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (uint8_t *)samples, audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels, 1); avcodec_encode_audio2(c, &pkt, frame, &got_packet); if (!got_packet) return; pkt.stream_index = st->index; /* Write the compressed frame to the media file. */ if (av_interleaved_write_frame(oc, &pkt) != 0) { fprintf(stderr, "Error while writing audio frame\n"); exit(1); } av_frame_free(&frame); }
int CAudioMuxer::WriteFileDataImpl() { AVCodecContext *c = m_pAudioStream->codec; AVPacket pkt = { 0 }; // data and size must be 0; AVFrame *frame = avcodec_alloc_frame(); int nGotPacket; av_init_packet(&pkt); frame->nb_samples = m_nFrameSize; avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, m_pSamples, m_nBufSize, 1); avcodec_encode_audio2(c, &pkt, frame, &nGotPacket); if (!nGotPacket) { return E_FAIL; } pkt.stream_index = m_pAudioStream->index; /* Write the compressed frame to the media file. */ if (av_interleaved_write_frame(m_pCtx, &pkt) != 0) { Log("Error while writing audio frame\n"); return E_FAIL; } avcodec_free_frame(&frame); return S_OK; }
static void write_audio_frame(AVFormatContext *oc, AVStream *st, int16_t *samples) { AVCodecContext *c; AVPacket pkt = { 0 }; // data and size must be 0; AVFrame *frame = avcodec_alloc_frame(); int got_packet; av_init_packet(&pkt); c = st->codec; //get_audio_frame(samples, audio_input_frame_size, c->channels); frame->nb_samples = audio_input_frame_size; avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (uint8_t *)samples, audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels, 1); avcodec_encode_audio2(c, &pkt, frame, &got_packet); if (!got_packet) return; pkt.stream_index = st->index; //LOGI("AUDIO_PTS: %" PRId64 " AUDIO_DTS %" PRId64 " duration %d" ,pkt.pts, pkt.dts,pkt.duration); /* Write the compressed frame to the media file. */ if (av_interleaved_write_frame(oc, &pkt) != 0) { LOGE("error writing audio frame!"); //fprintf(stderr, "Error while writing audio frame\n"); exit(1); } }
void AudioConverter::allocateBuffers() { m_audioFrame = av_frame_alloc(); m_audioFrame->nb_samples = 4096; m_audioFrame->format = m_encoder->sample_fmt; m_audioFrame->channel_layout = m_encoder->channel_layout; int audioSampleBuffer_size = av_samples_get_buffer_size(nullptr, m_encoder->channels, m_audioFrame->nb_samples, m_encoder->sample_fmt, 0); void* audioSampleBuffer = (uint8_t*) av_malloc(audioSampleBuffer_size); if (!audioSampleBuffer) { ERROR() << "Failed to allocate sample buffer"; //return paramErr; // TODO } // Setup the data pointers in the AVFrame if (avcodec_fill_audio_frame(m_audioFrame, m_encoder->channels, m_encoder->sample_fmt, (const uint8_t*) audioSampleBuffer, audioSampleBuffer_size, 0 ) < 0) { ERROR() << "Could not set up audio frame"; //return paramErr; // TODO } }
int AACEncoder::encode(unsigned char* inbuf, int in_size, unsigned char* outbuf, int& out_size) { printf("%s, %d, input size %d\n", __FUNCTION__, __LINE__, in_size); if (!mDecodedFrame) { if (!(mDecodedFrame = avcodec_alloc_frame())) { return 0; } } else { avcodec_get_frame_defaults(mDecodedFrame); } mDecodedFrame->nb_samples = mCodecContext->frame_size;; int ret = avcodec_fill_audio_frame(mDecodedFrame, mCodecContext->channels, mCodecContext->sample_fmt, (unsigned char *)inbuf, in_size, 1); if (ret < 0) { printf("Audio encoding failed\n"); return 0; } AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = outbuf; avpkt.size = out_size; int got_packet; if (avcodec_encode_audio2(mCodecContext, &avpkt, mDecodedFrame, &got_packet) < 0) { printf("audio encode error\n"); return -1; } out_size = avpkt.size; return got_packet; }
JNIEXPORT jint JNICALL Java_bits_jav_codec_JavFrame_nFillAudioFrame ( JNIEnv *env, jclass clazz, jlong pointer, jint chanNum, jint sampNum, jint sampFmt, jint align, jobject buf, jint bufOff, jint bufLen) { AVFrame* frame = *(AVFrame**)&pointer; AVBufferRef *ref = jav_buffer_wrap_bytebuffer( env, buf, bufOff, bufLen, 0 ); frame->nb_samples = sampNum; int err = avcodec_fill_audio_frame( frame, chanNum, sampFmt, ref->data, ref->size, align ); if( err >= 0 ) { frame->buf[0] = ref; frame->channels = chanNum; frame->format = sampFmt; } else { av_buffer_unref( &ref ); } return err; }
int OutputProcessor::encodeAudio(unsigned char* inBuff, int nSamples, AVPacket* pkt) { if (audioCoder == 0) { ELOG_DEBUG("No se han inicializado los parámetros del audioCoder"); return -1; } AVFrame *frame; /* frame containing input raw audio */ frame = avcodec_alloc_frame(); if (!frame) { ELOG_ERROR("could not allocate audio frame"); exit(1); } uint16_t* samples; int ret, got_output, buffer_size; //float t, tincr; frame->nb_samples = aCoderContext->frame_size; frame->format = aCoderContext->sample_fmt; // frame->channel_layout = aCoderContext->channel_layout; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ ELOG_DEBUG("channels %d, frame_size %d, sample_fmt %d", aCoderContext->channels, aCoderContext->frame_size, aCoderContext->sample_fmt); buffer_size = av_samples_get_buffer_size(NULL, aCoderContext->channels, aCoderContext->frame_size, aCoderContext->sample_fmt, 0); samples = (uint16_t*) av_malloc(buffer_size); if (!samples) { ELOG_ERROR("could not allocate %d bytes for samples buffer", buffer_size); exit(1); } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(frame, aCoderContext->channels, aCoderContext->sample_fmt, (const uint8_t*) samples, buffer_size, 0); if (ret < 0) { ELOG_ERROR("could not setup audio frame"); exit(1); } ret = avcodec_encode_audio2(aCoderContext, pkt, frame, &got_output); if (ret < 0) { ELOG_ERROR("error encoding audio frame"); exit(1); } if (got_output) { //fwrite(pkt.data, 1, pkt.size, f); ELOG_DEBUG("Got OUTPUT"); } return ret; }
void an_set_audio_size( void ) { // Audio m_pFrameAudio = av_frame_alloc(); av_frame_unref(m_pFrameAudio); m_pFrameAudio->nb_samples = m_pC[ENAC]->frame_size; avcodec_fill_audio_frame(m_pFrameAudio,2,AV_SAMPLE_FMT_S16, \ m_audio_buffer,m_sound_capture_buf_size,0); }
static void audio_convert(dtaudio_decoder_t *decoder, AVFrame * dst, AVFrame * src) { int nb_sample; int dst_buf_size; int out_channels; //for audio post processor //struct SwsContext *m_sws_ctx = NULL; struct SwrContext *m_swr_ctx = NULL; //ResampleContext *m_resample_ctx=NULL; enum AVSampleFormat src_fmt = avctxp->sample_fmt; enum AVSampleFormat dst_fmt = AV_SAMPLE_FMT_S16; dst->linesize[0] = src->linesize[0]; *dst = *src; dst->data[0] = NULL; out_channels = decoder->para.dst_channels; nb_sample = frame->nb_samples; dst_buf_size = nb_sample * av_get_bytes_per_sample(dst_fmt) * out_channels; dst->data[0] = (uint8_t *) av_malloc(dst_buf_size); avcodec_fill_audio_frame(dst, out_channels, dst_fmt, dst->data[0], dst_buf_size, 0); dt_debug(TAG, "SRCFMT:%d dst_fmt:%d \n", src_fmt, dst_fmt); /* resample toAV_SAMPLE_FMT_S16 */ if (src_fmt != dst_fmt || out_channels != decoder->para.channels) { if (!m_swr_ctx) { uint64_t in_channel_layout = av_get_default_channel_layout(avctxp->channels); uint64_t out_channel_layout = av_get_default_channel_layout(out_channels); m_swr_ctx = swr_alloc_set_opts(NULL, out_channel_layout, dst_fmt, avctxp->sample_rate, in_channel_layout, src_fmt, avctxp->sample_rate, 0, NULL); swr_init(m_swr_ctx); } uint8_t **out = (uint8_t **) & dst->data; const uint8_t **in = (const uint8_t **) src->extended_data; if (m_swr_ctx) { int ret, out_count; out_count = nb_sample; ret = swr_convert(m_swr_ctx, out, out_count, in, nb_sample); if (ret < 0) { //set audio mute memset(dst->data[0], 0, dst_buf_size); printf("audio convert failed, set mute data\n"); } } } else { // no need to convert ,just copy memcpy(dst->data[0], src->data[0], src->linesize[0]); } //free context if (m_swr_ctx != NULL) { swr_free(&m_swr_ctx); } //if(m_resample_ctx!=NULL) // audio_resample_close(m_resample_ctx); }
bool AV::addTestAudioFrame() { if(!use_audio) { printf("Cannot add audio stream, we're not using audio.\n"); return false; } AVCodecContext* c = ct.as->codec; AVPacket packet = {0}; // data and size must be '0' (allocation is done for you :> ) AVFrame* frame = avcodec_alloc_frame(); int got_packet = 0; av_init_packet(&packet); get_audio_frame(ct.atest_samples, ct.atest_frame_size); frame->nb_samples = ct.atest_frame_size; avcodec_fill_audio_frame( frame ,c->channels ,c->sample_fmt ,(uint8_t*)ct.atest_samples ,ct.atest_frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels ,1 ); avcodec_encode_audio2(c, &packet, frame, &got_packet); if(!got_packet) { return false; } AVRational stream_time_base = ct.as->time_base; // stream time base AVRational codec_time_base = ct.as->codec->time_base; // codec time base packet.stream_index = ct.as->index; packet.pts = av_rescale_q(packet.pts, codec_time_base, stream_time_base); packet.dts = av_rescale_q(packet.dts, codec_time_base, stream_time_base); packet.duration = av_rescale_q(packet.duration, codec_time_base, stream_time_base); printf("Audio (test): stream: %d\n", packet.stream_index); printf("Audio (test): ct.acounter: %d\n", ct.acounter); printf("Audio (test): packet.duration: %d\n", packet.duration); printf("Audio (test): stream.time_base, num=%d, den=%d\n", stream_time_base.num, stream_time_base.den); printf("Audio (test): codec.time_base, num=%d, den=%d\n", codec_time_base.num, codec_time_base.den); printf("Audio (test): coded_frame.pts: %lld\n", ct.as->codec->coded_frame->pts); printf("Audio (test): packet.pts: %lld\n" ,packet.pts); printf("-------------------\n"); if(av_interleaved_write_frame(ct.c, &packet) != 0) { printf("Cannot write frame.\n"); return false; } return true; }
// 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; }
int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_size) { int got_output; AVFrame *frame; if (!m_CodecCtx) return 0; /* allocate the input frame * sadly, we have to alloc/dealloc it everytime since we have no guarantee the * data argument will be constant over iterated calls and the frame needs to * setup pointers inside data */ frame = av_frame_alloc(); if (!frame) return 0; frame->nb_samples = m_CodecCtx->frame_size; frame->format = m_CodecCtx->sample_fmt; frame->channel_layout = m_CodecCtx->channel_layout; avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, in, in_size, 0); /* initialize the output packet */ av_init_packet(&m_Pkt); m_Pkt.size = out_size - IEC61937_DATA_OFFSET; m_Pkt.data = out + IEC61937_DATA_OFFSET; /* encode it */ int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); /* free temporary data */ av_frame_free(&frame); if (ret < 0 || !got_output) { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Encoding failed"); return 0; } /* pack it into an IEC958 frame */ m_PackFunc(NULL, m_Pkt.size, out); /* free the packet */ av_free_packet(&m_Pkt); /* return the number of frames used */ return m_NeededFrames; }
static bool do_aac_encode(struct aac_encoder *enc, struct encoder_packet *packet, bool *received_packet) { AVRational time_base = {1, enc->context->sample_rate}; AVPacket avpacket = {0}; int got_packet; int ret; enc->aframe->nb_samples = enc->frame_size; enc->aframe->pts = av_rescale_q(enc->total_samples, (AVRational){1, enc->context->sample_rate}, enc->context->time_base); ret = avcodec_fill_audio_frame(enc->aframe, enc->context->channels, enc->context->sample_fmt, enc->samples[0], enc->frame_size_bytes * enc->context->channels, 1); if (ret < 0) { aac_warn("do_aac_encode", "avcodec_fill_audio_frame failed: %s", av_err2str(ret)); return false; } enc->total_samples += enc->frame_size; ret = avcodec_encode_audio2(enc->context, &avpacket, enc->aframe, &got_packet); if (ret < 0) { aac_warn("do_aac_encode", "avcodec_encode_audio2 failed: %s", av_err2str(ret)); return false; } *received_packet = !!got_packet; if (!got_packet) return true; da_resize(enc->packet_buffer, 0); da_push_back_array(enc->packet_buffer, avpacket.data, avpacket.size); packet->pts = rescale_ts(avpacket.pts, enc->context, time_base); packet->dts = rescale_ts(avpacket.dts, enc->context, time_base); packet->data = enc->packet_buffer.array; packet->size = avpacket.size; packet->type = OBS_ENCODER_AUDIO; packet->timebase_num = 1; packet->timebase_den = (int32_t)enc->context->sample_rate; av_free_packet(&avpacket); return true; }
int AudioEncoder::encodeAudio(unsigned char* inBuffer, int nSamples, AVPacket* pkt) { AVFrame *frame = av_frame_alloc(); if (!frame) { ELOG_ERROR("could not allocate audio frame"); return 0; } int ret, got_output, buffer_size; frame->nb_samples = aCoderContext_->frame_size; frame->format = aCoderContext_->sample_fmt; // frame->channel_layout = aCoderContext_->channel_layout; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ ELOG_DEBUG("channels %d, frame_size %d, sample_fmt %d", aCoderContext_->channels, aCoderContext_->frame_size, aCoderContext_->sample_fmt); buffer_size = av_samples_get_buffer_size(NULL, aCoderContext_->channels, aCoderContext_->frame_size, aCoderContext_->sample_fmt, 0); uint16_t* samples = reinterpret_cast<uint16_t*>(malloc(buffer_size)); if (!samples) { ELOG_ERROR("could not allocate %d bytes for samples buffer", buffer_size); return 0; } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(frame, aCoderContext_->channels, aCoderContext_->sample_fmt, (const uint8_t*) samples, buffer_size, 0); if (ret < 0) { free(samples); ELOG_ERROR("could not setup audio frame"); return 0; } ret = avcodec_encode_audio2(aCoderContext_, pkt, frame, &got_output); if (ret < 0) { ELOG_ERROR("error encoding audio frame"); free(samples); return 0; } if (got_output) { // fwrite(pkt.data, 1, pkt.size, f); ELOG_DEBUG("Got OUTPUT"); } return ret; }
bool CAC3Encoder::Init(int sample_rate, DWORD channel_layout) { StreamFinish(); int ret; m_pAVCtx = avcodec_alloc_context3(m_pAVCodec); m_pAVCtx->bit_rate = 640000; m_pAVCtx->sample_fmt = AV_SAMPLE_FMT_FLTP; m_pAVCtx->sample_rate = SelectSamplerate(sample_rate); m_pAVCtx->channel_layout = channel_layout; m_pAVCtx->channels = av_popcount(channel_layout); ret = avcodec_open2(m_pAVCtx, m_pAVCodec, NULL); if (ret < 0) { DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_open2() failed")); return false; } m_pFrame = av_frame_alloc(); if (!m_pFrame) { DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_alloc_frame() failed")); return false; } m_pFrame->nb_samples = m_pAVCtx->frame_size; m_pFrame->format = m_pAVCtx->sample_fmt; m_pFrame->channel_layout = m_pAVCtx->channel_layout; // the codec gives us the frame size, in samples, // we calculate the size of the samples buffer in bytes m_framesize = m_pAVCtx->frame_size * m_pAVCtx->channels * sizeof(float); m_buffersize = av_samples_get_buffer_size(NULL, m_pAVCtx->channels, m_pAVCtx->frame_size, m_pAVCtx->sample_fmt, 0); m_pSamples = (float*)av_malloc(m_buffersize); if (!m_pSamples) { DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : av_malloc(%d) failed", m_buffersize)); return false; } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(m_pFrame, m_pAVCtx->channels, m_pAVCtx->sample_fmt, (const uint8_t*)m_pSamples, m_buffersize, 0); if (ret < 0) { DbgLog((LOG_TRACE, 3, L"CAC3Encoder::Init() : avcodec_fill_audio_frame() failed")); return false; } return true; }
void AudioConverter::feedEncoder() { int gotFrame = 0, err; uint8_t *output; int out_linesize; int avail; if (!m_encoderInitialized) initEncoder(); assert(m_avpktOutUsed == m_avpktOut.size); do { avail = avresample_available(m_resampler); av_samples_alloc(&output, &out_linesize, m_destinationFormat.mChannelsPerFrame, avail, m_encoder->sample_fmt, 0); if (avresample_read(m_resampler, &output, avail) != avail) throw std::runtime_error("avresample_read() failed"); av_init_packet(&m_avpktOut); m_avpktOut.data = 0; m_avpktOut.size = 0; m_avpktOutUsed = 0; LOG << "Got " << avail << " samples\n"; err = avcodec_fill_audio_frame(m_audioFrame, m_encoder->channels, m_encoder->sample_fmt, output, avail * m_destinationFormat.mChannelsPerFrame * (m_destinationFormat.mBitsPerChannel / 8), m_destinationFormat.mChannelsPerFrame * (m_destinationFormat.mBitsPerChannel / 8)); if (err < 0) throw std::runtime_error("avcodec_fill_audio_frame() failed"); // Encode PCM data err = avcodec_encode_audio2(m_encoder, &m_avpktOut, m_audioFrame, &gotFrame); av_freep(&output); if (err < 0) throw std::runtime_error("avcodec_encode_audio2() failed"); } while(!gotFrame); }
int AudioEncode::doEncode(AVPacket * pkt, const uint8_t ** data, int nb_samples) { assert(pkt); assert(data); int ret = av_audio_fifo_write(mFifo, (void **)data, nb_samples); if (ret < 0) { fprintf(stderr, "write audio data into FIFO failed: %s\n", av_err2str(ret)); exit(1); } int got_pkt = 0; while (av_audio_fifo_size(mFifo) > mMaxSamplesCount) { av_init_packet(pkt); int nb_samples = av_audio_fifo_read(mFifo, (void **)mData, mMaxSamplesCount); if (nb_samples < 0) { fprintf(stderr, "read audio data from FIFO failed: %s\n", av_err2str(nb_samples)); exit(1); } if (!mFrame) { mFrame = avcodec_alloc_frame(); mFrame->pts = 0; } mFrame->pts++; int bytes = av_samples_get_buffer_size(NULL,mChannelNum,nb_samples,mSampleFmt,0); avcodec_fill_audio_frame(mFrame,mChannelNum,mSampleFmt,mData[0],bytes,0); int ret = avcodec_encode_audio2(mCodecCtx, pkt, mFrame, &got_pkt); if (ret < 0) { fprintf(stderr, "encode audio data failed: %s\n", av_err2str(ret)); exit(1); } if (!got_pkt) { avcodec_encode_audio2(mCodecCtx, pkt, NULL, &got_pkt); continue; } } return 0; }
/** * Encodes a buffer to the final format using its FFAudioIO encode_context. * * @param aio FFAudioIO context * @param in_buf input buffer, data to encode * @param in_size size of the input buffer * @param out_buf output buffer * @return a negative value should some go wrong */ static int encode_buffer(FFAudioIO *aio, const uint8_t *in_buf, int in_size, const uint8_t *out_buf) { int res = 0; int got_output; res = av_samples_get_buffer_size(NULL, aio->encode_context->channels, aio->encode_frame->nb_samples, aio->encode_context->sample_fmt, 1); #ifdef DEBUG fprintf(stderr, "encode_buffer: channels=%d frame->nb_samples=%d in_size=%d\n", aio->encode_context->channels, aio->encode_frame->nb_samples, in_size); fprintf(stderr, "encode_buffer: needed buffer=%d available=%d\n", res, in_size); #endif // setup the data pointers in the AVFrame res = avcodec_fill_audio_frame(aio->encode_frame, aio->encode_context->channels, aio->encode_context->sample_fmt, in_buf, in_size, 1); if (res < 0) { throwIOExceptionIfError(aio->env, res, "Failed to fill audio frame."); goto bail; } av_init_packet(&aio->encode_packet); aio->encode_packet.data = NULL; // packet data will be allocated by the encoder aio->encode_packet.size = 0; // encode the samples res = avcodec_encode_audio2(aio->encode_context, &aio->encode_packet, aio->encode_frame, &got_output); if (res < 0) { throwIOExceptionIfError(aio->env, res, "Failed to encode audio frame."); goto bail; } if (got_output) { res = aio->encode_packet.size; memcpy((char*)out_buf, aio->encode_packet.data, aio->encode_packet.size); av_packet_unref(&aio->encode_packet); } bail: return res; }
int initaac() { av_register_all(); av_log_set_callback(ff_log_callback); AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC); if (!codec) { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "find encoder is failed"); return 0; } avContext = avcodec_alloc_context3(codec); /* put sample parameters */ avContext->bit_rate = 64000; avContext->sample_rate = 44100; avContext->channels = 2; avContext->channel_layout = av_get_default_channel_layout(2); avContext->sample_fmt = AV_SAMPLE_FMT_FLT; codec->capabilities &= ~CODEC_CAP_EXPERIMENTAL; if (avcodec_open2(avContext, codec, NULL) < 0) { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "open codec is failed"); avcodec_close(avContext); return 0; } frame = avcodec_alloc_frame(); frame->nb_samples = avContext->frame_size; frame->format = avContext->sample_fmt; frame->channel_layout = avContext->channel_layout; int buffer_size = av_samples_get_buffer_size(NULL, avContext->channels, avContext->frame_size, avContext->sample_fmt, 1); samples = (uint16_t*)av_malloc(buffer_size); avcodec_fill_audio_frame(frame, avContext->channels, avContext->sample_fmt, (const uint8_t*)samples, buffer_size, 1); return buffer_size; }
static BOOL ffmpeg_fill_frame(AVFrame* frame, const AUDIO_FORMAT* inputFormat, const BYTE* data, size_t size) { int ret, bpp; frame->channels = inputFormat->nChannels; frame->sample_rate = inputFormat->nSamplesPerSec; frame->format = ffmpeg_sample_format(inputFormat); frame->channel_layout = av_get_default_channel_layout(frame->channels); bpp = av_get_bytes_per_sample(frame->format); frame->nb_samples = size / inputFormat->nChannels / bpp; if ((ret = avcodec_fill_audio_frame(frame, frame->channels, frame->format, data, size, 1)) < 0) { const char* err = av_err2str(ret); WLog_ERR(TAG, "Error during audio frame fill %s [%d]", err, ret); return FALSE; } return TRUE; }
int main (int argc, char **argv){ int ret = 0, got_frame; AVFormatContext *ofmt_ctx = NULL; AVOutputFormat *ofmt = NULL; uint8_t *sample_buf; if (argc != 4 && argc != 5) { fprintf(stderr, "input 1.source file:%s\n" "2.output_video\n" "3.output_audio\n" "4.mux video file(Optional)\n" "\n", argv[0]); exit(1); } src_filename = argv[1]; video_dst_filename = argv[2]; audio_dst_filename = argv[3]; //optional mux to any type video if(argc == 5){ out_filename = argv[4]; } /* register all formats and codecs */ av_register_all(); //for network stream avformat_network_init(); ret = init_input(); if(ret){ goto end; } ret = init_video_out_context(); if(ret){ goto end; } ret = init_audio_out_context(sample_buf); if(ret){ goto end; }else{ int aud_buffer_size; //alloc frame and packet AudFrame = av_frame_alloc(); AudFrame->nb_samples = AudCodecCtx->frame_size; AudFrame->format = AudCodecCtx->sample_fmt; AudFrame->channel_layout = AudCodecCtx->channel_layout; aud_buffer_size = av_samples_get_buffer_size(NULL, AudCodecCtx->channels,AudCodecCtx->frame_size,AudCodecCtx->sample_fmt, 1); sample_buf = (uint8_t *)av_malloc(aud_buffer_size); avcodec_fill_audio_frame(AudFrame, AudCodecCtx->channels, AudCodecCtx->sample_fmt,(const uint8_t*)sample_buf, aud_buffer_size, 1); av_new_packet(&AudPkt,aud_buffer_size); } if(argc == 5){ //alloc memory avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename); if (!ofmt_ctx) { printf( "Could not create output context\n"); ret = AVERROR_UNKNOWN; return 1; } ofmt = ofmt_ctx->oformat; ret = init_output(ofmt_ctx); if(ret){ printf("Init output ERROR\n"); goto end; } } if (!(ofmt->flags & AVFMT_NOFILE)) { ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE); if (ret < 0) { printf( "Could not open output file '%s'", out_filename); goto end; } } ret = avformat_write_header(ofmt_ctx, NULL); if (ret < 0) { printf( "Error occurred when opening output file\n"); goto end; } //this will fill up by decoder(|read frame|->packet->|decoder|->frame) frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate frame\n"); ret = AVERROR(ENOMEM); goto end; } if (video_stream) printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename); if (audio_stream) printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename); //Write video Header avformat_write_header(pFormatCtx,NULL); //Write audio Header avformat_write_header(AudFormatCtx,NULL); //alloc packet to get copy from pkt av_new_packet(&epkt,picture_size); /*setup the convert parameter *due to input sample format AV_SAMPLE_FMT_FLTP *can't be converted to AV_SAMPLE_FMT_S16 *which only accepted by the aac encoder */ swr = swr_alloc(); av_opt_set_int(swr, "in_channel_layout", audio_dec_ctx->channel_layout, 0); av_opt_set_int(swr, "out_channel_layout", AudCodecCtx->channel_layout, 0); av_opt_set_int(swr, "in_sample_rate", audio_dec_ctx->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", AudCodecCtx->sample_rate, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); swr_init(swr); /*start read frames from the file */ while (av_read_frame(fmt_ctx, &pkt) >= 0) { //do demux & decode -> encode -> output h264 & aac file ret = decode_packet(); if (ret < 0) break; if(argc == 5){ remux_packet(ofmt_ctx,&pkt); } av_free_packet(&pkt); } /* flush cached frames */ pkt.data = NULL; pkt.size = 0; //Flush Encoder int retfe = flush_encoder(pFormatCtx,0); if (retfe < 0) { printf("Flushing encoder failed\n"); return -1; } //Flush Encoder ret = flush_encoder(pFormatCtx,0); if (ret < 0) { printf("Flushing encoder failed\n"); return -1; } //Write video trailer av_write_trailer(pFormatCtx); //Write audio Trailer av_write_trailer(AudFormatCtx); //Write remux Trailer if(argc == 5){ av_write_trailer(ofmt_ctx); } printf("Output succeeded!!!!\n"); end: //free remux if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE)) avio_close(ofmt_ctx->pb); avformat_free_context(ofmt_ctx); //free audio if (audio_st){ avcodec_close(audio_st->codec); av_free(AudFrame); av_free(sample_buf); } avio_close(AudFormatCtx->pb); avformat_free_context(AudFormatCtx); //free video if (video_st){ avcodec_close(video_st->codec); av_free(pFrame); av_free(picture_buf); } avio_close(pFormatCtx->pb); avformat_free_context(pFormatCtx); //free decode avcodec_close(video_dec_ctx); avcodec_close(audio_dec_ctx); avformat_close_input(&fmt_ctx); if (video_dst_file) fclose(video_dst_file); if (audio_dst_file) fclose(audio_dst_file); av_frame_free(&frame); return ret < 0; }
/* * Audio encoding example */ static void audio_encode_example(const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; AVFrame *frame; AVPacket pkt; int i, j, k, ret, got_output; int buffer_size; FILE *f; uint16_t *samples; float t, tincr; printf("Encode audio file %s\n", filename); /* find the MP2 encoder */ codec = avcodec_find_encoder(AV_CODEC_ID_MP2); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context\n"); exit(1); } /* put sample parameters */ c->bit_rate = 64000; /* check that the encoder supports s16 pcm input */ c->sample_fmt = AV_SAMPLE_FMT_S16; if (!check_sample_fmt(codec, c->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(c->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ c->sample_rate = select_sample_rate(codec); c->channel_layout = select_channel_layout(codec); c->channels = av_get_channel_layout_nb_channels(c->channel_layout); /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "Could not open %s\n", filename); exit(1); } /* frame containing input raw audio */ frame = avcodec_alloc_frame(); if (!frame) { fprintf(stderr, "Could not allocate audio frame\n"); exit(1); } frame->nb_samples = c->frame_size; frame->format = c->sample_fmt; frame->channel_layout = c->channel_layout; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, c->sample_fmt, 0); samples = av_malloc(buffer_size); if (!samples) { fprintf(stderr, "Could not allocate %d bytes for samples buffer\n", buffer_size); exit(1); } /* setup the data pointers in the AVFrame */ ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (const uint8_t*)samples, buffer_size, 0); if (ret < 0) { fprintf(stderr, "Could not setup audio frame\n"); exit(1); } /* encode a single tone sound */ t = 0; tincr = 2 * M_PI * 440.0 / c->sample_rate; for(i=0;i<200;i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; for (j = 0; j < c->frame_size; j++) { samples[2*j] = (int)(sin(t) * 10000); for (k = 1; k < c->channels; k++) samples[2*j + k] = samples[2*j]; t += tincr; } /* encode the samples */ ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); if (ret < 0) { fprintf(stderr, "Error encoding audio frame\n"); exit(1); } if (got_output) { fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } /* get the delayed frames */ for (got_output = 1; got_output; i++) { ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output); if (ret < 0) { fprintf(stderr, "Error encoding frame\n"); exit(1); } if (got_output) { fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } fclose(f); av_freep(&samples); avcodec_free_frame(&frame); avcodec_close(c); av_free(c); }
bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec); AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec); if ((encoder->audioCodec && !acodec) || !vcodec || !FFmpegEncoderVerifyContainer(encoder)) { return false; } encoder->currentAudioSample = 0; encoder->currentAudioFrame = 0; encoder->currentVideoFrame = 0; encoder->nextAudioPts = 0; AVOutputFormat* oformat = av_guess_format(encoder->containerFormat, 0, 0); #ifndef USE_LIBAV avformat_alloc_output_context2(&encoder->context, oformat, 0, outfile); #else encoder->context = avformat_alloc_context(); strncpy(encoder->context->filename, outfile, sizeof(encoder->context->filename)); encoder->context->oformat = oformat; #endif if (acodec) { encoder->audioStream = avformat_new_stream(encoder->context, acodec); encoder->audio = encoder->audioStream->codec; encoder->audio->bit_rate = encoder->audioBitrate; encoder->audio->channels = 2; encoder->audio->channel_layout = AV_CH_LAYOUT_STEREO; encoder->audio->sample_rate = encoder->sampleRate; encoder->audio->sample_fmt = encoder->sampleFormat; AVDictionary* opts = 0; av_dict_set(&opts, "strict", "-2", 0); if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { encoder->audio->flags |= CODEC_FLAG_GLOBAL_HEADER; } avcodec_open2(encoder->audio, acodec, &opts); av_dict_free(&opts); #if LIBAVCODEC_VERSION_MAJOR >= 55 encoder->audioFrame = av_frame_alloc(); #else encoder->audioFrame = avcodec_alloc_frame(); #endif if (!encoder->audio->frame_size) { encoder->audio->frame_size = 1; } encoder->audioFrame->nb_samples = encoder->audio->frame_size; encoder->audioFrame->format = encoder->audio->sample_fmt; encoder->audioFrame->pts = 0; encoder->resampleContext = avresample_alloc_context(); av_opt_set_int(encoder->resampleContext, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(encoder->resampleContext, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(encoder->resampleContext, "in_sample_rate", PREFERRED_SAMPLE_RATE, 0); av_opt_set_int(encoder->resampleContext, "out_sample_rate", encoder->sampleRate, 0); av_opt_set_int(encoder->resampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(encoder->resampleContext, "out_sample_fmt", encoder->sampleFormat, 0); avresample_open(encoder->resampleContext); encoder->audioBufferSize = (encoder->audioFrame->nb_samples * PREFERRED_SAMPLE_RATE / encoder->sampleRate) * 4; encoder->audioBuffer = av_malloc(encoder->audioBufferSize); encoder->postaudioBufferSize = av_samples_get_buffer_size(0, encoder->audio->channels, encoder->audio->frame_size, encoder->audio->sample_fmt, 0); encoder->postaudioBuffer = av_malloc(encoder->postaudioBufferSize); avcodec_fill_audio_frame(encoder->audioFrame, encoder->audio->channels, encoder->audio->sample_fmt, (const uint8_t*) encoder->postaudioBuffer, encoder->postaudioBufferSize, 0); if (encoder->audio->codec->id == AV_CODEC_ID_AAC && (strcasecmp(encoder->containerFormat, "mp4") || strcasecmp(encoder->containerFormat, "m4v") || strcasecmp(encoder->containerFormat, "mov"))) { // MP4 container doesn't support the raw ADTS AAC format that the encoder spits out encoder->absf = av_bitstream_filter_init("aac_adtstoasc"); } } encoder->videoStream = avformat_new_stream(encoder->context, vcodec); encoder->video = encoder->videoStream->codec; encoder->video->bit_rate = encoder->videoBitrate; encoder->video->width = encoder->width; encoder->video->height = encoder->height; encoder->video->time_base = (AVRational) { VIDEO_TOTAL_LENGTH, GBA_ARM7TDMI_FREQUENCY }; encoder->video->pix_fmt = encoder->pixFormat; encoder->video->gop_size = 60; encoder->video->max_b_frames = 3; if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { encoder->video->flags |= CODEC_FLAG_GLOBAL_HEADER; } if (strcmp(vcodec->name, "libx264") == 0) { // Try to adaptively figure out when you can use a slower encoder if (encoder->width * encoder->height > 1000000) { av_opt_set(encoder->video->priv_data, "preset", "superfast", 0); } else if (encoder->width * encoder->height > 500000) { av_opt_set(encoder->video->priv_data, "preset", "veryfast", 0); } else { av_opt_set(encoder->video->priv_data, "preset", "faster", 0); } av_opt_set(encoder->video->priv_data, "tune", "zerolatency", 0); } avcodec_open2(encoder->video, vcodec, 0); #if LIBAVCODEC_VERSION_MAJOR >= 55 encoder->videoFrame = av_frame_alloc(); #else encoder->videoFrame = avcodec_alloc_frame(); #endif encoder->videoFrame->format = encoder->video->pix_fmt; encoder->videoFrame->width = encoder->video->width; encoder->videoFrame->height = encoder->video->height; encoder->videoFrame->pts = 0; encoder->scaleContext = sws_getContext(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, #ifndef USE_LIBAV AV_PIX_FMT_0BGR32, #else AV_PIX_FMT_BGR32, #endif encoder->videoFrame->width, encoder->videoFrame->height, encoder->video->pix_fmt, SWS_POINT, 0, 0, 0); av_image_alloc(encoder->videoFrame->data, encoder->videoFrame->linesize, encoder->video->width, encoder->video->height, encoder->video->pix_fmt, 32); avio_open(&encoder->context->pb, outfile, AVIO_FLAG_WRITE); avformat_write_header(encoder->context, 0); return true; }
static int bt_play_open(struct voss_backend *pbe, const char *devname, int samplerate, int bufsize, int *pchannels, int *pformat) { struct bt_config *cfg = pbe->arg; int retval; bt_init_cfg(cfg); retval = bt_open(pbe, devname, samplerate, bufsize, pchannels, pformat, cfg, SDP_SERVICE_CLASS_AUDIO_SINK, 1); if (retval != 0) return (retval); /* setup codec */ switch (cfg->codec) { case CODEC_SBC: cfg->handle.sbc_enc = malloc(sizeof(*cfg->handle.sbc_enc)); if (cfg->handle.sbc_enc == NULL) return (-1); memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc)); break; #ifdef HAVE_FFMPEG case CODEC_AAC: av_register_all(); cfg->handle.av.codec = avcodec_find_encoder_by_name("aac"); if (cfg->handle.av.codec == NULL) { DPRINTF("Codec AAC encoder not found\n"); goto av_error_0; } cfg->handle.av.format = avformat_alloc_context(); if (cfg->handle.av.format == NULL) { DPRINTF("Could not allocate format context\n"); goto av_error_0; } cfg->handle.av.format->oformat = av_guess_format("latm", NULL, NULL); if (cfg->handle.av.format->oformat == NULL) { DPRINTF("Could not guess output format\n"); goto av_error_1; } cfg->handle.av.stream = avformat_new_stream( cfg->handle.av.format, cfg->handle.av.codec); if (cfg->handle.av.stream == NULL) { DPRINTF("Could not create new stream\n"); goto av_error_1; } cfg->handle.av.context = cfg->handle.av.stream->codec; if (cfg->handle.av.context == NULL) { DPRINTF("Could not allocate audio context\n"); goto av_error_1; } avcodec_get_context_defaults3(cfg->handle.av.context, cfg->handle.av.codec); cfg->handle.av.context->bit_rate = 128000; cfg->handle.av.context->sample_fmt = AV_SAMPLE_FMT_FLTP; cfg->handle.av.context->sample_rate = samplerate; switch (*pchannels) { case 1: cfg->handle.av.context->channel_layout = AV_CH_LAYOUT_MONO; cfg->handle.av.context->channels = 1; break; default: cfg->handle.av.context->channel_layout = AV_CH_LAYOUT_STEREO; cfg->handle.av.context->channels = 2; break; } cfg->handle.av.context->profile = FF_PROFILE_AAC_LOW; if (1) { AVDictionary *opts = NULL; av_dict_set(&opts, "strict", "-2", 0); av_dict_set_int(&opts, "latm", 1, 0); if (avcodec_open2(cfg->handle.av.context, cfg->handle.av.codec, &opts) < 0) { av_dict_free(&opts); DPRINTF("Could not open codec\n"); goto av_error_1; } av_dict_free(&opts); } cfg->handle.av.frame = av_frame_alloc(); if (cfg->handle.av.frame == NULL) { DPRINTF("Could not allocate audio frame\n"); goto av_error_2; } cfg->handle.av.frame->nb_samples = cfg->handle.av.context->frame_size; cfg->handle.av.frame->format = cfg->handle.av.context->sample_fmt; cfg->handle.av.frame->channel_layout = cfg->handle.av.context->channel_layout; cfg->rem_in_size = av_samples_get_buffer_size(NULL, cfg->handle.av.context->channels, cfg->handle.av.context->frame_size, cfg->handle.av.context->sample_fmt, 0); cfg->rem_in_data = av_malloc(cfg->rem_in_size); if (cfg->rem_in_data == NULL) { DPRINTF("Could not allocate %u bytes sample buffer\n", (unsigned)cfg->rem_in_size); goto av_error_3; } retval = avcodec_fill_audio_frame(cfg->handle.av.frame, cfg->handle.av.context->channels, cfg->handle.av.context->sample_fmt, cfg->rem_in_data, cfg->rem_in_size, 0); if (retval < 0) { DPRINTF("Could not setup audio frame\n"); goto av_error_4; } break; av_error_4: av_free(cfg->rem_in_data); av_error_3: av_frame_free(&cfg->handle.av.frame); av_error_2: avcodec_close(cfg->handle.av.context); av_error_1: avformat_free_context(cfg->handle.av.format); cfg->handle.av.context = NULL; av_error_0: bt_close(pbe); return (-1); #endif default: bt_close(pbe); return (-1); } return (0); }
int submitAudioFrame(char *data, int length, long frameTimestamp) { AVPacket pkt; int ret; AVFrame *frame; int got_packet; int sampleCount; // If no stream header has been written yet, don't do anything if (hasWrittenStreamHeader == 0) { return 0; } frame = avcodec_alloc_frame(); if (frame == NULL) { fprintf(stderr, "Failed to allocate frame\n"); return -1; } av_init_packet(&pkt); // Copy our data in memcpy(srcSamplesData[0], data, length); srcSamplesCount = length / 4; // Resample to floating point sampleCount = av_rescale_rnd(swr_get_delay(swrContext, audioCodecCtx->sample_rate) + srcSamplesCount, audioCodecCtx->sample_rate, audioCodecCtx->sample_rate, AV_ROUND_UP); if (sampleCount > maxDstSamplesCount) { // Need to resize the buffer av_free(dstSamplesData[0]); ret = av_samples_alloc(dstSamplesData, &dstSamplesLinesize, audioCodecCtx->channels, sampleCount, audioCodecCtx->sample_fmt, 0); if (ret < 0) { fprintf(stderr, "av_samples_alloc() failed: %d\n", ret); return ret; } maxDstSamplesCount = sampleCount; dstSamplesSize = av_samples_get_buffer_size(NULL, audioCodecCtx->channels, sampleCount, audioCodecCtx->sample_fmt, 0); } ret = swr_convert(swrContext, dstSamplesData, sampleCount, (const unsigned char **)srcSamplesData, srcSamplesCount); if (ret < 0) { fprintf(stderr, "swr_convert() failed: %d\n", ret); return ret; } frame->nb_samples = sampleCount; ret = avcodec_fill_audio_frame(frame, audioCodecCtx->channels, audioCodecCtx->sample_fmt, dstSamplesData[0], dstSamplesSize, 0); if (ret < 0) { fprintf(stderr, "avcodec_fill_audio_frame() failed: %d\n", ret); avcodec_free_frame(&frame); return ret; } // pkt is freed on failure or !got_packet pkt.data = NULL; pkt.size = 0; ret = avcodec_encode_audio2(audioCodecCtx, &pkt, frame, &got_packet); if (ret < 0) { fprintf(stderr, "avcodec_encode_audio2() failed: %d\n", ret); avcodec_free_frame(&frame); return ret; } if (!got_packet) { // Nothing to do here return 0; } pkt.stream_index = audioStream->index; pkt.pts = frameTimestamp; pthread_mutex_lock(&streamLock); ret = av_interleaved_write_frame(formatContext, &pkt); pthread_mutex_unlock(&streamLock); avcodec_free_frame(&frame); av_free_packet(&pkt); if (ret != 0) { fprintf(stderr, "av_interleaved_write_frame() failed: %d\n", ret); return ret; } return 0; }
static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i ) { hb_work_object_t * w; hb_work_private_t * pv; hb_sync_audio_t * sync; pv = calloc( 1, sizeof( hb_work_private_t ) ); sync = &pv->type.audio; sync->index = i; pv->job = job; pv->common = common; pv->common->ref++; pv->common->pts_count++; w = hb_get_work( WORK_SYNC_AUDIO ); w->private_data = pv; w->audio = hb_list_item( job->list_audio, i ); w->fifo_in = w->audio->priv.fifo_raw; if ( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG ) { w->fifo_out = w->audio->priv.fifo_out; } else { w->fifo_out = w->audio->priv.fifo_sync; } if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS || w->audio->config.out.codec == HB_ACODEC_AAC_PASS ) { /* Have a silent AC-3/AAC frame ready in case we have to fill a gap */ AVCodec * codec; AVCodecContext * c; switch ( w->audio->config.out.codec ) { case HB_ACODEC_AC3_PASS: { codec = avcodec_find_encoder( AV_CODEC_ID_AC3 ); } break; case HB_ACODEC_AAC_PASS: { codec = avcodec_find_encoder( AV_CODEC_ID_AAC ); } break; default: { // Never gets here codec = NULL; // Silence compiler warning } break; } c = avcodec_alloc_context3(codec); c->bit_rate = w->audio->config.in.bitrate; c->sample_rate = w->audio->config.in.samplerate; c->channels = av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout); hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLT); if (w->audio->config.in.channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX) { c->channel_layout = AV_CH_LAYOUT_STEREO; } else { c->channel_layout = w->audio->config.in.channel_layout; } if( hb_avcodec_open( c, codec, NULL, 0 ) < 0 ) { hb_log( "sync: avcodec_open failed" ); return; } // Prepare input frame AVFrame frame = { .nb_samples = c->frame_size, .pts = 0, }; int input_size = av_samples_get_buffer_size(NULL, c->channels, frame.nb_samples, c->sample_fmt, 1); uint8_t *zeros = calloc(1, input_size); avcodec_fill_audio_frame(&frame, c->channels, c->sample_fmt, zeros, input_size, 1); // Allocate enough space for the encoded silence // The output should be < the input sync->silence_buf = malloc( input_size ); // There is some delay in getting output from some audio encoders. // So encode a few packets till we get output. int ii; for ( ii = 0; ii < 10; ii++ ) { // Prepare output packet AVPacket pkt; int got_packet; av_init_packet(&pkt); pkt.data = sync->silence_buf; pkt.size = input_size; int ret = avcodec_encode_audio2( c, &pkt, &frame, &got_packet); if ( ret < 0 ) { hb_log( "sync: avcodec_encode_audio failed" ); break; } if ( got_packet ) { sync->silence_size = pkt.size; break; } } free( zeros ); hb_avcodec_close( c ); av_free( c ); } else { if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
static hb_buffer_t* Encode(hb_work_object_t *w) { hb_work_private_t *pv = w->private_data; hb_audio_t *audio = w->audio; uint64_t pts, pos; if (hb_list_bytes(pv->list) < pv->input_samples * sizeof(float)) { return NULL; } hb_list_getbytes(pv->list, pv->input_buf, pv->input_samples * sizeof(float), &pts, &pos); // Prepare input frame int out_linesize; int out_size = av_samples_get_buffer_size(&out_linesize, pv->context->channels, pv->samples_per_frame, pv->context->sample_fmt, 1); AVFrame frame = { .nb_samples = pv->samples_per_frame, }; avcodec_fill_audio_frame(&frame, pv->context->channels, pv->context->sample_fmt, pv->output_buf, out_size, 1); if (pv->avresample != NULL) { int in_linesize; av_samples_get_buffer_size(&in_linesize, pv->context->channels, frame.nb_samples, AV_SAMPLE_FMT_FLT, 1); int out_samples = avresample_convert(pv->avresample, frame.extended_data, out_linesize, frame.nb_samples, &pv->input_buf, in_linesize, frame.nb_samples); if (out_samples != pv->samples_per_frame) { // we're not doing sample rate conversion, so this shouldn't happen hb_log("encavcodecaWork: avresample_convert() failed"); return NULL; } } // Libav requires that timebase of audio frames be in sample_rate units frame.pts = pts + (90000 * pos / (sizeof(float) * pv->out_discrete_channels * audio->config.out.samplerate)); frame.pts = av_rescale(frame.pts, pv->context->sample_rate, 90000); // Prepare output packet AVPacket pkt; int got_packet; hb_buffer_t *out = hb_buffer_init(pv->max_output_bytes); av_init_packet(&pkt); pkt.data = out->data; pkt.size = out->alloc; // Encode int ret = avcodec_encode_audio2(pv->context, &pkt, &frame, &got_packet); if (ret < 0) { hb_log("encavcodeca: avcodec_encode_audio failed"); hb_buffer_close(&out); return NULL; } if (got_packet && pkt.size) { out->size = pkt.size; // The output pts from libav is in context->time_base. Convert it back // to our timebase. // // Also account for the "delay" factor that libav seems to arbitrarily // subtract from the packet. Not sure WTH they think they are doing by // offsetting the value in a negative direction. out->s.start = av_rescale_q(pv->context->delay + pkt.pts, pv->context->time_base, (AVRational){1, 90000}); out->s.stop = out->s.start + (90000 * pv->samples_per_frame / audio->config.out.samplerate); out->s.type = AUDIO_BUF; out->s.frametype = HB_FRAME_AUDIO; } else { hb_buffer_close(&out); return Encode(w); } return out; } static hb_buffer_t * Flush( hb_work_object_t * w ) { 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( 0 ); } else { first = hb_buffer_init( 0 ); } return first; }
int CAEEncoderFFmpeg::Encode(float *data, unsigned int frames) { int got_output; AVFrame *frame; const uint8_t *input = (const uint8_t*) data; if (!m_CodecCtx || frames < m_NeededFrames) return 0; /* size of the buffer sent to the encoder: either from the input data or after * conversion, in all cases it is in the m_CodecCtx->sample_fmt format */ int buf_size = av_samples_get_buffer_size(NULL, m_CodecCtx->channels, frames, m_CodecCtx->sample_fmt, 0); assert(buf_size>0); /* allocate the input frame * sadly, we have to alloc/dealloc it everytime since we have no guarantee the * data argument will be constant over iterated calls and the frame needs to * setup pointers inside data */ frame = av_frame_alloc(); if (!frame) return 0; frame->nb_samples = m_CodecCtx->frame_size; frame->format = m_CodecCtx->sample_fmt; frame->channel_layout = m_CodecCtx->channel_layout; if (m_NeedConversion) { if (!m_ResampBuffer || buf_size > m_ResampBufferSize) { m_ResampBuffer = (uint8_t*)av_realloc(m_ResampBuffer, buf_size); if (!m_ResampBuffer) { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Failed to allocate %i bytes buffer for resampling", buf_size); av_frame_free(&frame); return 0; } m_ResampBufferSize = buf_size; } avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, m_ResampBuffer, buf_size, 0); /* important note: the '&input' here works because we convert from a packed * format (ie, interleaved). If it were to be used to convert from planar * formats (ie, non-interleaved, which is not currently supported by AE), * we would need to adapt it or it would segfault. */ if (swr_convert(m_SwrCtx, frame->extended_data, frames, &input, frames) < 0) { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Resampling failed"); av_frame_free(&frame); return 0; } } else avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, input, buf_size, 0); /* initialize the output packet */ av_init_packet(&m_Pkt); m_Pkt.size = sizeof(m_Buffer) - IEC61937_DATA_OFFSET; m_Pkt.data = m_Buffer + IEC61937_DATA_OFFSET; /* encode it */ int ret = avcodec_encode_audio2(m_CodecCtx, &m_Pkt, frame, &got_output); /* free temporary data */ av_frame_free(&frame); if (ret < 0 || !got_output) { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Encoding failed"); return 0; } /* pack it into an IEC958 frame */ m_BufferSize = m_PackFunc(NULL, m_Pkt.size, m_Buffer); if (m_BufferSize != m_OutputSize) { m_OutputSize = m_BufferSize; m_OutputRatio = (double)m_NeededFrames / m_OutputSize; } /* free the packet */ av_free_packet(&m_Pkt); /* return the number of frames used */ return m_NeededFrames; }
static bool reinitialize_coder(struct libavcodec_codec_state *s, struct audio_desc desc) { av_freep(&s->samples); pthread_mutex_lock(s->libav_global_lock); avcodec_close(s->codec_ctx); pthread_mutex_unlock(s->libav_global_lock); /* put sample parameters */ s->codec_ctx->bit_rate = 64000; s->codec_ctx->sample_rate = desc.sample_rate; s->change_bps_to = 0; switch(desc.bps) { case 1: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_U8; break; case 2: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16; break; case 3: s->change_bps_to = 4; case 4: s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_S32; break; } if(!check_sample_fmt(s->codec, s->codec_ctx->sample_fmt)) { s->codec_ctx->sample_fmt = s->codec->sample_fmts[0]; s->change_bps_to = av_get_bytes_per_sample(s->codec_ctx->sample_fmt); } s->codec_ctx->channels = 1; s->codec_ctx->channel_layout = AV_CH_LAYOUT_MONO; pthread_mutex_lock(s->libav_global_lock); /* open it */ if (avcodec_open2(s->codec_ctx, s->codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); pthread_mutex_unlock(s->libav_global_lock); return false; } pthread_mutex_unlock(s->libav_global_lock); if(s->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) { s->codec_ctx->frame_size = 1; } s->av_frame->nb_samples = s->codec_ctx->frame_size; s->av_frame->format = s->codec_ctx->sample_fmt; s->av_frame->channel_layout = AV_CH_LAYOUT_MONO; int channels = 1; /* the codec gives us the frame size, in samples, * we calculate the size of the samples buffer in bytes */ int buffer_size = av_samples_get_buffer_size(NULL, channels, s->codec_ctx->frame_size, s->codec_ctx->sample_fmt, 0); s->samples = av_malloc(buffer_size); if (!s->samples) { fprintf(stderr, "could not allocate %d bytes for samples buffer\n", buffer_size); return false; } /* setup the data pointers in the AVFrame */ int ret = avcodec_fill_audio_frame(s->av_frame, channels, s->codec_ctx->sample_fmt, (const uint8_t*)s->samples, buffer_size, 0); if (ret < 0) { fprintf(stderr, "could not setup audio frame\n"); return false; } s->output_channel.sample_rate = desc.sample_rate; s->output_channel.bps = desc.bps; s->saved_desc = desc; return true; }