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