Revision cc0bc648

View differences:

Changelog
48 48
- MPEG-2 intra vlc support
49 49
- MPEG-2 4:2:2 encoder
50 50
- Flash Screen Video decoder
51
- GXF demuxer
51 52

  
52 53
version 0.4.9-pre1:
53 54

  
MAINTAINERS
190 190
  dc1394.c, dv.c                        Roman Shaposhnik
191 191
  flic.c                                Mike Melanson
192 192
  flvdec.c, flvenc.c                    Michael Niedermayer
193
  gxf.c                                 Reimar Doeffinger
193 194
  idcin.c                               Mike Melanson
194 195
  idroq.c                               Mike Melanson
195 196
  ipmovie.c                             Mike Melanson
doc/ffmpeg-doc.texi
704 704
@tab Multimedia format used by the Creature Shock game.
705 705
@item Smacker @tab    @tab X
706 706
@tab Multimedia format used by many games.
707
@item GXF @tab    @tab X
707 708
@end multitable
708 709

  
709 710
@code{X} means that encoding (resp. decoding) is supported.
libavformat/Makefile
18 18
      nut.o wc3movie.o mp3.o westwood.o segafilm.o idcin.o flic.o \
19 19
      sierravmd.o matroska.o sol.o electronicarts.o nsvdec.o asf.o \
20 20
      ogg2.o oggparsevorbis.o oggparsetheora.o oggparseflac.o daud.o aiff.o \
21
      voc.o tta.o mm.o avs.o smacker.o nuv.o oggparseogm.o
21
      voc.o tta.o mm.o avs.o smacker.o nuv.o gxf.o oggparseogm.o
22 22

  
23 23
# muxers
24 24
ifeq ($(CONFIG_MUXERS),yes)
libavformat/allformats.c
122 122
    tta_init();
123 123
    avs_init();
124 124
    nuv_init();
125
    gxf_init();
125 126

  
126 127
#ifdef CONFIG_MUXERS
127 128
    /* image formats */
libavformat/allformats.h
141 141
/* nuv.c */
142 142
int nuv_init(void);
143 143

  
144
/* gxf.c */
145
int gxf_init(void);
146

  
144 147
/* aiff.c */
145 148
int ff_aiff_init(void);
146 149

  
libavformat/gxf.c
1
/*
2
 * GXF demuxer.
3
 * Copyright (c) 2006 Reimar Doeffinger.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19
#include "avformat.h"
20
#include "avi.h"
21

  
22
typedef enum {
23
    PKT_MAP = 0xbc,
24
    PKT_MEDIA = 0xbf,
25
    PKT_EOS = 0xfb,
26
    PKT_FLT = 0xfc,
27
    PKT_UMF = 0xfd
28
} pkt_type_t;
29

  
30
/**
31
 * \brief parses a packet header, extracting type and length
32
 * \param pb ByteIOContext to read header from
33
 * \param type detected packet type is stored here
34
 * \param length detected packet length, excluding header is stored here
35
 * \return 0 if header not found or contains invalid data, 1 otherwise
36
 */
37
static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) {
38
    if (get_be32(pb))
39
        return 0;
40
    if (get_byte(pb) != 1)
41
        return 0;
42
    *type = get_byte(pb);
43
    *length = get_be32(pb);
44
    if ((*length >> 24) || *length < 16)
45
        return 0;
46
    *length -= 16;
47
    if (get_be32(pb))
48
        return 0;
49
    if (get_byte(pb) != 0xe1)
50
        return 0;
51
    if (get_byte(pb) != 0xe2)
52
        return 0;
53
    return 1;
54
}
55

  
56
/**
57
 * \brief check if file starts with a PKT_MAP header
58
 */
59
static int gxf_probe(AVProbeData *p) {
60
    static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet
61
    static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};
62
    if (p->buf_size < 16)
63
        return 0;
64
    if (!memcmp(p->buf, startcode, sizeof(startcode)) &&
65
        !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))
66
        return AVPROBE_SCORE_MAX;
67
    return 0;
68
}
69

  
70
/**
71
 * \brief gets the stream index for the track with the specified id, creates new
72
 *        stream if not found
73
 * \param stream id of stream to find / add
74
 * \param format stream format identifier
75
 */
