~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavformat/gxfenc.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * GXF muxer.
 
3
 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>.
 
4
 *
 
5
 * This file is part of FFmpeg.
 
6
 *
 
7
 * FFmpeg is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * FFmpeg is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with FFmpeg; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
20
 */
 
21
 
 
22
#include "avformat.h"
 
23
#include "gxf.h"
 
24
#include "riff.h"
 
25
#include "fifo.h"
 
26
 
 
27
#define GXF_AUDIO_PACKET_SIZE 65536
 
28
 
 
29
typedef struct GXFStreamContext {
 
30
    AVCodecContext *codec;
 
31
    AVFifoBuffer audio_buffer;
 
32
    uint32_t track_type;
 
33
    uint32_t sample_size;
 
34
    uint32_t sample_rate;
 
35
    uint16_t media_type;
 
36
    uint16_t media_info;
 
37
    uint8_t index;
 
38
    int frame_rate_index;
 
39
    int lines_index;
 
40
    int fields;
 
41
    int iframes;
 
42
    int pframes;
 
43
    int bframes;
 
44
    int p_per_gop;
 
45
    int b_per_gop;
 
46
    int first_gop_closed;
 
47
    int64_t current_dts;
 
48
    int dts_delay;
 
49
} GXFStreamContext;
 
50
 
 
51
typedef struct GXFContext {
 
52
    uint32_t nb_frames;
 
53
    uint32_t material_flags;
 
54
    uint16_t audio_tracks;
 
55
    uint16_t mpeg_tracks;
 
56
    int64_t creation_time;
 
57
    uint32_t umf_start_offset;
 
58
    uint32_t umf_track_offset;
 
59
    uint32_t umf_media_offset;
 
60
    uint32_t umf_user_data_offset;
 
61
    uint32_t umf_user_data_size;
 
62
    uint32_t umf_length;
 
63
    uint16_t umf_track_size;
 
64
    uint16_t umf_media_size;
 
65
    int audio_written;
 
66
    int sample_rate;
 
67
    int flags;
 
68
    AVFormatContext *fc;
 
69
    GXFStreamContext streams[48];
 
70
} GXFContext;
 
71
 
 
72
typedef struct GXF_Lines {
 
73
    int height;
 
74
    int index;
 
75
} GXF_Lines;
 
76
 
 
77
 
 
78
/* FIXME check if it is relevant */
 
79
static const GXF_Lines gxf_lines_tab[] = {
 
80
    { 480,  1 }, /* NTSC */
 
81
    { 512,  1 }, /* NTSC + VBI */
 
82
    { 576,  2 }, /* PAL */
 
83
    { 608,  2 }, /* PAL + VBI */
 
84
    { 1080, 4 },
 
85
    { 720,  6 },
 
86
};
 
87
 
 
88
static const AVCodecTag gxf_media_types[] = {
 
89
    { CODEC_ID_MJPEG     ,   3 }, /* NTSC */
 
90
    { CODEC_ID_MJPEG     ,   4 }, /* PAL */
 
91
    { CODEC_ID_PCM_S24LE ,   9 },
 
92
    { CODEC_ID_PCM_S16LE ,  10 },
 
93
    { CODEC_ID_MPEG2VIDEO,  11 }, /* NTSC */
 
94
    { CODEC_ID_MPEG2VIDEO,  12 }, /* PAL */
 
95
    { CODEC_ID_DVVIDEO   ,  13 }, /* NTSC */
 
96
    { CODEC_ID_DVVIDEO   ,  14 }, /* PAL */
 
97
    { CODEC_ID_DVVIDEO   ,  15 }, /* 50M NTSC */
 
98
    { CODEC_ID_DVVIDEO   ,  16 }, /* 50M PAL */
 
99
    { CODEC_ID_AC3       ,  17 },
 
100
    //{ CODEC_ID_NONE,  ,   18 }, /* Non compressed 24 bit audio */
 
101
    { CODEC_ID_MPEG2VIDEO,  20 }, /* MPEG HD */
 
102
    { CODEC_ID_MPEG1VIDEO,  22 }, /* NTSC */
 
103
    { CODEC_ID_MPEG1VIDEO,  23 }, /* PAL */
 
104
    { 0, 0 },
 
105
};
 
106
 
 
107
#define SERVER_PATH "/space/"
 
108
#define ES_NAME_PATTERN "ES."
 
109
 
 
110
static int gxf_find_lines_index(GXFStreamContext *ctx)
 
111
{
 
112
    int i;
 
113
 
 
114
    for (i = 0; i < 6; ++i) {
 
115
        if (ctx->codec->height == gxf_lines_tab[i].height) {
 
116
            ctx->lines_index = gxf_lines_tab[i].index;
 
117
            return 0;
 
118
        }
 
119
    }
 
120
    return -1;
 
121
}
 
122
 
 
123
static void gxf_write_padding(ByteIOContext *pb, offset_t to_pad)
 
124
{
 
125
    for (; to_pad > 0; to_pad--) {
 
126
        put_byte(pb, 0);
 
127
    }
 
128
}
 
129
 
 
130
static offset_t updatePacketSize(ByteIOContext *pb, offset_t pos)
 
131
{
 
132
    offset_t curpos;
 
133
    int size;
 
134
 
 
135
    size = url_ftell(pb) - pos;
 
136
    if (size % 4) {
 
137
        gxf_write_padding(pb, 4 - size % 4);
 
138
        size = url_ftell(pb) - pos;
 
139
    }
 
140
    curpos = url_ftell(pb);
 
141
    url_fseek(pb, pos + 6, SEEK_SET);
 
142
    put_be32(pb, size);
 
143
    url_fseek(pb, curpos, SEEK_SET);
 
144
    return curpos - pos;
 
145
}
 
146
 
 
147
static offset_t updateSize(ByteIOContext *pb, offset_t pos)
 
148
{
 
149
    offset_t curpos;
 
150
 
 
151
    curpos = url_ftell(pb);
 
152
    url_fseek(pb, pos, SEEK_SET);
 
153
    put_be16(pb, curpos - pos - 2);
 
154
    url_fseek(pb, curpos, SEEK_SET);
 
155
    return curpos - pos;
 
156
}
 
157
 
 
158
static void gxf_write_packet_header(ByteIOContext *pb, pkt_type_t type)
 
159
{
 
160
    put_be32(pb, 0); /* packet leader for synchro */
 
161
    put_byte(pb, 1);
 
162
    put_byte(pb, type); /* map packet */
 
163
    put_be32(pb, 0); /* size */
 
164
    put_be32(pb, 0); /* reserved */
 
165
    put_byte(pb, 0xE1); /* trailer 1 */
 
166
    put_byte(pb, 0xE2); /* trailer 2 */
 
167
}
 
168
 
 
169
static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx)
 
170
{
 
171
    char buffer[1024];
 
172
    int size;
 
173
 
 
174
    if (ctx->iframes) {
 
175
        ctx->p_per_gop = ctx->pframes / ctx->iframes;
 
176
        if (ctx->pframes % ctx->iframes)
 
177
            ctx->p_per_gop++;
 
178
        if (ctx->pframes)
 
179
            ctx->b_per_gop = ctx->bframes / ctx->pframes;
 
180
        if (ctx->p_per_gop > 9)
 
181
            ctx->p_per_gop = 9; /* ensure value won't take more than one char */
 
182
        if (ctx->b_per_gop > 9)
 
183
            ctx->b_per_gop = 9; /* ensure value won't take more than one char */
 
184
    }
 
185
    size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
 
186
                    "Pix 0\nCf %d\nCg %d\nSl 7\nnl16 %d\nVi 1\nf1 1\n",
 
187
                    (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_gop,
 
188
                    ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1,
 
189
                    ctx->codec->height / 16);
 
190
    put_byte(pb, 0x4F);
 
191
    put_byte(pb, size + 1);
 
192
    put_buffer(pb, (uint8_t *)buffer, size + 1);
 
193
    return size + 3;
 
194
}
 
195
 
 
196
static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx)
 
197
{
 
198
    /* FIXME implement that */
 
199
    put_byte(pb, 0); /* fields */
 
200
    put_byte(pb, 0);  /* seconds */
 
201
    put_byte(pb, 0); /* minutes */
 
202
    put_byte(pb, 0); /* flags + hours */
 
203
    /* reserved */
 
204
    put_be32(pb, 0);
 
205
    return 8;
 
206
}
 
207
 
 
208
static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream)
 
