"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/plugins/previewopus_extractor.c" between
libextractor-1.8.tar.gz and libextractor-1.9.tar.gz

About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.

previewopus_extractor.c  (libextractor-1.8):previewopus_extractor.c  (libextractor-1.9)
skipping to change at line 168 skipping to change at line 168
} }
/** /**
* write callback. * write callback.
* *
* @param opaque NULL * @param opaque NULL
* @param pBuffer to write * @param pBuffer to write
* @param pBufferSize , amount to write * @param pBufferSize , amount to write
* @return 0 on error * @return 0 on error
*/ */
static int writePacket(void *opaque, unsigned char *pBuffer, int pBufferSize) { static int
writePacket (void *opaque,
int sizeToCopy = pBufferSize; unsigned char *pBuffer,
if( (totalSize + pBufferSize) > HARD_LIMIT_SIZE) int pBufferSize)
sizeToCopy = HARD_LIMIT_SIZE - totalSize; {
int sizeToCopy = pBufferSize;
memcpy(buffer + totalSize, pBuffer, sizeToCopy);
totalSize+= sizeToCopy; if( (totalSize + pBufferSize) > HARD_LIMIT_SIZE)
sizeToCopy = HARD_LIMIT_SIZE - totalSize;
return sizeToCopy;
memcpy (buffer + totalSize, pBuffer, sizeToCopy);
totalSize += sizeToCopy;
return sizeToCopy;
} }
/** /**
* Open an output file and the required encoder. * Open an output file and the required encoder.
* Also set some basic encoder parameters. * Also set some basic encoder parameters.
* Some of these parameters are based on the input file's parameters. * Some of these parameters are based on the input file's parameters.
*/ */
static int open_output_file( static int open_output_file(
AVCodecContext *input_codec_context, AVCodecContext *input_codec_context,
AVFormatContext **output_format_context, AVFormatContext **output_format_context,
AVCodecContext **output_codec_context) AVCodecContext **output_codec_context)
{ {
AVStream *stream = NULL; AVStream *stream = NULL;
AVCodec *output_codec = NULL; AVCodec *output_codec = NULL;
AVIOContext *io_ctx; AVIOContext *io_ctx;
int error; int error;
unsigned char *iob;
unsigned char *iob;
if (NULL == (iob = av_malloc (16 * 1024))) if (NULL == (iob = av_malloc (16 * 1024)))
return AVERROR_EXIT; return AVERROR_EXIT;
if (NULL == (io_ctx = avio_alloc_context (iob, 16 * 1024, if (NULL == (io_ctx = avio_alloc_context (iob, 16 * 1024,
AVIO_FLAG_WRITE, NULL, AVIO_FLAG_WRITE, NULL,
NULL, NULL,
&writePacket /* no writing */, &writePacket /* no writing */,
NULL))) NULL)))
{ {
av_free (iob); av_free (iob);
return AVERROR_EXIT; return AVERROR_EXIT;
} }
if (NULL == ((*output_format_context) = avformat_alloc_context ())) if (NULL == ((*output_format_context) = avformat_alloc_context ()))
{ {
av_free (io_ctx); av_free (io_ctx);
return AVERROR_EXIT; return AVERROR_EXIT;
} }
(*output_format_context)->pb = io_ctx; (*output_format_context)->pb = io_ctx;
/** 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(NULL, "file.ogg", if (!((*output_format_context)->oformat = av_guess_format (NULL,
NULL))) { "file.ogg",
NULL)))
{
#if DEBUG #if DEBUG
fprintf(stderr, "Could not find output file format\n"); fprintf(stderr, "Could not find output file format\n");
#endif #endif
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_OPUS))) { if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_OPUS)))
{
#if DEBUG #if DEBUG
fprintf(stderr, "Could not find an OPUS encoder.\n"); fprintf(stderr, "Could not find an OPUS encoder.\n");
#endif #endif
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, output_codec))) { if (!(stream = avformat_new_stream(*output_format_context, output_codec)))
{
#if DEBUG #if DEBUG
fprintf(stderr, "Could not create new stream\n"); fprintf(stderr, "Could not create new stream\n");
#endif #endif
error = AVERROR(ENOMEM); error = AVERROR(ENOMEM);
goto cleanup; goto cleanup;
} }
/** Save the encoder context for easiert access later. */ /** Save the encoder context for easiert access later. */
*output_codec_context = stream->codec; *output_codec_context = stream->codec;
/** /**
* Set the basic encoder parameters. * Set the basic encoder parameters.
* The input file's sample rate is used to avoid a sample rate conversion. * The input file's sample rate is used to avoid a sample rate conversion.
*/ */
(*output_codec_context)->channels = OUTPUT_CHANNELS; (*output_codec_context)->channels = OUTPUT_CHANNELS;
(*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTP (*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTPUT
UT_CHANNELS); _CHANNELS);
(*output_codec_context)->sample_rate = 48000; //Opus need 48000 (*output_codec_context)->sample_rate = 48000; //Opus need 48000
(*output_codec_context)->sample_fmt = AV_SAMPLE_FMT_S16; (*output_codec_context)->sample_fmt = AV_SAMPLE_FMT_S16;
(*output_codec_context)->bit_rate = OUTPUT_BIT_RATE; (*output_codec_context)->bit_rate = OUTPUT_BIT_RATE;
/** 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(*output_codec_context, output_codec, NULL)) < 0) if ((error = avcodec_open2(*output_codec_context, output_codec, NULL)) < 0)
{ {
#if DEBUG #if DEBUG
fprintf(stderr, "Could not open output codec (error '%s')\n", fprintf(stderr, "Could not open output codec (error '%s')\n",
get_error_text(error)); get_error_text(error));
#endif #endif
goto cleanup; goto cleanup;
} }
return 0;
return 0;
cleanup: cleanup:
return error < 0 ? error : AVERROR_EXIT; av_free (io_ctx);
return error < 0 ? error : AVERROR_EXIT;
} }
/** Initialize one data packet for reading or writing. */ /** Initialize one data packet for reading or writing. */
static void init_packet(AVPacket *packet) static void
init_packet(AVPacket *packet)
{ {
av_init_packet(packet); av_init_packet(packet);
/** Set the packet data and size so that it is recognized as being empty. */ /** Set the packet data and size so that it is recognized as being empty. */
packet->data = NULL; packet->data = NULL;
packet->size = 0; packet->size = 0;
} }
/** Initialize one audio frame for reading from the input file */ /** Initialize one audio frame for reading from the input file */
static int init_input_frame(AVFrame **frame) static int
init_input_frame(AVFrame **frame)
{ {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1)
*frame = av_frame_alloc (); *frame = av_frame_alloc ();
#else #else
*frame = avcodec_alloc_frame(); *frame = avcodec_alloc_frame();
#endif #endif
if (NULL == *frame) { if (NULL == *frame)
{
#if DEBUG #if DEBUG
fprintf(stderr, "Could not allocate input frame\n"); fprintf(stderr, "Could not allocate input frame\n");
#endif #endif
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
return 0; return 0;
} }
/** /**
* Initialize the audio resampler based on the input and output codec settings. * Initialize the audio resampler based on the input and output codec settings.
* If the input and output sample formats differ, a conversion is required * If the input and output sample formats differ, a conversion is required
* libavresample takes care of this, but requires initialization. * libavresample takes care of this, but requires initialization.
*/ */
static int init_resampler(AVCodecContext *input_codec_context, static int
AVCodecContext *output_codec_context, init_resampler (AVCodecContext *input_codec_context,
AVAudioResampleContext **resample_context) AVCodecContext *output_codec_context,
AVAudioResampleContext **resample_context)
{ {
/** /**
* Only initialize the resampler if it is necessary, i.e., * Only initialize the resampler if it is necessary, i.e.,
* if and only if the sample formats differ. * if and only if the sample formats differ.
*/ */
if (input_codec_context->sample_fmt != output_codec_context->sample_fmt || if (input_codec_context->sample_fmt != output_codec_context->sample_fmt ||
input_codec_context->channels != output_codec_context->channels) { input_codec_context->channels != output_codec_context->channels) {
int error; int error;
/** Create a resampler context for the conversion. */ /** Create a resampler context for the conversion. */
skipping to change at line 846 skipping to change at line 857
AVAudioResampleContext *resample_context = NULL; AVAudioResampleContext *resample_context = NULL;
AVAudioFifo *fifo = NULL; AVAudioFifo *fifo = NULL;
int audio_stream_index; int audio_stream_index;
int i; int i;
int err; int err;
int duration; int duration;
unsigned char *iob; unsigned char *iob;
totalSize =0; totalSize =0;
if (NULL == (iob = av_malloc (16 * 1024))) if (NULL == (iob = av_malloc (16 * 1024)))
return; return;
if (NULL == (io_ctx = avio_alloc_context (iob, 16 * 1024, if (NULL == (io_ctx = avio_alloc_context (iob,
16 * 1024,
0, ec, 0, ec,
&read_cb, &read_cb,
NULL /* no writing */, NULL /* no writing */,
&seek_cb))) &seek_cb)))
{ {
av_free (iob); av_free (iob);
return; return;
} }
if (NULL == (format_ctx = avformat_alloc_context ())) if (NULL == (format_ctx = avformat_alloc_context ()))
{ {
av_free (io_ctx); av_free (io_ctx);
return; return;
} }
format_ctx->pb = io_ctx; format_ctx->pb = io_ctx;
options = NULL; options = NULL;
if (0 != avformat_open_input (&format_ctx, "<no file>", NULL, &options)) if (0 != avformat_open_input (&format_ctx, "<no file>", NULL, &options))
return; {
av_free (io_ctx);
return;
}
av_dict_free (&options); av_dict_free (&options);
if (0 > avformat_find_stream_info (format_ctx, NULL)) if (0 > avformat_find_stream_info (format_ctx, NULL))
{ {
#if DEBUG #if DEBUG
fprintf (stderr, fprintf (stderr,
"Failed to read stream info\n"); "Failed to read stream info\n");
#endif #endif
avformat_close_input (&format_ctx); avformat_close_input (&format_ctx);
av_free (io_ctx); av_free (io_ctx);
return; return;
skipping to change at line 929 skipping to change at line 943
#if DEBUG #if DEBUG
fprintf (stderr, fprintf (stderr,
"Failed to allocate frame\n"); "Failed to allocate frame\n");
#endif #endif
avcodec_close (codec_ctx); avcodec_close (codec_ctx);
avformat_close_input (&format_ctx); avformat_close_input (&format_ctx);
av_free (io_ctx); av_free (io_ctx);
return; return;
} }
if(!(buffer = malloc(HARD_LIMIT_SIZE))) if (! (buffer = malloc(HARD_LIMIT_SIZE)))
goto cleanup; goto cleanup;
/** Open the output file for writing. */
if (open_output_file( codec_ctx,&output_format_context, &output_codec_contex
t))
goto cleanup;
/** Initialize the resampler to be able to convert audio sample formats. */
if (init_resampler(codec_ctx, output_codec_context,
&resample_context))
goto cleanup;
/** Initialize the FIFO buffer to store audio samples to be encoded. */
if (init_fifo(&fifo))
goto cleanup;
/** Write the header of the output file container. */ /** Open the output file for writing. */
if (write_output_file_header(output_format_context)) if (open_output_file (codec_ctx,
goto cleanup; &output_format_context,
&output_codec_context))
goto cleanup;
/** Initialize the resampler to be able to convert audio sample formats. */
if (init_resampler (codec_ctx,
output_codec_context,
&resample_context))
goto cleanup;
/** Initialize the FIFO buffer to store audio samples to be encoded. */
if (init_fifo(&fifo))
goto cleanup;
/** Write the header of the output file container. */
if (write_output_file_header(output_format_context))
goto cleanup;
if (format_ctx->duration == AV_NOPTS_VALUE) if (format_ctx->duration == AV_NOPTS_VALUE)
{ {
duration = -1; duration = -1;
#if DEBUG #if DEBUG
fprintf (stderr, fprintf (stderr,
"Duration unknown\n"); "Duration unknown\n");
#endif #endif
} }
else else
{ {
#if DEBUG #if DEBUG
duration = format_ctx->duration; duration = format_ctx->duration;
fprintf (stderr, fprintf (stderr,
"Duration: %lld\n", "Duration: %lld\n",
format_ctx->duration); format_ctx->duration);
#endif #endif
} }
/* if duration is known, seek to first tried, /* if duration is known, seek to first tried,
* else use 10 sec into stream */ * else use 10 sec into stream */
if(-1 != duration) if(-1 != duration)
err = av_seek_frame (format_ctx, -1, (duration/3), 0); err = av_seek_frame (format_ctx, -1, (duration/3), 0);
else else
err = av_seek_frame (format_ctx, -1, 10 * AV_TIME_BASE, 0); err = av_seek_frame (format_ctx, -1, 10 * AV_TIME_BASE, 0);
if (err >= 0) if (err >= 0)
avcodec_flush_buffers (codec_ctx); avcodec_flush_buffers (codec_ctx);
/** /**
* Loop as long as we have input samples to read or output samples * Loop as long as we have input samples to read or output samples
* to write; abort as soon as we have neither. * to write; abort as soon as we have neither.
*/ */
while (1) { while (1)
/** Use the encoder's desired frame size for processing. */ {
const int output_frame_size = output_codec_context->frame_size; /** Use the encoder's desired frame size for processing. */
int finished = 0; const int output_frame_size = output_codec_context->frame_size;
int finished = 0;
/**
* Make sure that there is one frame worth of samples in the FIFO /**
* buffer so that the encoder can do its work. * Make sure that there is one frame worth of samples in the FIFO
* Since the decoder's and the encoder's frame size may differ, we * buffer so that the encoder can do its work.
* need to FIFO buffer to store as many frames worth of input samples * Since the decoder's and the encoder's frame size may differ, we
* that they make up at least one frame worth of output samples. * need to FIFO buffer to store as many frames worth of input samples
*/ * that they make up at least one frame worth of output samples.
*/
while ((av_audio_fifo_size(fifo) < output_frame_size)) {
/**
* Decode one frame worth of audio samples, convert it to the
* output sample format and put it into the FIFO buffer.
*/
if (read_decode_convert_and_store(fifo, format_ctx,codec_ctx,
output_codec_context,
resample_context,audio_stream_inde
x, &finished)){
goto cleanup;
}
/** while ((av_audio_fifo_size(fifo) < output_frame_size))
* If we are at the end of the input file, we continue {
* encoding the remaining audio samples to the output file. /**
*/ * Decode one frame worth of audio samples, convert it to the
if (finished) * output sample format and put it into the FIFO buffer.
break; */
if (read_decode_convert_and_store (fifo,
format_ctx,
codec_ctx,
output_codec_context,
resample_context,
audio_stream_index,
&finished))
{
goto cleanup;
}
/**
* If we are at the end of the input file, we continue
* encoding the remaining audio samples to the output file.
*/
if (finished)
break;
} }
/* Already over our limit*/ /* Already over our limit*/
if(totalSize >= MAX_SIZE) if (totalSize >= MAX_SIZE)
finished = 1; finished = 1;
/** /**
* If we have enough samples for the encoder, we encode them. * If we have enough samples for the encoder, we encode them.
* At the end of the file, we pass the remaining samples to * At the end of the file, we pass the remaining samples to
* the encoder. * the encoder.
*/ */
while (av_audio_fifo_size(fifo) >= output_frame_size ||
(finished && av_audio_fifo_size(fifo) > 0)){
/**
* Take one frame worth of audio samples from the FIFO buffer,
* encode it and write it to the output file.
*/
if (load_encode_and_write(fifo,output_format_context, output_codec_ while (av_audio_fifo_size(fifo) >= output_frame_size ||
context)) (finished && av_audio_fifo_size(fifo) > 0))
goto cleanup; {
} /**
/** * Take one frame worth of audio samples from the FIFO buffer,
* If we are at the end of the input file and have encoded * encode it and write it to the output file.
* all remaining samples, we can exit this loop and finish. */
*/ if (load_encode_and_write (fifo,
if (finished) { output_format_context,
int data_written; output_codec_context))
/** Flush the encoder as it may have delayed frames. */ goto cleanup;
do { }
encode_audio_frame(NULL, output_format_context, output_codec_con /**
text, &data_written); * If we are at the end of the input file and have encoded
} while (data_written); * all remaining samples, we can exit this loop and finish.
break; */
if (finished)
{
int data_written;
/** Flush the encoder as it may have delayed frames. */
do {
encode_audio_frame (NULL,
output_format_context,
output_codec_context,
&data_written);
} while (data_written);
break;
} }
} }
/** Write the trailer of the output file container. */ /** Write the trailer of the output file container. */
if (write_output_file_trailer(output_format_context)) if (write_output_file_trailer(output_format_context))
goto cleanup; goto cleanup;
ec->proc (ec->cls,
ec->proc (ec->cls, "previewopus",
"previewopus", EXTRACTOR_METATYPE_AUDIO_PREVIEW,
EXTRACTOR_METATYPE_AUDIO_PREVIEW, EXTRACTOR_METAFORMAT_BINARY,
EXTRACTOR_METAFORMAT_BINARY, "audio/opus",
"audio/opus", buffer,
buffer, totalSize);
totalSize);
#if OUTPUT_FILE #if OUTPUT_FILE
FILE *f; {
f = fopen("example.opus", "wb"); FILE *f;
if (!f) {
fprintf(stderr, "Could not open %s\n", "file");
exit(1);
}
fwrite(buffer, 1, totalSize, f);
fclose(f);
f = fopen ("example.opus", "wb");
if (!f)
{
fprintf (stderr, "Could not open %s\n", "file");
exit(1);
}
fwrite (buffer, 1, totalSize, f);
fclose(f);
}
#endif #endif
cleanup: cleanup:
av_free (frame); av_free (frame);
free (buffer);
free(buffer); if (fifo)
av_audio_fifo_free(fifo);
if (fifo) if (resample_context)
av_audio_fifo_free(fifo); {
if (resample_context) { avresample_close(resample_context);
avresample_close(resample_context); avresample_free(&resample_context);
avresample_free(&resample_context); }
} if (output_codec_context)
if (output_codec_context) avcodec_close(output_codec_context);
avcodec_close(output_codec_context);
if (codec_ctx)
avcodec_close(codec_ctx);
if (format_ctx)
avformat_close_input(&format_ctx);
av_free (io_ctx);
if (codec_ctx)
avcodec_close(codec_ctx);
if (format_ctx)
avformat_close_input(&format_ctx);
av_free (io_ctx);
} }
/** /**
* Main method for the opus-preview plugin. * Main method for the opus-preview plugin.
* *
* @param ec extraction context * @param ec extraction context
*/ */
void void
EXTRACTOR_previewopus_extract_method (struct EXTRACTOR_ExtractContext *ec) EXTRACTOR_previewopus_extract_method (struct EXTRACTOR_ExtractContext *ec)
{ {
 End of changes. 53 change blocks. 
205 lines changed or deleted 227 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)