diff mbox series

[FFmpeg-devel] avcodec/libdav1d: add support for closed captions stored in ITU-T T35 metadata

Message ID 20200602235043.3789-1-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel] avcodec/libdav1d: add support for closed captions stored in ITU-T T35 metadata
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

James Almer June 2, 2020, 11:50 p.m. UTC
Based on code from h264_sei.c

Signed-off-by: James Almer <jamrial@gmail.com>
---
 configure             |  2 +-
 libavcodec/libdav1d.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

Comments

Marton Balint June 3, 2020, 8:47 p.m. UTC | #1
On Tue, 2 Jun 2020, James Almer wrote:

> Based on code from h264_sei.c

hevc_sei.c also has a similar code snippet.

This seems like something that should be factorized to common code... Or 
is it too much pain for some reason?

Thanks,
Marton

>
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> configure             |  2 +-
> libavcodec/libdav1d.c | 49 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/configure b/configure
> index 8569a60bf8..2961118682 100755
> --- a/configure
> +++ b/configure
> @@ -6295,7 +6295,7 @@ enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
>                                die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
> enabled libcaca           && require_pkg_config libcaca caca caca.h caca_create_canvas
> enabled libcodec2         && require libcodec2 codec2/codec2.h codec2_create -lcodec2
> -enabled libdav1d          && require_pkg_config libdav1d "dav1d >= 0.4.0" "dav1d/dav1d.h" dav1d_version
> +enabled libdav1d          && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d/dav1d.h" dav1d_version
> enabled libdavs2          && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open
> enabled libdc1394         && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
> enabled libdrm            && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion
> diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
> index bbb3ec1e6c..e8010655d0 100644
> --- a/libavcodec/libdav1d.c
> +++ b/libavcodec/libdav1d.c
> @@ -28,6 +28,7 @@
> 
> #include "avcodec.h"
> #include "decode.h"
> +#include "get_bits.h"
> #include "internal.h"
> 
> typedef struct Libdav1dContext {
> @@ -364,6 +365,54 @@ FF_ENABLE_DEPRECATION_WARNINGS
>         light->MaxCLL = p->content_light->max_content_light_level;
>         light->MaxFALL = p->content_light->max_frame_average_light_level;
>     }
> +    if (p->itut_t35) {
> +        GetBitContext gb;
> +        unsigned int user_identifier;
> +
> +        res = init_get_bits8(&gb, p->itut_t35->payload, p->itut_t35->payload_size);
> +        if (res < 0)
> +            return res;
> +
> +        skip_bits(&gb, 8); // terminal provider code
> +        skip_bits(&gb, 8); // terminal provider oriented code
> +        user_identifier = get_bits_long(&gb, 32);
> +        switch (user_identifier) {
> +        case MKBETAG('G', 'A', '9', '4'): // closed captions
> +            if (get_bits(&gb, 8) == 0x3) { // user_data_type_code
> +                int flag;
> +
> +                skip_bits(&gb, 1); // reserved
> +                flag = get_bits(&gb, 1); // process_cc_data_flag
> +                if (flag) {
> +                    int size, cc_count;
> +
> +                    skip_bits(&gb, 1); // zero bit
> +                    cc_count = get_bits(&gb, 5);
> +                    skip_bits(&gb, 8); // reserved
> +
> +                    size = cc_count * 3;
> +                    if (cc_count && (get_bits_left(&gb) >> 3) >= size + 1) {
> +                        AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_A53_CC, size);
> +                        if (!sd) {
> +                            res = AVERROR(ENOMEM);
> +                            goto fail;
> +                        }
> +
> +                        for (int i = 0, j = 0; i < cc_count; i++) {
> +                            sd->data[j++] = get_bits(&gb, 8);
> +                            sd->data[j++] = get_bits(&gb, 8);
> +                            sd->data[j++] = get_bits(&gb, 8);
> +                        }
> +
> +                        skip_bits(&gb, 8); // marker_bits
> +                    }
> +                }
> +            }
> +            break;
> +        default: // ignore unsupported identifiers
> +            break;
> +        }
> +    }
>
>     res = 0;
> fail:
> -- 
> 2.26.2
>
> _______________________________________________
> 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 mbox series

Patch

diff --git a/configure b/configure
index 8569a60bf8..2961118682 100755
--- a/configure
+++ b/configure
@@ -6295,7 +6295,7 @@  enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
                                die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
 enabled libcaca           && require_pkg_config libcaca caca caca.h caca_create_canvas
 enabled libcodec2         && require libcodec2 codec2/codec2.h codec2_create -lcodec2
-enabled libdav1d          && require_pkg_config libdav1d "dav1d >= 0.4.0" "dav1d/dav1d.h" dav1d_version
+enabled libdav1d          && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d/dav1d.h" dav1d_version
 enabled libdavs2          && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open
 enabled libdc1394         && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
 enabled libdrm            && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index bbb3ec1e6c..e8010655d0 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -28,6 +28,7 @@ 
 
 #include "avcodec.h"
 #include "decode.h"
+#include "get_bits.h"
 #include "internal.h"
 
 typedef struct Libdav1dContext {
@@ -364,6 +365,54 @@  FF_ENABLE_DEPRECATION_WARNINGS
         light->MaxCLL = p->content_light->max_content_light_level;
         light->MaxFALL = p->content_light->max_frame_average_light_level;
     }
+    if (p->itut_t35) {
+        GetBitContext gb;
+        unsigned int user_identifier;
+
+        res = init_get_bits8(&gb, p->itut_t35->payload, p->itut_t35->payload_size);
+        if (res < 0)
+            return res;
+
+        skip_bits(&gb, 8); // terminal provider code
+        skip_bits(&gb, 8); // terminal provider oriented code
+        user_identifier = get_bits_long(&gb, 32);
+        switch (user_identifier) {
+        case MKBETAG('G', 'A', '9', '4'): // closed captions
+            if (get_bits(&gb, 8) == 0x3) { // user_data_type_code
+                int flag;
+
+                skip_bits(&gb, 1); // reserved
+                flag = get_bits(&gb, 1); // process_cc_data_flag
+                if (flag) {
+                    int size, cc_count;
+
+                    skip_bits(&gb, 1); // zero bit
+                    cc_count = get_bits(&gb, 5);
+                    skip_bits(&gb, 8); // reserved
+
+                    size = cc_count * 3;
+                    if (cc_count && (get_bits_left(&gb) >> 3) >= size + 1) {
+                        AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_A53_CC, size);
+                        if (!sd) {
+                            res = AVERROR(ENOMEM);
+                            goto fail;
+                        }
+
+                        for (int i = 0, j = 0; i < cc_count; i++) {
+                            sd->data[j++] = get_bits(&gb, 8);
+                            sd->data[j++] = get_bits(&gb, 8);
+                            sd->data[j++] = get_bits(&gb, 8);
+                        }
+
+                        skip_bits(&gb, 8); // marker_bits
+                    }
+                }
+            }
+            break;
+        default: // ignore unsupported identifiers
+            break;
+        }
+    }
 
     res = 0;
 fail: