/** * Read one audio frame from the input file, decode, convert and store * it in the FIFO buffer. * @param fifo Buffer used for temporary storage * @param input_format_context Format context of the input file * @param input_codec_context Codec context of the input file * @param output_codec_context Codec context of the output file * @param resampler_context Resample context for the conversion * @param[out] finished Indicates whether the end of file has * been reached and all data has been * decoded. If this flag is false, * there is more data to be decoded, * i.e., this function has to be called * again. * @return Error code (0 if successful) */ int Transcode::read_decode_convert_and_store(AVAudioFifo *fifo, AVFormatContext *input_format_context, AVCodecContext *input_codec_context, AVCodecContext *output_codec_context, SwrContext *resampler_context, int *finished) { /* Temporary storage of the input samples of the frame read from the file. */ AVFrame *input_frame = NULL; /* Temporary storage for the converted input samples. */ uint8_t **converted_input_samples = NULL; int data_present; int ret = AVERROR_EXIT; /* Initialize temporary storage for one input frame. */ if (init_input_frame(&input_frame)) goto cleanup; /* Decode one frame worth of audio samples. */ if (decode_audio_frame(input_frame, input_format_context, input_codec_context, &data_present, finished)) goto cleanup; /* If we are at the end of the file and there are no more samples * in the decoder which are delayed, we are actually finished. * This must not be treated as an error. */ if (*finished && !data_present) { ret = 0; goto cleanup; } /* If there is decoded data, convert and store it. */ if (data_present) { /* Initialize the temporary storage for the converted input samples. */ if (init_converted_samples(&converted_input_samples, output_codec_context, input_frame->nb_samples)) goto cleanup; /* Convert the input samples to the desired output sample format. * This requires a temporary storage provided by converted_input_samples. */ if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples, input_frame->nb_samples, resampler_context)) goto cleanup; /* Add the converted input samples to the FIFO buffer for later processing. */ if (add_samples_to_fifo(fifo, converted_input_samples, input_frame->nb_samples)) goto cleanup; ret = 0; } ret = 0; cleanup: if (converted_input_samples) { av_freep(&converted_input_samples[0]); free(converted_input_samples); } av_frame_free(&input_frame); return ret; }
int AudioDecoder::decodeAudio(AVPacket& input_packet, AVPacket& outPacket) { ELOG_DEBUG("decoding input packet, size %d", input_packet.size); AVFrame* input_frame; init_frame(&input_frame); int data_present; int error = avcodec_decode_audio4(input_codec_context, input_frame, &data_present,&input_packet); if (error < 0) { ELOG_DEBUG("decoding error %s", get_error_text(error)); return error; } if (data_present <= 0) { ELOG_DEBUG("data not present"); return 0; } // resample /** Initialize the temporary storage for the converted input samples. */ uint8_t **converted_input_samples = NULL; if (init_converted_samples(&converted_input_samples, output_codec_context, input_frame->nb_samples)) { ELOG_DEBUG("init_converted_samples fails"); return 0; } /** * Convert the input samples to the desired output sample format. * This requires a temporary storage provided by converted_input_samples */ if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,input_frame->nb_samples, resample_context)) { ELOG_WARN("convert_samples failed!!"); return 0; } /** Add converted input samples to the FIFO buffer for later processing. */ if (add_samples_to_fifo(fifo, converted_input_samples, input_frame->nb_samples)) { ELOG_WARN("add_samples to fifo failed !!"); } outPacket.pts = input_packet.pts; // meanwhile, encode; package return load_encode(outPacket); }