Statistics
| Branch: | Revision:

ffmpeg / libavformat / rmenc.c @ 72415b2a

History | View | Annotate | Download (14.6 KB)

1
/*
2
 * "Real" compatible muxer.
3
 * Copyright (c) 2000, 2001 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (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 GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License 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
#include "avformat.h"
22
#include "rm.h"
23

    
24
typedef struct {
25
    int nb_packets;
26
    int packet_total_size;
27
    int packet_max_size;
28
    /* codec related output */
29
    int bit_rate;
30
    float frame_rate;
31
    int nb_frames;    /* current frame number */
32
    int total_frames; /* total number of frames */
33
    int num;
34
    AVCodecContext *enc;
35
} StreamInfo;
36

    
37
typedef struct {
38
    StreamInfo streams[2];
39
    StreamInfo *audio_stream, *video_stream;
40
    int data_pos; /* position of the data after the header */
41
} RMMuxContext;
42

    
43
/* in ms */
44
#define BUFFER_DURATION 0
45

    
46

    
47
static void put_str(ByteIOContext *s, const char *tag)
48
{
49
    put_be16(s,strlen(tag));
50
    while (*tag) {
51
        put_byte(s, *tag++);
52
    }
53
}
54

    
55
static void put_str8(ByteIOContext *s, const char *tag)
56
{
57
    put_byte(s, strlen(tag));
58
    while (*tag) {
59
        put_byte(s, *tag++);
60
    }
61
}
62

    
63
static void rv10_write_header(AVFormatContext *ctx,
64
                              int data_size, int index_pos)
65
{
66
    RMMuxContext *rm = ctx->priv_data;
67
    ByteIOContext *s = ctx->pb;
68
    StreamInfo *stream;
69
    unsigned char *data_offset_ptr, *start_ptr;
70
    const char *desc, *mimetype;
71
    int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i;
72
    int bit_rate, v, duration, flags, data_pos;
73
    AVMetadataTag *tag;
74

    
75
    start_ptr = s->buf_ptr;
76

    
77
    put_tag(s, ".RMF");
78
    put_be32(s,18); /* header size */
79
    put_be16(s,0);
80
    put_be32(s,0);
81
    put_be32(s,4 + ctx->nb_streams); /* num headers */
82

    
83
    put_tag(s,"PROP");
84
    put_be32(s, 50);
85
    put_be16(s, 0);
86
    packet_max_size = 0;
87
    packet_total_size = 0;
88
    nb_packets = 0;
89
    bit_rate = 0;
90
    duration = 0;
91
    for(i=0;i<ctx->nb_streams;i++) {
92
        StreamInfo *stream = &rm->streams[i];
93
        bit_rate += stream->bit_rate;
94
        if (stream->packet_max_size > packet_max_size)
95
            packet_max_size = stream->packet_max_size;
96
        nb_packets += stream->nb_packets;
97
        packet_total_size += stream->packet_total_size;
98
        /* select maximum duration */
99
        v = (int) (1000.0 * (float)stream->total_frames / stream->frame_rate);
100
        if (v > duration)
101
            duration = v;
102
    }
103
    put_be32(s, bit_rate); /* max bit rate */
104
    put_be32(s, bit_rate); /* avg bit rate */
105
    put_be32(s, packet_max_size);        /* max packet size */
106
    if (nb_packets > 0)
107
        packet_avg_size = packet_total_size / nb_packets;
108
    else
109
        packet_avg_size = 0;
110
    put_be32(s, packet_avg_size);        /* avg packet size */
111
    put_be32(s, nb_packets);  /* num packets */
112
    put_be32(s, duration); /* duration */
113
    put_be32(s, BUFFER_DURATION);           /* preroll */
114
    put_be32(s, index_pos);           /* index offset */
115
    /* computation of data the data offset */
116
    data_offset_ptr = s->buf_ptr;
117
    put_be32(s, 0);           /* data offset : will be patched after */
118
    put_be16(s, ctx->nb_streams);    /* num streams */
119
    flags = 1 | 2; /* save allowed & perfect play */
120
    if (url_is_streamed(s))
121
        flags |= 4; /* live broadcast */
122
    put_be16(s, flags);
123

    
124
    /* comments */
125

    
126
    put_tag(s,"CONT");
127
    size =  4 * 2 + 10;
128
    for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
129
        tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
130
        if(tag) size += strlen(tag->value);
131
    }
