⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmenc.c

📁 杜比AC-3编码解码器(参考程序)
💻 C
📖 第 1 页 / 共 2 页
字号:
            if (coded_frame_size == 557)
                coded_frame_size--;
            put_long(s, coded_frame_size); /* frame length */
            put_long(s, 0x51540); /* unknown */
            put_long(s, 0x249f0); /* unknown */
            put_long(s, 0x249f0); /* unknown */
            put_short(s, 0x01);
            /* frame length : seems to be very important */
            put_short(s, coded_frame_size); 
            put_long(s, 0); /* unknown */
            put_short(s, stream->enc->rate); /* sample rate */
            put_long(s, 0x10); /* unknown */
            put_short(s, stream->enc->channels);
            put_str8(s, "Int0"); /* codec name */
            put_str8(s, "dnet"); /* codec name */
            put_short(s, 0); /* title length */
            put_short(s, 0); /* author length */
            put_short(s, 0); /* copyright length */
            put_byte(s, 0); /* end of header */
        } else {
            /* video codec info */
            put_long(s,34); /* size */
            put_tag(s,"VIDORV10");
            put_short(s, stream->enc->width);
            put_short(s, stream->enc->height);
            put_short(s, 24); /* frames per seconds ? */
            put_long(s,0);     /* unknown meaning */
            put_short(s, 12);  /* unknown meaning */
            put_long(s,0);     /* unknown meaning */
            put_short(s, 8);    /* unknown meaning */
            /* Seems to be the codec version: only use basic H263. The next
               versions seems to add a diffential DC coding as in
               MPEG... nothing new under the sun */
            put_long(s,0x10000000); 
            //put_long(s,0x10003000); 
        }
    }

    /* patch data offset field */
    data_pos = s->buf_ptr - start_ptr;
    rm->data_pos = data_pos;
    data_offset_ptr[0] = data_pos >> 24;
    data_offset_ptr[1] = data_pos >> 16;
    data_offset_ptr[2] = data_pos >> 8;
    data_offset_ptr[3] = data_pos;
    
    /* data stream */
    put_tag(s,"DATA");
    put_long(s,data_size + 10 + 8);
    put_short(s,0);

    put_long(s, nb_packets); /* number of packets */
    put_long(s,0); /* next data header */
}

static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream, 
                                int length, int key_frame)
{
    int timestamp;
    PutByteContext *s = &ctx->pb;

    stream->nb_packets++;
    stream->packet_total_size += length;
    if (length > stream->packet_max_size)
        stream->packet_max_size =  length;

    put_short(s,0); /* version */
    put_short(s,length + 12);
    put_short(s, stream->num); /* stream number */
    timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate;
    put_long(s, timestamp); /* timestamp */
    put_byte(s, 0); /* reserved */
    put_byte(s, key_frame ? 2 : 0); /* flags */
}

static int rm_write_header(AVFormatContext *s)
{
    StreamInfo *stream;
    RMContext *rm;
    int n;

    rm = malloc(sizeof(RMContext));
    if (!rm)
        return -1;
    memset(rm, 0, sizeof(RMContext));
    s->priv_data = rm;
    n = 0;
    if (s->audio_enc) {
        stream = &rm->streams[n];
        memset(stream, 0, sizeof(StreamInfo));
        stream->num = n;
        rm->audio_stream = stream;
        stream->bit_rate = s->audio_enc->bit_rate;
        stream->frame_rate = (float)s->audio_enc->rate / (float)s->audio_enc->frame_size;
        stream->enc = s->audio_enc;
        /* XXX: dummy values */
        stream->packet_max_size = 1024;
        stream->nb_packets = 1000;
        stream->total_frames = stream->nb_packets;
        n++;
    }
    if (s->video_enc) {
        stream = &rm->streams[n];
        memset(stream, 0, sizeof(StreamInfo));
        stream->num = n;
        rm->video_stream = stream;
        stream->bit_rate = s->video_enc->bit_rate;
        stream->frame_rate = s->video_enc->rate;
        stream->enc = s->video_enc;
        /* XXX: dummy values */
        stream->packet_max_size = 4096;
        stream->nb_packets = 1000;
        stream->total_frames = stream->nb_packets;
        n++;
    }
    rm->nb_streams = n;

    rv10_write_header(s, 0, 0);
    put_flush_packet(&s->pb);
    return 0;
}

