avformat/matroskaenc: implement AVOutputFormat.query_codec for webm
[ffmpeg.git] / libavformat / bit.c
index d68616e..76aae2d 100644 (file)
@@ -1,4 +1,25 @@
+/*
+ * G.729 bit format muxer and demuxer
+ * Copyright (c) 2007-2008 Vladimir Voroshilov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 #include "avformat.h"
+#include "internal.h"
 #include "libavcodec/get_bits.h"
 #include "libavcodec/put_bits.h"
 
 #define BIT_0      0x7f
 #define BIT_1      0x81
 
+#if CONFIG_BIT_DEMUXER
 static int probe(AVProbeData *p)
 {
-    int i, j;
+    int i = 0, j, valid = 0;
 
-    for(i=0; i+3<p->buf_size && i< 10*0x50; ){
-        if(AV_RL16(&p->buf[0]) != SYNC_WORD)
+    while (2 * i + 3 < p->buf_size){
+        if (AV_RL16(&p->buf[2 * i++]) != SYNC_WORD)
             return 0;
-        j=AV_RL16(&p->buf[2]);
-        if(j!=0x40 && j!=0x50)
+        j = AV_RL16(&p->buf[2 * i++]);
+        if (j != 0 && j != 0x10 && j != 0x40 && j != 0x50 && j != 0x76)
             return 0;
-        i+=j;
+        if (j)
+            valid++;
+        i += j;
     }
-    return AVPROBE_SCORE_MAX/2;
+    if (valid > 10)
+        return AVPROBE_SCORE_MAX;
+    if (valid > 2)
+        return AVPROBE_SCORE_EXTENSION - 1;
+    return 0;
 }
 
-static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+static int read_header(AVFormatContext *s)
 {
     AVStream* st;
-    ByteIOContext *pb = s->pb;
 
-    st=av_new_stream(s, 0);
+    st=avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
 
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id=CODEC_ID_G729;
-    st->codec->sample_rate=8000;
-    st->codec->block_align = 16;
-    st->codec->channels=1;
+    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codecpar->codec_id=AV_CODEC_ID_G729;
+    st->codecpar->sample_rate=8000;
+    st->codecpar->block_align = 16;
+    st->codecpar->channels=1;
 
-    av_set_pts_info(st, 64, 1, 100);
+    avpriv_set_pts_info(st, 64, 1, 100);
     return 0;
 }
 
 static int read_packet(AVFormatContext *s,
                           AVPacket *pkt)
 {
-    ByteIOContext *pb = s->pb;
+    AVIOContext *pb = s->pb;
     PutBitContext pbo;
     uint16_t buf[8 * MAX_FRAME_SIZE + 2];
     int packet_size;
@@ -53,21 +80,22 @@ static int read_packet(AVFormatContext *s,
     int i, j, ret;
     int64_t pos= avio_tell(pb);
 
-    if(url_feof(pb))
+    if(avio_feof(pb))
         return AVERROR_EOF;
 
-    get_le16(pb); // sync word
-    packet_size = get_le16(pb) / 8;
+    avio_rl16(pb); // sync word
+    packet_size = avio_rl16(pb) / 8;
     if(packet_size > MAX_FRAME_SIZE)
-        return AVERROR(EIO);
+        return AVERROR_INVALIDDATA;
 
-    ret = get_buffer(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
+    ret = avio_read(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
     if(ret<0)
         return ret;
     if(ret != 8 * packet_size * sizeof(uint16_t))
         return AVERROR(EIO);
 
-    av_new_packet(pkt, packet_size);
+    if (av_new_packet(pkt, packet_size) < 0)
+        return AVERROR(ENOMEM);
 
     init_put_bits(&pbo, pkt->data, packet_size);
     for(j=0; j < packet_size; j++)
@@ -89,34 +117,40 @@ AVInputFormat ff_bit_demuxer = {
     .read_packet = read_packet,
     .extensions  = "bit",
 };
+#endif
 
-#ifdef CONFIG_MUXERS
+#if CONFIG_BIT_MUXER
 static int write_header(AVFormatContext *s)
 {
-    AVCodecContext *enc = s->streams[0]->codec;
+    AVCodecParameters *par = s->streams[0]->codecpar;
 
-    enc->codec_id = CODEC_ID_G729;
-    enc->channels = 1;
-    enc->bits_per_coded_sample = 16;
-    enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
+    if ((par->codec_id != AV_CODEC_ID_G729) || par->channels != 1) {
+        av_log(s, AV_LOG_ERROR,
+               "only codec g729 with 1 channel is supported by this format\n");
+        return AVERROR(EINVAL);
+    }
+
+    par->bits_per_coded_sample = 16;
+    par->block_align = (par->bits_per_coded_sample * par->channels) >> 3;
 
     return 0;
 }
 
 static int write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    ByteIOContext *pb = s->pb;
+    AVIOContext *pb = s->pb;
     GetBitContext gb;
     int i;
-    uint16_t b;
 
-    put_le16(pb, SYNC_WORD);
-    put_le16(pb, 8 * 10);
+    if (pkt->size != 10)
+        return AVERROR(EINVAL);
+
+    avio_wl16(pb, SYNC_WORD);
+    avio_wl16(pb, 8 * pkt->size);
 
-    init_get_bits(&gb, pkt->data, 8*10);
-    for(i=0; i< 8 * 10; i++)
-        put_le16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
-    put_flush_packet(pb);
+    init_get_bits(&gb, pkt->data, 8 * pkt->size);
+    for (i = 0; i < 8 * pkt->size; i++)
+        avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
 
     return 0;
 }
@@ -126,8 +160,8 @@ AVOutputFormat ff_bit_muxer = {
     .long_name    = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
     .mime_type    = "audio/bit",
     .extensions   = "bit",
-    .audio_codec  = CODEC_ID_G729,
-    .video_codec  = CODEC_ID_NONE,
+    .audio_codec  = AV_CODEC_ID_G729,
+    .video_codec  = AV_CODEC_ID_NONE,
     .write_header = write_header,
     .write_packet = write_packet,
 };