132
    put_be32(s,size);
133
    put_be16(s,0);
134
    for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
135
        tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
136
        put_str(s, tag ? tag->value : "");
137
    }
138

    
139
    for(i=0;i<ctx->nb_streams;i++) {
140
        int codec_data_size;
141

    
142
        stream = &rm->streams[i];
143

    
144
        if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
145
            desc = "The Audio Stream";
146
            mimetype = "audio/x-pn-realaudio";
147
            codec_data_size = 73;
148
        } else {
149
            desc = "The Video Stream";
150
            mimetype = "video/x-pn-realvideo";
151
            codec_data_size = 34;
152
        }
153

    
154
        put_tag(s,"MDPR");
155
        size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size;
156
        put_be32(s, size);
157
        put_be16(s, 0);
158

    
159
        put_be16(s, i); /* stream number */
160
        put_be32(s, stream->bit_rate); /* max bit rate */
161
        put_be32(s, stream->bit_rate); /* avg bit rate */
162
        put_be32(s, stream->packet_max_size);        /* max packet size */
163
        if (stream->nb_packets > 0)
164
            packet_avg_size = stream->packet_total_size /
165
                stream->nb_packets;
166
        else
167
            packet_avg_size = 0;
168
        put_be32(s, packet_avg_size);        /* avg packet size */
169
        put_be32(s, 0);           /* start time */
170
        put_be32(s, BUFFER_DURATION);           /* preroll */
171
        /* duration */
172
        if (url_is_streamed(s) || !stream->total_frames)
173
            put_be32(s, (int)(3600 * 1000));
174
        else
175
            put_be32(s, (int)(stream->total_frames * 1000 / stream->frame_rate));
176
        put_str8(s, desc);
177
        put_str8(s, mimetype);
178
        put_be32(s, codec_data_size);
179

    
180
        if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
181
            int coded_frame_size, fscode, sample_rate;
182
            sample_rate = stream->enc->sample_rate;
183
            coded_frame_size = (stream->enc->bit_rate *
184
                                stream->enc->frame_size) / (8 * sample_rate);
185
            /* audio codec info */
186
            put_tag(s, ".ra");
187
            put_byte(s, 0xfd);
188
            put_be32(s, 0x00040000); /* version */
189
            put_tag(s, ".ra4");
190
            put_be32(s, 0x01b53530); /* stream length */
191
            put_be16(s, 4); /* unknown */
192
            put_be32(s, 0x39); /* header size */
193

    
194
            switch(sample_rate) {
195
            case 48000:
196
            case 24000:
197
            case 12000:
198
                fscode = 1;
199
                break;
200
            default:
201
            case 44100:
202
            case 22050:
203
            case 11025:
204
                fscode = 2;
205
                break;
206
            case 32000:
207
            case 16000:
208
            case 8000:
209
                fscode = 3;
210
            }
211
            put_be16(s, fscode); /* codec additional info, for AC-3, seems
212
                                     to be a frequency code */
213
            /* special hack to compensate rounding errors... */
214
            if (coded_frame_size == 557)
215
                coded_frame_size--;
216
            put_be32(s, coded_frame_size); /* frame length */
217
            put_be32(s, 0x51540); /* unknown */
218
            put_be32(s, 0x249f0); /* unknown */
219
            put_be32(s, 0x249f0); /* unknown */
220
            put_be16(s, 0x01);
221
            /* frame length : seems to be very important */
222
            put_be16(s, coded_frame_size);
223
            put_be32(s, 0); /* unknown */
224
            put_be16(s, stream->enc->sample_rate); /* sample rate */
225
            put_be32(s, 0x10); /* unknown */
226
            put_be16(s, stream->enc->channels);
227
            put_str8(s, "Int0"); /* codec name */
228
            put_str8(s, "dnet"); /* codec name */
229
            put_be16(s, 0); /* title length */
230
            put_be16(s, 0); /* author length */
231
            put_be16(s, 0); /* copyright length */
232
            put_byte(s, 0); /* end of header */
