> On May 25, 2018, at 8:32 AM, Marton Balint <[email protected]> wrote:
>
>
>
> On Fri, 25 May 2018, Jonathan Morley wrote:
>
>> I apologize in advance for the formatting of this message. My mail
>> configuration impeded my efforts to use ‘—send-email’.
>
> Your mail is corrupted by new lines, attach the .patch file if you cannot
> resolve this.
Will do! Sorry about that. The mail server’s auth setup kept me from using
‘—send-email’ directly. I will send future patches as attachments.
>>
>> This commit did pass 'make fate’ though the use of these changes requires
>> decklink hardware so I did not add any new fate tests. By default the new
>> optional behavior is skipped for old behavior.
>>
>> ---
>> libavdevice/decklink_common.cpp | 30 -----------------------------
>> libavdevice/decklink_common.h | 42 ++++++++++++++++++++++++++++++
>> +++++++++++
>
> Why is this huge chunk of function movement needed? If there is a good reason
> to do that, then split it into a separate patch, if there is not, then just
> get rid of it.
The move here was so that I could make use of the cross platform safe DECKLINK
string methods. I was only able to test with linux and build on mac, but I
wanted to do my best to make a contribution that _could_ work on all platforms.
I can break this into two patches if you prefer.
>> libavdevice/decklink_common_c.h | 1 +
>> libavdevice/decklink_dec.cpp | 19 +++++++++++++++++++
>> libavdevice/decklink_dec_c.c | 9 +++++++++
>> 5 files changed, 71 insertions(+), 30 deletions(-)
>>
>> diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.
>> cpp
>> index d8cced7c74..aab9d85b94 100644
>> --- a/libavdevice/decklink_common.cpp
>> +++ b/libavdevice/decklink_common.cpp
>> @@ -77,36 +77,6 @@ static IDeckLinkIterator
>> *decklink_create_iterator(AVFormatContext
>> *avctx)
>> return iter;
>> }
>>
>> -#ifdef _WIN32
>> -static char *dup_wchar_to_utf8(wchar_t *w)
>> -{
>> - char *s = NULL;
>> - int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
>> - s = (char *) av_malloc(l);
>> - if (s)
>> - WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
>> - return s;
>> -}
>> -#define DECKLINK_STR OLECHAR *
>> -#define DECKLINK_STRDUP dup_wchar_to_utf8
>> -#define DECKLINK_FREE(s) SysFreeString(s)
>> -#elif defined(__APPLE__)
>> -static char *dup_cfstring_to_utf8(CFStringRef w)
>> -{
>> - char s[256];
>> - CFStringGetCString(w, s, 255, kCFStringEncodingUTF8);
>> - return av_strdup(s);
>> -}
>> -#define DECKLINK_STR const __CFString *
>> -#define DECKLINK_STRDUP dup_cfstring_to_utf8
>> -#define DECKLINK_FREE(s) CFRelease(s)
>> -#else
>> -#define DECKLINK_STR const char *
>> -#define DECKLINK_STRDUP av_strdup
>> -/* free() is needed for a string returned by the DeckLink SDL. */
>> -#define DECKLINK_FREE(s) free((void *) s)
>> -#endif
>> -
>> HRESULT ff_decklink_get_display_name(IDeckLink *This, const char
>> **displayName)
>> {
>> DECKLINK_STR tmpDisplayName;
>> diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
>> index 57ee7d1d68..8c5f8e9f06 100644
>> --- a/libavdevice/decklink_common.h
>> +++ b/libavdevice/decklink_common.h
>> @@ -34,6 +34,36 @@
>> #define DECKLINK_BOOL bool
>> #endif
>>
>> +#ifdef _WIN32
>> +static char *dup_wchar_to_utf8(wchar_t *w)
>> +{
>> + char *s = NULL;
>> + int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
>> + s = (char *) av_malloc(l);
>> + if (s)
>> + WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
>> + return s;
>> +}
>> +#define DECKLINK_STR OLECHAR *
>> +#define DECKLINK_STRDUP dup_wchar_to_utf8
>> +#define DECKLINK_FREE(s) SysFreeString(s)
>> +#elif defined(__APPLE__)
>> +static char *dup_cfstring_to_utf8(CFStringRef w)
>> +{
>> + char s[256];
>> + CFStringGetCString(w, s, 255, kCFStringEncodingUTF8);
>> + return av_strdup(s);
>> +}
>> +#define DECKLINK_STR const __CFString *
>> +#define DECKLINK_STRDUP dup_cfstring_to_utf8
>> +#define DECKLINK_FREE(s) CFRelease(s)
>> +#else
>> +#define DECKLINK_STR const char *
>> +#define DECKLINK_STRDUP av_strdup
>> +/* free() is needed for a string returned by the DeckLink SDL. */
>> +#define DECKLINK_FREE(s) free((void *) s)
>> +#endif
>> +
>> class decklink_output_callback;
>> class decklink_input_callback;
>>
>> @@ -64,6 +94,7 @@ struct decklink_ctx {
>> BMDDisplayMode bmd_mode;
>> BMDVideoConnection video_input;
>> BMDAudioConnection audio_input;
>> + BMDTimecodeFormat tc_format;
>> int bmd_width;
>> int bmd_height;
>> int bmd_field_dominance;
>> @@ -140,6 +171,17 @@ static const BMDVideoConnection
>> decklink_video_connection_map[] = {
>> bmdVideoConnectionSVideo,
>> };
>>
>> +static const BMDTimecodeFormat decklink_timecode_format_map[] = {
>> + (BMDTimecodeFormat)0,
>> + bmdTimecodeRP188VITC1,
>> + bmdTimecodeRP188VITC2,
>> + bmdTimecodeRP188LTC,
>> + bmdTimecodeRP188Any,
>> + bmdTimecodeVITC,
>> + bmdTimecodeVITCField2,
>> + bmdTimecodeSerial,
>> +};
>> +
>> HRESULT ff_decklink_get_display_name(IDeckLink *This, const char
>> **displayName);
>> int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t
>> direction);
>> int ff_decklink_set_format(AVFormatContext *avctx, int width, int height,
>> int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t
>> direction = DIRECTION_OUT, int num = 0);
>> diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_
>> c.h
>> index 08e9f9bbd5..32a5d70ee1 100644
>> --- a/libavdevice/decklink_common_c.h
>> +++ b/libavdevice/decklink_common_c.h
>> @@ -50,6 +50,7 @@ struct decklink_cctx {
>> DecklinkPtsSource video_pts_source;
>> int audio_input;
>> int video_input;
>> + int tc_format;
>> int draw_bars;
>> char *format_code;
>> int raw_format;
>> diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
>> index 510637676c..818235bfa6 100644
>> --- a/libavdevice/decklink_dec.cpp
>> +++ b/libavdevice/decklink_dec.cpp
>> @@ -726,6 +726,23 @@ HRESULT decklink_input_callback::
>> VideoInputFrameArrived(
>> no_video = 0;
>> }
>>
>> + // Handle Timecode (if requested)
>> + if (ctx->tc_format && !(av_dict_get(ctx->video_st->metadata,
>> "timecode", NULL, 0)) && !no_video) {
>> + IDeckLinkTimecode *timecode;
>> + if (videoFrame->GetTimecode(ctx->tc_format, &timecode) ==
>> S_OK) {
>> + DECKLINK_STR timecodeString = NULL;
>> + timecode->GetString(&timecodeString);
>> + const char* tc = DECKLINK_STRDUP(timecodeString);
>> + if (!(av_dict_set(&ctx->video_st->metadata, "timecode",
>> tc, 0)))
>
> Don't you need AV_DICT_DONT_STRDUP_VAL flag here?
Yes. I agree.
>> + av_log(avctx, AV_LOG_ERROR, "Unable to set
>> timecode\n");
>> + if (timecodeString)
>> + DECKLINK_FREE(timecodeString);
>> + timecode->Release();
>> + } else {
>> + av_log(avctx, AV_LOG_ERROR, "Unable to find timecode.\n");
>> + }
>> + }
>
> Maybe it makes sense to put this under the else branch of if
> (videoFrame->GetFlags() & bmdFrameHasNoInputSource), because if you have no
> input, you won't have any (valid) timecode…
I can move this. The logic still checks for !no_video, but moving it should be
more explicit.
Sadly I no longer have access to the hardware I used when making these changes
and cannot test this kind of change. We have moved on to a video-for-linux
based solution with AJA hardware. (I am currently adding support for TC to the
v4l2 ffmpeg reader).
>> +
>> pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock,
>> abs_wallclock, ctx->video_pts_source, ctx->video_st->time_base,
>> &initial_video_pts, cctx->copyts);
>> pkt.dts = pkt.pts;
>>
>> @@ -939,6 +956,8 @@ av_cold int ff_decklink_read_header(AVFormatContext
>> *avctx)
>> ctx->teletext_lines = cctx->teletext_lines;
>> ctx->preroll = cctx->preroll;
>> ctx->duplex_mode = cctx->duplex_mode;
>> + if (cctx->tc_format > 0 && (unsigned int)cctx->tc_format <
>> FF_ARRAY_ELEMS(decklink_timecode_format_map))
>> + ctx->tc_format = decklink_timecode_format_map[cctx->tc_format];
>> if (cctx->video_input > 0 && (unsigned int)cctx->video_input <
>> FF_ARRAY_ELEMS(decklink_video_connection_map))
>> ctx->video_input = decklink_video_connection_map[cctx->video_input];
>> if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input <
>> FF_ARRAY_ELEMS(decklink_audio_connection_map))
>> diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
>> index 47018dc681..6ab3819375 100644
>> --- a/libavdevice/decklink_dec_c.c
>> +++ b/libavdevice/decklink_dec_c.c
>> @@ -48,6 +48,15 @@ static const AVOption options[] = {
>> { "unset", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"},
>> { "half", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"},
>> { "full", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "duplex_mode"},
>> + { "timecode_format", "timecode format", OFFSET(tc_format),
>> AV_OPT_TYPE_INT, { .i64 = 0}, 0, 7, DEC, "tc_format"},
>> + { "none", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "tc_format"},
>> + { "rp188vitc", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "tc_format"},
>> + { "rp188vitc2", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "tc_format"},
>> + { "rp188ltc", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0, DEC, "tc_format"},
>> + { "rp188any", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0, DEC, "tc_format"},
>> + { "vitc", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0, DEC, "tc_format"},
>> + { "vitc2", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0, DEC, "tc_format"},
>> + { "serial", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 7}, 0, 0, DEC, "tc_format"},
>> { "video_input", "video input", OFFSET(video_input),
>> AV_OPT_TYPE_INT, { .i64 = 0}, 0, 6, DEC, "video_input"},
>> { "unset", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "video_input"},
>> { "sdi", NULL, 0,
>> AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "video_input"},
>> --
>
> Documentation update is missing.
D’oh! Sloppy.
> Regards,
> Marton
> _______________________________________________
> ffmpeg-devel mailing list
> [email protected] <mailto:[email protected]>
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> <http://ffmpeg.org/mailman/listinfo/ffmpeg-devel>
Please have a look at my comments above and let me know about splitting this
into two patches and I will resubmit as attachments.
Thank you for taking a look!
_______________________________________________
ffmpeg-devel mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel