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 28static 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 46static 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 62static int nc_read_packet(AVFormatContext *s, AVPacket *pkt) 63{ 64 int size; 65 int ret; 66 67 uint32_t state=-1; 68 while (state != NC_VIDEO_FLAG) { 69 if (url_feof(s->pb)) 70 return AVERROR(EIO); 71 state = (state<<8) + get_byte(s->pb); 72 } 73 74 get_byte(s->pb); 75 size = get_le16(s->pb); 76 url_fskip(s->pb, 9); 77 78 if (size == 0) { 79 av_log(s, AV_LOG_DEBUG, "Next packet size is zero\n"); 80 return AVERROR(EAGAIN); 81 } 82 83 ret = av_get_packet(s->pb, pkt, size); 84 if (ret != size) { 85 if (ret > 0) av_free_packet(pkt); 86 return AVERROR(EIO); 87 } 88 89 pkt->stream_index = 0; 90 return size; 91} 92 93AVInputFormat nc_demuxer = { 94 "nc", 95 NULL_IF_CONFIG_SMALL("NC camera feed format"), 96 0, 97 nc_probe, 98 nc_read_header, 99 nc_read_packet, 100 .extensions = "v", 101}; 102