233
        } else {
234
            /* video codec info */
235
            put_be32(s,34); /* size */
236
            if(stream->enc->codec_id == CODEC_ID_RV10)
237
                put_tag(s,"VIDORV10");
238
            else
239
                put_tag(s,"VIDORV20");
240
            put_be16(s, stream->enc->width);
241
            put_be16(s, stream->enc->height);
242
            put_be16(s, (int) stream->frame_rate); /* frames per seconds ? */
243
            put_be32(s,0);     /* unknown meaning */
244
            put_be16(s, (int) stream->frame_rate);  /* unknown meaning */
245
            put_be32(s,0);     /* unknown meaning */
246
            put_be16(s, 8);    /* unknown meaning */
247
            /* Seems to be the codec version: only use basic H263. The next
248
               versions seems to add a diffential DC coding as in
249
               MPEG... nothing new under the sun */
250
            if(stream->enc->codec_id == CODEC_ID_RV10)
251
                put_be32(s,0x10000000);
252
            else
253
                put_be32(s,0x20103001);
254
            //put_be32(s,0x10003000);
255
        }
256
    }
257

    
258
    /* patch data offset field */
259
    data_pos = s->buf_ptr - start_ptr;
260
    rm->data_pos = data_pos;
261
    data_offset_ptr[0] = data_pos >> 24;
262
    data_offset_ptr[1] = data_pos >> 16;
263
    data_offset_ptr[2] = data_pos >> 8;
264
    data_offset_ptr[3] = data_pos;
265

    
266
    /* data stream */
267
    put_tag(s,"DATA");
268
    put_be32(s,data_size + 10 + 8);
269
    put_be16(s,0);
270

    
271
    put_be32(s, nb_packets); /* number of packets */
272
    put_be32(s,0); /* next data header */
273
}
274

    
275
static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream,
276
                                int length, int key_frame)
277
{
278
    int timestamp;
279
    ByteIOContext *s = ctx->pb;
280

    
281
    stream->nb_packets++;
282
    stream->packet_total_size += length;
283
    if (length > stream->packet_max_size)
284
        stream->packet_max_size =  length;
285

    
286
    put_be16(s,0); /* version */
287
    put_be16(s,length + 12);
288
    put_be16(s, stream->num); /* stream number */
289
    timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate;
290
    put_be32(s, timestamp); /* timestamp */
291
    put_byte(s, 0); /* reserved */
292
    put_byte(s, key_frame ? 2 : 0); /* flags */
293
}
294

    
295
static int rm_write_header(AVFormatContext *s)
296
{
297
    RMMuxContext *rm = s->priv_data;
298
    StreamInfo *stream;
299
    int n;
300
    AVCodecContext *codec;
301

    
302
    for(n=0;n<s->nb_streams;n++) {
303
        s->streams[n]->id = n;
304
        codec = s->streams[n]->codec;
305
        stream = &rm->streams[n];
306
        memset(stream, 0, sizeof(StreamInfo));
307
        stream->num = n;
308
        stream->bit_rate = codec->bit_rate;
309
        stream->enc = codec;
310

    
311
        switch(codec->codec_type) {
312
        case AVMEDIA_TYPE_AUDIO:
313
            rm->audio_stream = stream;
314
            stream->frame_rate = (float)codec->sample_rate / (float)codec->frame_size;
315
            /* XXX: dummy values */
316
            stream->packet_max_size = 1024;
317
            stream->nb_packets = 0;
318
            stream->total_frames = stream->nb_packets;
319
            break;
320
        case AVMEDIA_TYPE_VIDEO:
321
            rm->video_stream = stream;
322
            stream->frame_rate = (float)codec->time_base.den / (float)codec->time_base.num;
323
            /* XXX: dummy values */
324
            stream->packet_max_size = 4096;
325
            stream->nb_packets = 0;
326
            stream->total_frames = stream->nb_packets;
327
            break;
328
        default:
329
            return -1;
330
        }
331
    }
332

    
333
    rv10_write_header(s, 0, 0);
334
    put_flush_packet(s->pb);
335
    return 0;
336
}
337

    
338
static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags)
339
{
340
    uint8_t *buf1;
341
    RMMuxContext *rm = s->priv_data;
342
    ByteIOContext *pb = s->pb;
343
    StreamInfo *stream = rm->audio_stream;
344
    int i;
345

    
346
    /* XXX: suppress this malloc */
347
    buf1= (uint8_t*) av_malloc( size * sizeof(uint8_t) );
348

    
349
    write_packet_header(s, stream, size, !!(flags & PKT_FLAG_KEY));
350

    
351
    /* for AC-3, the words seem to be reversed */
352
    for(i=0;i<size;i+=2) {
353
        buf1[i] = buf[i+1];
354
        buf1[i+1] = buf[i];
355
    }
356
    put_buffer(pb, buf1, size);
357
    put_flush_packet(pb);
358
    stream->nb_frames++;
359
    av_free(buf1);
360
    return 0;
361
}
362

    
363
static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags)
364
{
365
    RMMuxContext *rm = s->priv_data;
366
    ByteIOContext *pb = s->pb;
367
    StreamInfo *stream = rm->video_stream;
368
    int key_frame = !!(flags & PKT_FLAG_KEY);
369

    
370
    /* XXX: this is incorrect: should be a parameter */
371

    
372
    /* Well, I spent some time finding the meaning of these bits. I am
373
       not sure I understood everything, but it works !! */
374
#if 1
375
    write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame);