209
{
 
210
    offset_t pos;
 
211
 
 
212
    /* track description section */
 
213
    put_byte(pb, stream->media_type + 0x80);
 
214
    put_byte(pb, stream->index + 0xC0);
 
215
 
 
216
    pos = url_ftell(pb);
 
217
    put_be16(pb, 0); /* size */
 
218
 
 
219
    /* media file name */
 
220
    put_byte(pb, 0x4C);
 
221
    put_byte(pb, strlen(ES_NAME_PATTERN) + 3);
 
222
    put_tag(pb, ES_NAME_PATTERN);
 
223
    put_be16(pb, stream->media_info);
 
224
    put_byte(pb, 0);
 
225
 
 
226
    if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) {
 
227
        /* auxiliary information */
 
228
        put_byte(pb, 0x4D);
 
229
        put_byte(pb, 8);
 
230
        if (stream->codec->codec_id == CODEC_ID_NONE)
 
231
            gxf_write_timecode_auxiliary(pb, stream);
 
232
        else
 
233
            put_le64(pb, 0);
 
234
    }
 
235
 
 
236
    /* file system version */
 
237
    put_byte(pb, 0x4E);
 
238
    put_byte(pb, 4);
 
239
    put_be32(pb, 0);
 
240
 
 
241
    if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)
 
242
        gxf_write_mpeg_auxiliary(pb, stream);
 
243
 
 
244
    /* frame rate */
 
245
    put_byte(pb, 0x50);
 
246
    put_byte(pb, 4);
 
247
    put_be32(pb, stream->frame_rate_index);
 
248
 
 
249
    /* lines per frame */
 
250
    put_byte(pb, 0x51);
 
251
    put_byte(pb, 4);
 
252
    put_be32(pb, stream->lines_index);
 
253
 
 
254
    /* fields per frame */
 
255
    put_byte(pb, 0x52);
 
256
    put_byte(pb, 4);
 
257
    put_be32(pb, stream->fields);
 
258
 
 
259
    return updateSize(pb, pos);
 
260
}
 
261
 
 
262
static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx)
 
263
{
 
264
    offset_t pos;
 
265
    const char *filename = strrchr(ctx->fc->filename, '/');
 
266
 
 
267
    pos = url_ftell(pb);
 
268
    put_be16(pb, 0); /* size */
 
269
 
 
270
    /* name */
 
271
    if (filename)
 
272
        filename++;
 
273
    else
 
274
        filename = ctx->fc->filename;
 
275
    put_byte(pb, 0x40);
 
276
    put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);
 
277
    put_tag(pb, SERVER_PATH);
 
278
    put_tag(pb, filename);
 
279
    put_byte(pb, 0);
 
280
 
 
281
    /* first field */
 
282
    put_byte(pb, 0x41);
 
283
    put_byte(pb, 4);
 
284
    put_be32(pb, 0);
 
285
 
 
286
    /* last field */
 
287
    put_byte(pb, 0x42);
 
288
    put_byte(pb, 4);
 
289
    put_be32(pb, ctx->nb_frames);
 
290
 
 
291
    /* reserved */
 
292
    put_byte(pb, 0x43);
 
293
    put_byte(pb, 4);
 
294
    put_be32(pb, 0);
 
295
 
 
296
    put_byte(pb, 0x44);
 
297
    put_byte(pb, 4);
 
298
    put_be32(pb, ctx->nb_frames);
 
299
 
 
300
    /* estimated size */
 
301
    put_byte(pb, 0x45);
 
302
    put_byte(pb, 4);
 
303
    put_be32(pb, url_fsize(pb) / 1024);
 
304
 
 
305
    return updateSize(pb, pos);
 
306
}
 
307
 
 
308
static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx)
 
309
{
 
310
    offset_t pos;
 
311
    int i;
 
312
 
 
313
    pos = url_ftell(pb);
 
314
    put_be16(pb, 0); /* size */
 
315
    for (i = 0; i < ctx->fc->nb_streams; ++i)
 
316
        gxf_write_track_description(pb, &ctx->streams[i]);
 
317
    return updateSize(pb, pos);
 
318
}
 
319
 
 
320
static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx)
 
321
{
 
322
    offset_t pos = url_ftell(pb);
 
323
 
 
324
    gxf_write_packet_header(pb, PKT_MAP);
 
325
 
 
326
    /* preamble */
 
327
    put_byte(pb, 0xE0); /* version */
 
328
    put_byte(pb, 0xFF); /* reserved */
 
329
 
 
330
    gxf_write_material_data_section(pb, ctx);
 
331
    gxf_write_track_description_section(pb, ctx);
 
332
 
 
333
    return updatePacketSize(pb, pos);
 
334
}
 
