libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

previewopus_extractor.c File Reference

this extractor produces a binary encoded audio snippet of music/video files using ffmpeg libs. More...

#include "platform.h"
#include "extractor.h"
#include <magic.h>
#include <libavutil/avutil.h>
#include <libavutil/audio_fifo.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavresample/avresample.h>
Include dependency graph for previewopus_extractor.c:

Go to the source code of this file.

Macros

#define DEBUG   0
 
#define OUTPUT_FILE   0
 
#define MAX_SIZE   (28 * 1024)
 
#define HARD_LIMIT_SIZE   (50 * 1024)
 
#define OUTPUT_BIT_RATE   28000
 
#define OUTPUT_CHANNELS   2
 
#define OUTPUT_SAMPLE_FORMAT   AV_SAMPLE_FMT_S16
 
#define ENUM_CODEC_ID   enum AVCodecID
 

Functions

static char *const get_error_text (const int error)
 
static int read_cb (void *opaque, uint8_t *buf, int buf_size)
 
static int64_t seek_cb (void *opaque, int64_t offset, int whence)
 
static int writePacket (void *opaque, unsigned char *pBuffer, int pBufferSize)
 
static int open_output_file (AVCodecContext *input_codec_context, AVFormatContext **output_format_context, AVCodecContext **output_codec_context)
 
static void init_packet (AVPacket *packet)
 
static int init_input_frame (AVFrame **frame)
 
static int init_resampler (AVCodecContext *input_codec_context, AVCodecContext *output_codec_context, AVAudioResampleContext **resample_context)
 
static int init_fifo (AVAudioFifo **fifo)
 
static int write_output_file_header (AVFormatContext *output_format_context)
 
static int decode_audio_frame (AVFrame *frame, AVFormatContext *input_format_context, AVCodecContext *input_codec_context, int audio_stream_index, int *data_present, int *finished)
 
static int init_converted_samples (uint8_t ***converted_input_samples, int *out_linesize, AVCodecContext *output_codec_context, int frame_size)
 
static int convert_samples (uint8_t **input_data, uint8_t **converted_data, const int in_sample, const int out_sample, const int out_linesize, AVAudioResampleContext *resample_context)
 
static int add_samples_to_fifo (AVAudioFifo *fifo, uint8_t **converted_input_samples, const int frame_size)
 
static int read_decode_convert_and_store (AVAudioFifo *fifo, AVFormatContext *input_format_context, AVCodecContext *input_codec_context, AVCodecContext *output_codec_context, AVAudioResampleContext *resampler_context, int audio_stream_index, int *finished)
 
static int init_output_frame (AVFrame **frame, AVCodecContext *output_codec_context, int frame_size)
 
static int encode_audio_frame (AVFrame *frame, AVFormatContext *output_format_context, AVCodecContext *output_codec_context, int *data_present)
 
static int load_encode_and_write (AVAudioFifo *fifo, AVFormatContext *output_format_context, AVCodecContext *output_codec_context)
 
static int write_output_file_trailer (AVFormatContext *output_format_context)
 
static void extract_audio (struct EXTRACTOR_ExtractContext *ec)
 
void EXTRACTOR_previewopus_extract_method (struct EXTRACTOR_ExtractContext *ec)
 
static void previewopus_av_log_callback (void *ptr, int level, const char *format, va_list ap)
 
void previewopus_lib_init (void)
 
void previewopus_ltdl_fini ()
 

Variables

static unsigned char * buffer
 
static int totalSize
 

Detailed Description

this extractor produces a binary encoded audio snippet of music/video files using ffmpeg libs.

Author
Bruno Cabral
Christian Grothoff

Based on ffmpeg samples.

Note that ffmpeg has a few issues: (1) there are no recent official releases of the ffmpeg libs (2) ffmpeg has a history of having security issues (parser is not robust)

So this plugin cannot be recommended for system with high security requirements.

Definition in file previewopus_extractor.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG   0

Set to 1 to enable debug output.

Definition at line 53 of file previewopus_extractor.c.

◆ ENUM_CODEC_ID

#define ENUM_CODEC_ID   enum AVCodecID

Definition at line 865 of file previewopus_extractor.c.

◆ HARD_LIMIT_SIZE

#define HARD_LIMIT_SIZE   (50 * 1024)

HardLimit for file

Definition at line 69 of file previewopus_extractor.c.

◆ MAX_SIZE

#define MAX_SIZE   (28 * 1024)

Maximum size in bytes for the preview.

Definition at line 64 of file previewopus_extractor.c.

◆ OUTPUT_BIT_RATE

#define OUTPUT_BIT_RATE   28000

The output bit rate in kbit/s

Definition at line 73 of file previewopus_extractor.c.

◆ OUTPUT_CHANNELS

#define OUTPUT_CHANNELS   2

