]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavformat/rmenc.c
O_DIRECT works!!!
[frescor/ffmpeg.git] / libavformat / rmenc.c
index 57a4e757def087476b1283dfb10d01ec7dc276ed..21748d5d5253f5c15618e66fc95028eef28816f2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * "Real" compatible muxer.
- * Copyright (c) 2000, 2001 Fabrice Bellard.
+ * Copyright (c) 2000, 2001 Fabrice Bellard
  *
  * This file is part of FFmpeg.
  *
 #include "avformat.h"
 #include "rm.h"
 
+typedef struct {
+    int nb_packets;
+    int packet_total_size;
+    int packet_max_size;
+    /* codec related output */
+    int bit_rate;
+    float frame_rate;
+    int nb_frames;    /* current frame number */
+    int total_frames; /* total number of frames */
+    int num;
+    AVCodecContext *enc;
+} StreamInfo;
+
+typedef struct {
+    StreamInfo streams[2];
+    StreamInfo *audio_stream, *video_stream;
+    int data_pos; /* position of the data after the header */
+} RMMuxContext;
+
 /* in ms */
 #define BUFFER_DURATION 0
 
@@ -44,13 +63,14 @@ static void put_str8(ByteIOContext *s, const char *tag)
 static void rv10_write_header(AVFormatContext *ctx,
                               int data_size, int index_pos)
 {
-    RMContext *rm = ctx->priv_data;
+    RMMuxContext *rm = ctx->priv_data;
     ByteIOContext *s = ctx->pb;
     StreamInfo *stream;
     unsigned char *data_offset_ptr, *start_ptr;
     const char *desc, *mimetype;
     int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i;
     int bit_rate, v, duration, flags, data_pos;
+    AVMetadataTag *tag;
 
     start_ptr = s->buf_ptr;
 
@@ -104,14 +124,17 @@ static void rv10_write_header(AVFormatContext *ctx,
     /* comments */
 
     put_tag(s,"CONT");
-    size = strlen(ctx->title) + strlen(ctx->author) + strlen(ctx->copyright) +
-        strlen(ctx->comment) + 4 * 2 + 10;
+    size =  4 * 2 + 10;
+    for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
+        tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
+        if(tag) size += strlen(tag->value);
+    }
     put_be32(s,size);
     put_be16(s,0);
-    put_str(s, ctx->title);
-    put_str(s, ctx->author);
-    put_str(s, ctx->copyright);
-    put_str(s, ctx->comment);
+    for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
+        tag = av_metadata_get(ctx->metadata, ff_rm_metadata[i], NULL, 0);
+        put_str(s, tag ? tag->value : "");
+    }
 
     for(i=0;i<ctx->nb_streams;i++) {
         int codec_data_size;
@@ -185,7 +208,7 @@ static void rv10_write_header(AVFormatContext *ctx,
             case 8000:
                 fscode = 3;
             }
-            put_be16(s, fscode); /* codec additional info, for AC3, seems
+            put_be16(s, fscode); /* codec additional info, for AC-3, seems
                                      to be a frequency code */
             /* special hack to compensate rounding errors... */
             if (coded_frame_size == 557)
@@ -271,7 +294,7 @@ static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream,
 
 static int rm_write_header(AVFormatContext *s)
 {
-    RMContext *rm = s->priv_data;
+    RMMuxContext *rm = s->priv_data;
     StreamInfo *stream;
     int n;
     AVCodecContext *codec;
@@ -315,7 +338,7 @@ static int rm_write_header(AVFormatContext *s)
 static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags)
 {
     uint8_t *buf1;
-    RMContext *rm = s->priv_data;
+    RMMuxContext *rm = s->priv_data;
     ByteIOContext *pb = s->pb;
     StreamInfo *stream = rm->audio_stream;
     int i;
@@ -325,7 +348,7 @@ static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int
 
     write_packet_header(s, stream, size, !!(flags & PKT_FLAG_KEY));
 
-    /* for AC3, the words seems to be reversed */
+    /* for AC-3, the words seem to be reversed */
     for(i=0;i<size;i+=2) {
         buf1[i] = buf[i+1];
         buf1[i+1] = buf[i];
@@ -339,7 +362,7 @@ static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int
 
 static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags)
 {
-    RMContext *rm = s->priv_data;
+    RMMuxContext *rm = s->priv_data;
     ByteIOContext *pb = s->pb;
     StreamInfo *stream = rm->video_stream;
     int key_frame = !!(flags & PKT_FLAG_KEY);
@@ -349,7 +372,7 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int
     /* Well, I spent some time finding the meaning of these bits. I am
        not sure I understood everything, but it works !! */
 #if 1
-    write_packet_header(s, stream, size + 7, key_frame);
+    write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame);
     /* bit 7: '1' if final packet of a frame converted in several packets */
     put_byte(pb, 0x81);
     /* bit 7: '1' if I frame. bits 6..0 : sequence number in current
@@ -359,8 +382,13 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int
     } else {
         put_byte(pb, 0x01);
     }
-    put_be16(pb, 0x4000 + (size)); /* total frame size */
-    put_be16(pb, 0x4000 + (size));              /* offset from the start or the end */
+    if(size >= 0x4000){
+        put_be32(pb, size); /* total frame size */
+        put_be32(pb, size); /* offset from the start or the end */
+    }else{
+        put_be16(pb, 0x4000 | size); /* total frame size */
+        put_be16(pb, 0x4000 | size); /* offset from the start or the end */
+    }
 #else
     /* full frame */
     write_packet_header(s, size + 6);
@@ -388,7 +416,7 @@ static int rm_write_packet(AVFormatContext *s, AVPacket *pkt)
 
 static int rm_write_trailer(AVFormatContext *s)
 {
-    RMContext *rm = s->priv_data;
+    RMMuxContext *rm = s->priv_data;
     int data_size, index_pos, i;
     ByteIOContext *pb = s->pb;
 
@@ -397,16 +425,8 @@ static int rm_write_trailer(AVFormatContext *s)
         index_pos = url_fseek(pb, 0, SEEK_CUR);
         data_size = index_pos - rm->data_pos;
 
-        /* index */
-        put_tag(pb, "INDX");
-        put_be32(pb, 10 + 10 * s->nb_streams);
-        put_be16(pb, 0);
+        /* FIXME: write index */
 
-        for(i=0;i<s->nb_streams;i++) {
-            put_be32(pb, 0); /* zero indices */
-            put_be16(pb, i); /* stream number */
-            put_be32(pb, 0); /* next index */
-        }
         /* undocumented end header */
         put_be32(pb, 0);
         put_be32(pb, 0);
@@ -414,7 +434,7 @@ static int rm_write_trailer(AVFormatContext *s)
         url_fseek(pb, 0, SEEK_SET);
         for(i=0;i<s->nb_streams;i++)
             rm->streams[i].total_frames = rm->streams[i].nb_frames;
-        rv10_write_header(s, data_size, index_pos);
+        rv10_write_header(s, data_size, 0);
     } else {
         /* undocumented end header */
         put_be32(pb, 0);
@@ -427,10 +447,10 @@ static int rm_write_trailer(AVFormatContext *s)
 
 AVOutputFormat rm_muxer = {
     "rm",
-    "rm format",
+    NULL_IF_CONFIG_SMALL("RealMedia format"),
     "application/vnd.rn-realmedia",
     "rm,ra",
-    sizeof(RMContext),
+    sizeof(RMMuxContext),
     CODEC_ID_AC3,
     CODEC_ID_RV10,
     rm_write_header,