};
/**
- * \brief parses a packet header, extracting type and length
- * \param pb AVIOContext 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
+ * @brief parses a packet header, extracting type and length
+ * @param pb AVIOContext 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(AVIOContext *pb, GXFPktType *type, int *length) {
if (avio_rb32(pb))
}
/**
- * \brief check if file starts with a PKT_MAP header
+ * @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
}
/**
- * \brief gets the stream index for the track with the specified id, creates new
+ * @brief gets the stream index for the track with the specified id, creates new
* stream if not found
- * \param id id of stream to find / add
- * \param format stream format identifier
+ * @param id id of stream to find / add
+ * @param format stream format identifier
*/
static int get_sindex(AVFormatContext *s, int id, int format) {
int i;
i = ff_find_stream_index(s, id);
if (i >= 0)
return i;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
+ st->id = id;
switch (format) {
case 3:
case 4:
}
/**
- * \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
+ * @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(AVIOContext *pb, int *len, struct gxf_stream_info *si) {
si->first_field = AV_NOPTS_VALUE;
}
/**
- * \brief convert fps tag value to AVRational fps
- * \param fps fps value from tag
- * \return fps as AVRational, or 0 / 0 if unknown
+ * @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[];
+ extern const AVRational avpriv_frame_rate_tab[];
if (fps < 1 || fps > 9) fps = 9;
- return ff_frame_rate_tab[9 - fps]; // values have opposite order
+ return avpriv_frame_rate_tab[9 - fps]; // values have opposite order
}
/**
- * \brief convert UMF attributes flags to AVRational fps
- * \param flags UMF flags to convert
- * \return fps as AVRational, or 0 / 0 if unknown
+ * @brief convert UMF attributes flags to AVRational fps
+ * @param flags UMF flags to convert
+ * @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},
}
/**
- * \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
+ * @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(AVIOContext *pb, int *len, struct gxf_stream_info *si) {
si->frames_per_second = (AVRational){0, 0};
}
/**
- * \brief read index from FLT packet into stream 0 av_index
+ * @brief read index from FLT packet into stream 0 av_index
*/
static void gxf_read_index(AVFormatContext *s, int pkt_len) {
AVIOContext *pb = s->pb;
avio_skip(pb, pkt_len);
}
-static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
+static int gxf_header(AVFormatContext *s) {
AVIOContext *pb = s->pb;
GXFPktType pkt_type;
int map_len;
int len;
AVRational main_timebase = {0, 0};
- struct gxf_stream_info si;
+ struct gxf_stream_info *si = s->priv_data;
int i;
if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
av_log(s, AV_LOG_ERROR, "map packet not found\n");
return 0;
}
map_len -= len;
- gxf_material_tags(pb, &len, &si);
+ gxf_material_tags(pb, &len, si);
avio_skip(pb, len);
map_len -= 2;
len = avio_rb16(pb); // length of track description
track_id = avio_r8(pb);
track_len = avio_rb16(pb);
len -= track_len;
- gxf_track_tags(pb, &track_len, &si);
+ gxf_track_tags(pb, &track_len, si);
avio_skip(pb, track_len);
if (!(track_type & 0x80)) {
av_log(s, AV_LOG_ERROR, "invalid track type %x\n", 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 * 2;
+ main_timebase.num = si->frames_per_second.den;
+ main_timebase.den = si->frames_per_second.num * 2;
}
- 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;
+ 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, "invalid track description length specified\n");
main_timebase = (AVRational){1001, 60000};
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);
+ avpriv_set_pts_info(st, 32, main_timebase.num, main_timebase.den);
}
return 0;
}
}
/**
- * \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
+ * @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;
AVIOContext *pb = s->pb;
GXFPktType pkt_type;
int pkt_len;
+ struct gxf_stream_info *si = s->priv_data;
+
while (!pb->eof_reached) {
AVStream *st;
int track_type, track_id, ret;
avio_skip(pb, skip);
pkt->stream_index = stream_index;
pkt->dts = field_nr;
+
+ //set duration manually for DV or else lavf misdetects the frame rate
+ if (st->codec->codec_id == CODEC_ID_DVVIDEO)
+ pkt->duration = si->fields_per_frame;
+
return ret;
}
return AVERROR(EIO);
}
AVInputFormat ff_gxf_demuxer = {
- "gxf",
- NULL_IF_CONFIG_SMALL("GXF format"),
- 0,
- gxf_probe,
- gxf_header,
- gxf_packet,
- NULL,
- gxf_seek,
- gxf_read_timestamp,
+ .name = "gxf",
+ .long_name = NULL_IF_CONFIG_SMALL("GXF format"),
+ .priv_data_size = sizeof(struct gxf_stream_info),
+ .read_probe = gxf_probe,
+ .read_header = gxf_header,
+ .read_packet = gxf_packet,
+ .read_seek = gxf_seek,
+ .read_timestamp = gxf_read_timestamp,
};