The number of output channels

Definition at line 75 of file previewopus_extractor.c.

◆ OUTPUT_FILE

#define OUTPUT_FILE   0

Set to 1 to enable a output file for testing.

Definition at line 58 of file previewopus_extractor.c.

◆ OUTPUT_SAMPLE_FORMAT

#define OUTPUT_SAMPLE_FORMAT   AV_SAMPLE_FMT_S16

The audio sample output format

Definition at line 77 of file previewopus_extractor.c.

Function Documentation

◆ add_samples_to_fifo()

static int add_samples_to_fifo ( AVAudioFifo *  fifo,
uint8_t **  converted_input_samples,
const int  frame_size 
)
static

Add converted input audio samples to the FIFO buffer for later processing.

Make the FIFO as large as it needs to be to hold both, the old and the new samples.

Store the new samples in the FIFO buffer.

Definition at line 550 of file previewopus_extractor.c.

Referenced by read_decode_convert_and_store().

◆ convert_samples()

static int convert_samples ( uint8_t **  input_data,
uint8_t **  converted_data,
const int  in_sample,
const int  out_sample,
const int  out_linesize,
AVAudioResampleContext *  resample_context 
)
static

Convert the input audio samples into the output sample format. The conversion happens on a per-frame basis, the size of which is specified by frame_size.

Convert the samples using the resampler.

Perform a sanity check so that the number of converted samples is not greater than the number of samples to be converted. If the sample rates differ, this case has to be handled differently

Definition at line 511 of file previewopus_extractor.c.

References get_error_text().

Referenced by read_decode_convert_and_store().

◆ decode_audio_frame()

static int decode_audio_frame ( AVFrame *  frame,
AVFormatContext *  input_format_context,
AVCodecContext *  input_codec_context,
int  audio_stream_index,
int *  data_present,
int *  finished 
)
static

Decode one audio frame from the input file.

Packet used for temporary storage.

Read one audio frame from the input file into a temporary packet.

If we are the the end of the file, flush the decoder below.

Decode the audio frame stored in the temporary packet. The input audio stream decoder is used to do this. If we are at the end of the file, pass an empty packet to the decoder to flush it.

If the decoder has not been flushed completely, we are not finished, so that this function has to be called again.

Definition at line 394 of file previewopus_extractor.c.

References get_error_text(), and init_packet().

Referenced by read_decode_convert_and_store().

◆ encode_audio_frame()

static int encode_audio_frame ( AVFrame *  frame,
AVFormatContext *  output_format_context,
AVCodecContext *  output_codec_context,
int *  data_present 
)
static

Encode one frame worth of audio to the output file.

Packet used for temporary storage.

Encode the audio frame and store it in the temporary packet. The output audio stream encoder is used to do this.

Write one audio frame from the temporary packet to the output file.

Definition at line 753 of file previewopus_extractor.c.

References get_error_text(), and init_packet().

Referenced by extract_audio(), and load_encode_and_write().

◆ extract_audio()

static void extract_audio ( struct EXTRACTOR_ExtractContext ec)
static

Perform the audio snippet extraction

Parameters
ecextraction context to use

Open the output file for writing.

Initialize the resampler to be able to convert audio sample formats.

Initialize the FIFO buffer to store audio samples to be encoded.

Write the header of the output file container.

Loop as long as we have input samples to read or output samples to write; abort as soon as we have neither.

Use the encoder's desired frame size for processing.

Make sure that there is one frame worth of samples in the FIFO buffer so that the encoder can do its work. Since the decoder's and the encoder's frame size may differ, we 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.

Decode one frame worth of audio samples, convert it to the output sample format and put it into the FIFO buffer.

If we are at the end of the input file, we continue encoding the remaining audio samples to the output file.

If we have enough samples for the encoder, we encode them. At the end of the file, we pass the remaining samples to the encoder.

Take one frame worth of audio samples from the FIFO buffer, encode it and write it to the output file.

If we are at the end of the input file and have encoded all remaining samples, we can exit this loop and finish.

Flush the encoder as it may have delayed frames.

Write the trailer of the output file container.

Definition at line 874 of file previewopus_extractor.c.

References buffer, EXTRACTOR_ExtractContext::cls, encode_audio_frame(), EXTRACTOR_METAFORMAT_BINARY, EXTRACTOR_METATYPE_AUDIO_PREVIEW, HARD_LIMIT_SIZE, init_fifo(), init_resampler(), load_encode_and_write(), MAX_SIZE, NULL, open_output_file(), EXTRACTOR_ExtractContext::proc, read_cb(), read_decode_convert_and_store(), seek_cb(), totalSize, write_output_file_header(), and write_output_file_trailer().

Referenced by EXTRACTOR_previewopus_extract_method().

◆ EXTRACTOR_previewopus_extract_method()

