Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * AMR Audio encoder stub
  3.  * Copyright (c) 2003 the ffmpeg project
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include <vo-amrwbenc/enc_if.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25.  
  26. #include "libavutil/avstring.h"
  27. #include "libavutil/internal.h"
  28. #include "libavutil/mem.h"
  29. #include "libavutil/opt.h"
  30. #include "avcodec.h"
  31. #include "internal.h"
  32.  
  33. #define MAX_PACKET_SIZE  (1 + (477 + 7) / 8)
  34.  
  35. typedef struct AMRWBContext {
  36.     AVClass *av_class;
  37.     void  *state;
  38.     int    mode;
  39.     int    last_bitrate;
  40.     int    allow_dtx;
  41. } AMRWBContext;
  42.  
  43. static const AVOption options[] = {
  44.     { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRWBContext, allow_dtx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
  45.     { NULL }
  46. };
  47.  
  48. static const AVClass amrwb_class = {
  49.     "libvo_amrwbenc", av_default_item_name, options, LIBAVUTIL_VERSION_INT
  50. };
  51.  
  52. static int get_wb_bitrate_mode(int bitrate, void *log_ctx)
  53. {
  54.     /* make the correspondance between bitrate and mode */
  55.     static const int rates[] = {  6600,  8850, 12650, 14250, 15850, 18250,
  56.                                  19850, 23050, 23850 };
  57.     int i, best = -1, min_diff = 0;
  58.     char log_buf[200];
  59.  
  60.     for (i = 0; i < 9; i++) {
  61.         if (rates[i] == bitrate)
  62.             return i;
  63.         if (best < 0 || abs(rates[i] - bitrate) < min_diff) {
  64.             best     = i;
  65.             min_diff = abs(rates[i] - bitrate);
  66.         }
  67.     }
  68.     /* no bitrate matching exactly, log a warning */
  69.     snprintf(log_buf, sizeof(log_buf), "bitrate not supported: use one of ");
  70.     for (i = 0; i < 9; i++)
  71.         av_strlcatf(log_buf, sizeof(log_buf), "%.2fk, ", rates[i]    / 1000.f);
  72.     av_strlcatf(log_buf, sizeof(log_buf), "using %.2fk", rates[best] / 1000.f);
  73.     av_log(log_ctx, AV_LOG_WARNING, "%s\n", log_buf);
  74.  
  75.     return best;
  76. }
  77.  
  78. static av_cold int amr_wb_encode_init(AVCodecContext *avctx)
  79. {
  80.     AMRWBContext *s = avctx->priv_data;
  81.  
  82.     if (avctx->sample_rate != 16000 && avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
  83.         av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n");
  84.         return AVERROR(ENOSYS);
  85.     }
  86.  
  87.     if (avctx->channels != 1) {
  88.         av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
  89.         return AVERROR(ENOSYS);
  90.     }
  91.  
  92.     s->mode            = get_wb_bitrate_mode(avctx->bit_rate, avctx);
  93.     s->last_bitrate    = avctx->bit_rate;
  94.  
  95.     avctx->frame_size  = 320;
  96.     avctx->delay       =  80;
  97.  
  98.     s->state     = E_IF_init();
  99.  
  100.     return 0;
  101. }
  102.  
  103. static int amr_wb_encode_close(AVCodecContext *avctx)
  104. {
  105.     AMRWBContext *s = avctx->priv_data;
  106.  
  107.     E_IF_exit(s->state);
  108.     return 0;
  109. }
  110.  
  111. static int amr_wb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
  112.                                const AVFrame *frame, int *got_packet_ptr)
  113. {
  114.     AMRWBContext *s = avctx->priv_data;
  115.     const int16_t *samples = (const int16_t *)frame->data[0];
  116.     int size, ret;
  117.  
  118.     if ((ret = ff_alloc_packet2(avctx, avpkt, MAX_PACKET_SIZE)) < 0)
  119.         return ret;
  120.  
  121.     if (s->last_bitrate != avctx->bit_rate) {
  122.         s->mode         = get_wb_bitrate_mode(avctx->bit_rate, avctx);
  123.         s->last_bitrate = avctx->bit_rate;
  124.     }
  125.     size = E_IF_encode(s->state, s->mode, samples, avpkt->data, s->allow_dtx);
  126.     if (size <= 0 || size > MAX_PACKET_SIZE) {
  127.         av_log(avctx, AV_LOG_ERROR, "Error encoding frame\n");
  128.         return AVERROR(EINVAL);
  129.     }
  130.  
  131.     if (frame->pts != AV_NOPTS_VALUE)
  132.         avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
  133.  
  134.     avpkt->size = size;
  135.     *got_packet_ptr = 1;
  136.     return 0;
  137. }
  138.  
  139. AVCodec ff_libvo_amrwbenc_encoder = {
  140.     .name           = "libvo_amrwbenc",
  141.     .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB "
  142.                                            "(Adaptive Multi-Rate Wide-Band)"),
  143.     .type           = AVMEDIA_TYPE_AUDIO,
  144.     .id             = AV_CODEC_ID_AMR_WB,
  145.     .priv_data_size = sizeof(AMRWBContext),
  146.     .init           = amr_wb_encode_init,
  147.     .encode2        = amr_wb_encode_frame,
  148.     .close          = amr_wb_encode_close,
  149.     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
  150.                                                      AV_SAMPLE_FMT_NONE },
  151.     .priv_class     = &amrwb_class,
  152. };
  153.