gxf: Fix 25 fps DV material in GXF being misdetected as 50 fps
Set DV packet durations using fields_per_frame. This requires turning gxf_stream_info into the demuxer's context for access to the value in gxf_packet(). Since MPEG-2 seems to work fine this done only for DV. Signed-off-by: Anton Khirnov <anton@khirnov.net> (cherry picked from commit 99fecc64b064a013559d3d61f7d9790e3c95c80e) Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
parent
9417761474
commit
c75ba07f6e
@ -264,7 +264,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
|
|||||||
int map_len;
|
int map_len;
|
||||||
int len;
|
int len;
|
||||||
AVRational main_timebase = {0, 0};
|
AVRational main_timebase = {0, 0};
|
||||||
struct gxf_stream_info si;
|
struct gxf_stream_info *si = s->priv_data;
|
||||||
int i;
|
int i;
|
||||||
if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
|
if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
|
||||||
av_log(s, AV_LOG_ERROR, "map packet not found\n");
|
av_log(s, AV_LOG_ERROR, "map packet not found\n");
|
||||||
@ -282,7 +282,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
map_len -= len;
|
map_len -= len;
|
||||||
gxf_material_tags(pb, &len, &si);
|
gxf_material_tags(pb, &len, si);
|
||||||
avio_skip(pb, len);
|
avio_skip(pb, len);
|
||||||
map_len -= 2;
|
map_len -= 2;
|
||||||
len = avio_rb16(pb); // length of track description
|
len = avio_rb16(pb); // length of track description
|
||||||
@ -300,7 +300,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
|
|||||||
track_id = avio_r8(pb);
|
track_id = avio_r8(pb);
|
||||||
track_len = avio_rb16(pb);
|
track_len = avio_rb16(pb);
|
||||||
len -= track_len;
|
len -= track_len;
|
||||||
gxf_track_tags(pb, &track_len, &si);
|
gxf_track_tags(pb, &track_len, si);
|
||||||
avio_skip(pb, track_len);
|
avio_skip(pb, track_len);
|
||||||
if (!(track_type & 0x80)) {
|
if (!(track_type & 0x80)) {
|
||||||
av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type);
|
av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type);
|
||||||
@ -316,12 +316,12 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
|
|||||||
if (idx < 0) continue;
|
if (idx < 0) continue;
|
||||||
st = s->streams[idx];
|
st = s->streams[idx];
|
||||||
if (!main_timebase.num || !main_timebase.den) {
|
if (!main_timebase.num || !main_timebase.den) {
|
||||||
main_timebase.num = si.frames_per_second.den;
|
main_timebase.num = si->frames_per_second.den;
|
||||||
main_timebase.den = si.frames_per_second.num * 2;
|
main_timebase.den = si->frames_per_second.num * 2;
|
||||||
}
|
}
|
||||||
st->start_time = si.first_field;
|
st->start_time = si->first_field;
|
||||||
if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE)
|
if (si->first_field != AV_NOPTS_VALUE && si->last_field != AV_NOPTS_VALUE)
|
||||||
st->duration = si.last_field - si.first_field;
|
st->duration = si->last_field - si->first_field;
|
||||||
}
|
}
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
av_log(s, AV_LOG_ERROR, "invalid track description length specified\n");
|
av_log(s, AV_LOG_ERROR, "invalid track description length specified\n");
|
||||||
@ -422,6 +422,8 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
|
|||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
GXFPktType pkt_type;
|
GXFPktType pkt_type;
|
||||||
int pkt_len;
|
int pkt_len;
|
||||||
|
struct gxf_stream_info *si = s->priv_data;
|
||||||
|
|
||||||
while (!pb->eof_reached) {
|
while (!pb->eof_reached) {
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
int track_type, track_id, ret;
|
int track_type, track_id, ret;
|
||||||
@ -473,6 +475,11 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
|
|||||||
avio_skip(pb, skip);
|
avio_skip(pb, skip);
|
||||||
pkt->stream_index = stream_index;
|
pkt->stream_index = stream_index;
|
||||||
pkt->dts = field_nr;
|
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 ret;
|
||||||
}
|
}
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
@ -518,7 +525,7 @@ static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index,
|
|||||||
AVInputFormat ff_gxf_demuxer = {
|
AVInputFormat ff_gxf_demuxer = {
|
||||||
"gxf",
|
"gxf",
|
||||||
NULL_IF_CONFIG_SMALL("GXF format"),
|
NULL_IF_CONFIG_SMALL("GXF format"),
|
||||||
0,
|
sizeof(struct gxf_stream_info),
|
||||||
gxf_probe,
|
gxf_probe,
|
||||||
gxf_header,
|
gxf_header,
|
||||||
gxf_packet,
|
gxf_packet,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user