335
 
 
336
#if 0
 
337
static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx)
 
338
{
 
339
    offset_t pos = url_ftell(pb);
 
340
    int i;
 
341
 
 
342
    gxf_write_packet_header(pb, PKT_FLT);
 
343
 
 
344
    put_le32(pb, 1000); /* number of fields */
 
345
    put_le32(pb, 0); /* number of active flt entries */
 
346
 
 
347
    for (i = 0; i < 1000; ++i) {
 
348
        put_le32(pb, 0);
 
349
    }
 
350
    return updatePacketSize(pb, pos);
 
351
}
 
352
#endif
 
353
 
 
354
static int gxf_write_umf_material_description(ByteIOContext *pb, GXFContext *ctx)
 
355
{
 
356
    put_le32(pb, ctx->flags);
 
357
    put_le32(pb, ctx->nb_frames); /* length of the longest track */
 
358
    put_le32(pb, ctx->nb_frames); /* length of the shortest track */
 
359
    put_le32(pb, 0); /* mark in */
 
360
    put_le32(pb, ctx->nb_frames); /* mark out */
 
361
    put_le32(pb, 0); /* timecode mark in */
 
362
    put_le32(pb, ctx->nb_frames); /* timecode mark out */
 
363
    put_le64(pb, ctx->fc->timestamp); /* modification time */
 
364
    put_le64(pb, ctx->fc->timestamp); /* creation time */
 
365
    put_le16(pb, 0); /* reserved */
 
366
    put_le16(pb, 0); /* reserved */
 
367
    put_le16(pb, ctx->audio_tracks);
 
368
    put_le16(pb, 0); /* timecode track count */
 
369
    put_le16(pb, 0); /* reserved */
 
370
    put_le16(pb, ctx->mpeg_tracks);
 
371
    return 48;
 
372
}
 
373
 
 
374
static int gxf_write_umf_payload(ByteIOContext *pb, GXFContext *ctx)
 
375
{
 
376
    put_le32(pb, ctx->umf_length); /* total length of the umf data */
 
377
    put_le32(pb, 3); /* version */
 
378
    put_le32(pb, ctx->fc->nb_streams);
 
379
    put_le32(pb, ctx->umf_track_offset); /* umf track section offset */
 
380
    put_le32(pb, ctx->umf_track_size);
 
381
    put_le32(pb, ctx->fc->nb_streams);
 
382
    put_le32(pb, ctx->umf_media_offset);
 
383
    put_le32(pb, ctx->umf_media_size);
 
384
    put_le32(pb, ctx->umf_user_data_offset); /* user data offset */
 
385
    put_le32(pb, ctx->umf_user_data_size); /* user data size */
 
386
    put_le32(pb, 0); /* reserved */
 
387
    put_le32(pb, 0); /* reserved */
 
388
    return 48;
 
389
}
 
390
 
 
391
static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx)
 
392
{
 
393
    offset_t pos = url_ftell(pb);
 
394
    int tracks[255]={0};
 
395
    int i;
 
396
 
 
397
    ctx->umf_track_offset = pos - ctx->umf_start_offset;
 
398
    for (i = 0; i < ctx->fc->nb_streams; ++i) {
 
399
        AVStream *st = ctx->fc->streams[i];
 
400
        GXFStreamContext *sc = &ctx->streams[i];
 
401
        int id = 0;
 
402
 
 
403
        switch (st->codec->codec_id) {
 
404
        case CODEC_ID_MPEG1VIDEO: id= 'L'; break;
 
405
        case CODEC_ID_MPEG2VIDEO: id= 'M'; break;
 
406
        case CODEC_ID_PCM_S16LE:  id= 'A'; break;
 
407
        case CODEC_ID_DVVIDEO:    id= sc->track_type == 6 ? 'E' : 'D'; break;
 
408
        case CODEC_ID_MJPEG:      id= 'V'; break;
 
409
        default:                  break;
 
410
        }
 
411
        sc->media_info= id << 8;
 
412
        /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
 
413
        sc->media_info |= '0' + (tracks[id]++);
 
414
        put_le16(pb, sc->media_info);
 
415
        put_le16(pb, 1);
 
416
    }
 
417
    return url_ftell(pb) - pos;
 
418
}
 
419
 
 
420
static int gxf_write_umf_media_mpeg(ByteIOContext *pb, GXFStreamContext *stream)
 
