Statistics
| Branch: | Revision:

ffmpeg / libavformat / rmenc.c @ da9e6c42

History | View | Annotate | Download (15.1 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 int 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
            if (stream->enc->codec_tag) {
229
                put_byte(s, 4); /* tag length */
230
                put_le32(s, stream->enc->codec_tag);
231
            } else {
232
                av_log(ctx, AV_LOG_ERROR, "Invalid codec tag\n");
233
                return -1;
234
            }
235
            put_be16(s, 0); /* title length */
236
            put_be16(s, 0); /* author length */
237
            put_be16(s, 0); /* copyright length */
238
            put_byte(s, 0); /* end of header */
239
        } else {
240
            /* video codec info */
241
            put_be32(s,34); /* size */
242
            if(stream->enc->codec_id == CODEC_ID_RV10)
243
                put_tag(s,"VIDORV10");
244
            else
245
                put_tag(s,"VIDORV20");
246
            put_be16(s, stream->enc->width);
247
            put_be16(s, stream->enc->height);
248
            put_be16(s, (int) stream->frame_rate); /* frames per seconds ? */
249
            put_be32(s,0);     /* unknown meaning */
250
            put_be16(s, (int) stream->frame_rate);  /* unknown meaning */
251
            put_be32(s,0);     /* unknown meaning */
252
            put_be16(s, 8);    /* unknown meaning */
253
            /* Seems to be the codec version: only use basic H263. The next
254
               versions seems to add a diffential DC coding as in
255
               MPEG... nothing new under the sun */
256
            if(stream->enc->codec_id == CODEC_ID_RV10)
257
                put_be32(s,0x10000000);
258
            else
259
                put_be32(s,0x20103001);
260
            //put_be32(s,0x10003000);
261
        }
262
    }
263

    
264
    /* patch data offset field */
265
    data_pos = s->buf_ptr - start_ptr;
266
    rm->data_pos = data_pos;
267
    data_offset_ptr[0] = data_pos >> 24;
268
    data_offset_ptr[1] = data_pos >> 16;
269
    data_offset_ptr[2] = data_pos >> 8;
270
    data_offset_ptr[3] = data_pos;
271

    
272
    /* data stream */
273
    put_tag(s,"DATA");
274
    put_be32(s,data_size + 10 + 8);
275
    put_be16(s,0);
276

    
277
    put_be32(s, nb_packets); /* number of packets */
278
    put_be32(s,0); /* next data header */
279
    return 0;
280
}
281

    
282
static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream,
283
                                int length, int key_frame)
284
{
285
    int timestamp;
286
    ByteIOContext *s = ctx->pb;
287

    
288
    stream->nb_packets++;
289
    stream->packet_total_size += length;
290
    if (length > stream->packet_max_size)
291
        stream->packet_max_size =  length;
292

    
293
    put_be16(s,0); /* version */
294
    put_be16(s,length + 12);
295
    put_be16(s, stream->num); /* stream number */
296
    timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate;
297
    put_be32(s, timestamp); /* timestamp */
298
    put_byte(s, 0); /* reserved */
299
    put_byte(s, key_frame ? 2 : 0); /* flags */
300
}
301

    
302
static int rm_write_header(AVFormatContext *s)
303
{
304
    RMMuxContext *rm = s->priv_data;
305
    StreamInfo *stream;
306
    int n;
307
    AVCodecContext *codec;
308

    
309
    for(n=0;n<s->nb_streams;n++) {
310
        s->streams[n]->id = n;
311
        codec = s->streams[n]->codec;
312
        stream = &rm->streams[n];
313
        memset(stream, 0, sizeof(StreamInfo));
314
        stream->num = n;
315
        stream->bit_rate = codec->bit_rate;
316
        stream->enc = codec;
317

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

    
340
    if (rv10_write_header(s, 0, 0))
341
        return AVERROR_INVALIDDATA;
342
    put_flush_packet(s->pb);
343
    return 0;
344
}
345

    
346
static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags)
347
{
348
    uint8_t *buf1;
349
    RMMuxContext *rm = s->priv_data;
350
    ByteIOContext *pb = s->pb;
351
    StreamInfo *stream = rm->audio_stream;
352
    int i;
353

    
354
    /* XXX: suppress this malloc */
355
    buf1= (uint8_t*) av_malloc( size * sizeof(uint8_t) );
356

    
357
    write_packet_header(s, stream, size, !!(flags & AV_PKT_FLAG_KEY));
358

    
359
    if (stream->enc->codec_id == CODEC_ID_AC3) {
360
        /* for AC-3, the words seem to be reversed */
361
        for(i=0;i<size;i+=2) {
362
            buf1[i] = buf[i+1];
363
            buf1[i+1] = buf[i];
364
        }
365
        put_buffer(pb, buf1, size);
366
    } else {
367
        put_buffer(pb, buf, size);
368
    }
369
    put_flush_packet(pb);
370
    stream->nb_frames++;
371
    av_free(buf1);
372
    return 0;
373
}
374

    
375
static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags)
376
{
377
    RMMuxContext *rm = s->priv_data;
378
    ByteIOContext *pb = s->pb;
379
    StreamInfo *stream = rm->video_stream;
380
    int key_frame = !!(flags & AV_PKT_FLAG_KEY);
381

    
382
    /* XXX: this is incorrect: should be a parameter */
383

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

    
413
    put_buffer(pb, buf, size);
414
    put_flush_packet(pb);
415

    
416
    stream->nb_frames++;
417
    return 0;
418
}
419

    
420
static int rm_write_packet(AVFormatContext *s, AVPacket *pkt)
421
{
422
    if (s->streams[pkt->stream_index]->codec->codec_type ==
423
        AVMEDIA_TYPE_AUDIO)
424
        return rm_write_audio(s, pkt->data, pkt->size, pkt->flags);
425
    else
426
        return rm_write_video(s, pkt->data, pkt->size, pkt->flags);
427
}
428

    
429
static int rm_write_trailer(AVFormatContext *s)
430
{
431
    RMMuxContext *rm = s->priv_data;
432
    int data_size, index_pos, i;
433
    ByteIOContext *pb = s->pb;
434

    
435
    if (!url_is_streamed(s->pb)) {
436
        /* end of file: finish to write header */
437
        index_pos = url_fseek(pb, 0, SEEK_CUR);
438
        data_size = index_pos - rm->data_pos;
439

    
440
        /* FIXME: write index */
441

    
442
        /* undocumented end header */
443
        put_be32(pb, 0);
444
        put_be32(pb, 0);
445

    
446
        url_fseek(pb, 0, SEEK_SET);
447
        for(i=0;i<s->nb_streams;i++)
448
            rm->streams[i].total_frames = rm->streams[i].nb_frames;
449
        rv10_write_header(s, data_size, 0);
450
    } else {
451
        /* undocumented end header */
452
        put_be32(pb, 0);
453
        put_be32(pb, 0);
454
    }
455
    put_flush_packet(pb);
456
    return 0;
457
}
458

    
459

    
460
AVOutputFormat rm_muxer = {
461
    "rm",
462
    NULL_IF_CONFIG_SMALL("RealMedia format"),
463
    "application/vnd.rn-realmedia",
464
    "rm,ra",
465
    sizeof(RMMuxContext),
466
    CODEC_ID_AC3,
467
    CODEC_ID_RV10,
468
    rm_write_header,
469
    rm_write_packet,
470
    rm_write_trailer,
471
    .codec_tag= (const AVCodecTag* const []){ff_rm_codec_tags, 0},
472
};