annotate ffmpeg/libavcodec/libtwolame.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Interface to libtwolame for mp2 encoding
yading@10 3 * Copyright (c) 2012 Paul B Mahol
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * Interface to libtwolame for mp2 encoding.
yading@10 25 */
yading@10 26
yading@10 27 #include <twolame.h>
yading@10 28
yading@10 29 #include "libavutil/opt.h"
yading@10 30 #include "avcodec.h"
yading@10 31 #include "internal.h"
yading@10 32 #include "mpegaudio.h"
yading@10 33
yading@10 34 typedef struct TWOLAMEContext {
yading@10 35 AVClass *class;
yading@10 36 int mode;
yading@10 37 int psymodel;
yading@10 38 int energy;
yading@10 39 int error_protection;
yading@10 40 int copyright;
yading@10 41 int original;
yading@10 42
yading@10 43 twolame_options *glopts;
yading@10 44 int64_t next_pts;
yading@10 45 } TWOLAMEContext;
yading@10 46
yading@10 47 static av_cold int twolame_encode_close(AVCodecContext *avctx)
yading@10 48 {
yading@10 49 TWOLAMEContext *s = avctx->priv_data;
yading@10 50 twolame_close(&s->glopts);
yading@10 51 return 0;
yading@10 52 }
yading@10 53
yading@10 54 static av_cold int twolame_encode_init(AVCodecContext *avctx)
yading@10 55 {
yading@10 56 TWOLAMEContext *s = avctx->priv_data;
yading@10 57 int ret;
yading@10 58
yading@10 59 avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
yading@10 60
yading@10 61 s->glopts = twolame_init();
yading@10 62 if (!s->glopts)
yading@10 63 return AVERROR(ENOMEM);
yading@10 64
yading@10 65 twolame_set_verbosity(s->glopts, 0);
yading@10 66 twolame_set_mode(s->glopts, s->mode);
yading@10 67 twolame_set_psymodel(s->glopts, s->psymodel);
yading@10 68 twolame_set_energy_levels(s->glopts, s->energy);
yading@10 69 twolame_set_error_protection(s->glopts, s->error_protection);
yading@10 70
yading@10 71 twolame_set_num_channels(s->glopts, avctx->channels);
yading@10 72 twolame_set_in_samplerate(s->glopts, avctx->sample_rate);
yading@10 73 twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
yading@10 74 if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
yading@10 75 twolame_set_VBR(s->glopts, TRUE);
yading@10 76 twolame_set_VBR_level(s->glopts, avctx->global_quality);
yading@10 77 av_log(avctx, AV_LOG_WARNING, "VBR mode is experimental!\n");
yading@10 78 } else {
yading@10 79 twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);
yading@10 80 }
yading@10 81
yading@10 82 if ((ret = twolame_init_params(s->glopts)))
yading@10 83 goto error;
yading@10 84
yading@10 85 return 0;
yading@10 86 error:
yading@10 87 twolame_encode_close(avctx);
yading@10 88 return ret;
yading@10 89 }
yading@10 90
yading@10 91 static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
yading@10 92 const AVFrame *frame, int *got_packet_ptr)
yading@10 93 {
yading@10 94 TWOLAMEContext *s = avctx->priv_data;
yading@10 95 int ret;
yading@10 96
yading@10 97 if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)) < 0)
yading@10 98 return ret;
yading@10 99
yading@10 100 if (frame) {
yading@10 101 switch (avctx->sample_fmt) {
yading@10 102 case AV_SAMPLE_FMT_FLT:
yading@10 103 ret = twolame_encode_buffer_float32_interleaved(s->glopts,
yading@10 104 frame->data[0],
yading@10 105 frame->nb_samples,
yading@10 106 avpkt->data, avpkt->size);
yading@10 107 break;
yading@10 108 case AV_SAMPLE_FMT_FLTP:
yading@10 109 ret = twolame_encode_buffer_float32(s->glopts,
yading@10 110 frame->data[0], frame->data[1],
yading@10 111 frame->nb_samples,
yading@10 112 avpkt->data, avpkt->size);
yading@10 113 break;
yading@10 114 case AV_SAMPLE_FMT_S16:
yading@10 115 ret = twolame_encode_buffer_interleaved(s->glopts,
yading@10 116 frame->data[0],
yading@10 117 frame->nb_samples,
yading@10 118 avpkt->data, avpkt->size);
yading@10 119 break;
yading@10 120 case AV_SAMPLE_FMT_S16P:
yading@10 121 ret = twolame_encode_buffer(s->glopts,
yading@10 122 frame->data[0], frame->data[1],
yading@10 123 frame->nb_samples,
yading@10 124 avpkt->data, avpkt->size);
yading@10 125 break;
yading@10 126 default:
yading@10 127 return AVERROR_BUG;
yading@10 128 }
yading@10 129 } else {
yading@10 130 ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);
yading@10 131 }
yading@10 132
yading@10 133 if (ret > 0) {
yading@10 134 avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
yading@10 135 if (frame) {
yading@10 136 if (frame->pts != AV_NOPTS_VALUE)
yading@10 137 avpkt->pts = frame->pts;
yading@10 138 } else {
yading@10 139 avpkt->pts = s->next_pts;
yading@10 140 }
yading@10 141 if (avpkt->pts != AV_NOPTS_VALUE)
yading@10 142 s->next_pts = avpkt->pts + avpkt->duration;
yading@10 143
yading@10 144 avpkt->size = ret;
yading@10 145 *got_packet_ptr = 1;
yading@10 146 return 0;
yading@10 147 }
yading@10 148
yading@10 149 return ret;
yading@10 150 }
yading@10 151
yading@10 152 #define OFFSET(x) offsetof(TWOLAMEContext, x)
yading@10 153 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
yading@10 154 static const AVOption options[] = {
yading@10 155 { "mode", "Mpeg Mode", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = TWOLAME_AUTO_MODE }, TWOLAME_AUTO_MODE, TWOLAME_MONO, AE, "mode"},
yading@10 156 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_AUTO_MODE }, 0, 0, AE, "mode" },
yading@10 157 { "stereo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_STEREO }, 0, 0, AE, "mode" },
yading@10 158 { "joint_stereo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_JOINT_STEREO }, 0, 0, AE, "mode" },
yading@10 159 { "dual_channel", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_DUAL_CHANNEL }, 0, 0, AE, "mode" },
yading@10 160 { "mono", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_MONO }, 0, 0, AE, "mode" },
yading@10 161 { "psymodel", "Psychoacoustic Model", OFFSET(psymodel), AV_OPT_TYPE_INT, { .i64 = 3 }, -1, 4, AE},
yading@10 162 { "energy_levels","enable energy levels", OFFSET(energy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
yading@10 163 { "error_protection","enable CRC error protection", OFFSET(error_protection), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
yading@10 164 { "copyright", "set MPEG Audio Copyright flag", OFFSET(copyright), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
yading@10 165 { "original", "set MPEG Audio Original flag", OFFSET(original), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
yading@10 166 { NULL },
yading@10 167 };
yading@10 168
yading@10 169 static const AVClass libtwolame_class = {
yading@10 170 .class_name = "libtwolame encoder",
yading@10 171 .item_name = av_default_item_name,
yading@10 172 .option = options,
yading@10 173 .version = LIBAVUTIL_VERSION_INT,
yading@10 174 };
yading@10 175
yading@10 176 AVCodec ff_libtwolame_encoder = {
yading@10 177 .name = "libtwolame",
yading@10 178 .type = AVMEDIA_TYPE_AUDIO,
yading@10 179 .id = AV_CODEC_ID_MP2,
yading@10 180 .priv_data_size = sizeof(TWOLAMEContext),
yading@10 181 .init = twolame_encode_init,
yading@10 182 .encode2 = twolame_encode_frame,
yading@10 183 .close = twolame_encode_close,
yading@10 184 .capabilities = CODEC_CAP_DELAY,
yading@10 185 .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
yading@10 186 AV_SAMPLE_FMT_FLTP,
yading@10 187 AV_SAMPLE_FMT_S16,
yading@10 188 AV_SAMPLE_FMT_S16P,
yading@10 189 AV_SAMPLE_FMT_NONE },
yading@10 190 .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
yading@10 191 AV_CH_LAYOUT_STEREO,
yading@10 192 0 },
yading@10 193 .supported_samplerates = (const int[]){ 16000, 22050, 24000, 32000, 44100, 48000, 0 },
yading@10 194 .long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
yading@10 195 .priv_class = &libtwolame_class,
yading@10 196 };