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

📄 gxf.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
                           i * (uint64_t)fields_per_map + 1, 0, 0, 0);    url_fskip(pb, pkt_len);}static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {    ByteIOContext *pb = &s->pb;    pkt_type_t pkt_type;    int map_len;    int len;    AVRational main_timebase = {0, 0};    st_info_t si;    int i;    if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {        av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");        return 0;    }    map_len -= 2;    if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {        av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");        return 0;    }    map_len -= 2;    len = get_be16(pb); // length of material data section    if (len > map_len) {        av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");        return 0;    }    map_len -= len;    gxf_material_tags(pb, &len, &si);    url_fskip(pb, len);    map_len -= 2;    len = get_be16(pb); // length of track description    if (len > map_len) {        av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");        return 0;    }    map_len -= len;    while (len > 0) {        int track_type, track_id, track_len;        AVStream *st;        int idx;        len -= 4;        track_type = get_byte(pb);        track_id = get_byte(pb);        track_len = get_be16(pb);        len -= track_len;        gxf_track_tags(pb, &track_len, &si);        url_fskip(pb, track_len);        if (!(track_type & 0x80)) {           av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);           continue;        }        track_type &= 0x7f;        if ((track_id & 0xc0) != 0xc0) {           av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);           continue;        }        track_id &= 0x3f;        idx = get_sindex(s, track_id, track_type);        if (idx < 0) continue;        st = s->streams[idx];        if (!main_timebase.num || !main_timebase.den) {            main_timebase.num = si.frames_per_second.den;            main_timebase.den = si.frames_per_second.num * si.fields_per_frame;        }        st->start_time = si.first_field;        if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE)            st->duration = si.last_field - si.first_field;    }    if (len < 0)        av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");    if (map_len)        url_fskip(pb, map_len);    if (!parse_packet_header(pb, &pkt_type, &len)) {        av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n");        return -1;    }    if (pkt_type == PKT_FLT) {        gxf_read_index(s, len);        if (!parse_packet_header(pb, &pkt_type, &len)) {            av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n");            return -1;        }    }    if (pkt_type == PKT_UMF) {        if (len >= 0x39) {            AVRational fps;            len -= 0x39;            url_fskip(pb, 5); // preamble            url_fskip(pb, 0x30); // payload description            fps = fps_umf2avr(get_le32(pb));            if (!main_timebase.num || !main_timebase.den) {                // this may not always be correct, but simply the best we can get                main_timebase.num = fps.den;                main_timebase.den = fps.num;            }        } else            av_log(s, AV_LOG_INFO, "GXF: UMF packet too short\n");    } else        av_log(s, AV_LOG_INFO, "GXF: UMF packet missing\n");    url_fskip(pb, len);    if (!main_timebase.num || !main_timebase.den)        main_timebase = (AVRational){1, 50}; // set some arbitrary fallback    for (i = 0; i < s->nb_streams; i++) {        AVStream *st = s->streams[i];        av_set_pts_info(st, 32, main_timebase.num, main_timebase.den);    }    return 0;}#define READ_ONE() \    { \        if (!max_interval-- || url_feof(pb)) \            goto out; \        tmp = tmp << 8 | get_byte(pb); \    }/** * \brief resync the stream on the next media packet with specified properties * \param max_interval how many bytes to search for matching packet at most * \param track track id the media packet must belong to, -1 for any * \param timestamp minimum timestamp (== field number) the packet must have, -1 for any * \return timestamp of packet found */static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) {    uint32_t tmp;    uint64_t last_pos;    uint64_t last_found_pos = 0;    int cur_track;    int64_t cur_timestamp = AV_NOPTS_VALUE;    int len;    ByteIOContext *pb = &s->pb;    pkt_type_t type;    tmp = get_be32(pb);start:    while (tmp)        READ_ONE();    READ_ONE();    if (tmp != 1)        goto start;    last_pos = url_ftell(pb);    url_fseek(pb, -5, SEEK_CUR);    if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) {        url_fseek(pb, last_pos, SEEK_SET);        goto start;    }    get_byte(pb);    cur_track = get_byte(pb);    cur_timestamp = get_be32(pb);    last_found_pos = url_ftell(pb) - 16 - 6;    if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) {        url_fseek(pb, last_pos, SEEK_SET);        goto start;    }out:    if (last_found_pos)        url_fseek(pb, last_found_pos, SEEK_SET);    return cur_timestamp;}static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {    ByteIOContext *pb = &s->pb;    pkt_type_t pkt_type;    int pkt_len;    while (!url_feof(pb)) {        int track_type, track_id, ret;        int field_nr;        if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {            if (!url_feof(pb))                av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");            return -1;        }        if (pkt_type == PKT_FLT) {            gxf_read_index(s, pkt_len);            continue;        }        if (pkt_type != PKT_MEDIA) {            url_fskip(pb, pkt_len);            continue;        }        if (pkt_len < 16) {            av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");            continue;        }        pkt_len -= 16;        track_type = get_byte(pb);        track_id = get_byte(pb);        field_nr = get_be32(pb);        get_be32(pb); // field information        get_be32(pb); // "timeline" field number        get_byte(pb); // flags        get_byte(pb); // reserved        // NOTE: there is also data length information in the        // field information, it might be better to take this into account        // as well.        ret = av_get_packet(pb, pkt, pkt_len);        pkt->stream_index = get_sindex(s, track_id, track_type);        pkt->dts = field_nr;        return ret;    }    return AVERROR(EIO);}static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {    uint64_t pos;    uint64_t maxlen = 100 * 1024 * 1024;    AVStream *st = s->streams[0];    int64_t start_time = s->streams[stream_index]->start_time;    int64_t found;    int idx;    if (timestamp < start_time) timestamp = start_time;    idx = av_index_search_timestamp(st, timestamp - start_time,                                    AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);    if (idx < 0)        return -1;    pos = st->index_entries[idx].pos;    if (idx < st->nb_index_entries - 2)        maxlen = st->index_entries[idx + 2].pos - pos;    maxlen = FFMAX(maxlen, 200 * 1024);    url_fseek(&s->pb, pos, SEEK_SET);    found = gxf_resync_media(s, maxlen, -1, timestamp);    if (FFABS(found - timestamp) > 4)        return -1;    return 0;}static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index,                                  int64_t *pos, int64_t pos_limit) {    ByteIOContext *pb = &s->pb;    int64_t res;    url_fseek(pb, *pos, SEEK_SET);    res = gxf_resync_media(s, pos_limit - *pos, -1, -1);    *pos = url_ftell(pb);    return res;}AVInputFormat gxf_demuxer = {    "gxf",    "GXF format",    0,    gxf_probe,    gxf_header,    gxf_packet,    NULL,    gxf_seek,    gxf_read_timestamp,};

⌨️ 快捷键说明

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