|
|
|
@ -2810,94 +2810,95 @@ static int mkv_parse_video(MatroskaTrack *track, AVStream *st, |
|
|
|
|
int *extradata_offset) |
|
|
|
|
{ |
|
|
|
|
FFStream *const sti = ffstream(st); |
|
|
|
|
MatroskaTrackPlane *planes = track->operation.combine_planes.elem; |
|
|
|
|
int display_width_mul = 1; |
|
|
|
|
int display_height_mul = 1; |
|
|
|
|
MatroskaTrackPlane *planes; |
|
|
|
|
int display_width_mul = 1; |
|
|
|
|
int display_height_mul = 1; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
if (track->video.color_space.size == 4) |
|
|
|
|
par->codec_tag = AV_RL32(track->video.color_space.data); |
|
|
|
|
if (track->video.color_space.size == 4) |
|
|
|
|
par->codec_tag = AV_RL32(track->video.color_space.data); |
|
|
|
|
|
|
|
|
|
ret = mkv_parse_video_codec(track, par, matroska, |
|
|
|
|
extradata_offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
par->codec_type = AVMEDIA_TYPE_VIDEO; |
|
|
|
|
par->width = track->video.pixel_width; |
|
|
|
|
par->height = track->video.pixel_height; |
|
|
|
|
|
|
|
|
|
if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED) |
|
|
|
|
par->field_order = mkv_field_order(matroska, track->video.field_order); |
|
|
|
|
else if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE) |
|
|
|
|
par->field_order = AV_FIELD_PROGRESSIVE; |
|
|
|
|
|
|
|
|
|
if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) |
|
|
|
|
mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul); |
|
|
|
|
ret = mkv_parse_video_codec(track, par, matroska, |
|
|
|
|
extradata_offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
if (track->video.display_unit < MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN) { |
|
|
|
|
if (track->video.display_width && track->video.display_height && |
|
|
|
|
par->height < INT64_MAX / track->video.display_width / display_width_mul && |
|
|
|
|
par->width < INT64_MAX / track->video.display_height / display_height_mul) |
|
|
|
|
av_reduce(&st->sample_aspect_ratio.num, |
|
|
|
|
&st->sample_aspect_ratio.den, |
|
|
|
|
par->height * track->video.display_width * display_width_mul, |
|
|
|
|
par->width * track->video.display_height * display_height_mul, |
|
|
|
|
INT_MAX); |
|
|
|
|
} |
|
|
|
|
if (par->codec_id != AV_CODEC_ID_HEVC) |
|
|
|
|
sti->need_parsing = AVSTREAM_PARSE_HEADERS; |
|
|
|
|
par->codec_type = AVMEDIA_TYPE_VIDEO; |
|
|
|
|
par->width = track->video.pixel_width; |
|
|
|
|
par->height = track->video.pixel_height; |
|
|
|
|
|
|
|
|
|
if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED) |
|
|
|
|
par->field_order = mkv_field_order(matroska, track->video.field_order); |
|
|
|
|
else if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_PROGRESSIVE) |
|
|
|
|
par->field_order = AV_FIELD_PROGRESSIVE; |
|
|
|
|
|
|
|
|
|
if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) |
|
|
|
|
mkv_stereo_mode_display_mul(track->video.stereo_mode, |
|
|
|
|
&display_width_mul, &display_height_mul); |
|
|
|
|
|
|
|
|
|
if (track->video.display_unit < MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN) { |
|
|
|
|
if (track->video.display_width && track->video.display_height && |
|
|
|
|
par->height < INT64_MAX / track->video.display_width / display_width_mul && |
|
|
|
|
par->width < INT64_MAX / track->video.display_height / display_height_mul) |
|
|
|
|
av_reduce(&st->sample_aspect_ratio.num, |
|
|
|
|
&st->sample_aspect_ratio.den, |
|
|
|
|
par->height * track->video.display_width * display_width_mul, |
|
|
|
|
par->width * track->video.display_height * display_height_mul, |
|
|
|
|
INT_MAX); |
|
|
|
|
} |
|
|
|
|
if (par->codec_id != AV_CODEC_ID_HEVC) |
|
|
|
|
sti->need_parsing = AVSTREAM_PARSE_HEADERS; |
|
|
|
|
|
|
|
|
|
if (track->default_duration) { |
|
|
|
|
int div = track->default_duration <= INT64_MAX ? 1 : 2; |
|
|
|
|
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, |
|
|
|
|
1000000000 / div, track->default_duration / div, 30000); |
|
|
|
|
if (track->default_duration) { |
|
|
|
|
int div = track->default_duration <= INT64_MAX ? 1 : 2; |
|
|
|
|
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, |
|
|
|
|
1000000000 / div, track->default_duration / div, 30000); |
|
|
|
|
#if FF_API_R_FRAME_RATE |
|
|
|
|
if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000LL |
|
|
|
|
&& st->avg_frame_rate.num > st->avg_frame_rate.den * 5LL) |
|
|
|
|
st->r_frame_rate = st->avg_frame_rate; |
|
|
|
|
if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000LL |
|
|
|
|
&& st->avg_frame_rate.num > st->avg_frame_rate.den * 5LL) |
|
|
|
|
st->r_frame_rate = st->avg_frame_rate; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* export stereo mode flag as metadata tag */ |
|
|
|
|
if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) |
|
|
|
|
av_dict_set(&st->metadata, "stereo_mode", ff_matroska_video_stereo_mode[track->video.stereo_mode], 0); |
|
|
|
|
|
|
|
|
|
/* export alpha mode flag as metadata tag */ |
|
|
|
|
if (track->video.alpha_mode) |
|
|
|
|
av_dict_set_int(&st->metadata, "alpha_mode", 1, 0); |
|
|
|
|
|
|
|
|
|
/* if we have virtual track, mark the real tracks */ |
|
|
|
|
for (int j = 0; j < track->operation.combine_planes.nb_elem; j++) { |
|
|
|
|
MatroskaTrack *tracks = matroska->tracks.elem; |
|
|
|
|
char buf[32]; |
|
|
|
|
if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT) |
|
|
|
|
continue; |
|
|
|
|
snprintf(buf, sizeof(buf), "%s_%d", |
|
|
|
|
matroska_video_stereo_plane[planes[j].type], st->index); |
|
|
|
|
for (int k = 0; k < matroska->tracks.nb_elem; k++) |
|
|
|
|
if (planes[j].uid == tracks[k].uid && tracks[k].stream) { |
|
|
|
|
av_dict_set(&tracks[k].stream->metadata, |
|
|
|
|
"stereo_mode", buf, 0); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// add stream level stereo3d side data if it is a supported format
|
|
|
|
|
if (track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB && |
|
|
|
|
track->video.stereo_mode != MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_CYAN_RED && |
|
|
|
|
track->video.stereo_mode != MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_GREEN_MAG) { |
|
|
|
|
int ret = mkv_stereo3d_conv(st, track->video.stereo_mode); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
/* export stereo mode flag as metadata tag */ |
|
|
|
|
if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB) |
|
|
|
|
av_dict_set(&st->metadata, "stereo_mode", ff_matroska_video_stereo_mode[track->video.stereo_mode], 0); |
|
|
|
|
|
|
|
|
|
/* export alpha mode flag as metadata tag */ |
|
|
|
|
if (track->video.alpha_mode) |
|
|
|
|
av_dict_set_int(&st->metadata, "alpha_mode", 1, 0); |
|
|
|
|
|
|
|
|
|
/* if we have virtual track, mark the real tracks */ |
|
|
|
|
planes = track->operation.combine_planes.elem; |
|
|
|
|
for (int j = 0; j < track->operation.combine_planes.nb_elem; j++) { |
|
|
|
|
MatroskaTrack *tracks = matroska->tracks.elem; |
|
|
|
|
char buf[32]; |
|
|
|
|
if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT) |
|
|
|
|
continue; |
|
|
|
|
snprintf(buf, sizeof(buf), "%s_%d", |
|
|
|
|
matroska_video_stereo_plane[planes[j].type], st->index); |
|
|
|
|
for (int k = 0; k < matroska->tracks.nb_elem; k++) |
|
|
|
|
if (planes[j].uid == tracks[k].uid && tracks[k].stream) { |
|
|
|
|
av_dict_set(&tracks[k].stream->metadata, |
|
|
|
|
"stereo_mode", buf, 0); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// add stream level stereo3d side data if it is a supported format
|
|
|
|
|
if (track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB && |
|
|
|
|
track->video.stereo_mode != MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_CYAN_RED && |
|
|
|
|
track->video.stereo_mode != MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_GREEN_MAG) { |
|
|
|
|
int ret = mkv_stereo3d_conv(st, track->video.stereo_mode); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = mkv_parse_video_color(st, track); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
ret = mkv_parse_video_projection(st, track, matroska->ctx); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
ret = mkv_parse_video_color(st, track); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
ret = mkv_parse_video_projection(st, track, matroska->ctx); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|