If the user provides a valid timecode_format look for timecode of that format in the capture and if found store it on the video avstream's metadata. Slightly modified by Marton Balint to capture per-frame timecode as well.
Showing the changes to libavdevice/decklink_dec.cpp (1 of 6 files). Show all
Unified · Split
| @@ -752,6 +752,35 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( · 751 unmodified lines | |||
| 752 | "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped); | 752 | "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped); |
| 753 | } | 753 | } |
| 754 | no_video = 0; | 754 | no_video = 0; |
| 755 | |||
| 756 | // Handle Timecode (if requested) | ||
| 757 | if (ctx->tc_format) { | ||
| 758 | IDeckLinkTimecode *timecode; | ||
| 759 | if (videoFrame->GetTimecode(ctx->tc_format, &timecode) == S_OK) { | ||
| 760 | const char *tc = NULL; | ||
| 761 | DECKLINK_STR decklink_tc; | ||
| 762 | if (timecode->GetString(&decklink_tc) == S_OK) { | ||
| 763 | tc = DECKLINK_STRDUP(decklink_tc); | ||
| 764 | DECKLINK_FREE(decklink_tc); | ||
| 765 | } | ||
| 766 | timecode->Release(); | ||
| 767 | if (tc) { | ||
| 768 | AVDictionary* metadata_dict = NULL; | ||
| 769 | int metadata_len; | ||
| 770 | uint8_t* packed_metadata; | ||
| 771 | if (av_dict_set(&metadata_dict, "timecode", tc, AV_DICT_DONT_STRDUP_VAL) >= 0) { | ||
| 772 | packed_metadata = av_packet_pack_dictionary(metadata_dict, &metadata_len); | ||
| 773 | av_dict_free(&metadata_dict); | ||
| 774 | if (packed_metadata) { | ||
| 775 | if (av_packet_add_side_data(&pkt, AV_PKT_DATA_STRINGS_METADATA, packed_metadata, metadata_len) < 0) | ||
| 776 | av_freep(&packed_metadata); | ||
| 777 | } | ||
| 778 | } | ||
| 779 | } | ||
| 780 | } else { | ||
| 781 | av_log(avctx, AV_LOG_DEBUG, "Unable to find timecode.\n"); | ||
| 782 | } | ||
| 783 | } | ||
| 755 | } | 784 | } |
| 756 | 785 | ||
| 757 | pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, abs_wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts, cctx->copyts); | 786 | pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, abs_wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts, cctx->copyts); |
| @@ -969,6 +998,8 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) · 211 unmodified lines | |||
| 969 | ctx->teletext_lines = cctx->teletext_lines; | 998 | ctx->teletext_lines = cctx->teletext_lines; |
| 970 | ctx->preroll = cctx->preroll; | 999 | ctx->preroll = cctx->preroll; |
| 971 | ctx->duplex_mode = cctx->duplex_mode; | 1000 | ctx->duplex_mode = cctx->duplex_mode; |
| 1001 | if (cctx->tc_format > 0 && (unsigned int)cctx->tc_format < FF_ARRAY_ELEMS(decklink_timecode_format_map)) | ||
| 1002 | ctx->tc_format = decklink_timecode_format_map[cctx->tc_format]; | ||
| 972 | if (cctx->video_input > 0 && (unsigned int)cctx->video_input < FF_ARRAY_ELEMS(decklink_video_connection_map)) | 1003 | if (cctx->video_input > 0 && (unsigned int)cctx->video_input < FF_ARRAY_ELEMS(decklink_video_connection_map)) |
| 973 | ctx->video_input = decklink_video_connection_map[cctx->video_input]; | 1004 | ctx->video_input = decklink_video_connection_map[cctx->video_input]; |
| 974 | if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input < FF_ARRAY_ELEMS(decklink_audio_connection_map)) | 1005 | if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input < FF_ARRAY_ELEMS(decklink_audio_connection_map)) |
| @@ -1222,6 +1253,15 @@ int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt) · 247 unmodified lines | |||
| 1222 | 1253 | ||
| 1223 | avpacket_queue_get(&ctx->queue, pkt, 1); | 1254 | avpacket_queue_get(&ctx->queue, pkt, 1); |
| 1224 | 1255 | ||
| 1256 | if (ctx->tc_format && !(av_dict_get(ctx->video_st->metadata, "timecode", NULL, 0))) { | ||
| 1257 | int size; | ||
| 1258 | const uint8_t *side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size); | ||
| 1259 | if (side_metadata) { | ||
| 1260 | if (av_packet_unpack_dictionary(side_metadata, size, &ctx->video_st->metadata) < 0) | ||
| 1261 | av_log(avctx, AV_LOG_ERROR, "Unable to set timecode\n"); | ||
| 1262 | } | ||
| 1263 | } | ||
| 1264 | |||
| 1225 | return 0; | 1265 | return 0; |
| 1226 | } | 1266 | } |
| 1227 | 1267 | ||