76
static int get_sindex(AVFormatContext *s, int id, int format) {
77
    int i;
78
    AVStream *st = NULL;
79
    for (i = 0; i < s->nb_streams; i++) {
80
        if (s->streams[i]->id == id)
81
            return i;
82
    }
83
    st = av_new_stream(s, id);
84
    switch (format) {
85
        case 3:
86
        case 4:
87
            st->codec->codec_type = CODEC_TYPE_VIDEO;
88
            st->codec->codec_id = CODEC_ID_MJPEG;
89
            st->codec->codec_tag = MKTAG('M', 'J', 'P', 'G');
90
            break;
91
        case 13:
92
        case 15:
93
            st->codec->codec_type = CODEC_TYPE_VIDEO;
94
            st->codec->codec_id = CODEC_ID_DVVIDEO;
95
            st->codec->codec_tag = MKTAG('d', 'v', 'c', ' ');
96
            break;
97
        case 14:
98
        case 16:
99
            st->codec->codec_type = CODEC_TYPE_VIDEO;
100
            st->codec->codec_id = CODEC_ID_DVVIDEO;
101
            st->codec->codec_tag = MKTAG('d', 'v', 'c', 'p');
102
            break;
103
        case 11:
104
        case 12:
105
        case 20:
106
            st->codec->codec_type = CODEC_TYPE_VIDEO;
107
            st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
108
            st->codec->codec_tag = MKTAG('M', 'P', 'G', '2');
109
            break;
110
        case 22:
111
        case 23:
112
            st->codec->codec_type = CODEC_TYPE_VIDEO;
113
            st->codec->codec_id = CODEC_ID_MPEG1VIDEO;
114
            st->codec->codec_tag = MKTAG('M', 'P', 'G', '1');
115
            break;
116
        case 9:
117
            st->codec->codec_type = CODEC_TYPE_AUDIO;
118
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
119
            st->codec->codec_tag = 0x1;
120
            st->codec->channels = 1;
121
            st->codec->sample_rate = 48000;
122
            st->codec->bit_rate = 3 * 1 * 48000 * 8;
123
            st->codec->block_align = 3 * 1;
124
            st->codec->bits_per_sample = 24;
125
            break;
126
        case 10:
127
            st->codec->codec_type = CODEC_TYPE_AUDIO;
128
            st->codec->codec_id = CODEC_ID_PCM_S16LE;
129
            st->codec->codec_tag = 0x1;
130
            st->codec->channels = 1;
131
            st->codec->sample_rate = 48000;
132
            st->codec->bit_rate = 2 * 1 * 48000 * 8;
133
            st->codec->block_align = 2 * 1;
134
            st->codec->bits_per_sample = 16;
135
            break;
136
        case 17:
137
            st->codec->codec_type = CODEC_TYPE_AUDIO;
138
            st->codec->codec_id = CODEC_ID_AC3;
139
            st->codec->codec_tag = 0x2000;
140
            st->codec->channels = 2;
141
            st->codec->sample_rate = 48000;
142
            break;
143
        default:
144
            st->codec->codec_type = CODEC_TYPE_UNKNOWN;
145
            st->codec->codec_id = CODEC_ID_NONE;
146
            break;
147
    }
148
    return s->nb_streams - 1;
149
}
150

  
151
static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
152
    ByteIOContext *pb = &s->pb;
153
    pkt_type_t pkt_type;
154
    int map_len;
155
    int len;
156
    if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
157
        av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");
158
        return 0;
159
    }
160
    map_len -= 2;
161
    if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {
162
        av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");
163
        return 0;
164
    }
165
    map_len -= 2;
166
    len = get_be16(pb); // length of material data section
167
    if (len > map_len) {
168
        av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");
169
        return 0;
170
    }
171
    map_len -= len;
172
    url_fskip(pb, len);
173
    map_len -= 2;
174
    len = get_be16(pb); // length of track description
175
    if (len > map_len) {
176
        av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");
177
        return 0;
178
    }
179
    map_len -= len;
180
    while (len > 0) {
181
        int track_type, track_id, track_len;
182
        len -= 4;
183
        track_type = get_byte(pb);
184
        track_id = get_byte(pb);
185
        track_len = get_be16(pb);
186
        len -= track_len;
187
        url_fskip(pb, track_len);
188
        if (!(track_type & 0x80)) {
189
           av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);
190
           continue;
191
        }
192
        track_type &= 0x7f;
193
        if ((track_id & 0xc0) != 0xc0) {
194
           av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);
195
           continue;
196
        }
197
        track_id &= 0x3f;
198
        get_sindex(s, track_id, track_type);
199
    }
200
    if (len < 0)
201
        av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");
202
    if (map_len)
203
        url_fskip(pb, map_len);
204
    return 0;
205
}
206

  
207
static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
208
    ByteIOContext *pb = &s->pb;
209
    pkt_type_t pkt_type;
210
    int pkt_len;
211
    while (!url_feof(pb)) {
212
        int track_type, track_id, ret;
213
        if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
214
            if (!url_feof(pb))
215
                av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");
216
            return -1;
217
        }
218
        if (pkt_type != PKT_MEDIA) {
219
            url_fskip(pb, pkt_len);
220
            continue;
221
        }
222
        if (pkt_len < 16) {
223
            av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");
224
            continue;
225
        }
226
        pkt_len -= 16;
227
        track_type = get_byte(pb);
228
        track_id = get_byte(pb);
229
        get_be32(pb); // field number
230
        get_be32(pb); // field information
231
        get_be32(pb); // "timeline" field number
232
        get_byte(pb); // flags
233
        get_byte(pb); // reserved
234
        // NOTE: there is also data length information in the
235
        // field information, it might be better to take this int account
236
        // as well.
237
        ret = av_get_packet(pb, pkt, pkt_len);
238
        pkt->stream_index = get_sindex(s, track_id, track_type);
239
        return ret;
240
    }
241
    return AVERROR_IO;
242
}
243

  
244
static AVInputFormat gxf_iformat = {
245
    "gxf",
246
    "GXF format",
247
    0,
248
    gxf_probe,
249
    gxf_header,
250
    gxf_packet,
251
    NULL,
252
    NULL,
253
};
254

  
255
int gxf_init(void) {
256
    av_register_input_format(&gxf_iformat);
257
    return 0;
258
}
259

  

Also available in: Unified diff