1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * G.729 bit format muxer and demuxer
3cabdff1aSopenharmony_ci * Copyright (c) 2007-2008 Vladimir Voroshilov
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "config_components.h"
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#include "avformat.h"
25cabdff1aSopenharmony_ci#include "internal.h"
26cabdff1aSopenharmony_ci#include "libavcodec/get_bits.h"
27cabdff1aSopenharmony_ci#include "libavcodec/put_bits.h"
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#define MAX_FRAME_SIZE 10
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_ci#define SYNC_WORD  0x6b21
32cabdff1aSopenharmony_ci#define BIT_0      0x7f
33cabdff1aSopenharmony_ci#define BIT_1      0x81
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_ci#if CONFIG_BIT_DEMUXER
36cabdff1aSopenharmony_cistatic int probe(const AVProbeData *p)
37cabdff1aSopenharmony_ci{
38cabdff1aSopenharmony_ci    int i = 0, j, valid = 0;
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_ci    while (2 * i + 3 < p->buf_size){
41cabdff1aSopenharmony_ci        if (AV_RL16(&p->buf[2 * i++]) != SYNC_WORD)
42cabdff1aSopenharmony_ci            return 0;
43cabdff1aSopenharmony_ci        j = AV_RL16(&p->buf[2 * i++]);
44cabdff1aSopenharmony_ci        if (j != 0 && j != 0x10 && j != 0x40 && j != 0x50 && j != 0x76)
45cabdff1aSopenharmony_ci            return 0;
46cabdff1aSopenharmony_ci        if (j)
47cabdff1aSopenharmony_ci            valid++;
48cabdff1aSopenharmony_ci        i += j;
49cabdff1aSopenharmony_ci    }
50cabdff1aSopenharmony_ci    if (valid > 10)
51cabdff1aSopenharmony_ci        return AVPROBE_SCORE_MAX;
52cabdff1aSopenharmony_ci    if (valid > 2)
53cabdff1aSopenharmony_ci        return AVPROBE_SCORE_EXTENSION - 1;
54cabdff1aSopenharmony_ci    return 0;
55cabdff1aSopenharmony_ci}
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_cistatic int read_header(AVFormatContext *s)
58cabdff1aSopenharmony_ci{
59cabdff1aSopenharmony_ci    AVStream* st;
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci    st=avformat_new_stream(s, NULL);
62cabdff1aSopenharmony_ci    if (!st)
63cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
64cabdff1aSopenharmony_ci
65cabdff1aSopenharmony_ci    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
66cabdff1aSopenharmony_ci    st->codecpar->codec_id=AV_CODEC_ID_G729;
67cabdff1aSopenharmony_ci    st->codecpar->sample_rate=8000;
68cabdff1aSopenharmony_ci    st->codecpar->block_align = 16;
69cabdff1aSopenharmony_ci    st->codecpar->ch_layout.nb_channels = 1;
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci    avpriv_set_pts_info(st, 64, 1, 100);
72cabdff1aSopenharmony_ci    return 0;
73cabdff1aSopenharmony_ci}
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_cistatic int read_packet(AVFormatContext *s,
76cabdff1aSopenharmony_ci                          AVPacket *pkt)
77cabdff1aSopenharmony_ci{
78cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
79cabdff1aSopenharmony_ci    PutBitContext pbo;
80cabdff1aSopenharmony_ci    uint16_t buf[8 * MAX_FRAME_SIZE + 2];
81cabdff1aSopenharmony_ci    int packet_size;
82cabdff1aSopenharmony_ci    uint16_t* src=buf;
83cabdff1aSopenharmony_ci    int i, j, ret;
84cabdff1aSopenharmony_ci    int64_t pos= avio_tell(pb);
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci    if(avio_feof(pb))
87cabdff1aSopenharmony_ci        return AVERROR_EOF;
88cabdff1aSopenharmony_ci
89cabdff1aSopenharmony_ci    avio_rl16(pb); // sync word
90cabdff1aSopenharmony_ci    packet_size = avio_rl16(pb) / 8;
91cabdff1aSopenharmony_ci    if(packet_size > MAX_FRAME_SIZE)
92cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
93cabdff1aSopenharmony_ci
94cabdff1aSopenharmony_ci    ret = avio_read(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
95cabdff1aSopenharmony_ci    if(ret<0)
96cabdff1aSopenharmony_ci        return ret;
97cabdff1aSopenharmony_ci    if(ret != 8 * packet_size * sizeof(uint16_t))
98cabdff1aSopenharmony_ci        return AVERROR(EIO);
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci    if ((ret = av_new_packet(pkt, packet_size)) < 0)
101cabdff1aSopenharmony_ci        return ret;
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci    init_put_bits(&pbo, pkt->data, packet_size);
104cabdff1aSopenharmony_ci    for(j=0; j < packet_size; j++)
105cabdff1aSopenharmony_ci        for(i=0; i<8;i++)
106cabdff1aSopenharmony_ci            put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0);
107cabdff1aSopenharmony_ci
108cabdff1aSopenharmony_ci    flush_put_bits(&pbo);
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci    pkt->duration=1;
111cabdff1aSopenharmony_ci    pkt->pos = pos;
112cabdff1aSopenharmony_ci    return 0;
113cabdff1aSopenharmony_ci}
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ciconst AVInputFormat ff_bit_demuxer = {
116cabdff1aSopenharmony_ci    .name        = "bit",
117cabdff1aSopenharmony_ci    .long_name   = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
118cabdff1aSopenharmony_ci    .read_probe  = probe,
119cabdff1aSopenharmony_ci    .read_header = read_header,
120cabdff1aSopenharmony_ci    .read_packet = read_packet,
121cabdff1aSopenharmony_ci    .extensions  = "bit",
122cabdff1aSopenharmony_ci};
123cabdff1aSopenharmony_ci#endif
124cabdff1aSopenharmony_ci
125cabdff1aSopenharmony_ci#if CONFIG_BIT_MUXER
126cabdff1aSopenharmony_cistatic int write_header(AVFormatContext *s)
127cabdff1aSopenharmony_ci{
128cabdff1aSopenharmony_ci    AVCodecParameters *par = s->streams[0]->codecpar;
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci    if ((par->codec_id != AV_CODEC_ID_G729) || par->ch_layout.nb_channels != 1) {
131cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR,
132cabdff1aSopenharmony_ci               "only codec g729 with 1 channel is supported by this format\n");
133cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
134cabdff1aSopenharmony_ci    }
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    par->bits_per_coded_sample = 16;
137cabdff1aSopenharmony_ci    par->block_align = (par->bits_per_coded_sample * par->ch_layout.nb_channels) >> 3;
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_ci    return 0;
140cabdff1aSopenharmony_ci}
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_cistatic int write_packet(AVFormatContext *s, AVPacket *pkt)
143cabdff1aSopenharmony_ci{
144cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
145cabdff1aSopenharmony_ci    GetBitContext gb;
146cabdff1aSopenharmony_ci    int i;
147cabdff1aSopenharmony_ci
148cabdff1aSopenharmony_ci    if (pkt->size != 10)
149cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci    avio_wl16(pb, SYNC_WORD);
152cabdff1aSopenharmony_ci    avio_wl16(pb, 8 * pkt->size);
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci    init_get_bits(&gb, pkt->data, 8 * pkt->size);
155cabdff1aSopenharmony_ci    for (i = 0; i < 8 * pkt->size; i++)
156cabdff1aSopenharmony_ci        avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
157cabdff1aSopenharmony_ci
158cabdff1aSopenharmony_ci    return 0;
159cabdff1aSopenharmony_ci}
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ciconst AVOutputFormat ff_bit_muxer = {
162cabdff1aSopenharmony_ci    .name         = "bit",
163cabdff1aSopenharmony_ci    .long_name    = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
164cabdff1aSopenharmony_ci    .mime_type    = "audio/bit",
165cabdff1aSopenharmony_ci    .extensions   = "bit",
166cabdff1aSopenharmony_ci    .audio_codec  = AV_CODEC_ID_G729,
167cabdff1aSopenharmony_ci    .video_codec  = AV_CODEC_ID_NONE,
168cabdff1aSopenharmony_ci    .write_header = write_header,
169cabdff1aSopenharmony_ci    .write_packet = write_packet,
170cabdff1aSopenharmony_ci};
171cabdff1aSopenharmony_ci#endif
172