void EXTRACTOR_previewopus_extract_method ( struct EXTRACTOR_ExtractContext ec)

Main method for the opus-preview plugin.

Parameters
ecextraction context

Definition at line 1164 of file previewopus_extractor.c.

References EXTRACTOR_ExtractContext::cls, extract_audio(), EXTRACTOR_ExtractContext::read, and EXTRACTOR_ExtractContext::seek.

◆ get_error_text()

static char* const get_error_text ( const int  error)
static

Convert an error code into a text message.

Parameters
errorError code to be converted
Returns
Corresponding error text (not thread-safe)

Definition at line 92 of file previewopus_extractor.c.

Referenced by convert_samples(), decode_audio_frame(), encode_audio_frame(), init_converted_samples(), init_output_frame(), open_output_file(), write_output_file_header(), and write_output_file_trailer().

◆ init_converted_samples()

static int init_converted_samples ( uint8_t ***  converted_input_samples,
int *  out_linesize,
AVCodecContext *  output_codec_context,
int  frame_size 
)
static

Initialize a temporary storage for the specified number of audio samples. The conversion requires temporary storage due to the different format. The number of audio samples to be allocated is specified in frame_size.

Allocate as many pointers as there are audio channels. Each pointer will later point to the audio samples of the corresponding channels (although it may be NULL for interleaved formats).

Allocate memory for the samples of all channels in one consecutive block for convenience.

Definition at line 464 of file previewopus_extractor.c.

References get_error_text().

Referenced by read_decode_convert_and_store().

◆ init_fifo()

static int init_fifo ( AVAudioFifo **  fifo)
static

Initialize a FIFO buffer for the audio samples to be encoded.

Create the FIFO buffer based on the specified output sample format.

Definition at line 360 of file previewopus_extractor.c.

References OUTPUT_CHANNELS, and OUTPUT_SAMPLE_FORMAT.

Referenced by extract_audio().

◆ init_input_frame()

static int init_input_frame ( AVFrame **  frame)
static

Initialize one audio frame for reading from the input file

Definition at line 281 of file previewopus_extractor.c.

References NULL.

Referenced by read_decode_convert_and_store().

◆ init_output_frame()

static int init_output_frame ( AVFrame **  frame,
AVCodecContext *  output_codec_context,
int  frame_size 
)
static

Initialize one input frame for writing to the output file. The frame will be exactly frame_size samples large.

Create a new frame to store the audio samples.

Set the frame's parameters, especially its size and format. av_frame_get_buffer needs this to allocate memory for the audio samples of the frame. Default channel layouts based on the number of channels are assumed for simplicity.

Allocate the samples of the created frame. This call will make sure that the audio frame can hold as many samples as specified.

Definition at line 703 of file previewopus_extractor.c.

References get_error_text(), and NULL.

Referenced by load_encode_and_write().

◆ init_packet()

static void init_packet ( AVPacket *  packet)
static

Initialize one data packet for reading or writing.

Set the packet data and size so that it is recognized as being empty.

Definition at line 270 of file previewopus_extractor.c.

References NULL.

Referenced by decode_audio_frame(), and encode_audio_frame().

◆ init_resampler()

static int init_resampler ( AVCodecContext *  input_codec_context,
AVCodecContext *  output_codec_context,
AVAudioResampleContext **  resample_context 
)
static

Initialize the audio resampler based on the input and output codec settings. If the input and output sample formats differ, a conversion is required libavresample takes care of this, but requires initialization.

Only initialize the resampler if it is necessary, i.e., if and only if the sample formats differ.

Create a resampler context for the conversion.

Set the conversion parameters. Default channel layouts based on the number of channels are assumed for simplicity (they are sometimes not detected properly by the demuxer and/or decoder).

Open the resampler with the specified parameters.

Definition at line 301 of file previewopus_extractor.c.

Referenced by extract_audio().

◆ load_encode_and_write()

static int load_encode_and_write ( AVAudioFifo *  fifo,
AVFormatContext *  output_format_context,
AVCodecContext *  output_codec_context 
)
static

Load one audio frame from the FIFO buffer, encode and write it to the output file.

Temporary storage of the output samples of the frame written to the file.

Use the maximum number of possible samples per frame. If there is less than the maximum possible frame size in the FIFO buffer use this number. Otherwise, use the maximum possible frame size

Initialize temporary storage for one output frame.

Read as many samples from the FIFO buffer as required to fill the frame. The samples are stored in the frame temporarily.

Encode one frame worth of audio samples.

Definition at line 804 of file previewopus_extractor.c.

References encode_audio_frame(), and init_output_frame().

Referenced by extract_audio().

◆ open_output_file()

static int open_output_file ( AVCodecContext *  input_codec_context,
AVFormatContext **  output_format_context,
AVCodecContext **  output_codec_context 
)
static