static int rm_write_audio(AVFormatContext *s, UINT8 *buf, int size)
{
    UINT8 buf1[size];
    RMContext *rm = s->priv_data;
    PutByteContext *pb = &s->pb;
    StreamInfo *stream = rm->audio_stream;
    int i;

    write_packet_header(s, stream, size, stream->enc->key_frame);
    
    /* for AC3, the words seems to be reversed */
    for(i=0;i<size;i+=2) {
        buf1[i] = buf[i+1];
        buf1[i+1] = buf[i];
    }
    put_buffer(pb, buf1, size);
    put_flush_packet(pb);
    stream->nb_frames++;
    return 0;
}

static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size)
{
    RMContext *rm = s->priv_data;
    PutByteContext *pb = &s->pb;
    StreamInfo *stream = rm->video_stream;
    int key_frame = stream->enc->key_frame;
    
    /* XXX: this is incorrect: should be a parameter */

    /* 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);
    /* 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
       frame starting from 1 */
    if (key_frame) {
        put_byte(pb, 0x81); 
    } else {
        put_byte(pb, 0x01); 
    }
    put_short(pb, 0x4000 | (size)); /* total frame size */
    put_short(pb, 0x4000 | (size));              /* offset from the start or the end */
#else
    /* seems to be used for prefetch/error correction. Help me ! */
    write_packet_header(s, size + 6);
    put_byte(pb, 0xc0); 
    put_short(pb, 0x4000 | size); /* total frame size */
    put_short(pb, 0x4000 + packet_number * 126);
#endif
    put_byte(pb, stream->nb_frames & 0xff); 
    
    put_buffer(pb, buf, size);
    put_flush_packet(pb);

    stream->nb_frames++;
    return 0;
}

static int rm_write_trailer(AVFormatContext *s)
{
    RMContext *rm = s->priv_data;
    int data_size, index_pos, i;
    PutByteContext *pb = &s->pb;

    if (!s->is_streamed) {
        /* end of file: finish to write header */
        index_pos = put_seek(pb, 0, SEEK_CUR);
        data_size = index_pos - rm->data_pos;

        /* index */
        put_tag(pb, "INDX");
        put_long(pb, 10 + 10 * rm->nb_streams);
        put_short(pb, 0);
        
        for(i=0;i<rm->nb_streams;i++) {
            put_long(pb, 0); /* zero indices */
            put_short(pb, i); /* stream number */
            put_long(pb, 0); /* next index */
        }
        /* undocumented end header */
        put_long(pb, 0);
        put_long(pb, 0);
        
        put_seek(pb, 0, SEEK_SET);
        for(i=0;i<rm->nb_streams;i++)
            rm->streams[i].total_frames = rm->streams[i].nb_frames;
        rv10_write_header(s, data_size, index_pos);
    } else {
        /* undocumented end header */
        put_long(pb, 0);
        put_long(pb, 0);
    }
    put_flush_packet(pb);

    free(rm);
    return 0;
}

AVFormat rm_format = {
    "rm",
    "rm format",
    "audio/x-pn-realaudio",
    "rm,ra",
    CODEC_ID_AC3,
    CODEC_ID_RV10,
    rm_write_header,
    rm_write_audio,
    rm_write_video,
    rm_write_trailer,
};

AVFormat ra_format = {
    "ra",
    "ra format",
    "audio/x-pn-realaudio",
    "ra",
    CODEC_ID_AC3,
    CODEC_ID_NONE,
    rm_write_header,
    rm_write_audio,
    NULL,
    rm_write_trailer,
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -