avdevice/decklink: new option 'format_code' to set video format by fourCC
[ffmpeg.git] / libavdevice / decklink_dec.cpp
index fc81d4d..ffe65db 100644 (file)
@@ -206,8 +206,9 @@ private:
 decklink_input_callback::decklink_input_callback(AVFormatContext *_avctx) : m_refCount(0)
 {
     avctx = _avctx;
-    decklink_cctx       *cctx = (struct decklink_cctx *) avctx->priv_data;
-    ctx = (struct decklink_ctx *) cctx->ctx;
+    decklink_cctx       *cctx = (struct decklink_cctx *)avctx->priv_data;
+    ctx = (struct decklink_ctx *)cctx->ctx;
+    no_video = 0;
     initial_audio_pts = initial_video_pts = AV_NOPTS_VALUE;
     pthread_mutex_init(&m_mutex, NULL);
 }
@@ -309,18 +310,18 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                                   ctx->video_st->time_base.den);
 
         if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
-            if (videoFrame->GetPixelFormat() == bmdFormat8BitYUV) {
-            unsigned bars[8] = {
-                0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
-                0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
-            int width  = videoFrame->GetWidth();
-            int height = videoFrame->GetHeight();
-            unsigned *p = (unsigned *)frameBytes;
-
-            for (int y = 0; y < height; y++) {
-                for (int x = 0; x < width; x += 2)
-                    *p++ = bars[(x * 8) / width];
-            }
+            if (ctx->draw_bars && videoFrame->GetPixelFormat() == bmdFormat8BitYUV) {
+                unsigned bars[8] = {
+                    0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
+                    0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
+                int width  = videoFrame->GetWidth();
+                int height = videoFrame->GetHeight();
+                unsigned *p = (unsigned *)frameBytes;
+
+                for (int y = 0; y < height; y++) {
+                    for (int x = 0; x < width; x += 2)
+                        *p++ = bars[(x * 8) / width];
+                }
             }
 
             if (!no_video) {
@@ -431,8 +432,8 @@ HRESULT decklink_input_callback::VideoInputFormatChanged(
 
 static HRESULT decklink_start_input(AVFormatContext *avctx)
 {
-    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
-    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
+    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
 
     ctx->input_callback = new decklink_input_callback(avctx);
     ctx->dli->SetCallback(ctx->input_callback);
@@ -443,8 +444,8 @@ extern "C" {
 
 av_cold int ff_decklink_read_close(AVFormatContext *avctx)
 {
-    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
-    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
+    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
 
     if (ctx->capture_started) {
         ctx->dli->StopStreams();
@@ -462,7 +463,7 @@ av_cold int ff_decklink_read_close(AVFormatContext *avctx)
 
 av_cold int ff_decklink_read_header(AVFormatContext *avctx)
 {
-    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
     struct decklink_ctx *ctx;
     AVStream *st;
     HRESULT result;
@@ -485,6 +486,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         ctx->audio_input = decklink_audio_connection_map[cctx->audio_input];
     ctx->audio_pts_source = cctx->audio_pts_source;
     ctx->video_pts_source = cctx->video_pts_source;
+    ctx->draw_bars = cctx->draw_bars;
     cctx->ctx = ctx;
 
 #if !CONFIG_LIBZVBI
@@ -537,9 +539,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
         goto error;
     }
 
-    if (mode_num > 0) {
+    if (mode_num > 0 || cctx->format_code) {
         if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname);
+            av_log(avctx, AV_LOG_ERROR, "Could not set mode number %d or format code %s for %s\n",
+                mode_num, (cctx->format_code) ? cctx->format_code : "(unset)", fname);
             ret = AVERROR(EIO);
             goto error;
         }
@@ -571,6 +574,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
 
     st->time_base.den      = ctx->bmd_tb_den;
     st->time_base.num      = ctx->bmd_tb_num;
+    av_stream_set_r_frame_rate(st, av_make_q(st->time_base.den, st->time_base.num));
 
     if (cctx->v210) {
         st->codecpar->codec_id    = AV_CODEC_ID_V210;
@@ -638,8 +642,8 @@ error:
 
 int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt)
 {
-    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
-    struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
+    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
     AVFrame *frame = ctx->video_st->codec->coded_frame;
 
     avpacket_queue_get(&ctx->queue, pkt, 1);