Statistics
| Branch: | Revision:

ffmpeg / libavcodec / libgsm.c @ df3a80b5

History | View | Annotate | Download (3.82 KB)

1
/*
2
 * Interface to libgsm for gsm encoding/decoding
3
 * Copyright (c) 2005 Alban Bedel <albeu@free.fr>
4
 * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be>
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22

    
23
/**
24
 * @file libgsm.c
25
 * Interface to libgsm for gsm encoding/decoding
26
 */
27

    
28
// The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html
29

    
30
#include "avcodec.h"
31
#include <gsm.h>
32

    
33
// gsm.h misses some essential constants
34
#define GSM_BLOCK_SIZE 33
35
#define GSM_MS_BLOCK_SIZE 65
36
#define GSM_FRAME_SIZE 160
37

    
38
static int libgsm_init(AVCodecContext *avctx) {
39
    if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000)
40
        return -1;
41

    
42
    avctx->priv_data = gsm_create();
43

    
44
    switch(avctx->codec_id) {
45
    case CODEC_ID_GSM:
46
        avctx->frame_size = GSM_FRAME_SIZE;
47
        avctx->block_align = GSM_BLOCK_SIZE;
48
        break;
49
    case CODEC_ID_GSM_MS: {
50
        int one = 1;
51
        gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
52
        avctx->frame_size = 2*GSM_FRAME_SIZE;
53
        avctx->block_align = GSM_MS_BLOCK_SIZE;
54
        }
55
    }
56

    
57
    avctx->coded_frame= avcodec_alloc_frame();
58
    avctx->coded_frame->key_frame= 1;
59

    
60
    return 0;
61
}
62

    
63
static int libgsm_close(AVCodecContext *avctx) {
64
    gsm_destroy(avctx->priv_data);
65
    avctx->priv_data = NULL;
66
    return 0;
67
}
68

    
69
static int libgsm_encode_frame(AVCodecContext *avctx,
70
                               unsigned char *frame, int buf_size, void *data) {
71
    // we need a full block
72
    if(buf_size < avctx->block_align) return 0;
73

    
74
    switch(avctx->codec_id) {
75
    case CODEC_ID_GSM:
76
        gsm_encode(avctx->priv_data,data,frame);
77
        break;
78
    case CODEC_ID_GSM_MS:
79
        gsm_encode(avctx->priv_data,data,frame);
80
        gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32);
81
    }
82
    return avctx->block_align;
83
}
84

    
85

    
86
AVCodec libgsm_encoder = {
87
    "libgsm",
88
    CODEC_TYPE_AUDIO,
89
    CODEC_ID_GSM,
90
    0,
91
    libgsm_init,
92
    libgsm_encode_frame,
93
    libgsm_close,
94
};
95

    
96
AVCodec libgsm_ms_encoder = {
97
    "libgsm_ms",
98
    CODEC_TYPE_AUDIO,
99
    CODEC_ID_GSM_MS,
100
    0,
101
    libgsm_init,
102
    libgsm_encode_frame,
103
    libgsm_close,
104
};
105

    
106
static int libgsm_decode_frame(AVCodecContext *avctx,
107
                               void *data, int *data_size,
108
                               uint8_t *buf, int buf_size) {
109

    
110
    if(buf_size < avctx->block_align) return 0;
111

    
112
    switch(avctx->codec_id) {
113
    case CODEC_ID_GSM:
114
        if(gsm_decode(avctx->priv_data,buf,data)) return -1;
115
        *data_size = GSM_FRAME_SIZE*sizeof(int16_t);
116
        break;
117
    case CODEC_ID_GSM_MS:
118
        if(gsm_decode(avctx->priv_data,buf,data) ||
119
           gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1;
120
        *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2;
121
    }
122
    return avctx->block_align;
123
}
124

    
125
AVCodec libgsm_decoder = {
126
    "libgsm",
127
    CODEC_TYPE_AUDIO,
128
    CODEC_ID_GSM,
129
    0,
130
    libgsm_init,
131
    NULL,
132
    libgsm_close,
133
    libgsm_decode_frame,
134
};
135

    
136
AVCodec libgsm_ms_decoder = {
137
    "libgsm_ms",
138
    CODEC_TYPE_AUDIO,
139
    CODEC_ID_GSM_MS,
140
    0,
141
    libgsm_init,
142
    NULL,
143
    libgsm_close,
144
    libgsm_decode_frame,
145
};