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

📄 gxfenc.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * GXF muxer. * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>. * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avformat.h"#include "gxf.h"#include "riff.h"#include "fifo.h"#define GXF_AUDIO_PACKET_SIZE 65536typedef struct GXFStreamContext {    AVCodecContext *codec;    AVFifoBuffer audio_buffer;    uint32_t track_type;    uint32_t sample_size;    uint32_t sample_rate;    uint16_t media_type;    uint16_t media_info;    uint8_t index;    int frame_rate_index;    int lines_index;    int fields;    int iframes;    int pframes;    int bframes;    int p_per_gop;    int b_per_gop;    int first_gop_closed;    int64_t current_dts;    int dts_delay;} GXFStreamContext;typedef struct GXFContext {    uint32_t nb_frames;    uint32_t material_flags;    uint16_t audio_tracks;    uint16_t mpeg_tracks;    int64_t creation_time;    uint32_t umf_start_offset;    uint32_t umf_track_offset;    uint32_t umf_media_offset;    uint32_t umf_user_data_offset;    uint32_t umf_user_data_size;    uint32_t umf_length;    uint16_t umf_track_size;    uint16_t umf_media_size;    int audio_written;    int sample_rate;    int flags;    AVFormatContext *fc;    GXFStreamContext streams[48];} GXFContext;typedef struct GXF_Lines {    int height;    int index;} GXF_Lines;/* FIXME check if it is relevant */static const GXF_Lines gxf_lines_tab[] = {    { 480,  1 }, /* NTSC */    { 512,  1 }, /* NTSC + VBI */    { 576,  2 }, /* PAL */    { 608,  2 }, /* PAL + VBI */    { 1080, 4 },    { 720,  6 },};static const AVCodecTag gxf_media_types[] = {    { CODEC_ID_MJPEG     ,   3 }, /* NTSC */    { CODEC_ID_MJPEG     ,   4 }, /* PAL */    { CODEC_ID_PCM_S24LE ,   9 },    { CODEC_ID_PCM_S16LE ,  10 },    { CODEC_ID_MPEG2VIDEO,  11 }, /* NTSC */    { CODEC_ID_MPEG2VIDEO,  12 }, /* PAL */    { CODEC_ID_DVVIDEO   ,  13 }, /* NTSC */    { CODEC_ID_DVVIDEO   ,  14 }, /* PAL */    { CODEC_ID_DVVIDEO   ,  15 }, /* 50M NTSC */    { CODEC_ID_DVVIDEO   ,  16 }, /* 50M PAL */    { CODEC_ID_AC3       ,  17 },    //{ CODEC_ID_NONE,  ,   18 }, /* Non compressed 24 bit audio */    { CODEC_ID_MPEG2VIDEO,  20 }, /* MPEG HD */    { CODEC_ID_MPEG1VIDEO,  22 }, /* NTSC */    { CODEC_ID_MPEG1VIDEO,  23 }, /* PAL */    { 0, 0 },};#define SERVER_PATH "/space/"#define ES_NAME_PATTERN "ES."static int gxf_find_lines_index(GXFStreamContext *ctx){    int i;    for (i = 0; i < 6; ++i) {        if (ctx->codec->height == gxf_lines_tab[i].height) {            ctx->lines_index = gxf_lines_tab[i].index;            return 0;        }    }    return -1;}static void gxf_write_padding(ByteIOContext *pb, offset_t to_pad){    for (; to_pad > 0; to_pad--) {        put_byte(pb, 0);    }}static offset_t updatePacketSize(ByteIOContext *pb, offset_t pos){    offset_t curpos;    int size;    size = url_ftell(pb) - pos;    if (size % 4) {        gxf_write_padding(pb, 4 - size % 4);        size = url_ftell(pb) - pos;    }    curpos = url_ftell(pb);    url_fseek(pb, pos + 6, SEEK_SET);    put_be32(pb, size);    url_fseek(pb, curpos, SEEK_SET);    return curpos - pos;}static offset_t updateSize(ByteIOContext *pb, offset_t pos){    offset_t curpos;    curpos = url_ftell(pb);    url_fseek(pb, pos, SEEK_SET);    put_be16(pb, curpos - pos - 2);    url_fseek(pb, curpos, SEEK_SET);    return curpos - pos;}static void gxf_write_packet_header(ByteIOContext *pb, pkt_type_t type){    put_be32(pb, 0); /* packet leader for synchro */    put_byte(pb, 1);    put_byte(pb, type); /* map packet */    put_be32(pb, 0); /* size */    put_be32(pb, 0); /* reserved */    put_byte(pb, 0xE1); /* trailer 1 */    put_byte(pb, 0xE2); /* trailer 2 */}static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx){    char buffer[1024];    int size;    if (ctx->iframes) {        ctx->p_per_gop = ctx->pframes / ctx->iframes;        if (ctx->pframes % ctx->iframes)            ctx->p_per_gop++;        if (ctx->pframes)            ctx->b_per_gop = ctx->bframes / ctx->pframes;        if (ctx->p_per_gop > 9)            ctx->p_per_gop = 9; /* ensure value won't take more than one char */        if (ctx->b_per_gop > 9)            ctx->b_per_gop = 9; /* ensure value won't take more than one char */    }    size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"                    "Pix 0\nCf %d\nCg %d\nSl 7\nnl16 %d\nVi 1\nf1 1\n",                    (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_gop,                    ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1,                    ctx->codec->height / 16);    put_byte(pb, TRACK_MPG_AUX);    put_byte(pb, size + 1);    put_buffer(pb, (uint8_t *)buffer, size + 1);    return size + 3;}static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx){    /* FIXME implement that */    put_byte(pb, 0); /* fields */    put_byte(pb, 0);  /* seconds */    put_byte(pb, 0); /* minutes */    put_byte(pb, 0); /* flags + hours */    /* reserved */    put_be32(pb, 0);    return 8;}static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream){    offset_t pos;    /* track description section */    put_byte(pb, stream->media_type + 0x80);    put_byte(pb, stream->index + 0xC0);    pos = url_ftell(pb);    put_be16(pb, 0); /* size */    /* media file name */    put_byte(pb, TRACK_NAME);    put_byte(pb, strlen(ES_NAME_PATTERN) + 3);    put_tag(pb, ES_NAME_PATTERN);    put_be16(pb, stream->media_info);    put_byte(pb, 0);    if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) {        /* auxiliary information */        put_byte(pb, TRACK_AUX);        put_byte(pb, 8);        if (stream->codec->codec_id == CODEC_ID_NONE)            gxf_write_timecode_auxiliary(pb, stream);        else            put_le64(pb, 0);    }    /* file system version */    put_byte(pb, TRACK_VER);    put_byte(pb, 4);    put_be32(pb, 0);    if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)        gxf_write_mpeg_auxiliary(pb, stream);    /* frame rate */    put_byte(pb, TRACK_FPS);    put_byte(pb, 4);    put_be32(pb, stream->frame_rate_index);    /* lines per frame */    put_byte(pb, TRACK_LINES);    put_byte(pb, 4);    put_be32(pb, stream->lines_index);    /* fields per frame */    put_byte(pb, TRACK_FPF);    put_byte(pb, 4);    put_be32(pb, stream->fields);    return updateSize(pb, pos);}static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx){    offset_t pos;    const char *filename = strrchr(ctx->fc->filename, '/');    pos = url_ftell(pb);    put_be16(pb, 0); /* size */    /* name */    if (filename)        filename++;    else        filename = ctx->fc->filename;    put_byte(pb, MAT_NAME);    put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);    put_tag(pb, SERVER_PATH);    put_tag(pb, filename);    put_byte(pb, 0);    /* first field */    put_byte(pb, MAT_FIRST_FIELD);    put_byte(pb, 4);    put_be32(pb, 0);    /* last field */    put_byte(pb, MAT_LAST_FIELD);    put_byte(pb, 4);    put_be32(pb, ctx->nb_frames);    /* reserved */    put_byte(pb, MAT_MARK_IN);    put_byte(pb, 4);    put_be32(pb, 0);    put_byte(pb, MAT_MARK_OUT);    put_byte(pb, 4);    put_be32(pb, ctx->nb_frames);    /* estimated size */    put_byte(pb, MAT_SIZE);    put_byte(pb, 4);    put_be32(pb, url_fsize(pb) / 1024);    return updateSize(pb, pos);}static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx){    offset_t pos;    int i;    pos = url_ftell(pb);    put_be16(pb, 0); /* size */    for (i = 0; i < ctx->fc->nb_streams; ++i)        gxf_write_track_description(pb, &ctx->streams[i]);    return updateSize(pb, pos);}static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx){    offset_t pos = url_ftell(pb);    gxf_write_packet_header(pb, PKT_MAP);    /* preamble */    put_byte(pb, 0xE0); /* version */    put_byte(pb, 0xFF); /* reserved */    gxf_write_material_data_section(pb, ctx);    gxf_write_track_description_section(pb, ctx);    return updatePacketSize(pb, pos);}#if 0static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx){    offset_t pos = url_ftell(pb);    int i;    gxf_write_packet_header(pb, PKT_FLT);    put_le32(pb, 1000); /* number of fields */    put_le32(pb, 0); /* number of active flt entries */    for (i = 0; i < 1000; ++i) {        put_le32(pb, 0);    }    return updatePacketSize(pb, pos);}#endifstatic int gxf_write_umf_material_description(ByteIOContext *pb, GXFContext *ctx){    put_le32(pb, ctx->flags);    put_le32(pb, ctx->nb_frames); /* length of the longest track */    put_le32(pb, ctx->nb_frames); /* length of the shortest track */    put_le32(pb, 0); /* mark in */    put_le32(pb, ctx->nb_frames); /* mark out */    put_le32(pb, 0); /* timecode mark in */    put_le32(pb, ctx->nb_frames); /* timecode mark out */    put_le64(pb, ctx->fc->timestamp); /* modification time */    put_le64(pb, ctx->fc->timestamp); /* creation time */    put_le16(pb, 0); /* reserved */    put_le16(pb, 0); /* reserved */    put_le16(pb, ctx->audio_tracks);    put_le16(pb, 0); /* timecode track count */    put_le16(pb, 0); /* reserved */    put_le16(pb, ctx->mpeg_tracks);    return 48;}static int gxf_write_umf_payload(ByteIOContext *pb, GXFContext *ctx){    put_le32(pb, ctx->umf_length); /* total length of the umf data */    put_le32(pb, 3); /* version */    put_le32(pb, ctx->fc->nb_streams);    put_le32(pb, ctx->umf_track_offset); /* umf track section offset */    put_le32(pb, ctx->umf_track_size);    put_le32(pb, ctx->fc->nb_streams);    put_le32(pb, ctx->umf_media_offset);    put_le32(pb, ctx->umf_media_size);    put_le32(pb, ctx->umf_user_data_offset); /* user data offset */    put_le32(pb, ctx->umf_user_data_size); /* user data size */    put_le32(pb, 0); /* reserved */    put_le32(pb, 0); /* reserved */    return 48;}static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx){    offset_t pos = url_ftell(pb);    int tracks[255]={0};    int i;    ctx->umf_track_offset = pos - ctx->umf_start_offset;    for (i = 0; i < ctx->fc->nb_streams; ++i) {        AVStream *st = ctx->fc->streams[i];        GXFStreamContext *sc = &ctx->streams[i];        int id = 0;        switch (st->codec->codec_id) {        case CODEC_ID_MPEG1VIDEO: id= 'L'; break;        case CODEC_ID_MPEG2VIDEO: id= 'M'; break;        case CODEC_ID_PCM_S16LE:  id= 'A'; break;        case CODEC_ID_DVVIDEO:    id= sc->track_type == 6 ? 'E' : 'D'; break;        case CODEC_ID_MJPEG:      id= 'V'; break;        default:                  break;        }        sc->media_info= id << 8;        /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */        sc->media_info |= '0' + (tracks[id]++);        put_le16(pb, sc->media_info);        put_le16(pb, 1);

⌨️ 快捷键说明

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