Commit 505c1a6f authored by GitLab CI's avatar GitLab CI

Merge remote-tracking branch 'upstream/master' into master-build

* upstream/master:
  encx265: set level
  work: fix logging of SSA import tracks
  decssasub: fix p-to-p encoding with SSA import
  decsrtsub: fix missing initial sub with p-to-p
parents f8277fd4 eaf44268
Pipeline #70798870 failed with stages
in 53 minutes and 49 seconds
......@@ -493,7 +493,10 @@ static hb_buffer_t *srt_read( hb_work_private_t *pv )
uint64_t stop_time = ( pv->current_entry.stop +
pv->subtitle->config.offset ) * 90;
if( !( start_time >= pv->start_time && stop_time < pv->stop_time ) )
// Drop subtitles that end before the start time
// or start after the stop time
if (stop_time <= pv->start_time ||
start_time >= pv->stop_time)
{
hb_deep_log( 3, "Discarding SRT at time start %"PRId64", stop %"PRId64, start_time, stop_time);
memset( &pv->current_entry, 0, sizeof( srt_entry_t ) );
......@@ -501,6 +504,14 @@ static hb_buffer_t *srt_read( hb_work_private_t *pv )
pv->current_state = k_state_timecode;
continue;
}
if (start_time < pv->start_time)
{
start_time = pv->start_time;
}
if (stop_time > pv->stop_time)
{
stop_time = pv->stop_time;
}
for (q = p = pv->current_entry.text; *p != '\0'; p++)
{
......
......@@ -40,6 +40,10 @@ struct hb_work_private_s
// SSA Import
FILE * file;
int readOrder;
// Time of first desired subtitle adjusted by reader_pts_offset
uint64_t start_time;
uint64_t stop_time;
};
#define SSA_VERBOSE_PACKETS 0
......@@ -110,6 +114,7 @@ static int extradataInit( hb_work_private_t * pv )
static int decssaInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv;
int ii;
pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
......@@ -133,6 +138,42 @@ static int decssaInit( hb_work_object_t * w, hb_job_t * job )
}
}
/*
* Figure out the start and stop times from the chapters being
* encoded - drop subtitle not in this range.
*/
pv->start_time = 0;
for (ii = 1; ii < job->chapter_start; ++ii)
{
hb_chapter_t * chapter = hb_list_item(job->list_chapter, ii - 1);
if (chapter)
{
pv->start_time += chapter->duration;
} else {
hb_error("Could not locate chapter %d for SSA start time", ii);
}
}
pv->stop_time = pv->start_time;
for (ii = job->chapter_start; ii <= job->chapter_end; ++ii)
{
hb_chapter_t * chapter = hb_list_item(job->list_chapter, ii - 1);
if (chapter)
{
pv->stop_time += chapter->duration;
} else {
hb_error("Could not locate chapter %d for SSA start time", ii);
}
}
hb_deep_log(3, "SSA Start time %"PRId64", stop time %"PRId64,
pv->start_time, pv->stop_time);
if (job->pts_to_start != 0)
{
// Compute start_time after reader sets reader_pts_offset
pv->start_time = AV_NOPTS_VALUE;
}
return 0;
fail:
......@@ -215,6 +256,12 @@ decode_line_to_mkv_ssa( hb_work_private_t * pv, char * line, int size )
{
hb_buffer_t * out;
// Trim trailing CR/LF
while (size > 0 && (line[size - 1] == '\n' || line[size - 1] == '\r'))
{
line[--size] = 0;
}
int64_t start, stop;
if (parse_timing(line, &start, &stop))
{
......@@ -267,10 +314,33 @@ decode_line_to_mkv_ssa( hb_work_private_t * pv, char * line, int size )
out->s.duration = stop - start;
out->s.stop = stop + pv->subtitle->config.offset * 90;
if( out->size == 0 )
if (out->size == 0)
{
hb_buffer_close(&out);
}
else if (out->s.stop <= pv->start_time ||
out->s.start >= pv->stop_time)
{
// Drop subtitles that end before the start time
// or start after the stop time
hb_deep_log(3, "Discarding SSA at time start %"PRId64", stop %"PRId64,
out->s.start, out->s.stop);
hb_buffer_close(&out);
}
else
{
if (out->s.start < pv->start_time)
{
out->s.start = pv->start_time;
}
if (out->s.stop > pv->stop_time)
{
out->s.stop = pv->stop_time;
}
out->s.start -= pv->start_time;
out->s.stop -= pv->start_time;
}
free( layerField );
......@@ -288,6 +358,20 @@ static hb_buffer_t * ssa_read( hb_work_private_t * pv )
{
hb_buffer_t * out;
if (pv->job->reader_pts_offset == AV_NOPTS_VALUE)
{
// We need to wait for reader to initialize it's pts offset so that
// we know where to start reading SSA.
return NULL;
}
if (pv->start_time == AV_NOPTS_VALUE)
{
pv->start_time = pv->job->reader_pts_offset;
if (pv->job->pts_to_stop > 0)
{
pv->stop_time = pv->job->pts_to_start + pv->job->pts_to_stop;
}
}
while (!feof(pv->file))
{
char * line = NULL;
......@@ -323,10 +407,15 @@ static int decssaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_work_private_t * pv = w->private_data;
hb_buffer_t * in = *buf_in;
*buf_in = NULL;
*buf_in = NULL;
*buf_out = NULL;
if (in == NULL && pv->file != NULL)
{
in = ssa_read(pv);
if (in == NULL)
{
return HB_WORK_OK;
}
}
*buf_out = in;
if (in->s.flags & HB_BUF_FLAG_EOF)
......
......@@ -81,6 +81,29 @@ static int param_parse(hb_work_private_t *pv, x265_param *param,
return ret;
}
int apply_h265_level(hb_work_private_t *pv, x265_param *param,
const char *h265_level)
{
if (h265_level == NULL ||
!strcasecmp(h265_level, hb_h265_level_names[0]))
{
return 0;
}
// Verify that level is valid
int i;
for (i = 1; hb_h265_level_values[i]; i++)
{
if (!strcmp(hb_h265_level_names[i], h265_level))
{
return param_parse(pv, param, "level-idc", h265_level);
}
}
// error (invalid or unsupported level), abort
hb_error("apply_h265_level: invalid level %s", h265_level);
return X265_PARAM_BAD_VALUE;
}
/***********************************************************************
* hb_work_encx265_init
***********************************************************************
......@@ -273,6 +296,10 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
{
goto fail;
}
if (apply_h265_level(pv, param, job->encoder_level) < 0)
{
goto fail;
}
/* we should now know whether B-frames are enabled */
job->areBframes = (param->bframes > 0) + (param->bframes > 0 &&
......
......@@ -1605,7 +1605,14 @@ static void OutputBuffer( sync_common_t * common )
out_stream->frame_count);
out_stream->frame_count++;
}
if (buf->s.start < common->start_pts)
if (out_stream->type == SYNC_TYPE_SUBTITLE &&
buf->s.stop > common->start_pts)
{
// Subtitle ends after start time, keep sub and
// adjust it's start time
buf->s.start = common->start_pts;
}
else if (buf->s.start < common->start_pts)
{
out_stream->next_pts = buf->s.start + buf->s.duration;
hb_list_rem(out_stream->in_queue, buf);
......@@ -2133,6 +2140,7 @@ static void QueueBuffer( sync_stream_t * stream, hb_buffer_t * buf )
hb_job_t * job = stream->common->job;
if (job->pts_to_start > 0)
{
stream->common->start_pts =
stream->common->pts_to_start =
MAX(0, job->pts_to_start - job->reader_pts_offset);
}
......
......@@ -546,6 +546,9 @@ void hb_display_job_info(hb_job_t *job)
{
case HB_VCODEC_X264_8BIT:
case HB_VCODEC_X264_10BIT:
case HB_VCODEC_X265_8BIT:
case HB_VCODEC_X265_10BIT:
case HB_VCODEC_X265_12BIT:
case HB_VCODEC_QSV_H264:
case HB_VCODEC_QSV_H265:
case HB_VCODEC_QSV_H265_10BIT:
......@@ -620,6 +623,18 @@ void hb_display_job_info(hb_job_t *job)
subtitle->config.default_track ? ", Default" : "",
subtitle->config.offset, subtitle->config.src_codeset);
}
else if (subtitle->source == IMPORTSSA)
{
/* For SSA, print offset */
hb_log(" * subtitle track %d, %s (track %d, id 0x%x, Text) -> "
"%s%s, offset: %"PRId64,
subtitle->out_track, subtitle->lang, subtitle->track,
subtitle->id,
subtitle->config.dest == RENDERSUB ? "Render/Burn-in"
: "Passthrough",
subtitle->config.default_track ? ", Default" : "",
subtitle->config.offset);
}
else
{
hb_log(" * subtitle track %d, %s (track %d, id 0x%x, %s) -> "
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment