mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 05:01:23 +00:00
h264parse, h265parse: Fix timecode parsing
The scaling factor for nFrame part should be "(1 + nuit_field_based_flag) / 2" Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5254>
This commit is contained in:
parent
22c8d1890e
commit
2c4cb82afc
2 changed files with 76 additions and 7 deletions
|
@ -3208,6 +3208,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
GstEvent *event;
|
||||
GstBuffer *parse_buffer = NULL;
|
||||
gboolean is_interlaced = FALSE;
|
||||
GstH264SPS *sps;
|
||||
|
||||
h264parse = GST_H264_PARSE (parse);
|
||||
|
||||
|
@ -3369,8 +3370,15 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
|
||||
}
|
||||
|
||||
if (!gst_buffer_get_video_time_code_meta (parse_buffer)) {
|
||||
sps = h264parse->nalparser->last_sps;
|
||||
if (sps && sps->vui_parameters_present_flag &&
|
||||
sps->vui_parameters.timing_info_present_flag &&
|
||||
sps->vui_parameters.time_scale > 0 &&
|
||||
sps->vui_parameters.num_units_in_tick > 0 &&
|
||||
h264parse->parsed_fps_n > 0 && h264parse->parsed_fps_d > 0 &&
|
||||
!gst_buffer_get_video_time_code_meta (parse_buffer)) {
|
||||
guint i = 0;
|
||||
GstH264VUIParams *vui = &sps->vui_parameters;
|
||||
|
||||
for (i = 0; i < 3 && h264parse->num_clock_timestamp; i++) {
|
||||
GstH264ClockTimestamp *tim =
|
||||
|
@ -3378,6 +3386,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
gint field_count = -1;
|
||||
guint n_frames;
|
||||
GstVideoTimeCodeFlags flags = 0;
|
||||
guint64 scale_n, scale_d;
|
||||
|
||||
if (!h264parse->pic_timing_sei.clock_timestamp_flag[i])
|
||||
continue;
|
||||
|
@ -3424,9 +3433,37 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
is_interlaced = TRUE;
|
||||
}
|
||||
|
||||
n_frames =
|
||||
gst_util_uint64_scale_int (tim->n_frames, 1,
|
||||
2 - tim->nuit_field_based_flag);
|
||||
/* Equation D-1 (without and tOffset)
|
||||
*
|
||||
* clockTimestamp = ( ( hH * 60 + mM ) * 60 + sS ) * time_scale +
|
||||
* nFrames * ( num_units_in_tick * ( 1 + nuit_field_based_flag ) )
|
||||
* => timestamp = clockTimestamp / time_scale
|
||||
*
|
||||
* <taking only frame part>
|
||||
* timestamp = nFrames * ( num_units_in_tick * ( 1 + nuit_field_based_flag ) ) / time_scale
|
||||
*
|
||||
* <timecode's timestamp of frame part>
|
||||
* timecode_timestamp = n_frames * fps_d / fps_n
|
||||
*
|
||||
* <Scaling Equation>
|
||||
* n_frames = nFrames * ( num_units_in_tick * ( 1 + nuit_field_based_flag ) ) / time_scale
|
||||
* * fps_n / fps_d
|
||||
*
|
||||
* fps_n * ( num_units_in_tick * ( 1 + nuit_field_based_flag ) )
|
||||
* = nFrames * --------------------------------------------------------------
|
||||
* fps_d * time_scale
|
||||
*
|
||||
* NOTE: "time_scale / num_units_in_tick" value is expected field rate
|
||||
* (i.e., framerate = time_scale / (2 * num_units_in_tick)), so the above
|
||||
* equation can be simplified if the bitstream is conveying field rate
|
||||
* using time_scale / num_units_in_tick
|
||||
* => "n_frames = nFrames * (1 + nuit_field_based_flag) / 2".
|
||||
*/
|
||||
scale_n = h264parse->parsed_fps_n * vui->num_units_in_tick
|
||||
* (1 + tim->nuit_field_based_flag);
|
||||
scale_d = h264parse->parsed_fps_d * vui->time_scale;
|
||||
|
||||
n_frames = gst_util_uint64_scale (tim->n_frames, scale_n, scale_d);
|
||||
|
||||
GST_LOG_OBJECT (h264parse,
|
||||
"Add time code meta %02u:%02u:%02u:%02u",
|
||||
|
|
|
@ -2910,6 +2910,7 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
GstBuffer *buffer;
|
||||
GstEvent *event;
|
||||
GstBuffer *parse_buffer = NULL;
|
||||
GstH265SPS *sps;
|
||||
|
||||
h265parse = GST_H265_PARSE (parse);
|
||||
|
||||
|
@ -3043,13 +3044,20 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
break;
|
||||
}
|
||||
|
||||
{
|
||||
sps = h265parse->nalparser->last_sps;
|
||||
if (sps && sps->vui_parameters_present_flag &&
|
||||
sps->vui_params.timing_info_present_flag &&
|
||||
sps->vui_params.time_scale > 0 &&
|
||||
sps->vui_params.num_units_in_tick > 0 &&
|
||||
!gst_buffer_get_video_time_code_meta (parse_buffer)) {
|
||||
guint i = 0;
|
||||
GstH265VUIParams *vui = &sps->vui_params;
|
||||
|
||||
for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
|
||||
gint field_count = -1;
|
||||
guint n_frames;
|
||||
GstVideoTimeCodeFlags flags = 0;
|
||||
guint64 scale_n, scale_d;
|
||||
|
||||
if (!h265parse->time_code.clock_timestamp_flag[i])
|
||||
break;
|
||||
|
@ -3100,9 +3108,33 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME)
|
||||
flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
|
||||
|
||||
/* Equation D-26 (without and tOffset)
|
||||
*
|
||||
* clockTimestamp[i] = ( ( hH * 60 + mM ) * 60 + sS ) * vui_time_scale +
|
||||
* nFrames * ( vui_num_units_in_tick * ( 1 + unit_field_based_flag[i] ) )
|
||||
* => timestamp = clockTimestamp / time_scale
|
||||
*
|
||||
* <taking only frame part>
|
||||
* timestamp = nFrames * ( vui_num_units_in_tick * ( 1 + unit_field_based_flag ) ) / vui_time_scale
|
||||
*
|
||||
* <timecode's timestamp of frame part>
|
||||
* timecode_timestamp = n_frames * fps_d / fps_n
|
||||
*
|
||||
* <Scaling Equation>
|
||||
* n_frames = nFrames * ( vui_num_units_in_tick * ( 1 + unit_field_based_flag ) ) / vui_time_scale
|
||||
* * fps_n / fps_d
|
||||
*
|
||||
* fps_n * ( vui_num_units_in_tick * ( 1 + unit_field_based_flag ) )
|
||||
* = nFrames * ------------------------------------------------------------------
|
||||
* fps_d * vui_time_scale
|
||||
*/
|
||||
scale_n = h265parse->parsed_fps_n * vui->num_units_in_tick
|
||||
* (1 + h265parse->time_code.units_field_based_flag[i]);
|
||||
scale_d = h265parse->parsed_fps_d * vui->time_scale;
|
||||
|
||||
n_frames =
|
||||
gst_util_uint64_scale_int (h265parse->time_code.n_frames[i], 1,
|
||||
2 - h265parse->time_code.units_field_based_flag[i]);
|
||||
gst_util_uint64_scale_int (h265parse->time_code.n_frames[i], scale_n,
|
||||
scale_d);
|
||||
|
||||
gst_buffer_add_video_time_code_meta_full (parse_buffer,
|
||||
h265parse->parsed_fps_n,
|
||||
|
|
Loading…
Reference in a new issue