421
{
 
422
    if (stream->codec->pix_fmt == PIX_FMT_YUV422P)
 
423
        put_le32(pb, 2);
 
424
    else
 
425
        put_le32(pb, 1); /* default to 420 */
 
426
    put_le32(pb, stream->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
 
427
    put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
 
428
    put_le32(pb, 1); /* I picture per GOP */
 
429
    put_le32(pb, stream->p_per_gop);
 
430
    put_le32(pb, stream->b_per_gop);
 
431
    if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)
 
432
        put_le32(pb, 2);
 
433
    else if (stream->codec->codec_id == CODEC_ID_MPEG1VIDEO)
 
434
        put_le32(pb, 1);
 
435
    else
 
436
        put_le32(pb, 0);
 
437
    put_le32(pb, 0); /* reserved */
 
438
    return 32;
 
439
}
 
440
 
 
441
static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *track)
 
442
{
 
443
    /* FIXME implement */
 
444
    put_be32(pb, 0); /* drop frame flag */
 
445
    put_be32(pb, 0); /* reserved */
 
446
    put_be32(pb, 0); /* reserved */
 
447
    put_be32(pb, 0); /* reserved */
 
448
    put_be32(pb, 0); /* reserved */
 
449
    put_be32(pb, 0); /* reserved */
 
450
    put_be32(pb, 0); /* reserved */
 
451
    put_be32(pb, 0); /* reserved */
 
452
    return 32;
 
453
}
 
454
 
 
455
static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *track)
 
456
{
 
457
    int i;
 
458
 
 
459
    for (i = 0; i < 8; i++) {
 
460
        put_be32(pb, 0);
 
461
    }
 
462
    return 32;
 
463
}
 
464
 
 
465
static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *track)
 
466
{
 
467
    put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
 
468
    put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
 
469
    put_le32(pb, 0); /* number of fields over which to ramp up sound level */
 
470
    put_le32(pb, 0); /* number of fields over which to ramp down sound level */
 
471
    put_le32(pb, 0); /* reserved */
 
472
    put_le32(pb, 0); /* reserved */
 
473
    return 32;
 
474
}
 
475
 
 
476
#if 0
 
477
static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *track)
 
478
{
 
479
    put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */
 
480
    put_be64(pb, 0); /* FIXME FLOAT max luma quant level */
 
481
    put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */
 
482
    put_be64(pb, 0); /* FIXME FLOAT min luma quant level */
 
483
    return 32;
 
484
}
 
485
#endif
 
486
 
 
487
static int gxf_write_umf_media_description(ByteIOContext *pb, GXFContext *ctx)
 
488
{
 
489
    offset_t pos;
 
490
    int i;
 
491
 
 
492
    pos = url_ftell(pb);
 
493
    ctx->umf_media_offset = pos - ctx->umf_start_offset;
 
494
    for (i = 0; i < ctx->fc->nb_streams; ++i) {
 
495
        GXFStreamContext *sc = &ctx->streams[i];
 
496
        char buffer[88];
 
497
        offset_t startpos, curpos;
 
498
        int path_size = strlen(ES_NAME_PATTERN);
 
499
 
 
500
        memset(buffer, 0, 88);
 
501
        startpos = url_ftell(pb);
 
502
        put_le16(pb, 0); /* length */
 
503
        put_le16(pb, sc->media_info);
 
504
        put_le16(pb, 0); /* reserved */
 
505
        put_le16(pb, 0); /* reserved */
 
506
        put_le32(pb, ctx->nb_frames);
 
507
        put_le32(pb, 0); /* attributes rw, ro */
 
508
        put_le32(pb, 0); /* mark in */
 
509
        put_le32(pb, ctx->nb_frames); /* mark out */
 
510
        strncpy(buffer, ES_NAME_PATTERN, path_size);
 
511
        put_buffer(pb, (uint8_t *)buffer, path_size);
 
512
        put_be16(pb, sc->media_info);
 
513
        put_buffer(pb, (uint8_t *)buffer + path_size + 2, 88 - path_size - 2);
 
514
        put_le32(pb, sc->track_type);
 
515
        put_le32(pb, sc->sample_rate);
 
516
        put_le32(pb, sc->sample_size);
 
517
        put_le32(pb, 0); /* reserved */
 
518
        switch (sc->codec->codec_id) {
 
519
        case CODEC_ID_MPEG2VIDEO:
 
520
            gxf_write_umf_media_mpeg(pb, sc);
 
521
            break;
 
522
        case CODEC_ID_PCM_S16LE:
 
523
            gxf_write_umf_media_audio(pb, sc);
 
524
            break;
 
525
        case CODEC_ID_DVVIDEO:
 
526
            gxf_write_umf_media_dv(pb, sc);
 
527
            break;
 
528
        default:
 
529
            gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
 
530
        }
 
531
        curpos = url_ftell(pb);
 
532
        url_fseek(pb, startpos, SEEK_SET);
 
533
        put_le16(pb, curpos - startpos);
 
534
        url_fseek(pb, curpos, SEEK_SET);
 
535
    }
 
536
    return url_ftell(pb) - pos;
 
537
}
 
