]> git.sesse.net Git - ffmpeg/blobdiff - libavdevice/decklink_dec.cpp
avdevice/decklink_dec: map the raw_format instead of hardcode
[ffmpeg] / libavdevice / decklink_dec.cpp
index a499972df8ff92fe8c6905ad26557735816d1991..049e1335b63a1225cfce1af07997b805545fd377 100644 (file)
@@ -42,6 +42,7 @@ extern "C" {
 #include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/time.h"
+#include "libavutil/timecode.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/reverse.h"
 #include "avdevice.h"
@@ -882,6 +883,19 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                         AVDictionary* metadata_dict = NULL;
                         int metadata_len;
                         uint8_t* packed_metadata;
+                        AVTimecode tcr;
+
+                        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);
+
+                            if (sd) {
+                                *sd       = 1;       // one TC
+                                *(sd + 1) = tc_data; // TC
+                            }
+                        }
+
                         if (av_dict_set(&metadata_dict, "timecode", tc, AV_DICT_DONT_STRDUP_VAL) >= 0) {
                             packed_metadata = av_packet_pack_dictionary(metadata_dict, &metadata_len);
                             av_dict_free(&metadata_dict);
@@ -1030,9 +1044,13 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
 
 HRESULT decklink_input_callback::VideoInputFormatChanged(
     BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
-    BMDDetectedVideoInputFormatFlags)
+    BMDDetectedVideoInputFormatFlags formatFlags)
 {
+    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
     ctx->bmd_mode = mode->GetDisplayMode();
+    // check the C context member to make sure we set both raw_format and bmd_mode with data from the same format change callback
+    if (!cctx->raw_format)
+        ctx->raw_format = (formatFlags & bmdDetectedVideoInputRGB444) ? bmdFormat8BitARGB : bmdFormat8BitYUV;
     return S_OK;
 }
 
@@ -1134,6 +1152,8 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     ctx->video_pts_source = cctx->video_pts_source;
     ctx->draw_bars = cctx->draw_bars;
     ctx->audio_depth = cctx->audio_depth;
+    if (cctx->raw_format > 0 && (unsigned int)cctx->raw_format < FF_ARRAY_ELEMS(decklink_raw_format_map))
+        ctx->raw_format = decklink_raw_format_map[cctx->raw_format];
     cctx->ctx = ctx;
 
     /* Check audio channel option for valid values: 2, 8 or 16 */
@@ -1213,6 +1233,8 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         }
         av_log(avctx, AV_LOG_INFO, "Autodetected the input mode\n");
     }
+    if (ctx->raw_format == (BMDPixelFormat)0)
+        ctx->raw_format = bmdFormat8BitYUV;
     if (ff_decklink_set_format(avctx, DIRECTION_IN) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not set format code %s for %s\n",
             cctx->format_code ? cctx->format_code : "(unset)", avctx->url);
@@ -1256,7 +1278,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     st->time_base.num      = ctx->bmd_tb_num;
     st->r_frame_rate       = av_make_q(st->time_base.den, st->time_base.num);
 
-    switch((BMDPixelFormat)cctx->raw_format) {
+    switch(ctx->raw_format) {
     case bmdFormat8BitYUV:
         st->codecpar->codec_id    = AV_CODEC_ID_RAWVIDEO;
         st->codecpar->codec_tag   = MKTAG('U', 'Y', 'V', 'Y');
@@ -1289,7 +1311,9 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         st->codecpar->bits_per_coded_sample = 10;
         break;
     default:
-        av_log(avctx, AV_LOG_ERROR, "Raw Format %.4s not supported\n", (char*) &cctx->raw_format);
+        char fourcc_str[AV_FOURCC_MAX_STRING_SIZE] = {0};
+        av_fourcc_make_string(fourcc_str, ctx->raw_format);
+        av_log(avctx, AV_LOG_ERROR, "Raw Format %s not supported\n", fourcc_str);
         ret = AVERROR(EINVAL);
         goto error;
     }
@@ -1350,7 +1374,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
     }
 
     result = ctx->dli->EnableVideoInput(ctx->bmd_mode,
-                                        (BMDPixelFormat) cctx->raw_format,
+                                        ctx->raw_format,
                                         bmdVideoInputFlagDefault);
 
     if (result != S_OK) {