mirror of
https://github.com/alexkay/spek.git
synced 2025-06-02 00:20:57 +03:00
Use avcodec_decode_audio4
This commit is contained in:
parent
69d400e34c
commit
b1b102044e
@ -32,7 +32,7 @@ AC_MSG_RESULT([$os])
|
|||||||
|
|
||||||
AC_CHECK_LIB(m, log10)
|
AC_CHECK_LIB(m, log10)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(FFMPEG, [libavformat >= 52.111 libavcodec >= 52.123 libavutil])
|
PKG_CHECK_MODULES(FFMPEG, [libavformat >= 54.2 libavcodec >= 53.25 libavutil >= 51.18])
|
||||||
|
|
||||||
AM_OPTIONS_WXCONFIG
|
AM_OPTIONS_WXCONFIG
|
||||||
reqwx=2.8.0
|
reqwx=2.8.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* spek-audio.cc
|
/* spek-audio.cc
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
|
* Copyright (C) 2010-2013 Alexander Kojevnikov <alexander@kojevnikov.com>
|
||||||
*
|
*
|
||||||
* Spek is free software: you can redistribute it and/or modify
|
* Spek is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -35,8 +35,10 @@ struct spek_audio_context
|
|||||||
AVStream *stream;
|
AVStream *stream;
|
||||||
AVCodec *codec;
|
AVCodec *codec;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
AVPacket *packet;
|
AVPacket packet;
|
||||||
int offset;
|
int offset;
|
||||||
|
int is_planar;
|
||||||
|
AVFrame *frame;
|
||||||
|
|
||||||
struct spek_audio_properties properties;
|
struct spek_audio_properties properties;
|
||||||
};
|
};
|
||||||
@ -44,7 +46,6 @@ struct spek_audio_context
|
|||||||
|
|
||||||
void spek_audio_init()
|
void spek_audio_init()
|
||||||
{
|
{
|
||||||
// TODO: register only audio decoders.
|
|
||||||
av_register_all();
|
av_register_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,31 +115,29 @@ struct spek_audio_context * spek_audio_open(const char *path)
|
|||||||
cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_DECODER;
|
cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_DECODER;
|
||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
cx->is_planar = av_sample_fmt_is_planar(cx->codec_context->sample_fmt);
|
||||||
|
cx->properties.width = 8 * av_get_bytes_per_sample(cx->codec_context->sample_fmt);
|
||||||
switch (cx->codec_context->sample_fmt) {
|
switch (cx->codec_context->sample_fmt) {
|
||||||
case AV_SAMPLE_FMT_S16:
|
case AV_SAMPLE_FMT_S16:
|
||||||
cx->properties.width = 16;
|
case AV_SAMPLE_FMT_S16P:
|
||||||
cx->properties.fp = false;
|
|
||||||
break;
|
|
||||||
case AV_SAMPLE_FMT_S32:
|
case AV_SAMPLE_FMT_S32:
|
||||||
cx->properties.width = 32;
|
case AV_SAMPLE_FMT_S32P:
|
||||||
cx->properties.fp = false;
|
cx->properties.fp = false;
|
||||||
break;
|
break;
|
||||||
case AV_SAMPLE_FMT_FLT:
|
case AV_SAMPLE_FMT_FLT:
|
||||||
cx->properties.width = 32;
|
case AV_SAMPLE_FMT_FLTP:
|
||||||
cx->properties.fp = true;
|
|
||||||
break;
|
|
||||||
case AV_SAMPLE_FMT_DBL:
|
case AV_SAMPLE_FMT_DBL:
|
||||||
cx->properties.width = 64;
|
case AV_SAMPLE_FMT_DBLP:
|
||||||
cx->properties.fp = true;
|
cx->properties.fp = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cx->properties.error = SPEK_AUDIO_BAD_SAMPLE_FORMAT;
|
cx->properties.error = SPEK_AUDIO_BAD_SAMPLE_FORMAT;
|
||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
|
cx->buffer_size = 0;
|
||||||
cx->properties.buffer = (uint8_t*)av_malloc(cx->buffer_size);
|
cx->properties.buffer = NULL;
|
||||||
cx->packet = (AVPacket*)av_mallocz(sizeof(AVPacket));
|
av_init_packet(&cx->packet);
|
||||||
av_init_packet(cx->packet);
|
cx->frame = avcodec_alloc_frame();
|
||||||
cx->offset = 0;
|
cx->offset = 0;
|
||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
@ -160,38 +159,45 @@ int spek_audio_read(struct spek_audio_context *cx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (cx->packet->size > 0) {
|
while (cx->packet.size > 0) {
|
||||||
int buffer_size = cx->buffer_size;
|
avcodec_get_frame_defaults(cx->frame);
|
||||||
int len = avcodec_decode_audio3(
|
int got_frame = 0;
|
||||||
cx->codec_context, (int16_t *)cx->properties.buffer, &buffer_size, cx->packet);
|
int len = avcodec_decode_audio4(cx->codec_context, cx->frame, &got_frame, &cx->packet);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
// Error, skip the frame.
|
// Error, skip the frame.
|
||||||
cx->packet->size = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cx->packet->data += len;
|
cx->packet.data += len;
|
||||||
cx->packet->size -= len;
|
cx->packet.size -= len;
|
||||||
cx->offset += len;
|
cx->offset += len;
|
||||||
if (buffer_size <= 0) {
|
if (!got_frame) {
|
||||||
// No data yet, get more frames.
|
// No data yet, get more frames.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// We have data, return it and come back for more later.
|
// We have data, return it and come back for more later.
|
||||||
|
int buffer_size =
|
||||||
|
cx->frame->nb_samples * cx->properties.channels *
|
||||||
|
(cx->properties.width / 8);
|
||||||
|
if (buffer_size > cx->buffer_size) {
|
||||||
|
cx->properties.buffer = (uint8_t*)av_realloc(cx->properties.buffer, buffer_size);
|
||||||
|
cx->buffer_size = buffer_size;
|
||||||
|
}
|
||||||
|
memcpy(cx->properties.buffer, cx->frame->data[0], buffer_size);
|
||||||
return buffer_size;
|
return buffer_size;
|
||||||
}
|
}
|
||||||
if (cx->packet->data) {
|
if (cx->packet.data) {
|
||||||
cx->packet->data -= cx->offset;
|
cx->packet.data -= cx->offset;
|
||||||
cx->packet->size += cx->offset;
|
cx->packet.size += cx->offset;
|
||||||
cx->offset = 0;
|
cx->offset = 0;
|
||||||
av_free_packet (cx->packet);
|
av_free_packet (&cx->packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
while ((res = av_read_frame(cx->format_context, cx->packet)) >= 0) {
|
while ((res = av_read_frame(cx->format_context, &cx->packet)) >= 0) {
|
||||||
if (cx->packet->stream_index == cx->audio_stream) {
|
if (cx->packet.stream_index == cx->audio_stream) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
av_free_packet(cx->packet);
|
av_free_packet(&cx->packet);
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
// End of file or error.
|
// End of file or error.
|
||||||
@ -205,23 +211,23 @@ void spek_audio_close(struct spek_audio_context *cx)
|
|||||||
if (cx->properties.codec_name != NULL) {
|
if (cx->properties.codec_name != NULL) {
|
||||||
free(cx->properties.codec_name);
|
free(cx->properties.codec_name);
|
||||||
}
|
}
|
||||||
|
if (cx->frame != NULL) {
|
||||||
|
avcodec_free_frame(&cx->frame);
|
||||||
|
}
|
||||||
|
if (cx->packet.data) {
|
||||||
|
cx->packet.data -= cx->offset;
|
||||||
|
cx->packet.size += cx->offset;
|
||||||
|
cx->offset = 0;
|
||||||
|
av_free_packet(&cx->packet);
|
||||||
|
}
|
||||||
if (cx->properties.buffer) {
|
if (cx->properties.buffer) {
|
||||||
av_free(cx->properties.buffer);
|
av_free(cx->properties.buffer);
|
||||||
}
|
}
|
||||||
if (cx->packet) {
|
|
||||||
if (cx->packet->data) {
|
|
||||||
cx->packet->data -= cx->offset;
|
|
||||||
cx->packet->size += cx->offset;
|
|
||||||
cx->offset = 0;
|
|
||||||
av_free_packet(cx->packet);
|
|
||||||
}
|
|
||||||
av_free(cx->packet);
|
|
||||||
}
|
|
||||||
if (cx->codec_context != NULL) {
|
if (cx->codec_context != NULL) {
|
||||||
avcodec_close(cx->codec_context);
|
avcodec_close(cx->codec_context);
|
||||||
}
|
}
|
||||||
if (cx->format_context != NULL) {
|
if (cx->format_context != NULL) {
|
||||||
av_close_input_file(cx->format_context);
|
avformat_close_input(&cx->format_context);
|
||||||
}
|
}
|
||||||
free(cx);
|
free(cx);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* spek-audio.h
|
/* spek-audio.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
|
* Copyright (C) 2010-2013 Alexander Kojevnikov <alexander@kojevnikov.com>
|
||||||
*
|
*
|
||||||
* Spek is free software: you can redistribute it and/or modify
|
* Spek is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,8 +19,8 @@
|
|||||||
#ifndef SPEK_AUDIO_H_
|
#ifndef SPEK_AUDIO_H_
|
||||||
#define SPEK_AUDIO_H_
|
#define SPEK_AUDIO_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <tr1/cstdint>
|
||||||
#include <stdint.h>
|
#include <string>
|
||||||
|
|
||||||
struct spek_audio_context;
|
struct spek_audio_context;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user