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

📄 formats.c

📁 杜比AC-3编码解码器(参考程序)
💻 C
字号:
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <linux/videodev.h>
#include <linux/soundcard.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/time.h>
#include <getopt.h>
#include <string.h>

#include "mpegenc.h"

AVFormat *first_format;
/* XXX: suppress it ! */
int data_out_size;

const char *comment_string = 
"+title=Test Video +author=FFMpeg +copyright=Free +comment=Generated by FFMpeg 1.0";

void register_avformat(AVFormat *format)
{
    AVFormat **p;
    p = &first_format;
    while (*p != NULL) p = &(*p)->next;
    *p = format;
    format->next = NULL;
}

AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
{
    AVFormat *fmt, *fmt_found;
    int score_max, score;
    const char *ext, *p;
    char ext1[32], *q;

    /* find the proper file type */
    fmt_found = NULL;
    score_max = 0;
    fmt = first_format;
    while (fmt != NULL) {
        score = 0;
        if (fmt->name && short_name && !strcmp(fmt->name, short_name))
            score += 100;
        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
            score += 10;
        if (filename && fmt->extensions) {
            ext = strrchr(filename, '.');
            if (ext) {
                ext++;
                p = fmt->extensions;
                for(;;) {
                    q = ext1;
                    while (*p != '\0' && *p != ',') 
                        *q++ = *p++;
                    *q = '\0';
                    if (!strcasecmp(ext1, ext)) {
                        score += 5;
                        break;
                    }
                    if (*p == '\0') 
                        break;
                    p++;
                }
            }
        }
        if (score > score_max) {
            score_max = score;
            fmt_found = fmt;
        }
        fmt = fmt->next;
    }
    return fmt_found;
}   

/* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
   set to the next character in 'str' after the prefix */
int strstart(const char *str, const char *val, const char **ptr)
{
    const char *p, *q;
    p = str;
    q = val;
    while (*q != '\0') {
        if (*p != *q)
            return 0;
        p++;
        q++;
    }
    if (ptr)
        *ptr = p;
    return 1;
}

/* simple formats */
int raw_write_header(struct AVFormatContext *s)
{
    return 0;
}

int raw_write_audio(struct AVFormatContext *s, 
                    unsigned char *buf, int size)
{
    put_buffer(&s->pb, buf, size);
    put_flush_packet(&s->pb);
    return 0;
}

int raw_write_video(struct AVFormatContext *s, 
                    unsigned char *buf, int size)
{
    put_buffer(&s->pb, buf, size);
    put_flush_packet(&s->pb);
    return 0;
}

int raw_write_trailer(struct AVFormatContext *s)
{
    return 0;
}

AVFormat mp2_format = {
    "mp2",
    "MPEG audio layer 2",
    "audio/x-mpeg",
    "mp2,mp3",
    CODEC_ID_MP2,
    0,
    raw_write_header,
    raw_write_audio,
    NULL,
    raw_write_trailer,
};

AVFormat ac3_format = {
    "ac3",
    "raw ac3",
    "audio/x-ac3", 
    "ac3",
    CODEC_ID_AC3,
    0,
    raw_write_header,
    raw_write_audio,
    NULL,
    raw_write_trailer,
};

AVFormat h263_format = {
    "h263",
    "raw h263",
    "video/x-h263",
    "h263",
    0,
    CODEC_ID_H263,
    raw_write_header,
    NULL,
    raw_write_video,
    raw_write_trailer,
};

AVFormat mpeg1video_format = {
    "mpeg1video",
    "MPEG1 video",
    "video/mpeg",
    "mpg,mpeg",
    0,
    CODEC_ID_MPEG1VIDEO,
    raw_write_header,
    NULL,
    raw_write_video,
    raw_write_trailer,
};

/* encoder management */
AVEncoder *first_encoder;

void register_avencoder(AVEncoder *format)
{
    AVEncoder **p;
    p = &first_encoder;
    while (*p != NULL) p = &(*p)->next;
    *p = format;
    format->next = NULL;
}

int avencoder_open(AVEncodeContext *avctx, AVEncoder *codec)
{
    int ret;

    avctx->codec = codec;
    avctx->frame_number = 0;
    avctx->priv_data = malloc(codec->priv_data_size);
    if (!avctx->priv_data) 
        return -ENOMEM;
    memset(avctx->priv_data, 0, codec->priv_data_size);
    ret = avctx->codec->init(avctx);
    if (ret < 0) {
        free(avctx->priv_data);
        avctx->priv_data = NULL;
        return ret;
    }
    return 0;
}

