]> git.sesse.net Git - ffmpeg/blob - libavformat/bit.c
Merge remote-tracking branch 'luzero/segment'
[ffmpeg] / libavformat / bit.c
1 #include "avformat.h"
2 #include "libavcodec/get_bits.h"
3 #include "libavcodec/put_bits.h"
4
5 #define MAX_FRAME_SIZE 10
6
7 #define SYNC_WORD  0x6b21
8 #define BIT_0      0x7f
9 #define BIT_1      0x81
10
11 static int probe(AVProbeData *p)
12 {
13     int i, j;
14
15     if(p->buf_size < 0x40)
16         return 0;
17
18     for(i=0; i+3<p->buf_size && i< 10*0x50; ){
19         if(AV_RL16(&p->buf[0]) != SYNC_WORD)
20             return 0;
21         j=AV_RL16(&p->buf[2]);
22         if(j!=0x40 && j!=0x50)
23             return 0;
24         i+=j;
25     }
26     return AVPROBE_SCORE_MAX/2;
27 }
28
29 static int read_header(AVFormatContext *s, AVFormatParameters *ap)
30 {
31     AVStream* st;
32
33     st=av_new_stream(s, 0);
34     if (!st)
35         return AVERROR(ENOMEM);
36
37     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
38     st->codec->codec_id=CODEC_ID_G729;
39     st->codec->sample_rate=8000;
40     st->codec->block_align = 16;
41     st->codec->channels=1;
42
43     av_set_pts_info(st, 64, 1, 100);
44     return 0;
45 }
46
47 static int read_packet(AVFormatContext *s,
48                           AVPacket *pkt)
49 {
50     ByteIOContext *pb = s->pb;
51     PutBitContext pbo;
52     uint16_t buf[8 * MAX_FRAME_SIZE + 2];
53     int packet_size;
54     uint16_t* src=buf;
55     int i, j, ret;
56     int64_t pos= avio_tell(pb);
57
58     if(url_feof(pb))
59         return AVERROR_EOF;
60
61     get_le16(pb); // sync word
62     packet_size = get_le16(pb) / 8;
63     if(packet_size > MAX_FRAME_SIZE)
64         return AVERROR_INVALIDDATA;
65
66     ret = get_buffer(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
67     if(ret<0)
68         return ret;
69     if(ret != 8 * packet_size * sizeof(uint16_t))
70         return AVERROR(EIO);
71
72     av_new_packet(pkt, packet_size);
73
74     init_put_bits(&pbo, pkt->data, packet_size);
75     for(j=0; j < packet_size; j++)
76         for(i=0; i<8;i++)
77             put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0);
78
79     flush_put_bits(&pbo);
80
81     pkt->duration=1;
82     pkt->pos = pos;
83     return 0;
84 }
85
86 AVInputFormat ff_bit_demuxer = {
87     .name        = "bit",
88     .long_name   = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
89     .read_probe  = probe,
90     .read_header = read_header,
91     .read_packet = read_packet,
92     .extensions  = "bit",
93 };
94
95 #ifdef CONFIG_MUXERS
96 static int write_header(AVFormatContext *s)
97 {
98     AVCodecContext *enc = s->streams[0]->codec;
99
100     enc->codec_id = CODEC_ID_G729;
101     enc->channels = 1;
102     enc->bits_per_coded_sample = 16;
103     enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
104
105     return 0;
106 }
107
108 static int write_packet(AVFormatContext *s, AVPacket *pkt)
109 {
110     ByteIOContext *pb = s->pb;
111     GetBitContext gb;
112     int i;
113
114     put_le16(pb, SYNC_WORD);
115     put_le16(pb, 8 * 10);
116
117     init_get_bits(&gb, pkt->data, 8*10);
118     for(i=0; i< 8 * 10; i++)
119         put_le16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
120     put_flush_packet(pb);
121
122     return 0;
123 }
124
125 AVOutputFormat ff_bit_muxer = {
126     .name         = "bit",
127     .long_name    = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
128     .mime_type    = "audio/bit",
129     .extensions   = "bit",
130     .audio_codec  = CODEC_ID_G729,
131     .video_codec  = CODEC_ID_NONE,
132     .write_header = write_header,
133     .write_packet = write_packet,
134 };
135 #endif