538
 
 
539
static int gxf_write_umf_user_data(ByteIOContext *pb, GXFContext *ctx)
 
540
{
 
541
    offset_t pos = url_ftell(pb);
 
542
    ctx->umf_user_data_offset = pos - ctx->umf_start_offset;
 
543
    put_le32(pb, 20);
 
544
    put_le32(pb,  0);
 
545
    put_le16(pb,  0);
 
546
    put_le16(pb,  0);
 
547
    put_le32(pb,  0);
 
548
    put_byte(pb,  0);
 
549
    put_byte(pb,  0);
 
550
    put_byte(pb,  0);
 
551
    put_byte(pb,  0);
 
552
    return 20;
 
553
}
 
554
 
 
555
static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx)
 
556
{
 
557
    offset_t pos = url_ftell(pb);
 
558
 
 
559
    gxf_write_packet_header(pb, PKT_UMF);
 
560
 
 
561
    /* preamble */
 
562
    put_byte(pb, 3); /* first and last (only) packet */
 
563
    put_be32(pb, ctx->umf_length); /* data length */
 
564
 
 
565
    ctx->umf_start_offset = url_ftell(pb);
 
566
    gxf_write_umf_payload(pb, ctx);
 
567
    gxf_write_umf_material_description(pb, ctx);
 
568
    ctx->umf_track_size = gxf_write_umf_track_description(pb, ctx);
 
569
    ctx->umf_media_size = gxf_write_umf_media_description(pb, ctx);
 
570
    ctx->umf_user_data_size = gxf_write_umf_user_data(pb, ctx);
 
571
    ctx->umf_length = url_ftell(pb) - ctx->umf_start_offset;
 
572
    return updatePacketSize(pb, pos);
 
573
}
 
574
 
 
575
#define GXF_NODELAY -5000
 
576
 
 
577
static int gxf_write_header(AVFormatContext *s)
 
578
{
 
579
    ByteIOContext *pb = &s->pb;
 
580
    GXFContext *gxf = s->priv_data;
 
581
    int i;
 
582
 
 
583
    gxf->fc = s;
 
584
    gxf->flags |= 0x00080000; /* material is simple clip */
 
585
    for (i = 0; i < s->nb_streams; ++i) {
 
586
        AVStream *st = s->streams[i];
 
587
        GXFStreamContext *sc = &gxf->streams[i];
 
588
 
 
589
        sc->codec = st->codec;
 
590
        sc->index = i;
 
591
        sc->media_type = codec_get_tag(gxf_media_types, sc->codec->codec_id);
 
592
        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
 
593
            if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
 
594
                av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
 
595
                return -1;
 
596
            }
 
597
            if (st->codec->sample_rate != 48000) {
 
598
                av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
 
599
                return -1;
 
600
            }
 
601
            if (st->codec->channels != 1) {
 
602
                av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
 
603
                return -1;
 
604
            }
 
605
            sc->track_type = 2;
 
606
            sc->sample_rate = st->codec->sample_rate;
 
607
            av_set_pts_info(st, 64, 1, sc->sample_rate);
 
608
            sc->sample_size = 16;
 
609
            sc->frame_rate_index = -2;
 
610
            sc->lines_index = -2;
 
611
            sc->fields = -2;
 
612
            gxf->audio_tracks++;
 
613
            gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
 
614
            av_fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
 
615
        } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
 
616
            /* FIXME check from time_base ? */
 
617
            if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */
 
618
                sc->frame_rate_index = 5;
 
619
                sc->sample_rate = 60;
 
620
                gxf->flags |= 0x00000080;
 