Open an output file and the required encoder. Also set some basic encoder parameters. Some of these parameters are based on the input file's parameters.

Guess the desired container format based on the file extension.

Find the encoder to be used by its name.

Create a new audio stream in the output file container.

Save the encoder context for easiert access later.

Set the basic encoder parameters. The input file's sample rate is used to avoid a sample rate conversion.

Open the encoder for the audio stream to use it later.

Definition at line 176 of file previewopus_extractor.c.

References get_error_text(), NULL, OUTPUT_BIT_RATE, OUTPUT_CHANNELS, and writePacket().

Referenced by extract_audio().

◆ previewopus_av_log_callback()

static void previewopus_av_log_callback ( void *  ptr,
int  level,
const char *  format,
va_list  ap 
)
static

Log callback. Does nothing.

Parameters
ptrNULL
levellog level
formatformat string
aparguments for format

Definition at line 1190 of file previewopus_extractor.c.

Referenced by previewopus_lib_init().

◆ previewopus_lib_init()

void previewopus_lib_init ( void  )

Initialize av-libs

Definition at line 1205 of file previewopus_extractor.c.

References previewopus_av_log_callback().

◆ previewopus_ltdl_fini()

void previewopus_ltdl_fini ( )

Destructor for the library, cleans up.

Definition at line 1215 of file previewopus_extractor.c.

◆ read_cb()

static int read_cb ( void *  opaque,
uint8_t *  buf,
int  buf_size 
)
static

Read callback.

Parameters
opaquethe 'struct EXTRACTOR_ExtractContext'
bufwhere to write data
buf_sizehow many bytes to read
Returns
-1 on error (or for unknown file size)

Definition at line 109 of file previewopus_extractor.c.

References EXTRACTOR_ExtractContext::cls, and EXTRACTOR_ExtractContext::read.

Referenced by extract_audio().

◆ read_decode_convert_and_store()

static int read_decode_convert_and_store ( AVAudioFifo *  fifo,
AVFormatContext *  input_format_context,
AVCodecContext *  input_codec_context,
AVCodecContext *  output_codec_context,
AVAudioResampleContext *  resampler_context,
int  audio_stream_index,
int *  finished 
)
static

Read one audio frame from the input file, decodes, converts and stores it in the FIFO buffer.

Temporary storage of the input samples of the frame read from the file.

Temporary storage for the converted input samples.

Initialize temporary storage for one input frame.

Decode one frame worth of audio samples.

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 there is decoded data, convert and store it

Initialize the temporary storage for the converted input samples.

Convert the input samples to the desired output sample format. This requires a temporary storage provided by converted_input_samples.

Add the converted input samples to the FIFO buffer for later processing.

Definition at line 587 of file previewopus_extractor.c.

References add_samples_to_fifo(), convert_samples(), decode_audio_frame(), init_converted_samples(), init_input_frame(), and NULL.

Referenced by extract_audio().

◆ seek_cb()

static int64_t seek_cb ( void *  opaque,
int64_t  offset,
int  whence 
)
static

Seek callback.

Parameters
opaquethe 'struct EXTRACTOR_ExtractContext'
offsetwhere to seek
whencehow to seek; AVSEEK_SIZE to return file size without seeking
Returns
-1 on error (or for unknown file size)

Definition at line 134 of file previewopus_extractor.c.

References EXTRACTOR_ExtractContext::cls, EXTRACTOR_ExtractContext::get_size, and EXTRACTOR_ExtractContext::seek.

Referenced by extract_audio().

◆ write_output_file_header()

static int write_output_file_header ( AVFormatContext *  output_format_context)
static

Write the header of the output file container.

Definition at line 377 of file previewopus_extractor.c.

References get_error_text(), and NULL.

Referenced by extract_audio().

◆ write_output_file_trailer()

static int write_output_file_trailer ( AVFormatContext *  output_format_context)
static

Write the trailer of the output file container.

Definition at line 850 of file previewopus_extractor.c.

References get_error_text().

Referenced by extract_audio().

◆ writePacket()

static int writePacket ( void *  opaque,
unsigned char *  pBuffer,
int  pBufferSize 
)
static

write callback.

Parameters
opaqueNULL
pBufferto write
pBufferSize,amountto write
Returns
0 on error

Definition at line 155 of file previewopus_extractor.c.

References buffer, HARD_LIMIT_SIZE, and totalSize.

Referenced by open_output_file().

Variable Documentation

◆ buffer

unsigned char* buffer
static

Our output buffer

Definition at line 81 of file previewopus_extractor.c.

Referenced by extract_audio(), feed_data(), flac_read(), read_cb(), and writePacket().

◆ totalSize

int totalSize
static

Actual output buffer size

Definition at line 84 of file previewopus_extractor.c.

Referenced by extract_audio(), and writePacket().