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

📄 gxf.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * GXF demuxer. * Copyright (c) 2006 Reimar Doeffinger. * * 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 "common.h"#include "gxf.h"typedef struct {    int64_t first_field;    int64_t last_field;    AVRational frames_per_second;    int32_t fields_per_frame;} st_info_t;/** * \brief parses a packet header, extracting type and length * \param pb ByteIOContext to read header from * \param type detected packet type is stored here * \param length detected packet length, excluding header is stored here * \return 0 if header not found or contains invalid data, 1 otherwise */static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) {    if (get_be32(pb))        return 0;    if (get_byte(pb) != 1)        return 0;    *type = get_byte(pb);    *length = get_be32(pb);    if ((*length >> 24) || *length < 16)        return 0;    *length -= 16;    if (get_be32(pb))        return 0;    if (get_byte(pb) != 0xe1)        return 0;    if (get_byte(pb) != 0xe2)        return 0;    return 1;}/** * \brief check if file starts with a PKT_MAP header */static int gxf_probe(AVProbeData *p) {    static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet    static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};    if (!memcmp(p->buf, startcode, sizeof(startcode)) &&        !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))        return AVPROBE_SCORE_MAX;    return 0;}/** * \brief gets the stream index for the track with the specified id, creates new *        stream if not found * \param stream id of stream to find / add * \param format stream format identifier */static int get_sindex(AVFormatContext *s, int id, int format) {    int i;    AVStream *st = NULL;    for (i = 0; i < s->nb_streams; i++) {        if (s->streams[i]->id == id)            return i;    }    st = av_new_stream(s, id);    switch (format) {        case 3:        case 4:            st->codec->codec_type = CODEC_TYPE_VIDEO;            st->codec->codec_id = CODEC_ID_MJPEG;            break;        case 13:        case 15:            st->codec->codec_type = CODEC_TYPE_VIDEO;            st->codec->codec_id = CODEC_ID_DVVIDEO;            break;        case 14:        case 16:            st->codec->codec_type = CODEC_TYPE_VIDEO;            st->codec->codec_id = CODEC_ID_DVVIDEO;            break;        case 11:        case 12:        case 20:            st->codec->codec_type = CODEC_TYPE_VIDEO;            st->codec->codec_id = CODEC_ID_MPEG2VIDEO;            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.            break;        case 22:        case 23:            st->codec->codec_type = CODEC_TYPE_VIDEO;            st->codec->codec_id = CODEC_ID_MPEG1VIDEO;            st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc.            break;        case 9:            st->codec->codec_type = CODEC_TYPE_AUDIO;            st->codec->codec_id = CODEC_ID_PCM_S24LE;            st->codec->channels = 1;            st->codec->sample_rate = 48000;            st->codec->bit_rate = 3 * 1 * 48000 * 8;            st->codec->block_align = 3 * 1;            st->codec->bits_per_sample = 24;            break;        case 10:            st->codec->codec_type = CODEC_TYPE_AUDIO;            st->codec->codec_id = CODEC_ID_PCM_S16LE;            st->codec->channels = 1;            st->codec->sample_rate = 48000;            st->codec->bit_rate = 2 * 1 * 48000 * 8;            st->codec->block_align = 2 * 1;            st->codec->bits_per_sample = 16;            break;        case 17:            st->codec->codec_type = CODEC_TYPE_AUDIO;            st->codec->codec_id = CODEC_ID_AC3;            st->codec->channels = 2;            st->codec->sample_rate = 48000;            break;        // timecode tracks:        case 7:        case 8:        case 24:            st->codec->codec_type = CODEC_TYPE_DATA;            st->codec->codec_id = CODEC_ID_NONE;            break;        default:            st->codec->codec_type = CODEC_TYPE_UNKNOWN;            st->codec->codec_id = CODEC_ID_NONE;            break;    }    return s->nb_streams - 1;}/** * \brief filters out interesting tags from material information. * \param len length of tag section, will be adjusted to contain remaining bytes * \param si struct to store collected information into */static void gxf_material_tags(ByteIOContext *pb, int *len, st_info_t *si) {    si->first_field = AV_NOPTS_VALUE;    si->last_field = AV_NOPTS_VALUE;    while (*len >= 2) {        mat_tag_t tag = get_byte(pb);        int tlen = get_byte(pb);        *len -= 2;        if (tlen > *len)            return;        *len -= tlen;        if (tlen == 4) {            uint32_t value = get_be32(pb);            if (tag == MAT_FIRST_FIELD)                si->first_field = value;            else if (tag == MAT_LAST_FIELD)                si->last_field = value;        } else            url_fskip(pb, tlen);    }}/** * \brief convert fps tag value to AVRational fps * \param fps fps value from tag * \return fps as AVRational, or 0 / 0 if unknown */static AVRational fps_tag2avr(int32_t fps) {    extern const AVRational ff_frame_rate_tab[];    if (fps < 1 || fps > 9) fps = 9;    return ff_frame_rate_tab[9 - fps]; // values have opposite order}/** * \brief convert UMF attributes flags to AVRational fps * \param fps fps value from flags * \return fps as AVRational, or 0 / 0 if unknown */static AVRational fps_umf2avr(uint32_t flags) {    static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1},        {25, 1}, {30000, 1001}};    int idx =  av_log2((flags & 0x7c0) >> 6);    return map[idx];}/** * \brief filters out interesting tags from track information. * \param len length of tag section, will be adjusted to contain remaining bytes * \param si struct to store collected information into */static void gxf_track_tags(ByteIOContext *pb, int *len, st_info_t *si) {    si->frames_per_second = (AVRational){0, 0};    si->fields_per_frame = 0;    while (*len >= 2) {        track_tag_t tag = get_byte(pb);        int tlen = get_byte(pb);        *len -= 2;        if (tlen > *len)            return;        *len -= tlen;        if (tlen == 4) {            uint32_t value = get_be32(pb);            if (tag == TRACK_FPS)                si->frames_per_second = fps_tag2avr(value);            else if (tag == TRACK_FPF && (value == 1 || value == 2))                si->fields_per_frame = value;        } else            url_fskip(pb, tlen);    }}/** * \brief read index from FLT packet into stream 0 av_index */static void gxf_read_index(AVFormatContext *s, int pkt_len) {    ByteIOContext *pb = &s->pb;    AVStream *st = s->streams[0];    uint32_t fields_per_map = get_le32(pb);    uint32_t map_cnt = get_le32(pb);    int i;    pkt_len -= 8;    if (map_cnt > 1000) {        av_log(s, AV_LOG_ERROR, "GXF: too many index entries %u (%x)\n", map_cnt, map_cnt);        map_cnt = 1000;    }    if (pkt_len < 4 * map_cnt) {        av_log(s, AV_LOG_ERROR, "GXF: invalid index length\n");        url_fskip(pb, pkt_len);        return;    }    pkt_len -= 4 * map_cnt;    av_add_index_entry(st, 0, 0, 0, 0, 0);    for (i = 0; i < map_cnt; i++)        av_add_index_entry(st, (uint64_t)get_le32(pb) * 1024,

⌨️ 快捷键说明

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