X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpegaudioenc.c;h=ba0d8cfcab480896ebec934ac9ccc1638691a208;hb=7a95afe433b2a692f490b98948c082e62ffc1d27;hp=69d5243db8d96de2f38a4bd4a7b57d026ee7aa80;hpb=162d4fc99d07fcd3322aee9bcc99f045463da2b7;p=ffmpeg diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c index 69d5243db8d..ba0d8cfcab4 100644 --- a/libavcodec/mpegaudioenc.c +++ b/libavcodec/mpegaudioenc.c @@ -1,32 +1,40 @@ /* * The simplest mpeg audio layer 2 encoder - * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2000, 2001 Fabrice Bellard * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file mpegaudio.c + * @file * The simplest mpeg audio layer 2 encoder. */ +#include "libavutil/channel_layout.h" + #include "avcodec.h" -#include "bitstream.h" +#include "internal.h" +#include "put_bits.h" + +#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */ +#define WFRAC_BITS 14 /* fractional bits for window */ + #include "mpegaudio.h" +#include "mpegaudiodsp.h" /* currently, cannot change these constants (need to modify quantization stage) */ @@ -37,12 +45,10 @@ typedef struct MpegAudioContext { PutBitContext pb; int nb_channels; - int freq, bit_rate; int lsf; /* 1 if mpeg2 low bitrate selected */ int bitrate_index; /* bit rate */ int freq_index; int frame_size; /* frame size, in bits, without padding */ - int64_t nb_samples; /* total number of samples encoded */ /* padding computation */ int frame_frac, frame_frac_incr, do_padding; short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ @@ -56,7 +62,7 @@ typedef struct MpegAudioContext { } MpegAudioContext; /* define it to use floats in quantization (I don't like floats !) */ -//#define USE_FLOATS +#define USE_FLOATS #include "mpegaudiodata.h" #include "mpegaudiotab.h" @@ -72,38 +78,37 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) if (channels <= 0 || channels > 2){ av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); - return -1; + return AVERROR(EINVAL); } bitrate = bitrate / 1000; s->nb_channels = channels; - s->freq = freq; - s->bit_rate = bitrate * 1000; avctx->frame_size = MPA_FRAME_SIZE; + avctx->delay = 512 - 32 + 1; /* encoding freq */ s->lsf = 0; for(i=0;i<3;i++) { - if (ff_mpa_freq_tab[i] == freq) + if (avpriv_mpa_freq_tab[i] == freq) break; - if ((ff_mpa_freq_tab[i] / 2) == freq) { + if ((avpriv_mpa_freq_tab[i] / 2) == freq) { s->lsf = 1; break; } } if (i == 3){ av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return -1; + return AVERROR(EINVAL); } s->freq_index = i; /* encoding bitrate & frequency */ for(i=0;i<15;i++) { - if (ff_mpa_bitrate_tab[s->lsf][1][i] == bitrate) + if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate) break; } if (i == 15){ av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return -1; + return AVERROR(EINVAL); } s->bitrate_index = i; @@ -123,10 +128,8 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) s->sblimit = ff_mpa_sblimit_table[table]; s->alloc_table = ff_mpa_alloc_tables[table]; -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", - bitrate, freq, s->frame_size, table, s->frame_frac_incr); -#endif + av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", + bitrate, freq, s->frame_size, table, s->frame_frac_incr); for(i=0;inb_channels;i++) s->samples_offset[i] = 0; @@ -181,8 +184,11 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) total_quant_bits[i] = 12 * v; } +#if FF_API_OLD_ENCODE_AUDIO avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; + if (!avctx->coded_frame) + return AVERROR(ENOMEM); +#endif return 0; } @@ -309,7 +315,7 @@ static void idct32(int *out, int *tab) #define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) -static void filter(MpegAudioContext *s, int ch, short *samples, int incr) +static void filter(MpegAudioContext *s, int ch, const short *samples, int incr) { short *p, *q; int sum, offset, i, j; @@ -317,8 +323,6 @@ static void filter(MpegAudioContext *s, int ch, short *samples, int incr) int tmp1[32]; int *out; - // print_pow1(samples, 1152); - offset = s->samples_offset[ch]; out = &s->sb_samples[ch][0][0][0]; for(j=0;j<36;j++) { @@ -362,8 +366,6 @@ static void filter(MpegAudioContext *s, int ch, short *samples, int incr) } } s->samples_offset[ch] = offset; - - // print_pow(s->sb_samples, 1152); } static void compute_scale_factors(unsigned char scale_code[SBLIMIT], @@ -387,7 +389,7 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT], vmax = v; } /* compute the scale factor index using log 2 computations */ - if (vmax > 0) { + if (vmax > 1) { n = av_log2(vmax); /* n is the position of the MSB of vmax. now use at most 2 compares to find the index */ @@ -402,10 +404,8 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT], index = 62; /* value 63 is not allowed */ } -#if 0 - printf("%2d:%d in=%x %x %d\n", - j, i, vmax, scale_factor_table[index], index); -#endif + av_dlog(NULL, "%2d:%d in=%x %x %d\n", + j, i, vmax, scale_factor_table[index], index); /* store the scale factor */ assert(index >=0 && index <= 63); sf[i] = index; @@ -473,10 +473,8 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT], code = 0; /* kill warning */ } -#if 0 - printf("%d: %2d %2d %2d %d %d -> %d\n", j, - sf[0], sf[1], sf[2], d1, d2, code); -#endif + av_dlog(NULL, "%d: %2d %2d %2d %d %d -> %d\n", j, + sf[0], sf[1], sf[2], d1, d2, code); scale_code[j] = code; sf += 3; } @@ -540,7 +538,7 @@ static void compute_bit_allocation(MpegAudioContext *s, /* look for the subband with the largest signal to mask ratio */ max_sb = -1; max_ch = -1; - max_smr = 0x80000000; + max_smr = INT_MIN; for(ch=0;chnb_channels;ch++) { for(i=0;isblimit;i++) { if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { @@ -550,13 +548,11 @@ static void compute_bit_allocation(MpegAudioContext *s, } } } -#if 0 - printf("current=%d max=%d max_sb=%d alloc=%d\n", - current_frame_size, max_frame_size, max_sb, - bit_alloc[max_sb]); -#endif if (max_sb < 0) break; + av_dlog(NULL, "current=%d max=%d max_sb=%d max_ch=%d alloc=%d\n", + current_frame_size, max_frame_size, max_sb, max_ch, + bit_alloc[max_ch][max_sb]); /* find alloc table entry (XXX: not optimal, should use pointer table) */ @@ -594,13 +590,6 @@ static void compute_bit_allocation(MpegAudioContext *s, } *padding = max_frame_size - current_frame_size; assert(*padding >= 0); - -#if 0 - for(i=0;isblimit;i++) { - printf("%d ", bit_alloc[i]); - } - printf("\n"); -#endif } /* @@ -722,15 +711,7 @@ static void encode_frame(MpegAudioContext *s, /* group the 3 values to save bits */ put_bits(p, -bits, q[0] + steps * (q[1] + steps * q[2])); -#if 0 - printf("%d: gr1 %d\n", - i, q[0] + steps * (q[1] + steps * q[2])); -#endif } else { -#if 0 - printf("%d: gr3 %d %d %d\n", - i, q[0], q[1], q[2]); -#endif put_bits(p, bits, q[0]); put_bits(p, bits, q[1]); put_bits(p, bits, q[2]); @@ -751,14 +732,14 @@ static void encode_frame(MpegAudioContext *s, flush_put_bits(p); } -static int MPA_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) +static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) { MpegAudioContext *s = avctx->priv_data; - short *samples = data; + const int16_t *samples = (const int16_t *)frame->data[0]; short smr[MPA_MAX_CHANNELS][SBLIMIT]; unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - int padding, i; + int padding, i, ret; for(i=0;inb_channels;i++) { filter(s, i, samples + i, s->nb_channels); @@ -773,30 +754,52 @@ static int MPA_encode_frame(AVCodecContext *avctx, } compute_bit_allocation(s, smr, bit_alloc, &padding); - init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE); + if ((ret = ff_alloc_packet(avpkt, MPA_MAX_CODED_FRAME_SIZE))) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); + return ret; + } + + init_put_bits(&s->pb, avpkt->data, avpkt->size); encode_frame(s, bit_alloc, padding); - s->nb_samples += MPA_FRAME_SIZE; - return pbBufPtr(&s->pb) - s->pb.buf; + if (frame->pts != AV_NOPTS_VALUE) + avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay); + + avpkt->size = put_bits_count(&s->pb) / 8; + *got_packet_ptr = 1; + return 0; } static av_cold int MPA_encode_close(AVCodecContext *avctx) { +#if FF_API_OLD_ENCODE_AUDIO av_freep(&avctx->coded_frame); +#endif return 0; } -AVCodec mp2_encoder = { - "mp2", - CODEC_TYPE_AUDIO, - CODEC_ID_MP2, - sizeof(MpegAudioContext), - MPA_encode_init, - MPA_encode_frame, - MPA_encode_close, - NULL, - .long_name = "MP2 (MPEG audio layer 2)", +static const AVCodecDefault mp2_defaults[] = { + { "b", "128k" }, + { NULL }, }; -#undef FIX +AVCodec ff_mp2_encoder = { + .name = "mp2", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_MP2, + .priv_data_size = sizeof(MpegAudioContext), + .init = MPA_encode_init, + .encode2 = MPA_encode_frame, + .close = MPA_encode_close, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }, + .supported_samplerates = (const int[]){ + 44100, 48000, 32000, 22050, 24000, 16000, 0 + }, + .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + 0 }, + .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), + .defaults = mp2_defaults, +};