FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libshine.c
Go to the documentation of this file.
1 /*
2  * Interface to libshine for mp3 encoding
3  * Copyright (c) 2012 Paul B Mahol
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 <shine/layer3.h>
23 
24 #include "libavutil/intreadwrite.h"
25 #include "audio_frame_queue.h"
26 #include "avcodec.h"
27 #include "internal.h"
28 #include "mpegaudio.h"
29 #include "mpegaudiodecheader.h"
30 
31 #define BUFFER_SIZE (4096 * 20)
32 
33 typedef struct SHINEContext {
34  shine_config_t config;
35  shine_t shine;
39 } SHINEContext;
40 
42 {
43  SHINEContext *s = avctx->priv_data;
44 
45  if (avctx->channels <= 0 || avctx->channels > 2){
46  av_log(avctx, AV_LOG_ERROR, "only mono or stereo is supported\n");
47  return AVERROR(EINVAL);
48  }
49 
50  shine_set_config_mpeg_defaults(&s->config.mpeg);
51  if (avctx->bit_rate)
52  s->config.mpeg.bitr = avctx->bit_rate / 1000;
53  if (shine_find_bitrate_index(s->config.mpeg.bitr) < 0) {
54  av_log(avctx, AV_LOG_ERROR, "invalid bitrate\n");
55  return AVERROR(EINVAL);
56  }
57  s->config.mpeg.mode = avctx->channels == 2 ? STEREO : MONO;
58  s->config.wave.samplerate = avctx->sample_rate;
59  s->config.wave.channels = avctx->channels == 2 ? PCM_STEREO : PCM_MONO;
60  s->shine = shine_initialise(&s->config);
61  if (!s->shine)
62  return AVERROR(ENOMEM);
63  avctx->frame_size = samp_per_frame;
64  ff_af_queue_init(avctx, &s->afq);
65  return 0;
66 }
67 
68 static int libshine_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
69  const AVFrame *frame, int *got_packet_ptr)
70 {
71  SHINEContext *s = avctx->priv_data;
72  MPADecodeHeader hdr;
73  unsigned char *data;
74  long written;
75  int ret, len;
76 
77  if (frame)
78  data = shine_encode_frame(s->shine, frame->data[0], &written);
79  else
80  data = shine_flush(s->shine, &written);
81  if (written < 0)
82  return -1;
83  if (written > 0) {
84  if (s->buffer_index + written > BUFFER_SIZE) {
85  av_log(avctx, AV_LOG_ERROR, "internal buffer too small\n");
86  return AVERROR_BUG;
87  }
88  memcpy(s->buffer + s->buffer_index, data, written);
89  s->buffer_index += written;
90  }
91  if (frame) {
92  if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
93  return ret;
94  }
95 
96  if (s->buffer_index < 4 || !s->afq.frame_count)
97  return 0;
99  av_log(avctx, AV_LOG_ERROR, "free format output not supported\n");
100  return -1;
101  }
102 
103  len = hdr.frame_size;
104  if (len <= s->buffer_index) {
105  if ((ret = ff_alloc_packet2(avctx, avpkt, len)))
106  return ret;
107  memcpy(avpkt->data, s->buffer, len);
108  s->buffer_index -= len;
109  memmove(s->buffer, s->buffer + len, s->buffer_index);
110 
111  ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
112  &avpkt->duration);
113 
114  avpkt->size = len;
115  *got_packet_ptr = 1;
116  }
117  return 0;
118 }
119 
121 {
122  SHINEContext *s = avctx->priv_data;
123 
124  ff_af_queue_close(&s->afq);
125  shine_close(s->shine);
126  return 0;
127 }
128 
129 static const int libshine_sample_rates[] = {
130  44100, 48000, 32000, 0
131 };
132 
134  .name = "libshine",
135  .type = AVMEDIA_TYPE_AUDIO,
136  .id = CODEC_ID_MP3,
137  .priv_data_size = sizeof(SHINEContext),
139  .encode2 = libshine_encode_frame,
141  .capabilities = CODEC_CAP_DELAY,
142  .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
144  .supported_samplerates = libshine_sample_rates,
145  .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
147  0 },
148  .long_name = NULL_IF_CONFIG_SMALL("libshine MP3 (MPEG audio layer 3)"),
149 };