NC camera demuxer
[ffmpeg.git] / libavformat / ncdec.c
1 /*
2  * NC camera feed demuxer
3  * Copyright (c) 2009  Nicolas Martin (martinic at iro dot umontreal dot ca)
4  *                     Edouard Auvinet
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 #include "libavutil/intreadwrite.h"
24 #include "avformat.h"
25
26 #define NC_VIDEO_FLAG 0x1A5
27
28 static int nc_probe(AVProbeData *probe_packet)
29 {
30     int size;
31
32     if (AV_RB32(probe_packet->buf) != NC_VIDEO_FLAG)
33         return 0;
34
35     size = AV_RL16(probe_packet->buf + 5);
36
37     if (size + 20 > probe_packet->buf_size)
38         return 3*AVPROBE_SCORE_MAX/2;
39
40     if (AV_RB32(probe_packet->buf+16+size) == NC_VIDEO_FLAG)
41         return AVPROBE_SCORE_MAX;
42
43     return 0;
44 }
45
46 static int nc_read_header(AVFormatContext *s, AVFormatParameters *ap)
47 {
48     AVStream *st = av_new_stream(s, 0);
49
50     if (!st)
51         return AVERROR(ENOMEM);
52
53     st->codec->codec_type = CODEC_TYPE_VIDEO;
54     st->codec->codec_id   = CODEC_ID_MPEG4;
55     st->need_parsing      = AVSTREAM_PARSE_FULL;
56
57     av_set_pts_info(st, 64, 1, 100);
58
59     return 0;
60 }
61
62 static int nc_read_packet(AVFormatContext *s, AVPacket *pkt)
63 {
64     int size;
65
66     uint32_t state=-1;
67     while (state != NC_VIDEO_FLAG) {
68         if (url_feof(s->pb))
69             return AVERROR(EIO);
70         state = (state<<8) + get_byte(s->pb);
71     }
72
73     get_byte(s->pb);
74     size = get_le16(s->pb);
75     url_fskip(s->pb, 9);
76
77     if (size == 0) {
78         av_log(s, AV_LOG_DEBUG, "Next packet size is zero\n");
79         return AVERROR(EAGAIN);
80     }
81
82     int ret = av_get_packet(s->pb, pkt, size);
83     if (ret != size) {
84         if (ret > 0) av_free_packet(pkt);
85         return AVERROR(EIO);
86     }
87
88     pkt->stream_index = 0;
89     return size;
90 }
91
92 AVInputFormat nc_demuxer = {
93     "nc",
94     NULL_IF_CONFIG_SMALL("NC camera feed format"),
95     0,
96     nc_probe,
97     nc_read_header,
98     nc_read_packet,
99     .extensions = "v",
100 };