Message ID | 1594992398-29104-1-git-send-email-lance.lmwang@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/2] avdevice/decklink_dec: mark the field flag if framerate > 30FPS | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: > From: Limin Wang <lance.lmwang@gmail.com> > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag if the frame rate > 30FPS to > avoid interoperability issues. It will be used by the encoder to identify even or odd frames > and correctly calculate the frame number of the SEI TC. This feature looks like it belongs to av_timecode_get_smpte_from_framenum and not into decklink. Also checking previous timecode and guessing something is a hack, especially since you have the exact source timecode. Regards, Marton > > --- > libavdevice/decklink_common.h | 1 + > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ > 2 files changed, 15 insertions(+) > > diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h > index bd68c7b..8ddc411 100644 > --- a/libavdevice/decklink_common.h > +++ b/libavdevice/decklink_common.h > @@ -151,6 +151,7 @@ struct decklink_ctx { > int channels; > int audio_depth; > unsigned long tc_seen; // used with option wait_for_tc > + uint32_t last_tc; > }; > > typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp > index dde68ff..a60c01b 100644 > --- a/libavdevice/decklink_dec.cpp > +++ b/libavdevice/decklink_dec.cpp > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( > int metadata_len; > uint8_t* packed_metadata; > AVTimecode tcr; > + AVRational rate = ctx->video_st->r_frame_rate; > > if (av_timecode_init_from_string(&tcr, ctx->video_st->r_frame_rate, tc, ctx) >= 0) { > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); > int size = sizeof(uint32_t) * 4; > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); > > + /* set the field flag if frame rate > 30FPS */ > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { > + /* Odd frame */ > + if (ctx->last_tc == tc_data) { > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) > + tc_data |= (1 << 7); > + else > + tc_data |= (1 << 23); > + } > + } > + ctx->last_tc = tc_data; > + > if (sd) { > *sd = 1; // one TC > *(sd + 1) = tc_data; // TC > -- > 2.9.4 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: > > > From: Limin Wang <lance.lmwang@gmail.com> > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag if the frame rate > 30FPS to > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames > > and correctly calculate the frame number of the SEI TC. > > This feature looks like it belongs to av_timecode_get_smpte_from_framenum > and not into decklink. Also checking previous timecode and guessing > something is a hack, especially since you have the exact source timecode. If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps if you tested with SDI with TC. 00:00:00:24 00:00:00:24 00:00:00:25 00:00:00:25 00:00:00:00 00:00:00:00 That's why I check the last TC to get the frame is even or odd. Why not use av_timecode_get_smpte_from_framenum(), for it's calculated by the string TC by one time, so it lacks the information whether it's odd or even frame. > > Regards, > Marton > > > > > --- > > libavdevice/decklink_common.h | 1 + > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ > > 2 files changed, 15 insertions(+) > > > > diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h > > index bd68c7b..8ddc411 100644 > > --- a/libavdevice/decklink_common.h > > +++ b/libavdevice/decklink_common.h > > @@ -151,6 +151,7 @@ struct decklink_ctx { > > int channels; > > int audio_depth; > > unsigned long tc_seen; // used with option wait_for_tc > > + uint32_t last_tc; > > }; > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp > > index dde68ff..a60c01b 100644 > > --- a/libavdevice/decklink_dec.cpp > > +++ b/libavdevice/decklink_dec.cpp > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( > > int metadata_len; > > uint8_t* packed_metadata; > > AVTimecode tcr; > > + AVRational rate = ctx->video_st->r_frame_rate; > > > > if (av_timecode_init_from_string(&tcr, ctx->video_st->r_frame_rate, tc, ctx) >= 0) { > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); > > int size = sizeof(uint32_t) * 4; > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); > > > > + /* set the field flag if frame rate > 30FPS */ > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { > > + /* Odd frame */ > > + if (ctx->last_tc == tc_data) { > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) > > + tc_data |= (1 << 7); > > + else > > + tc_data |= (1 << 23); > > + } > > + } > > + ctx->last_tc = tc_data; > > + > > if (sd) { > > *sd = 1; // one TC > > *(sd + 1) = tc_data; // TC > > -- > > 2.9.4 > > > > _______________________________________________ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: >> >> >> On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: >> >> > From: Limin Wang <lance.lmwang@gmail.com> >> > >> > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag if the frame rate > 30FPS to >> > avoid interoperability issues. It will be used by the encoder to identify even or odd frames >> > and correctly calculate the frame number of the SEI TC. >> >> This feature looks like it belongs to av_timecode_get_smpte_from_framenum >> and not into decklink. Also checking previous timecode and guessing >> something is a hack, especially since you have the exact source timecode. > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps > if you tested with SDI with TC. > 00:00:00:24 > 00:00:00:24 > 00:00:00:25 > 00:00:00:25 > 00:00:00:00 > 00:00:00:00 Have you actually tested this with a real SDI signal containing timecode? Thanks, Marton > > That's why I check the last TC to get the frame is even or odd. > > Why not use av_timecode_get_smpte_from_framenum(), for it's calculated by the string TC by one time, > so it lacks the information whether it's odd or even frame. > >> >> Regards, >> Marton >> >> > >> > --- >> > libavdevice/decklink_common.h | 1 + >> > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ >> > 2 files changed, 15 insertions(+) >> > >> > diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h >> > index bd68c7b..8ddc411 100644 >> > --- a/libavdevice/decklink_common.h >> > +++ b/libavdevice/decklink_common.h >> > @@ -151,6 +151,7 @@ struct decklink_ctx { >> > int channels; >> > int audio_depth; >> > unsigned long tc_seen; // used with option wait_for_tc >> > + uint32_t last_tc; >> > }; >> > >> > typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; >> > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >> > index dde68ff..a60c01b 100644 >> > --- a/libavdevice/decklink_dec.cpp >> > +++ b/libavdevice/decklink_dec.cpp >> > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >> > int metadata_len; >> > uint8_t* packed_metadata; >> > AVTimecode tcr; >> > + AVRational rate = ctx->video_st->r_frame_rate; >> > >> > if (av_timecode_init_from_string(&tcr, ctx->video_st->r_frame_rate, tc, ctx) >= 0) { >> > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); >> > int size = sizeof(uint32_t) * 4; >> > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); >> > >> > + /* set the field flag if frame rate > 30FPS */ >> > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ >> > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { >> > + /* Odd frame */ >> > + if (ctx->last_tc == tc_data) { >> > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) >> > + tc_data |= (1 << 7); >> > + else >> > + tc_data |= (1 << 23); >> > + } >> > + } >> > + ctx->last_tc = tc_data; >> > + >> > if (sd) { >> > *sd = 1; // one TC >> > *(sd + 1) = tc_data; // TC >> > -- >> > 2.9.4 >> > >> > _______________________________________________ >> > ffmpeg-devel mailing list >> > ffmpeg-devel@ffmpeg.org >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > >> > To unsubscribe, visit link above, or email >> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > -- > Thanks, > Limin Wang > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > > > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: > > > > > > > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > From: Limin Wang <lance.lmwang@gmail.com> > > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag > > > if the frame rate > 30FPS to > > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames > > > > and correctly calculate the frame number of the SEI TC. > > > > > > This feature looks like it belongs to av_timecode_get_smpte_from_framenum > > > and not into decklink. Also checking previous timecode and guessing > > > something is a hack, especially since you have the exact source timecode. > > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be > > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps > > if you tested with SDI with TC. > > 00:00:00:24 > > 00:00:00:24 > > 00:00:00:25 > > 00:00:00:25 > > 00:00:00:00 > > 00:00:00:00 > > Have you actually tested this with a real SDI signal containing timecode? Yes, have tested with SDI playback by decklink UltraStudio 4K mini with TC enabled. > > Thanks, > Marton > > > > > That's why I check the last TC to get the frame is even or odd. > > > > Why not use av_timecode_get_smpte_from_framenum(), for it's calculated by the string TC by one time, > > so it lacks the information whether it's odd or even frame. > > > > > > > > Regards, > > > Marton > > > > > > > > --- > > > > libavdevice/decklink_common.h | 1 + > > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ > > > > 2 files changed, 15 insertions(+) > > > > > diff --git a/libavdevice/decklink_common.h > > > b/libavdevice/decklink_common.h > > > > index bd68c7b..8ddc411 100644 > > > > --- a/libavdevice/decklink_common.h > > > > +++ b/libavdevice/decklink_common.h > > > > @@ -151,6 +151,7 @@ struct decklink_ctx { > > > > int channels; > > > > int audio_depth; > > > > unsigned long tc_seen; // used with option wait_for_tc > > > > + uint32_t last_tc; > > > > }; > > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} > > > decklink_direction_t; > > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp > > > > index dde68ff..a60c01b 100644 > > > > --- a/libavdevice/decklink_dec.cpp > > > > +++ b/libavdevice/decklink_dec.cpp > > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( > > > > int metadata_len; > > > > uint8_t* packed_metadata; > > > > AVTimecode tcr; > > > > + AVRational rate = ctx->video_st->r_frame_rate; > > > > > if (av_timecode_init_from_string(&tcr, > > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { > > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); > > > > int size = sizeof(uint32_t) * 4; > > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); > > > > > + /* set the field flag if frame rate > > > > 30FPS */ > > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ > > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { > > > > + /* Odd frame */ > > > > + if (ctx->last_tc == tc_data) { > > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) > > > > + tc_data |= (1 << 7); > > > > + else > > > > + tc_data |= (1 << 23); > > > > + } > > > > + } > > > > + ctx->last_tc = tc_data; > > > > + > > > > if (sd) { > > > > *sd = 1; // one TC > > > > *(sd + 1) = tc_data; // TC > > > > -- > 2.9.4 > > > > > _______________________________________________ > > > > ffmpeg-devel mailing list > > > > ffmpeg-devel@ffmpeg.org > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > To unsubscribe, visit link above, or email > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > _______________________________________________ > > > ffmpeg-devel mailing list > > > ffmpeg-devel@ffmpeg.org > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > To unsubscribe, visit link above, or email > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > -- > > Thanks, > > Limin Wang > > _______________________________________________ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: >> >> >> On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: >> >> > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: >> > > >> > > >> > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: >> > > >> > > > From: Limin Wang <lance.lmwang@gmail.com> >> > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag >> > > if the frame rate > 30FPS to >> > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames >> > > > and correctly calculate the frame number of the SEI TC. >> > > >> > > This feature looks like it belongs to av_timecode_get_smpte_from_framenum >> > > and not into decklink. Also checking previous timecode and guessing >> > > something is a hack, especially since you have the exact source timecode. >> > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be >> > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps >> > if you tested with SDI with TC. >> > 00:00:00:24 >> > 00:00:00:24 >> > 00:00:00:25 >> > 00:00:00:25 >> > 00:00:00:00 >> > 00:00:00:00 >> >> Have you actually tested this with a real SDI signal containing timecode? > > Yes, have tested with SDI playback by decklink UltraStudio 4K mini with TC enabled. I still don't understand how this works. Isn't timecode in the SDI signal also contain the so called "field bit" flag to support 50fps timecode? And if it does, then why can't you query it from decklink? Timecode in SDI signal is also supposed to be an SMPTE 12M timecode, so all the bits you need should be in it, you should not need to guess anything. Therefore it makes little sense to me that the DeckLink API does not provide a proper timecode as string, unless the original capture you made with your UltraStudio and which you played back also has a faulty timecode. What generated the signal which you captured with UltraStudio? Not ffmpeg I hope... Regards, Marton > >> >> Thanks, >> Marton >> >> > >> > That's why I check the last TC to get the frame is even or odd. >> > >> > Why not use av_timecode_get_smpte_from_framenum(), for it's calculated by the string TC by one time, >> > so it lacks the information whether it's odd or even frame. >> > >> > > >> > > Regards, >> > > Marton >> > > >> > > > > --- >> > > > libavdevice/decklink_common.h | 1 + >> > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ >> > > > 2 files changed, 15 insertions(+) >> > > > > diff --git a/libavdevice/decklink_common.h >> > > b/libavdevice/decklink_common.h >> > > > index bd68c7b..8ddc411 100644 >> > > > --- a/libavdevice/decklink_common.h >> > > > +++ b/libavdevice/decklink_common.h >> > > > @@ -151,6 +151,7 @@ struct decklink_ctx { >> > > > int channels; >> > > > int audio_depth; >> > > > unsigned long tc_seen; // used with option wait_for_tc >> > > > + uint32_t last_tc; >> > > > }; >> > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} >> > > decklink_direction_t; >> > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >> > > > index dde68ff..a60c01b 100644 >> > > > --- a/libavdevice/decklink_dec.cpp >> > > > +++ b/libavdevice/decklink_dec.cpp >> > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >> > > > int metadata_len; >> > > > uint8_t* packed_metadata; >> > > > AVTimecode tcr; >> > > > + AVRational rate = ctx->video_st->r_frame_rate; >> > > > > if (av_timecode_init_from_string(&tcr, >> > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { >> > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); >> > > > int size = sizeof(uint32_t) * 4; >> > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); >> > > > > + /* set the field flag if frame rate >> > > > 30FPS */ >> > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ >> > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { >> > > > + /* Odd frame */ >> > > > + if (ctx->last_tc == tc_data) { >> > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) >> > > > + tc_data |= (1 << 7); >> > > > + else >> > > > + tc_data |= (1 << 23); >> > > > + } >> > > > + } >> > > > + ctx->last_tc = tc_data; >> > > > + >> > > > if (sd) { >> > > > *sd = 1; // one TC >> > > > *(sd + 1) = tc_data; // TC >> > > > -- > 2.9.4 >> > > > > _______________________________________________ >> > > > ffmpeg-devel mailing list >> > > > ffmpeg-devel@ffmpeg.org >> > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > To unsubscribe, visit link above, or email >> > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > _______________________________________________ >> > > ffmpeg-devel mailing list >> > > ffmpeg-devel@ffmpeg.org >> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > >> > > To unsubscribe, visit link above, or email >> > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > >> > -- >> > Thanks, >> > Limin Wang >> > _______________________________________________ >> > ffmpeg-devel mailing list >> > ffmpeg-devel@ffmpeg.org >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > >> > To unsubscribe, visit link above, or email >> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > -- > Thanks, > Limin Wang > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sat, Jul 18, 2020 at 08:38:16PM +0200, Marton Balint wrote: > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > > > On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: > > > > > > > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: > > > > > > > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > > From: Limin Wang <lance.lmwang@gmail.com> > > > > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag > > > > > if the frame rate > 30FPS to > > > > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames > > > > > > and correctly calculate the frame number of the SEI TC. > > > > > > > This feature looks like it belongs to > > > av_timecode_get_smpte_from_framenum > > > > > and not into decklink. Also checking previous timecode and guessing > > > > > something is a hack, especially since you have the exact source timecode. > > > > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be > > > > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps > > > > if you tested with SDI with TC. > > > > 00:00:00:24 > > > > 00:00:00:24 > > > > 00:00:00:25 > > > > 00:00:00:25 > > > > 00:00:00:00 > > > > 00:00:00:00 > > > > > > Have you actually tested this with a real SDI signal containing timecode? > > > > Yes, have tested with SDI playback by decklink UltraStudio 4K mini with TC enabled. > > I still don't understand how this works. Isn't timecode in the SDI signal > also contain the so called "field bit" flag to support 50fps timecode? And > if it does, then why can't you query it from decklink? Timecode in SDI > signal is also supposed to be an SMPTE 12M timecode, so all the bits you > need should be in it, you should not need to guess anything. Therefore it > makes little sense to me that the DeckLink API does not provide a proper > timecode as string, unless the original capture you made with your > UltraStudio and which you played back also has a faulty timecode. > What generated the signal which you captured with UltraStudio? Not ffmpeg I > hope... It's auto-generated by configure of UltraStudio. I have tested with bmdTimecodeFieldMark flag, it's not set as expected for testing. I have no clue how to get the flag as the API provide the TC string is same for the frame pair. Maybe I miss something. > > Regards, > Marton > > > > > > > > > > Thanks, > > > Marton > > > > > > > > That's why I check the last TC to get the frame is even or odd. > > > > > Why not use av_timecode_get_smpte_from_framenum(), for it's > > > calculated by the string TC by one time, > > > > so it lacks the information whether it's odd or even frame. > > > > > > > > Regards, > > > > > Marton > > > > > > > > > --- > > > > > > libavdevice/decklink_common.h | 1 + > > > > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ > > > > > > 2 files changed, 15 insertions(+) > > > > > > > diff --git a/libavdevice/decklink_common.h > > > > > b/libavdevice/decklink_common.h > > > > > > index bd68c7b..8ddc411 100644 > > > > > > --- a/libavdevice/decklink_common.h > > > > > > +++ b/libavdevice/decklink_common.h > > > > > > @@ -151,6 +151,7 @@ struct decklink_ctx { > > > > > > int channels; > > > > > > int audio_depth; > > > > > > unsigned long tc_seen; // used with option wait_for_tc > > > > > > + uint32_t last_tc; > > > > > > }; > > > > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} > > > > > decklink_direction_t; > > > > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp > > > > > > index dde68ff..a60c01b 100644 > > > > > > --- a/libavdevice/decklink_dec.cpp > > > > > > +++ b/libavdevice/decklink_dec.cpp > > > > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( > > > > > > int metadata_len; > > > > > > uint8_t* packed_metadata; > > > > > > AVTimecode tcr; > > > > > > + AVRational rate = ctx->video_st->r_frame_rate; > > > > > > > if (av_timecode_init_from_string(&tcr, > > > > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { > > > > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); > > > > > > int size = sizeof(uint32_t) * 4; > > > > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); > > > > > > > + /* set the field flag if frame rate > > > > > > 30FPS */ > > > > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ > > > > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { > > > > > > + /* Odd frame */ > > > > > > + if (ctx->last_tc == tc_data) { > > > > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) > > > > > > + tc_data |= (1 << 7); > > > > > > + else > > > > > > + tc_data |= (1 << 23); > > > > > > + } > > > > > > + } > > > > > > + ctx->last_tc = tc_data; > > > > > > + > > > > > > if (sd) { > > > > > > *sd = 1; // one TC > > > > > > *(sd + 1) = tc_data; // TC > > > > > > -- > 2.9.4 > > > > > > > _______________________________________________ > > > > > > ffmpeg-devel mailing list > > > > > > ffmpeg-devel@ffmpeg.org > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > To unsubscribe, visit link above, or email > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > _______________________________________________ > > > > > ffmpeg-devel mailing list > > > > > ffmpeg-devel@ffmpeg.org > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > To unsubscribe, visit link above, or email > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > -- > Thanks, > > > > Limin Wang > > > > _______________________________________________ > > > > ffmpeg-devel mailing list > > > > ffmpeg-devel@ffmpeg.org > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > To unsubscribe, visit link above, or email > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > _______________________________________________ > > > ffmpeg-devel mailing list > > > ffmpeg-devel@ffmpeg.org > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > To unsubscribe, visit link above, or email > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > -- > > Thanks, > > Limin Wang > > _______________________________________________ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, 19 Jul 2020, lance.lmwang@gmail.com wrote: > On Sat, Jul 18, 2020 at 08:38:16PM +0200, Marton Balint wrote: >> >> >> On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: >> >> > On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: >> > > >> > > >> > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: >> > > >> > > > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint wrote: >> > > > > > > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: >> > > > > > > > From: Limin Wang <lance.lmwang@gmail.com> >> > > > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag >> > > > > if the frame rate > 30FPS to >> > > > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames >> > > > > > and correctly calculate the frame number of the SEI TC. >> > > > > > > This feature looks like it belongs to >> > > av_timecode_get_smpte_from_framenum >> > > > > and not into decklink. Also checking previous timecode and guessing >> > > > > something is a hack, especially since you have the exact source timecode. >> > > > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be >> > > > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps >> > > > if you tested with SDI with TC. >> > > > 00:00:00:24 >> > > > 00:00:00:24 >> > > > 00:00:00:25 >> > > > 00:00:00:25 >> > > > 00:00:00:00 >> > > > 00:00:00:00 >> > > >> > > Have you actually tested this with a real SDI signal containing timecode? >> > >> > Yes, have tested with SDI playback by decklink UltraStudio 4K mini with TC enabled. >> >> I still don't understand how this works. Isn't timecode in the SDI signal >> also contain the so called "field bit" flag to support 50fps timecode? And >> if it does, then why can't you query it from decklink? Timecode in SDI >> signal is also supposed to be an SMPTE 12M timecode, so all the bits you >> need should be in it, you should not need to guess anything. Therefore it >> makes little sense to me that the DeckLink API does not provide a proper >> timecode as string, unless the original capture you made with your >> UltraStudio and which you played back also has a faulty timecode. >> What generated the signal which you captured with UltraStudio? Not ffmpeg I >> hope... > > It's auto-generated by configure of UltraStudio. You mean using XLR timecode input selection? I would not trust that with 50fps... > I have tested with bmdTimecodeFieldMark > flag, it's not set as expected for testing. I have no clue how to get the flag as the API > provide the TC string is same for the frame pair. Maybe I miss something. I'd try to generate SDI video with timecode by some other means. E.g. using MediaExpress / DaVinci Resolve and a native 1080p50 file. Regards, Marton > >> >> Regards, >> Marton >> >> >> > >> > > >> > > Thanks, >> > > Marton >> > > >> > > > > That's why I check the last TC to get the frame is even or odd. >> > > > > Why not use av_timecode_get_smpte_from_framenum(), for it's >> > > calculated by the string TC by one time, >> > > > so it lacks the information whether it's odd or even frame. >> > > > > > > > Regards, >> > > > > Marton >> > > > > > > > > --- >> > > > > > libavdevice/decklink_common.h | 1 + >> > > > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ >> > > > > > 2 files changed, 15 insertions(+) >> > > > > > > diff --git a/libavdevice/decklink_common.h >> > > > > b/libavdevice/decklink_common.h >> > > > > > index bd68c7b..8ddc411 100644 >> > > > > > --- a/libavdevice/decklink_common.h >> > > > > > +++ b/libavdevice/decklink_common.h >> > > > > > @@ -151,6 +151,7 @@ struct decklink_ctx { >> > > > > > int channels; >> > > > > > int audio_depth; >> > > > > > unsigned long tc_seen; // used with option wait_for_tc >> > > > > > + uint32_t last_tc; >> > > > > > }; >> > > > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} >> > > > > decklink_direction_t; >> > > > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >> > > > > > index dde68ff..a60c01b 100644 >> > > > > > --- a/libavdevice/decklink_dec.cpp >> > > > > > +++ b/libavdevice/decklink_dec.cpp >> > > > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >> > > > > > int metadata_len; >> > > > > > uint8_t* packed_metadata; >> > > > > > AVTimecode tcr; >> > > > > > + AVRational rate = ctx->video_st->r_frame_rate; >> > > > > > > if (av_timecode_init_from_string(&tcr, >> > > > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { >> > > > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); >> > > > > > int size = sizeof(uint32_t) * 4; >> > > > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); >> > > > > > > + /* set the field flag if frame rate >> > > > > > 30FPS */ >> > > > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ >> > > > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { >> > > > > > + /* Odd frame */ >> > > > > > + if (ctx->last_tc == tc_data) { >> > > > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) >> > > > > > + tc_data |= (1 << 7); >> > > > > > + else >> > > > > > + tc_data |= (1 << 23); >> > > > > > + } >> > > > > > + } >> > > > > > + ctx->last_tc = tc_data; >> > > > > > + >> > > > > > if (sd) { >> > > > > > *sd = 1; // one TC >> > > > > > *(sd + 1) = tc_data; // TC >> > > > > > -- > 2.9.4 >> > > > > > > _______________________________________________ >> > > > > > ffmpeg-devel mailing list >> > > > > > ffmpeg-devel@ffmpeg.org >> > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > To unsubscribe, visit link above, or email >> > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > _______________________________________________ >> > > > > ffmpeg-devel mailing list >> > > > > ffmpeg-devel@ffmpeg.org >> > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > To unsubscribe, visit link above, or email >> > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > -- > Thanks, >> > > > Limin Wang >> > > > _______________________________________________ >> > > > ffmpeg-devel mailing list >> > > > ffmpeg-devel@ffmpeg.org >> > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > To unsubscribe, visit link above, or email >> > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > _______________________________________________ >> > > ffmpeg-devel mailing list >> > > ffmpeg-devel@ffmpeg.org >> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > >> > > To unsubscribe, visit link above, or email >> > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > >> > -- >> > Thanks, >> > Limin Wang >> > _______________________________________________ >> > ffmpeg-devel mailing list >> > ffmpeg-devel@ffmpeg.org >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > >> > To unsubscribe, visit link above, or email >> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > -- > Thanks, > Limin Wang > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Sun, Jul 19, 2020 at 09:05:33AM +0200, Marton Balint wrote: > > > On Sun, 19 Jul 2020, lance.lmwang@gmail.com wrote: > > > On Sat, Jul 18, 2020 at 08:38:16PM +0200, Marton Balint wrote: > > > > > > > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: > > > > > > > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint > > > wrote: > > > > > > > > > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: > > > > > > > > > > From: Limin Wang <lance.lmwang@gmail.com> > > > > > > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag > > > > > > > if the frame rate > 30FPS to > > > > > > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames > > > > > > > > and correctly calculate the frame number of the SEI TC. > > > > > > > > > This feature looks like it belongs to > > > > > av_timecode_get_smpte_from_framenum > > > > > > > and not into decklink. Also checking previous timecode and guessing > > > > > > > something is a hack, especially since you have the exact source timecode. > > > > > > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be > > > > > > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps > > > > > > if you tested with SDI with TC. > > > > > > 00:00:00:24 > > > > > > 00:00:00:24 > > > > > > 00:00:00:25 > > > > > > 00:00:00:25 > > > > > > 00:00:00:00 > > > > > > 00:00:00:00 > > > > > > > Have you actually tested this with a real SDI signal > > > containing timecode? > > > > > Yes, have tested with SDI playback by decklink UltraStudio 4K > > > mini with TC enabled. > > > > > > I still don't understand how this works. Isn't timecode in the SDI signal > > > also contain the so called "field bit" flag to support 50fps timecode? And > > > if it does, then why can't you query it from decklink? Timecode in SDI > > > signal is also supposed to be an SMPTE 12M timecode, so all the bits you > > > need should be in it, you should not need to guess anything. Therefore it > > > makes little sense to me that the DeckLink API does not provide a proper > > > timecode as string, unless the original capture you made with your > > > UltraStudio and which you played back also has a faulty timecode. > > > What generated the signal which you captured with UltraStudio? Not ffmpeg I > > > hope... > > > > It's auto-generated by configure of UltraStudio. > > You mean using XLR timecode input selection? I would not trust that with > 50fps... I'm not sure it's XLR or not, it's configured by the menu. > > > I have tested with bmdTimecodeFieldMark > > flag, it's not set as expected for testing. I have no clue how to get > > the flag as the API provide the TC string is same for the frame pair. > > Maybe I miss something. > > I'd try to generate SDI video with timecode by some other means. E.g. using > MediaExpress / DaVinci Resolve and a native 1080p50 file. What's your tested result for the 1080p50 file? I haven't MediaExpress / DaVinci Resolve to generate the native 1080p50 file to try. > > Regards, > Marton > > > > > > > > > > Regards, > > > Marton > > > > > > > > > > > > > > Thanks, > > > > > Marton > > > > > > > > > That's why I check the last TC to get the frame is even > > > or odd. > > > > > > > Why not use av_timecode_get_smpte_from_framenum(), for it's > > > > > calculated by the string TC by one time, > > > > > > so it lacks the information whether it's odd or even frame. > > > > > > > > > > Regards, > > > > > > > Marton > > > > > > > > > > > --- > > > > > > > > libavdevice/decklink_common.h | 1 + > > > > > > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ > > > > > > > > 2 files changed, 15 insertions(+) > > > > > > > > > diff --git a/libavdevice/decklink_common.h > > > > > > > b/libavdevice/decklink_common.h > > > > > > > > index bd68c7b..8ddc411 100644 > > > > > > > > --- a/libavdevice/decklink_common.h > > > > > > > > +++ b/libavdevice/decklink_common.h > > > > > > > > @@ -151,6 +151,7 @@ struct decklink_ctx { > > > > > > > > int channels; > > > > > > > > int audio_depth; > > > > > > > > unsigned long tc_seen; // used with option wait_for_tc > > > > > > > > + uint32_t last_tc; > > > > > > > > }; > > > > > > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} > > > > > > > decklink_direction_t; > > > > > > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp > > > > > > > > index dde68ff..a60c01b 100644 > > > > > > > > --- a/libavdevice/decklink_dec.cpp > > > > > > > > +++ b/libavdevice/decklink_dec.cpp > > > > > > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( > > > > > > > > int metadata_len; > > > > > > > > uint8_t* packed_metadata; > > > > > > > > AVTimecode tcr; > > > > > > > > + AVRational rate = ctx->video_st->r_frame_rate; > > > > > > > > > if (av_timecode_init_from_string(&tcr, > > > > > > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { > > > > > > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); > > > > > > > > int size = sizeof(uint32_t) * 4; > > > > > > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); > > > > > > > > > + /* set the field flag if frame rate > > > > > > > > 30FPS */ > > > > > > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ > > > > > > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { > > > > > > > > + /* Odd frame */ > > > > > > > > + if (ctx->last_tc == tc_data) { > > > > > > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) > > > > > > > > + tc_data |= (1 << 7); > > > > > > > > + else > > > > > > > > + tc_data |= (1 << 23); > > > > > > > > + } > > > > > > > > + } > > > > > > > > + ctx->last_tc = tc_data; > > > > > > > > + > > > > > > > > if (sd) { > > > > > > > > *sd = 1; // one TC > > > > > > > > *(sd + 1) = tc_data; // TC > > > > > > > > -- > 2.9.4 > > > > > > > > > _______________________________________________ > > > > > > > > ffmpeg-devel mailing list > > > > > > > > ffmpeg-devel@ffmpeg.org > > > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > > > To unsubscribe, visit link above, or email > > > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > > > _______________________________________________ > > > > > > > ffmpeg-devel mailing list > > > > > > > ffmpeg-devel@ffmpeg.org > > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > > > To unsubscribe, visit link above, or email > > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > > > -- > Thanks, > > > > > > Limin Wang > > > > > > _______________________________________________ > > > > > > ffmpeg-devel mailing list > > > > > > ffmpeg-devel@ffmpeg.org > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > To unsubscribe, visit link above, or email > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > _______________________________________________ > > > > > ffmpeg-devel mailing list > > > > > ffmpeg-devel@ffmpeg.org > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > > To unsubscribe, visit link above, or email > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > > -- > Thanks, > > > > Limin Wang > > > > _______________________________________________ > > > > ffmpeg-devel mailing list > > > > ffmpeg-devel@ffmpeg.org > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > To unsubscribe, visit link above, or email > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > _______________________________________________ > > > ffmpeg-devel mailing list > > > ffmpeg-devel@ffmpeg.org > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > > > To unsubscribe, visit link above, or email > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > > -- > > Thanks, > > Limin Wang > > _______________________________________________ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Mon, 20 Jul 2020, lance.lmwang@gmail.com wrote: > On Sun, Jul 19, 2020 at 09:05:33AM +0200, Marton Balint wrote: >> >> >> On Sun, 19 Jul 2020, lance.lmwang@gmail.com wrote: >> >> > On Sat, Jul 18, 2020 at 08:38:16PM +0200, Marton Balint wrote: >> > > >> > > >> > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: >> > > >> > > > On Sat, Jul 18, 2020 at 09:44:03AM +0200, Marton Balint wrote: >> > > > > > > > > On Sat, 18 Jul 2020, lance.lmwang@gmail.com wrote: >> > > > > > > > On Fri, Jul 17, 2020 at 07:13:28PM +0200, Marton Balint >> > > wrote: >> > > > > > > > > > > On Fri, 17 Jul 2020, lance.lmwang@gmail.com wrote: >> > > > > > > > > > From: Limin Wang <lance.lmwang@gmail.com> >> > > > > > > > > In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag >> > > > > > > if the frame rate > 30FPS to >> > > > > > > > avoid interoperability issues. It will be used by the encoder to identify even or odd frames >> > > > > > > > and correctly calculate the frame number of the SEI TC. >> > > > > > > > > This feature looks like it belongs to >> > > > > av_timecode_get_smpte_from_framenum >> > > > > > > and not into decklink. Also checking previous timecode and guessing >> > > > > > > something is a hack, especially since you have the exact source timecode. >> > > > > > If I understand correctly, it's not hacky, for the framerate > 30, the source timecode will be >> > > > > > frame pair(it's limited by 2bits limit of frame number ten digital. Below is one exmaple for 50fps >> > > > > > if you tested with SDI with TC. >> > > > > > 00:00:00:24 >> > > > > > 00:00:00:24 >> > > > > > 00:00:00:25 >> > > > > > 00:00:00:25 >> > > > > > 00:00:00:00 >> > > > > > 00:00:00:00 >> > > > > > > Have you actually tested this with a real SDI signal >> > > containing timecode? >> > > > > Yes, have tested with SDI playback by decklink UltraStudio 4K >> > > mini with TC enabled. >> > > >> > > I still don't understand how this works. Isn't timecode in the SDI signal >> > > also contain the so called "field bit" flag to support 50fps timecode? And >> > > if it does, then why can't you query it from decklink? Timecode in SDI >> > > signal is also supposed to be an SMPTE 12M timecode, so all the bits you >> > > need should be in it, you should not need to guess anything. Therefore it >> > > makes little sense to me that the DeckLink API does not provide a proper >> > > timecode as string, unless the original capture you made with your >> > > UltraStudio and which you played back also has a faulty timecode. >> > > What generated the signal which you captured with UltraStudio? Not ffmpeg I >> > > hope... >> > >> > It's auto-generated by configure of UltraStudio. >> >> You mean using XLR timecode input selection? I would not trust that with >> 50fps... > > I'm not sure it's XLR or not, it's configured by the menu. > >> >> > I have tested with bmdTimecodeFieldMark >> > flag, it's not set as expected for testing. I have no clue how to get >> > the flag as the API provide the TC string is same for the frame pair. >> > Maybe I miss something. >> >> I'd try to generate SDI video with timecode by some other means. E.g. using >> MediaExpress / DaVinci Resolve and a native 1080p50 file. > > What's your tested result for the 1080p50 file? I haven't MediaExpress / DaVinci Resolve > to generate the native 1080p50 file to try. I have not tested anything, all I am saying is that I find that highly unlikely that decklink API cannot detect a 50fps timecode properly in the SDI signal, so I suspect that your tests are somehow flawed, and you should try testing by some other means. I can do tests next week if you don't figure it out until then. Regards, Marton > > >> >> Regards, >> Marton >> >> >> > >> > > >> > > Regards, >> > > Marton >> > > >> > > >> > > > > > > > Thanks, >> > > > > Marton >> > > > > > > > > That's why I check the last TC to get the frame is even >> > > or odd. >> > > > > > > Why not use av_timecode_get_smpte_from_framenum(), for it's >> > > > > calculated by the string TC by one time, >> > > > > > so it lacks the information whether it's odd or even frame. >> > > > > > > > > > Regards, >> > > > > > > Marton >> > > > > > > > > > > --- >> > > > > > > > libavdevice/decklink_common.h | 1 + >> > > > > > > > libavdevice/decklink_dec.cpp | 14 ++++++++++++++ >> > > > > > > > 2 files changed, 15 insertions(+) >> > > > > > > > > diff --git a/libavdevice/decklink_common.h >> > > > > > > b/libavdevice/decklink_common.h >> > > > > > > > index bd68c7b..8ddc411 100644 >> > > > > > > > --- a/libavdevice/decklink_common.h >> > > > > > > > +++ b/libavdevice/decklink_common.h >> > > > > > > > @@ -151,6 +151,7 @@ struct decklink_ctx { >> > > > > > > > int channels; >> > > > > > > > int audio_depth; >> > > > > > > > unsigned long tc_seen; // used with option wait_for_tc >> > > > > > > > + uint32_t last_tc; >> > > > > > > > }; >> > > > > > > > > typedef enum { DIRECTION_IN, DIRECTION_OUT} >> > > > > > > decklink_direction_t; >> > > > > > > > diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp >> > > > > > > > index dde68ff..a60c01b 100644 >> > > > > > > > --- a/libavdevice/decklink_dec.cpp >> > > > > > > > +++ b/libavdevice/decklink_dec.cpp >> > > > > > > > @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( >> > > > > > > > int metadata_len; >> > > > > > > > uint8_t* packed_metadata; >> > > > > > > > AVTimecode tcr; >> > > > > > > > + AVRational rate = ctx->video_st->r_frame_rate; >> > > > > > > > > if (av_timecode_init_from_string(&tcr, >> > > > > > > ctx->video_st->r_frame_rate, tc, ctx) >= 0) { >> > > > > > > > uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); >> > > > > > > > int size = sizeof(uint32_t) * 4; >> > > > > > > > uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); >> > > > > > > > > + /* set the field flag if frame rate >> > > > > > > > 30FPS */ >> > > > > > > > + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ >> > > > > > > > + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { >> > > > > > > > + /* Odd frame */ >> > > > > > > > + if (ctx->last_tc == tc_data) { >> > > > > > > > + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) >> > > > > > > > + tc_data |= (1 << 7); >> > > > > > > > + else >> > > > > > > > + tc_data |= (1 << 23); >> > > > > > > > + } >> > > > > > > > + } >> > > > > > > > + ctx->last_tc = tc_data; >> > > > > > > > + >> > > > > > > > if (sd) { >> > > > > > > > *sd = 1; // one TC >> > > > > > > > *(sd + 1) = tc_data; // TC >> > > > > > > > -- > 2.9.4 >> > > > > > > > > _______________________________________________ >> > > > > > > > ffmpeg-devel mailing list >> > > > > > > > ffmpeg-devel@ffmpeg.org >> > > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > > > To unsubscribe, visit link above, or email >> > > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > > > _______________________________________________ >> > > > > > > ffmpeg-devel mailing list >> > > > > > > ffmpeg-devel@ffmpeg.org >> > > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > > > To unsubscribe, visit link above, or email >> > > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > > > -- > Thanks, >> > > > > > Limin Wang >> > > > > > _______________________________________________ >> > > > > > ffmpeg-devel mailing list >> > > > > > ffmpeg-devel@ffmpeg.org >> > > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > To unsubscribe, visit link above, or email >> > > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > _______________________________________________ >> > > > > ffmpeg-devel mailing list >> > > > > ffmpeg-devel@ffmpeg.org >> > > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > > > To unsubscribe, visit link above, or email >> > > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > > > -- > Thanks, >> > > > Limin Wang >> > > > _______________________________________________ >> > > > ffmpeg-devel mailing list >> > > > ffmpeg-devel@ffmpeg.org >> > > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > > > To unsubscribe, visit link above, or email >> > > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > > _______________________________________________ >> > > ffmpeg-devel mailing list >> > > ffmpeg-devel@ffmpeg.org >> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > >> > > To unsubscribe, visit link above, or email >> > > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> > >> > -- >> > Thanks, >> > Limin Wang >> > _______________________________________________ >> > ffmpeg-devel mailing list >> > ffmpeg-devel@ffmpeg.org >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > >> > To unsubscribe, visit link above, or email >> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > -- > Thanks, > Limin Wang > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
On Mon, 20 Jul 2020, Marton Balint wrote: > > This feature looks like it belongs to > av_timecode_get_smpte_from_framenum and not into decklink. I just sent a patch which implements this, because I confirmed that other code using av_timecode_get_smpte_from_framenum also seem to require the special handling for 50/60fps which you already implemented in av_timecode_get_smpte. Regards, Marton
>>> > > > > > if you tested with SDI with TC. >>> > > > > > 00:00:00:24 >>> > > > > > 00:00:00:24 >>> > > > > > 00:00:00:00 >>> > > > > > 00:00:00:00 I did tests, and depending on which timecode you select, and the timecode formats which are available in the SDI signal, this really can be the case, so you were right that the decklink API usually does not provide the proper timecode as string, only the value of "raw" timecodes in the signal, regardless of used frame rate. I could not test, but assume that if a high frame rate timecode is detected then valid string timecode is returned. Otherwise max 30fps timecode. >>> > I have tested with bmdTimecodeFieldMark >>> > flag, it's not set as expected for testing. I have no clue how to get >>> > the flag as the API provide the TC string is same for the frame pair. >>> > Maybe I miss something. SMPTE ST 12-2 has a good overview of the used signalling in section 7. Basically for 50/60 fps different timecode types (VITC1, VITC2) are used for different parity frames. We have to be smart here to generate proper timecode, because the decklink API does not tell you which timecode it had found for an rp188any query... I suggest the following: - If the user selects high frame rate timecode (not available as an option at the moment, but can be added), then use that directly. - If the user selects rp188any then - Query high frame rate timecode, if exists use that directly. - Otherwise - for <= 30fps query rp188any and use that directly - for > 30fps - query VITC1, if exists use that with frame doubling and field flag checking - otherwise query VITC2, if exists use that with frame doubling and field flag checking - otherwise query LTC, if exists use that with frame doubling and field flag checking - note that this special ordering of querying the timecode types is slightly different from what the decklink API does and it should be mentioned in the docs. - Otherwise - for <= 30fps query the selected timecode and use that directly - for > 30fps query the selected timecode and use that with frame doubling and field flag checking Also probably it is better to use IDeckLinkTimecode->GetComponents() and use av_timecode_get_smpte() instead of using the string value. Regards, Marton
On Wed, Jul 29, 2020 at 10:16:33PM +0200, Marton Balint wrote: > > > > > > > > > > > if you tested with SDI with TC. > > > > > > > > > 00:00:00:24 > > > > > > > > > 00:00:00:24 > > > > > > > > > 00:00:00:00 > > > > > > > > > 00:00:00:00 > > I did tests, and depending on which timecode you select, and the timecode > formats which are available in the SDI signal, this really can be the case, > so you were right that the decklink API usually does not provide the proper > timecode as string, only the value of "raw" timecodes in the signal, > regardless of used frame rate. > > I could not test, but assume that if a high frame rate timecode is detected > then valid string timecode is returned. Otherwise max 30fps timecode. > > > > > > I have tested with bmdTimecodeFieldMark > > > > > flag, it's not set as expected for testing. I have no clue how to get > > > > > the flag as the API provide the TC string is same for the frame pair. > > > > > Maybe I miss something. > > SMPTE ST 12-2 has a good overview of the used signalling in section 7. > Basically for 50/60 fps different timecode types (VITC1, VITC2) are used for > different parity frames. > > We have to be smart here to generate proper timecode, because the decklink > API does not tell you which timecode it had found for an rp188any query... I > suggest the following: > > - If the user selects high frame rate timecode (not available as an > option at the moment, but can be added), then use that directly. > - If the user selects rp188any then > - Query high frame rate timecode, if exists use that directly. > - Otherwise > - for <= 30fps query rp188any and use that directly > - for > 30fps > - query VITC1, if exists use that with frame doubling and field flag > checking > - otherwise query VITC2, if exists use that with frame doubling > and field flag checking > - otherwise query LTC, if exists use that with frame doubling and > field flag checking > - note that this special ordering of querying the timecode types > is slightly different from what the decklink API does and it > should be mentioned in the docs. > - Otherwise > - for <= 30fps query the selected timecode and use that directly > - for > 30fps query the selected timecode and use that with frame > doubling and field flag checking The suggestion is very clear, I lacks the different TC test signal so I can't try to implement and test it yet. > > Also probably it is better to use IDeckLinkTimecode->GetComponents() and use > av_timecode_get_smpte() instead of using the string value. Yes, the TC format is rp188any when I test, I recall I have try to get by GetComponents, the result is consistent with string() before, I'll try to retest again if I test signal is avaiable. > > Regards, > Marton > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index bd68c7b..8ddc411 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -151,6 +151,7 @@ struct decklink_ctx { int channels; int audio_depth; unsigned long tc_seen; // used with option wait_for_tc + uint32_t last_tc; }; typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index dde68ff..a60c01b 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -884,12 +884,26 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( int metadata_len; uint8_t* packed_metadata; AVTimecode tcr; + AVRational rate = ctx->video_st->r_frame_rate; if (av_timecode_init_from_string(&tcr, ctx->video_st->r_frame_rate, tc, ctx) >= 0) { uint32_t tc_data = av_timecode_get_smpte_from_framenum(&tcr, 0); int size = sizeof(uint32_t) * 4; uint32_t *sd = (uint32_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size); + /* set the field flag if frame rate > 30FPS */ + /* Refer to SMPTE ST 12-1:2014 Sec 12.2 */ + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + /* Odd frame */ + if (ctx->last_tc == tc_data) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + tc_data |= (1 << 7); + else + tc_data |= (1 << 23); + } + } + ctx->last_tc = tc_data; + if (sd) { *sd = 1; // one TC *(sd + 1) = tc_data; // TC
From: Limin Wang <lance.lmwang@gmail.com> In SMPTE ST 12-1: 2014 Sec 12.2, we need to mark the frame flag if the frame rate > 30FPS to avoid interoperability issues. It will be used by the encoder to identify even or odd frames and correctly calculate the frame number of the SEI TC. --- libavdevice/decklink_common.h | 1 + libavdevice/decklink_dec.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+)