Statistics
| Branch: | Revision:

ffmpeg / libavformat / msnwc_tcp.c @ 72415b2a

History | View | Annotate | Download (3.96 KB)

1
/*
2
 * Copyright (C) 2008  Ramiro Polla <ramiro@lisha.ufsc.br>
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

    
21
#include "libavcodec/bytestream.h"
22
#include "avformat.h"
23

    
24
#define HEADER_SIZE         24
25

    
26
/*
27
 * Header structure:
28
 *  uint16_t    ss;     // struct size
29
 *  uint16_t    width;  // frame width
30
 *  uint16_t    height; // frame height
31
 *  uint16_t    ff;     // keyframe + some other info(???)
32
 *  uint32_t    size;   // size of data
33
 *  uint32_t    fourcc; // ML20
34
 *  uint32_t    u3;     // ?
35
 *  uint32_t    ts;     // time
36
 */
37

    
38
static int msnwc_tcp_probe(AVProbeData *p)
39
{
40
    int i;
41

    
42
    for(i = 0 ; i + HEADER_SIZE <= p->buf_size ; i++) {
43
        uint16_t width, height;
44
        uint32_t fourcc;
45
        const uint8_t *bytestream = p->buf+i;
46

    
47
        if(bytestream_get_le16(&bytestream) != HEADER_SIZE)
48
            continue;
49
        width  = bytestream_get_le16(&bytestream);
50
        height = bytestream_get_le16(&bytestream);
51
        if(!(width==320 && height==240) && !(width==160 && height==120))
52
            continue;
53
        bytestream += 2; // keyframe
54
        bytestream += 4; // size
55
        fourcc = bytestream_get_le32(&bytestream);
56
        if(fourcc != MKTAG('M', 'L', '2', '0'))
57
            continue;
58

    
59
        if(i) {
60
            if(i < 14)  /* starts with SwitchBoard connection info */
61
                return AVPROBE_SCORE_MAX / 2;
62
            else        /* starts in the middle of stream */
63
                return AVPROBE_SCORE_MAX / 3;
64
        } else {
65
            return AVPROBE_SCORE_MAX;
66
        }
67
    }
68

    
69
    return -1;
70
}
71

    
72
static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap)
73
{
74
    ByteIOContext *pb = ctx->pb;
75
    AVCodecContext *codec;
76
    AVStream *st;
77

    
78
    st = av_new_stream(ctx, 0);
79
    if(!st)
80
        return AVERROR_NOMEM;
81

    
82
    codec = st->codec;
83
    codec->codec_type = AVMEDIA_TYPE_VIDEO;
84
    codec->codec_id = CODEC_ID_MIMIC;
85
    codec->codec_tag = MKTAG('M', 'L', '2', '0');
86

    
87
    av_set_pts_info(st, 32, 1, 1000);
88

    
89
    /* Some files start with "connected\r\n\r\n".
90
     * So skip until we find the first byte of struct size */
91
    while(get_byte(pb) != HEADER_SIZE && !url_feof(pb));
92

    
93
    if(url_feof(pb)) {
94
        av_log(ctx, AV_LOG_ERROR, "Could not find valid start.");
95
        return -1;
96
    }
97

    
98
    return 0;
99
}
100

    
101
static int msnwc_tcp_read_packet(AVFormatContext *ctx, AVPacket *pkt)
102
{
103
    ByteIOContext *pb = ctx->pb;
104
    uint16_t keyframe;
105
    uint32_t size, timestamp;
106

    
107
    url_fskip(pb, 1); /* one byte has been read ahead */
108
    url_fskip(pb, 2);
109
    url_fskip(pb, 2);
110
    keyframe = get_le16(pb);
111
    size = get_le32(pb);
112
    url_fskip(pb, 4);
113
    url_fskip(pb, 4);
114
    timestamp = get_le32(pb);
115

    
116
    if(!size || av_get_packet(pb, pkt, size) != size)
117
        return -1;
118

    
119
    url_fskip(pb, 1); /* Read ahead one byte of struct size like read_header */
120

    
121
    pkt->pts = timestamp;
122
    pkt->dts = timestamp;
123
    pkt->stream_index = 0;
124

    
125
    /* Some aMsn generated videos (or was it Mercury Messenger?) don't set
126
     * this bit and rely on the codec to get keyframe information */
127
    if(keyframe&1)
128
        pkt->flags |= PKT_FLAG_KEY;
129

    
130
    return HEADER_SIZE + size;
131
}
132

    
133
AVInputFormat msnwc_tcp_demuxer = {
134
    "msnwctcp",
135
    NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"),
136
    0,
137
    msnwc_tcp_probe,
138
    msnwc_tcp_read_header,
139
    msnwc_tcp_read_packet,
140
};