376
    /* bit 7: '1' if final packet of a frame converted in several packets */
377
    put_byte(pb, 0x81);
378
    /* bit 7: '1' if I frame. bits 6..0 : sequence number in current
379
       frame starting from 1 */
380
    if (key_frame) {
381
        put_byte(pb, 0x81);
382
    } else {
383
        put_byte(pb, 0x01);
384
    }
385
    if(size >= 0x4000){
386
        put_be32(pb, size); /* total frame size */
387
        put_be32(pb, size); /* offset from the start or the end */
388
    }else{
389
        put_be16(pb, 0x4000 | size); /* total frame size */
390
        put_be16(pb, 0x4000 | size); /* offset from the start or the end */
391
    }
392
#else
393
    /* full frame */
394
    write_packet_header(s, size + 6);
395
    put_byte(pb, 0xc0);
396
    put_be16(pb, 0x4000 + size); /* total frame size */
397
    put_be16(pb, 0x4000 + packet_number * 126); /* position in stream */
398
#endif
399
    put_byte(pb, stream->nb_frames & 0xff);
400

    
401
    put_buffer(pb, buf, size);
402
    put_flush_packet(pb);
403

    
404
    stream->nb_frames++;
405
    return 0;
406
}
407

    
408
static int rm_write_packet(AVFormatContext *s, AVPacket *pkt)
409
{
410
    if (s->streams[pkt->stream_index]->codec->codec_type ==
411
        AVMEDIA_TYPE_AUDIO)
412
        return rm_write_audio(s, pkt->data, pkt->size, pkt->flags);
413
    else
414
        return rm_write_video(s, pkt->data, pkt->size, pkt->flags);
415
}
416

    
417
static int rm_write_trailer(AVFormatContext *s)
418
{
419
    RMMuxContext *rm = s->priv_data;
420
    int data_size, index_pos, i;
421
    ByteIOContext *pb = s->pb;
422

    
423
    if (!url_is_streamed(s->pb)) {
424
        /* end of file: finish to write header */
425
        index_pos = url_fseek(pb, 0, SEEK_CUR);
426
        data_size = index_pos - rm->data_pos;
427

    
428
        /* FIXME: write index */
429

    
430
        /* undocumented end header */
431
        put_be32(pb, 0);
432
        put_be32(pb, 0);
433

    
434
        url_fseek(pb, 0, SEEK_SET);
435
        for(i=0;i<s->nb_streams;i++)
436
            rm->streams[i].total_frames = rm->streams[i].nb_frames;
437
        rv10_write_header(s, data_size, 0);
438
    } else {
439
        /* undocumented end header */
440
        put_be32(pb, 0);
441
        put_be32(pb, 0);
442
    }
443
    put_flush_packet(pb);
444
    return 0;
445
}
446

    
447

    
448
AVOutputFormat rm_muxer = {
449
    "rm",
450
    NULL_IF_CONFIG_SMALL("RealMedia format"),
451
    "application/vnd.rn-realmedia",
452
    "rm,ra",
453
    sizeof(RMMuxContext),
454
    CODEC_ID_AC3,
455
    CODEC_ID_RV10,
456
    rm_write_header,
457
    rm_write_packet,
458
    rm_write_trailer,
459
};