@@ -2808,6 +2808,50 @@ static int set_side_data(HEVCContext *s)
}
s->sei.unregistered.nb_buf_ref = 0;
+ if (s->sei.timecode.present) {
+ uint32_t tc = 0;
+ uint32_t *tc_sd;
+ AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE,
+ sizeof(uint32_t) * 4);
+ if (!tcside)
+ return AVERROR(ENOMEM);
+
+ tc_sd = (uint32_t*)tcside->data;
+ tc_sd[0] = s->sei.timecode.num_clock_ts;
+
+ for (int i = 0; i < tc_sd[0]; i++) {
+ uint32_t frames;
+
+ /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
+ See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
+ if (av_cmp_q(s->avctx->framerate, (AVRational) {30, 1}) == 1) {
+ frames = s->sei.timecode.n_frames[i] / 2;
+ if (s->sei.timecode.n_frames[i] % 2 == 1) {
+ if (av_cmp_q(s->avctx->framerate, (AVRational) {50, 1}) == 0)
+ tc |= (1 << 7);
+ else
+ tc |= (1 << 23);
+ }
+ } else {
+ frames = s->sei.timecode.n_frames[i];
+ }
+
+ tc |= s->sei.timecode.cnt_dropped_flag[i] << 30;
+ tc |= (frames / 10) << 28;
+ tc |= (frames % 10) << 24;
+ tc |= (s->sei.timecode.seconds_value[i] / 10) << 20;
+ tc |= (s->sei.timecode.seconds_value[i] % 10) << 16;
+ tc |= (s->sei.timecode.minutes_value[i] / 10) << 12;
+ tc |= (s->sei.timecode.minutes_value[i] % 10) << 8;
+ tc |= (s->sei.timecode.hours_value[i] / 10) << 4;
+ tc |= (s->sei.timecode.hours_value[i] % 10);
+
+ tc_sd[i + 1] = tc;
+ }
+
+ s->sei.timecode.num_clock_ts = 0;
+ }
+
return 0;
}