[FFmpeg-devel] [PATCHv3] avcodec: Add support for Closed Caption export in h264

Kieran Kunhya kierank at ob-encoder.com
Thu Jul 2 21:18:13 CEST 2015


---
 libavcodec/h264.c     | 11 +++++++++++
 libavcodec/h264.h     |  2 ++
 libavcodec/h264_sei.c | 35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 1cbd4cb..1569ec8 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -609,6 +609,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
     h->prev_frame_num        = -1;
     h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
     h->has_afd               = 0;
+    h->a53_caption_size      = 0;
+    h->a53_caption           = NULL;
 
     h->next_outputed_poc = INT_MIN;
     for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
@@ -879,6 +881,15 @@ static void decode_postinit(H264Context *h, int setup_finished)
         }
     }
 
+    if (h->a53_caption) {
+        AVFrameSideData *sd =
+            av_frame_new_side_data(cur->f, AV_FRAME_DATA_A53_CC, h->a53_caption_size);
+        if (sd)
+            memcpy(sd->data, h->a53_caption, h->a53_caption_size);
+        av_freep(&h->a53_caption);
+        h->a53_caption_size = 0;
+    }
+
     cur->mmco_reset = h->mmco_reset;
     h->mmco_reset = 0;
 
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 7565e03..3aef49f 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -784,6 +784,8 @@ typedef struct H264Context {
     uint8_t afd;
     int has_afd;
 
+    int a53_caption_size;
+    uint8_t *a53_caption;
 
     // Timestamp stuff
     int sei_buffering_period_present;   ///< Buffering period SEI flag
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index b6ec5c7..5c6fcc0 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -111,7 +111,7 @@ static int decode_picture_timing(H264Context *h)
 static int decode_user_data_itu_t_t35(H264Context *h, int size)
 {
     uint32_t user_identifier;
-    int dtg_active_format;
+    int dtg_active_format, cc_count, user_data_type_code;
 
     if (size < 7)
         return -1;
@@ -143,6 +143,39 @@ FF_ENABLE_DEPRECATION_WARNINGS
                 skip_bits(&h->gb, 6);
             }
             break;
+        case 0x47413934: // "GA94" closed captions
+            if (size < 3)
+                return AVERROR(EINVAL);
+            user_data_type_code = get_bits(&h->gb, 8);
+            if (user_data_type_code == 0x3) {
+                skip_bits(&h->gb, 1);
+                if (get_bits(&h->gb, 1)) {
+                    skip_bits(&h->gb, 1);
+                    cc_count = get_bits(&h->gb, 5);
+                    skip_bits(&h->gb, 8);
+                    size -= 2;
+                    if (cc_count && size >= cc_count*3) {
+                        int i;
+                        uint8_t *tmp;
+                        if ((int64_t)h->a53_caption_size + (int64_t)cc_count*3 > INT_MAX)
+                            return AVERROR(EINVAL);
+
+                        // Allow merging of the cc data from two fields
+                        tmp = av_realloc(h->a53_caption, h->a53_caption_size + cc_count*3);
+                        if (!tmp)
+                            return AVERROR(ENOMEM);
+                        h->a53_caption = tmp;
+                        for (i = 0; i < cc_count; i++) {
+                            h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8);
+                            h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8);
+                            h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8);
+                        }
+
+                        skip_bits(&h->gb, 8);
+                    }
+                }
+            }
+            break;
         default:
             skip_bits(&h->gb, size * 8);
             break;
-- 
1.9.1



More information about the ffmpeg-devel mailing list