621
            } else { /* assume PAL */
 
622
                sc->frame_rate_index = 6;
 
623
                sc->media_type++;
 
624
                sc->sample_rate = 50;
 
625
                gxf->flags |= 0x00000040;
 
626
            }
 
627
            gxf->sample_rate = sc->sample_rate;
 
628
            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
 
629
            sc->dts_delay = GXF_NODELAY;
 
630
            if (gxf_find_lines_index(sc) < 0)
 
631
                sc->lines_index = -1;
 
632
            sc->sample_size = st->codec->bit_rate;
 
633
            sc->fields = 2; /* interlaced */
 
634
            switch (sc->codec->codec_id) {
 
635
            case CODEC_ID_MPEG2VIDEO:
 
636
                sc->first_gop_closed = -1;
 
637
                sc->track_type = 4;
 
638
                gxf->mpeg_tracks++;
 
639
                gxf->flags |= 0x00008000;
 
640
                break;
 
641
            case CODEC_ID_DVVIDEO:
 
642
                if (sc->codec->pix_fmt == PIX_FMT_YUV422P) {
 
643
                    sc->media_type += 2;
 
644
                    sc->track_type = 6;
 
645
                    gxf->flags |= 0x00002000;
 
646
                } else {
 
647
                    sc->track_type = 5;
 
648
                    gxf->flags |= 0x00001000;
 
649
                }
 
650
                break;
 
651
            default:
 
652
                av_log(s, AV_LOG_ERROR, "video codec not supported\n");
 
653
                return -1;
 
654
            }
 
655
        }
 
656
    }
 
657
    gxf_write_map_packet(pb, gxf);
 
658
    //gxf_write_flt_packet(pb, gxf);
 
659
    gxf_write_umf_packet(pb, gxf);
 
660
    put_flush_packet(pb);
 
661
    return 0;
 
662
}
 
663
 
 
664
static int gxf_write_eos_packet(ByteIOContext *pb, GXFContext *ctx)
 
665
{
 
666
    offset_t pos = url_ftell(pb);
 
667
 
 
668
    gxf_write_packet_header(pb, PKT_EOS);
 
669
    return updatePacketSize(pb, pos);
 
670
}
 
671
 
 
672
static int gxf_write_trailer(AVFormatContext *s)
 
673
{
 
674
    ByteIOContext *pb = &s->pb;
 
675
    GXFContext *gxf = s->priv_data;
 
676
    offset_t end;
 
677
    int i;
 
678
 
 
679
    for (i = 0; i < s->nb_streams; ++i) {
 
680
        if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
 
681
            av_fifo_free(&gxf->streams[i].audio_buffer);
 
682
        }
 
683
        if (s->streams[i]->codec->frame_number > gxf->nb_frames)
 
684
            gxf->nb_frames = 2 * s->streams[i]->codec->frame_number;
 
685
    }
 
686
 
 
687
    gxf_write_eos_packet(pb, gxf);
 
688
    end = url_ftell(pb);
 
689
    url_fseek(pb, 0, SEEK_SET);
 
690
    /* overwrite map and umf packets with new values */
 
691
    gxf_write_map_packet(pb, gxf);
 
692
    //gxf_write_flt_packet(pb, gxf);
 
693
    gxf_write_umf_packet(pb, gxf);
 
694
    url_fseek(pb, end, SEEK_SET);
 
695
    return 0;
 
696
}
 
697
 
 
698
static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
 
699
{
 
700
    uint32_t c=-1;
 
701
    int i;
 
702
    for(i=0; i<size-4 && c!=0x100; i++){
 
703
        c = (c<<8) + buf[i];
 
704
        if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
 
705
            sc->first_gop_closed= (buf[i+4]>>6)&1;
 
706
    }
 
707
    return (buf[i+1]>>3)&7;
 
708
}
 
709
 
 
710
static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size)
 
711
{
 
712
    GXFStreamContext *sc = &ctx->streams[pkt->stream_index];
 
713
    int64_t dts = av_rescale(pkt->dts, ctx->sample_rate, sc->codec->time_base.den);
 
714
 
 
715
    put_byte(pb, sc->media_type);
 
716
    put_byte(pb, sc->index);
 
717
    put_be32(pb, dts);
 
718
    if (sc->codec->codec_type == CODEC_TYPE_AUDIO) {
 
719
        put_be16(pb, 0);
 
720
        put_be16(pb, size / 2);
 
721
    } else if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
 
722
        int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
 
723
        if (frame_type == FF_I_TYPE) {
 
724
            put_byte(pb, 0x0d);
 
725
            sc->iframes++;
 
726
        } else if (frame_type == FF_B_TYPE) {
 
727
            put_byte(pb, 0x0f);
 
728
            sc->bframes++;
 
729
        } else {
 
730
            put_byte(pb, 0x0e);
 
731
            sc->pframes++;
 
732
        }
 
733
        put_be24(pb, size);
 
734
    } else if (sc->codec->codec_id == CODEC_ID_DVVIDEO) {
 
735
        put_byte(pb, size / 4096);
 
736
        put_be24(pb, 0);
 
737
    } else
 
738
        put_be32(pb, size);
 
739
    put_be32(pb, dts);
 
740
    put_byte(pb, 1); /* flags */
 
741
    put_byte(pb, 0); /* reserved */
 
742
    return 16;
 
743
}
 
744
 
 
745
static int gxf_write_media_packet(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt)
 
746
{
 
747
    GXFStreamContext *sc = &ctx->streams[pkt->stream_index];
 
748
    offset_t pos = url_ftell(pb);
 
749
    int padding = 0;
 
750
 
 
751
    gxf_write_packet_header(pb, PKT_MEDIA);
 
752
    if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
 
753
        padding = 4 - pkt->size % 4;
 
754
    else if (sc->codec->codec_type == CODEC_TYPE_AUDIO)
 
755
        padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
 
756
    gxf_write_media_preamble(pb, ctx, pkt, pkt->size + padding);
 
757
    put_buffer(pb, pkt->data, pkt->size);
 
758
    gxf_write_padding(pb, padding);
 
759
    return updatePacketSize(pb, pos);
 
760
}
 
761
 
 
762
static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
763
{
 
764
    GXFContext *gxf = s->priv_data;
 
765
 
 
766
    gxf_write_media_packet(&s->pb, gxf, pkt);
 
767
    put_flush_packet(&s->pb);
 
768
    return 0;
 
769
}
 
770
 
 
771
static int gxf_new_audio_packet(GXFContext *gxf, GXFStreamContext *sc, AVPacket *pkt, int flush)
 
772
{
 
773
    int size = flush ? av_fifo_size(&sc->audio_buffer) : GXF_AUDIO_PACKET_SIZE;
 
774
 
 
775
    if (!size)
 
776
        return 0;
 
777
    av_new_packet(pkt, size);
 
778
    av_fifo_read(&sc->audio_buffer, pkt->data, size);
 
779
    pkt->stream_index = sc->index;
 
780
    pkt->dts = sc->current_dts;
 
781
    sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */
 
782
    return size;
 
783
}
 
784
 
 
785
static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
 
786
{
 
787
    GXFContext *gxf = s->priv_data;
 
788
    AVPacket new_pkt;
 
789
    int i;
 
790
 
 
791
    for (i = 0; i < s->nb_streams; i++) {
 
792
        AVStream *st = s->streams[i];
 
793
        GXFStreamContext *sc = &gxf->streams[i];
 
794
        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
 
795
            if (pkt && pkt->stream_index == i) {
 
796
                av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size);
 
797
                pkt = NULL;
 
798
            }
 
799
            if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) {
 
800
                if (!pkt && gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) {
 
801
                    pkt = &new_pkt;
 
802
                    break; /* add pkt right now into list */
 
803
                }
 
804
            }
 
805
        } else if (pkt && pkt->stream_index == i) {
 
806
            if (sc->dts_delay == GXF_NODELAY) /* adjust dts if needed */
 
807
                sc->dts_delay = pkt->dts;
 
808
            pkt->dts -= sc->dts_delay;
 
809
        }
 
810
    }
 
811
    return av_interleave_packet_per_dts(s, out, pkt, flush);
 
812
}
 
813
 
 
814
AVOutputFormat gxf_muxer = {
 
815
    "gxf",
 
816
    "GXF format",
 
817
    NULL,
 
818
    "gxf",
 
819
    sizeof(GXFContext),
 
820
    CODEC_ID_PCM_S16LE,
 
821
    CODEC_ID_MPEG2VIDEO,
 
822
    gxf_write_header,
 
823
    gxf_write_packet,
 
824
    gxf_write_trailer,
 
825
    0,
 
826
    NULL,
 
827
    gxf_interleave_packet,
 
828
};