|
|
@ -35,14 +35,6 @@ extern "C" { |
|
|
|
/* Global timestamp for the audio frames. */ |
|
|
|
/* Global timestamp for the audio frames. */ |
|
|
|
static int64_t pts = 0; |
|
|
|
static int64_t pts = 0; |
|
|
|
|
|
|
|
|
|
|
|
static void log_error(const char *functionName, int errorNumber) { |
|
|
|
|
|
|
|
int buffer_len = 1024; |
|
|
|
|
|
|
|
char *buffer = new char [buffer_len]; |
|
|
|
|
|
|
|
av_strerror(errorNumber, buffer, buffer_len); |
|
|
|
|
|
|
|
ALOGE("%s: %s", functionName, buffer); |
|
|
|
|
|
|
|
delete []buffer; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Open an input file and the required decoder. |
|
|
|
* Open an input file and the required decoder. |
|
|
|
* |
|
|
|
* |
|
|
@ -58,31 +50,28 @@ static int open_input_file(const char *filename, |
|
|
|
/* Open the input file to read from it. */ |
|
|
|
/* Open the input file to read from it. */ |
|
|
|
if ((error = avformat_open_input(input_format_context, filename, nullptr, |
|
|
|
if ((error = avformat_open_input(input_format_context, filename, nullptr, |
|
|
|
nullptr)) < 0) { |
|
|
|
nullptr)) < 0) { |
|
|
|
fprintf(stderr, "Could not open input file '%s' (error '%s')\n", |
|
|
|
ALOGE("Could not open input file:%s (error:%s)\n", filename, av_err2str(error)); |
|
|
|
filename, av_err2str(error)); |
|
|
|
|
|
|
|
*input_format_context = nullptr; |
|
|
|
*input_format_context = nullptr; |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Get information on the input file (number of streams etc.). */ |
|
|
|
/* Get information on the input file (number of streams etc.). */ |
|
|
|
if ((error = avformat_find_stream_info(*input_format_context, nullptr)) < 0) { |
|
|
|
if ((error = avformat_find_stream_info(*input_format_context, nullptr)) < 0) { |
|
|
|
fprintf(stderr, "Could not open find stream info (error '%s')\n", |
|
|
|
ALOGE("Could not open find stream info (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
avformat_close_input(input_format_context); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Make sure that there is only one stream in the input file. */ |
|
|
|
/* Make sure that there is only one stream in the input file. */ |
|
|
|
if ((*input_format_context)->nb_streams != 1) { |
|
|
|
if ((*input_format_context)->nb_streams != 1) { |
|
|
|
fprintf(stderr, "Expected one audio input stream, but found %d\n", |
|
|
|
ALOGE("Expected one audio input stream, but found %d\n", (*input_format_context)->nb_streams); |
|
|
|
(*input_format_context)->nb_streams); |
|
|
|
|
|
|
|
avformat_close_input(input_format_context); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
return AVERROR_EXIT; |
|
|
|
return AVERROR_EXIT; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Find a decoder for the audio stream. */ |
|
|
|
/* Find a decoder for the audio stream. */ |
|
|
|
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) { |
|
|
|
if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) { |
|
|
|
fprintf(stderr, "Could not find input codec\n"); |
|
|
|
ALOGE("Could not find input codec\n"); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
return AVERROR_EXIT; |
|
|
|
return AVERROR_EXIT; |
|
|
|
} |
|
|
|
} |
|
|
@ -90,7 +79,7 @@ static int open_input_file(const char *filename, |
|
|
|
/* Allocate a new decoding context. */ |
|
|
|
/* Allocate a new decoding context. */ |
|
|
|
avctx = avcodec_alloc_context3(input_codec); |
|
|
|
avctx = avcodec_alloc_context3(input_codec); |
|
|
|
if (!avctx) { |
|
|
|
if (!avctx) { |
|
|
|
fprintf(stderr, "Could not allocate a decoding context\n"); |
|
|
|
ALOGE("Could not allocate a decoding context\n"); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
@ -105,8 +94,7 @@ static int open_input_file(const char *filename, |
|
|
|
|
|
|
|
|
|
|
|
/* Open the decoder for the audio stream to use it later. */ |
|
|
|
/* Open the decoder for the audio stream to use it later. */ |
|
|
|
if ((error = avcodec_open2(avctx, input_codec, nullptr)) < 0) { |
|
|
|
if ((error = avcodec_open2(avctx, input_codec, nullptr)) < 0) { |
|
|
|
fprintf(stderr, "Could not open input codec (error '%s')\n", |
|
|
|
ALOGE("Could not open input codec (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
avcodec_free_context(&avctx); |
|
|
|
avcodec_free_context(&avctx); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
avformat_close_input(input_format_context); |
|
|
|
return error; |
|
|
|
return error; |
|
|
@ -139,14 +127,13 @@ static int open_output_file(const char *filename, |
|
|
|
/* Open the output file to write to it. */ |
|
|
|
/* Open the output file to write to it. */ |
|
|
|
if ((error = avio_open(&output_io_context, filename, |
|
|
|
if ((error = avio_open(&output_io_context, filename, |
|
|
|
AVIO_FLAG_WRITE)) < 0) { |
|
|
|
AVIO_FLAG_WRITE)) < 0) { |
|
|
|
fprintf(stderr, "Could not open output file '%s' (error '%s')\n", |
|
|
|
ALOGE("Could not open output file:%s (error:%s)\n", filename, av_err2str(error)); |
|
|
|
filename, av_err2str(error)); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Create a new format context for the output container format. */ |
|
|
|
/* Create a new format context for the output container format. */ |
|
|
|
if (!(*output_format_context = avformat_alloc_context())) { |
|
|
|
if (!(*output_format_context = avformat_alloc_context())) { |
|
|
|
fprintf(stderr, "Could not allocate output format context\n"); |
|
|
|
ALOGE("Could not allocate output format context\n"); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -156,32 +143,32 @@ static int open_output_file(const char *filename, |
|
|
|
/* Guess the desired container format based on the file extension. */ |
|
|
|
/* Guess the desired container format based on the file extension. */ |
|
|
|
if (!((*output_format_context)->oformat = av_guess_format(nullptr, filename, |
|
|
|
if (!((*output_format_context)->oformat = av_guess_format(nullptr, filename, |
|
|
|
nullptr))) { |
|
|
|
nullptr))) { |
|
|
|
fprintf(stderr, "Could not find output file format\n"); |
|
|
|
ALOGE("Could not find output file format\n"); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!((*output_format_context)->url = av_strdup(filename))) { |
|
|
|
if (!((*output_format_context)->url = av_strdup(filename))) { |
|
|
|
fprintf(stderr, "Could not allocate url.\n"); |
|
|
|
ALOGE("Could not allocate url.\n"); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Find the encoder to be used by its name. */ |
|
|
|
/* Find the encoder to be used by its name. */ |
|
|
|
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) { |
|
|
|
if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) { |
|
|
|
fprintf(stderr, "Could not find an AAC encoder.\n"); |
|
|
|
ALOGE( "Could not find an AAC encoder.\n"); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Create a new audio stream in the output file container. */ |
|
|
|
/* Create a new audio stream in the output file container. */ |
|
|
|
if (!(stream = avformat_new_stream(*output_format_context, nullptr))) { |
|
|
|
if (!(stream = avformat_new_stream(*output_format_context, nullptr))) { |
|
|
|
fprintf(stderr, "Could not create new stream\n"); |
|
|
|
ALOGE("Could not create new stream\n"); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
avctx = avcodec_alloc_context3(output_codec); |
|
|
|
avctx = avcodec_alloc_context3(output_codec); |
|
|
|
if (!avctx) { |
|
|
|
if (!avctx) { |
|
|
|
fprintf(stderr, "Could not allocate an encoding context\n"); |
|
|
|
ALOGE("Could not allocate an encoding context\n"); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
error = AVERROR(ENOMEM); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
@ -208,20 +195,17 @@ static int open_output_file(const char *filename, |
|
|
|
|
|
|
|
|
|
|
|
/* Open the encoder for the audio stream to use it later. */ |
|
|
|
/* Open the encoder for the audio stream to use it later. */ |
|
|
|
if ((error = avcodec_open2(avctx, output_codec, nullptr)) < 0) { |
|
|
|
if ((error = avcodec_open2(avctx, output_codec, nullptr)) < 0) { |
|
|
|
fprintf(stderr, "Could not open output codec (error '%s')\n", |
|
|
|
ALOGE("Could not open output codec (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
error = avcodec_parameters_from_context(stream->codecpar, avctx); |
|
|
|
error = avcodec_parameters_from_context(stream->codecpar, avctx); |
|
|
|
if (error < 0) { |
|
|
|
if (error < 0) { |
|
|
|
fprintf(stderr, "Could not initialize stream parameters\n"); |
|
|
|
ALOGE("Could not initialize stream parameters\n"); |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Save the encoder context for easier access later. */ |
|
|
|
|
|
|
|
*output_codec_context = avctx; |
|
|
|
*output_codec_context = avctx; |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
cleanup: |
|
|
|
cleanup: |
|
|
@ -250,7 +234,7 @@ static void init_packet(AVPacket *packet) |
|
|
|
static int init_input_frame(AVFrame **frame) |
|
|
|
static int init_input_frame(AVFrame **frame) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!(*frame = av_frame_alloc())) { |
|
|
|
if (!(*frame = av_frame_alloc())) { |
|
|
|
fprintf(stderr, "Could not allocate input frame\n"); |
|
|
|
ALOGE("Could not allocate input frame\n"); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -282,7 +266,7 @@ static int init_resampler(AVCodecContext *input_codec_context, |
|
|
|
input_codec_context->sample_rate, |
|
|
|
input_codec_context->sample_rate, |
|
|
|
0, nullptr); |
|
|
|
0, nullptr); |
|
|
|
if (!*resample_context) { |
|
|
|
if (!*resample_context) { |
|
|
|
fprintf(stderr, "Could not allocate resample context\n"); |
|
|
|
ALOGE("Could not allocate resample context\n"); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -294,7 +278,7 @@ static int init_resampler(AVCodecContext *input_codec_context, |
|
|
|
|
|
|
|
|
|
|
|
/* Open the re-sampler with the specified parameters. */ |
|
|
|
/* Open the re-sampler with the specified parameters. */ |
|
|
|
if ((error = swr_init(*resample_context)) < 0) { |
|
|
|
if ((error = swr_init(*resample_context)) < 0) { |
|
|
|
fprintf(stderr, "Could not open resample context\n"); |
|
|
|
ALOGE("Could not open resample context\n"); |
|
|
|
swr_free(resample_context); |
|
|
|
swr_free(resample_context); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
@ -310,7 +294,7 @@ static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context) |
|
|
|
/* Create the FIFO buffer based on the specified output sample format. */ |
|
|
|
/* Create the FIFO buffer based on the specified output sample format. */ |
|
|
|
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt, |
|
|
|
if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt, |
|
|
|
output_codec_context->channels, 1))) { |
|
|
|
output_codec_context->channels, 1))) { |
|
|
|
fprintf(stderr, "Could not allocate FIFO\n"); |
|
|
|
ALOGE("Could not allocate FIFO\n"); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -324,7 +308,7 @@ static int write_output_file_header(AVFormatContext *output_format_context) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int error; |
|
|
|
int error; |
|
|
|
if ((error = avformat_write_header(output_format_context, nullptr)) < 0) { |
|
|
|
if ((error = avformat_write_header(output_format_context, nullptr)) < 0) { |
|
|
|
fprintf(stderr, "Could not write output file header (error '%s')\n", |
|
|
|
ALOGE("Could not write output file header (error '%s')\n", |
|
|
|
av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
@ -351,7 +335,7 @@ static int decode_audio_frame(AVFrame *frame, |
|
|
|
if (error == AVERROR_EOF) |
|
|
|
if (error == AVERROR_EOF) |
|
|
|
*finished = 1; |
|
|
|
*finished = 1; |
|
|
|
else { |
|
|
|
else { |
|
|
|
fprintf(stderr, "Could not read frame (error '%s')\n", |
|
|
|
ALOGE("Could not read frame (error:%s)\n", |
|
|
|
av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
@ -360,8 +344,7 @@ static int decode_audio_frame(AVFrame *frame, |
|
|
|
/* Send the audio frame stored in the temporary packet to the decoder.
|
|
|
|
/* Send the audio frame stored in the temporary packet to the decoder.
|
|
|
|
* The input audio stream decoder is used to do this. */ |
|
|
|
* The input audio stream decoder is used to do this. */ |
|
|
|
if ((error = avcodec_send_packet(input_codec_context, &input_packet)) < 0) { |
|
|
|
if ((error = avcodec_send_packet(input_codec_context, &input_packet)) < 0) { |
|
|
|
fprintf(stderr, "Could not send packet for decoding (error '%s')\n", |
|
|
|
ALOGE("Could not send packet for decoding (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -378,10 +361,8 @@ static int decode_audio_frame(AVFrame *frame, |
|
|
|
error = 0; |
|
|
|
error = 0; |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} else if (error < 0) { |
|
|
|
} else if (error < 0) { |
|
|
|
fprintf(stderr, "Could not decode frame (error '%s')\n", |
|
|
|
ALOGE("Could not decode frame (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
/* Default case: Return decoded data. */ |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
*data_present = 1; |
|
|
|
*data_present = 1; |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
@ -409,7 +390,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (!(*converted_input_samples = (uint8_t **) calloc(output_codec_context->channels, |
|
|
|
if (!(*converted_input_samples = (uint8_t **) calloc(output_codec_context->channels, |
|
|
|
sizeof(**converted_input_samples)))) { |
|
|
|
sizeof(**converted_input_samples)))) { |
|
|
|
fprintf(stderr, "Could not allocate converted input sample pointers\n"); |
|
|
|
ALOGE("Could not allocate converted input sample pointers\n"); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -419,9 +400,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples, |
|
|
|
output_codec_context->channels, |
|
|
|
output_codec_context->channels, |
|
|
|
frame_size, |
|
|
|
frame_size, |
|
|
|
output_codec_context->sample_fmt, 0)) < 0) { |
|
|
|
output_codec_context->sample_fmt, 0)) < 0) { |
|
|
|
fprintf(stderr, |
|
|
|
ALOGE("Could not allocate converted input samples (error:%s)\n", av_err2str(error)); |
|
|
|
"Could not allocate converted input samples (error '%s')\n", |
|
|
|
|
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
av_freep(&(*converted_input_samples)[0]); |
|
|
|
av_freep(&(*converted_input_samples)[0]); |
|
|
|
free(*converted_input_samples); |
|
|
|
free(*converted_input_samples); |
|
|
|
return error; |
|
|
|
return error; |
|
|
@ -445,8 +424,7 @@ static int convert_samples(const uint8_t **input_data, |
|
|
|
if ((error = swr_convert(resample_context, |
|
|
|
if ((error = swr_convert(resample_context, |
|
|
|
converted_data, frame_size, |
|
|
|
converted_data, frame_size, |
|
|
|
input_data , frame_size)) < 0) { |
|
|
|
input_data , frame_size)) < 0) { |
|
|
|
fprintf(stderr, "Could not convert input samples (error '%s')\n", |
|
|
|
ALOGE("Could not convert input samples (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -466,14 +444,14 @@ static int add_samples_to_fifo(AVAudioFifo *fifo, |
|
|
|
/* Make the FIFO as large as it needs to be to hold both,
|
|
|
|
/* Make the FIFO as large as it needs to be to hold both,
|
|
|
|
* the old and the new samples. */ |
|
|
|
* the old and the new samples. */ |
|
|
|
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) { |
|
|
|
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) { |
|
|
|
fprintf(stderr, "Could not reallocate FIFO\n"); |
|
|
|
ALOGE("Could not reallocate FIFO\n"); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Store the new samples in the FIFO buffer. */ |
|
|
|
/* Store the new samples in the FIFO buffer. */ |
|
|
|
if (av_audio_fifo_write(fifo, (void **)converted_input_samples, |
|
|
|
if (av_audio_fifo_write(fifo, (void **)converted_input_samples, |
|
|
|
frame_size) < frame_size) { |
|
|
|
frame_size) < frame_size) { |
|
|
|
fprintf(stderr, "Could not write data to FIFO\n"); |
|
|
|
ALOGE("Could not write data to FIFO\n"); |
|
|
|
return AVERROR_EXIT; |
|
|
|
return AVERROR_EXIT; |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -556,7 +534,7 @@ static int init_output_frame(AVFrame **frame, |
|
|
|
|
|
|
|
|
|
|
|
/* Create a new frame to store the audio samples. */ |
|
|
|
/* Create a new frame to store the audio samples. */ |
|
|
|
if (!(*frame = av_frame_alloc())) { |
|
|
|
if (!(*frame = av_frame_alloc())) { |
|
|
|
fprintf(stderr, "Could not allocate output frame\n"); |
|
|
|
ALOGE("Could not allocate output frame\n"); |
|
|
|
return AVERROR_EXIT; |
|
|
|
return AVERROR_EXIT; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -573,8 +551,7 @@ static int init_output_frame(AVFrame **frame, |
|
|
|
/* Allocate the samples of the created frame. This call will make
|
|
|
|
/* Allocate the samples of the created frame. This call will make
|
|
|
|
* sure that the audio frame can hold as many samples as specified. */ |
|
|
|
* sure that the audio frame can hold as many samples as specified. */ |
|
|
|
if ((error = av_frame_get_buffer(*frame, 0)) < 0) { |
|
|
|
if ((error = av_frame_get_buffer(*frame, 0)) < 0) { |
|
|
|
fprintf(stderr, "Could not allocate output frame samples (error '%s')\n", |
|
|
|
ALOGE("Could not allocate output frame samples (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
av_frame_free(frame); |
|
|
|
av_frame_free(frame); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
@ -584,12 +561,7 @@ static int init_output_frame(AVFrame **frame, |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Encode one frame worth of audio to the output file. |
|
|
|
* Encode one frame worth of audio to the output file. |
|
|
|
* @param frame Samples to be encoded |
|
|
|
* |
|
|
|
* @param output_format_context Format context of the output file |
|
|
|
|
|
|
|
* @param output_codec_context Codec context of the output file |
|
|
|
|
|
|
|
* @param[out] data_present Indicates whether data has been |
|
|
|
|
|
|
|
* encoded |
|
|
|
|
|
|
|
* @return Error code (0 if successful) |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static int encode_audio_frame(AVFrame *frame, |
|
|
|
static int encode_audio_frame(AVFrame *frame, |
|
|
|
AVFormatContext *output_format_context, |
|
|
|
AVFormatContext *output_format_context, |
|
|
@ -615,8 +587,7 @@ static int encode_audio_frame(AVFrame *frame, |
|
|
|
error = 0; |
|
|
|
error = 0; |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} else if (error < 0) { |
|
|
|
} else if (error < 0) { |
|
|
|
fprintf(stderr, "Could not send packet for encoding (error '%s')\n", |
|
|
|
ALOGE("Could not send packet for encoding (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -632,8 +603,7 @@ static int encode_audio_frame(AVFrame *frame, |
|
|
|
error = 0; |
|
|
|
error = 0; |
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} else if (error < 0) { |
|
|
|
} else if (error < 0) { |
|
|
|
fprintf(stderr, "Could not encode frame (error '%s')\n", |
|
|
|
ALOGE("Could not encode frame (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
/* Default case: Return encoded data. */ |
|
|
|
/* Default case: Return encoded data. */ |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -643,12 +613,11 @@ static int encode_audio_frame(AVFrame *frame, |
|
|
|
/* Write one audio frame from the temporary packet to the output file. */ |
|
|
|
/* Write one audio frame from the temporary packet to the output file. */ |
|
|
|
if (*data_present && |
|
|
|
if (*data_present && |
|
|
|
(error = av_write_frame(output_format_context, &output_packet)) < 0) { |
|
|
|
(error = av_write_frame(output_format_context, &output_packet)) < 0) { |
|
|
|
fprintf(stderr, "Could not write frame (error '%s')\n", |
|
|
|
ALOGE("Could not write frame (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
goto cleanup; |
|
|
|
goto cleanup; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cleanup: |
|
|
|
cleanup: |
|
|
|
av_packet_unref(&output_packet); |
|
|
|
av_packet_unref(&output_packet); |
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
@ -678,7 +647,7 @@ static int load_encode_and_write(AVAudioFifo *fifo, |
|
|
|
/* Read as many samples from the FIFO buffer as required to fill the frame.
|
|
|
|
/* Read as many samples from the FIFO buffer as required to fill the frame.
|
|
|
|
* The samples are stored in the frame temporarily. */ |
|
|
|
* The samples are stored in the frame temporarily. */ |
|
|
|
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) { |
|
|
|
if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) { |
|
|
|
fprintf(stderr, "Could not read data from FIFO\n"); |
|
|
|
ALOGE("Could not read data from FIFO\n"); |
|
|
|
av_frame_free(&output_frame); |
|
|
|
av_frame_free(&output_frame); |
|
|
|
return AVERROR_EXIT; |
|
|
|
return AVERROR_EXIT; |
|
|
|
} |
|
|
|
} |
|
|
@ -701,8 +670,7 @@ static int write_output_file_trailer(AVFormatContext *output_format_context) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int error; |
|
|
|
int error; |
|
|
|
if ((error = av_write_trailer(output_format_context)) < 0) { |
|
|
|
if ((error = av_write_trailer(output_format_context)) < 0) { |
|
|
|
fprintf(stderr, "Could not write output file trailer (error '%s')\n", |
|
|
|
ALOGE("Could not write output file trailer (error:%s)\n", av_err2str(error)); |
|
|
|
av_err2str(error)); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|