int avencoder_encode(AVEncodeContext *avctx, UINT8 *buf, int buf_size, void *data)
{
    int ret;

    ret = avctx->codec->encode(avctx, buf, buf_size, data);
    avctx->frame_number++;
    return ret;
}

int avencoder_close(AVEncodeContext *avctx)
{
    if (avctx->codec->close)
        avctx->codec->close(avctx);
    free(avctx->priv_data);
    avctx->priv_data = NULL;
    return 0;
}

AVEncoder *avencoder_find(enum CodecID id)
{
    AVEncoder *p;
    p = first_encoder;
    while (p) {
        if (p->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}


void avencoder_string(char *buf, int buf_size, AVEncodeContext *enc)
{
    switch(enc->codec->type) {
    case CODEC_TYPE_VIDEO:
        snprintf(buf, buf_size,
                 "Video: %s%s, %dx%d, %d fps, %d kb/s",
                 enc->codec->name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : "", 
                 enc->width, enc->height, enc->rate, enc->bit_rate / 1000);
        break;
    case CODEC_TYPE_AUDIO:
        snprintf(buf, buf_size,
                 "Audio: %s, %d Hz, %s, %d kb/s",
                 enc->codec->name, enc->rate,
                 enc->channels == 2 ? "stereo" : "mono", 
                 enc->bit_rate / 1000);
        break;
    default:
        abort();
    }
}

/* PutByteFormat */

int init_put_byte(PutByteContext *s,
                  unsigned char *buffer,
                  int buffer_size,
                  void *opaque,
                  void (*write_packet)(void *opaque, UINT8 *buf, int buf_size),
                  int (*write_seek)(void *opaque, long long offset, int whence))
{
    s->buffer = buffer;
    s->buf_ptr = buffer;
    s->buf_end = buffer + buffer_size;
    s->opaque = opaque;
    s->write_packet = write_packet;
    s->write_seek = write_seek;
    s->pos = 0;
    s->must_flush = 0;
    return 0;
}
                  

static void flush_buffer(PutByteContext *s)
{
    if (s->buf_ptr > s->buffer) {
        if (s->write_packet)
            s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
        s->pos += s->buf_ptr - s->buffer;
    }
    s->buf_ptr = s->buffer;
}

void put_byte(PutByteContext *s, int b)
{
    *(s->buf_ptr)++ = b;
    if (s->buf_ptr >= s->buf_end) 
        flush_buffer(s);
}

void put_buffer(PutByteContext *s, unsigned char *buf, int size)
{
    int len;

    while (size > 0) {
        len = (s->buf_end - s->buf_ptr);
        if (len > size)
            len = size;
        memcpy(s->buf_ptr, buf, len);
        s->buf_ptr += len;

        if (s->buf_ptr >= s->buf_end) 
            flush_buffer(s);

        buf += len;
        size -= len;
    }
}

void put_flush_packet(PutByteContext *s)
{
    flush_buffer(s);
    s->must_flush = 0;
}

long long put_seek(PutByteContext *s, long long offset, int whence)
{
    long long offset1;

    if (whence != SEEK_CUR && whence != SEEK_SET)
        return -1;
    if (whence == SEEK_CUR) {
        offset1 = s->pos + s->buf_ptr - s->buffer;
        if (offset == 0)
            return offset1;
        offset += offset1;
    }
    offset1 = offset - s->pos;
    if (!s->must_flush && 
        offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
        /* can do the seek inside the buffer */
        s->buf_ptr = s->buffer + offset1;
    } else {
        if (!s->write_seek)
            return -1;
        flush_buffer(s);
        s->write_seek(s->opaque, offset, SEEK_SET);
        s->pos = offset;
        s->must_flush = 1;
    }
    return offset;
}

long long put_pos(PutByteContext *s)
{
    return put_seek(s, 0, SEEK_CUR);
}

void put_le32(PutByteContext *s, unsigned int val)
{
    put_byte(s, val);
    put_byte(s, val >> 8);
    put_byte(s, val >> 16);
    put_byte(s, val >> 24);
}

void put_le64(PutByteContext *s, unsigned long long val)
{
    put_le32(s, val & 0xffffffff);
    put_le32(s, val >> 32);
}

void put_le16(PutByteContext *s, unsigned int val)
{
    put_byte(s, val);
    put_byte(s, val >> 8);
}

void put_tag(PutByteContext *s, char *tag)
{
    while (*tag) {
        put_byte(s, *tag++);
    }
}

⌨️ 快捷键说明

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