--- libavcodec/h264.c | 10 ++++++++++ libavcodec/h264.h | 2 ++ libavcodec/h264_sei.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 1cbd4cb..d971c7b 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,14 @@ 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); + } + 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..5a61020 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,36 @@ FF_ENABLE_DEPRECATION_WARNINGS skip_bits(&h->gb, 6); } break; + case 0x47413934: // "GA94" closed captions + if (size < 3) + return -1; + user_data_type_code = get_bits(&h->gb, 8); + #undef printf + 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; + // Allow merging of the cc data from two fields + uint8_t *tmp = av_realloc(tmp, h->a53_caption_size + cc_count*3); + if (!tmp) + return -1; + 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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel