Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-20 Thread Aman Gupta
On Mon, Mar 12, 2018 at 9:25 AM, Mark Thompson  wrote:

> On 12/03/18 15:10, Hendrik Leppkes wrote:
> > On Mon, Mar 12, 2018 at 2:38 PM, Mark Thompson  wrote:
> >> On 12/03/18 09:54, Hendrik Leppkes wrote:
> >>> On Sun, Mar 11, 2018 at 7:30 PM, Mark Thompson  wrote:
>  ---
>   libavcodec/h264_metadata_bsf.c | 121 ++
> +++
>   1 file changed, 121 insertions(+)
> 
>  diff --git a/libavcodec/h264_metadata_bsf.c
> b/libavcodec/h264_metadata_bsf.c
>  index 36047887ca..d340c55990 100644
>  --- a/libavcodec/h264_metadata_bsf.c
>  +++ b/libavcodec/h264_metadata_bsf.c
>  @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>   int display_orientation;
>   double rotate;
>   int flip;
>  +
>  +int a53_cc;
>   } H264MetadataContext;
> 
> 
>  @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext
> *bsf, AVPacket *out)
>   int err, i, j, has_sps;
>   uint8_t *displaymatrix_side_data = NULL;
>   size_t displaymatrix_side_data_size = 0;
>  +uint8_t *a53_side_data = NULL;
>  +size_t a53_side_data_size = 0;
> 
>   err = ff_bsf_get_packet(bsf, &in);
>   if (err < 0)
>  @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext
> *bsf, AVPacket *out)
>   }
>   }
> 
>  +if (ctx->a53_cc == INSERT) {
>  +uint8_t *data;
>  +int size;
>  +
>  +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC,
> &size);
>  +if (data) {
>  +H264RawSEIPayload payload = {
>  +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
>  +};
>  +H264RawSEIUserDataRegistered *udr =
>  +&payload.payload.user_data_registered;
>  +
>  +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d
> bytes.\n", size);
>  +
>  +udr->data_length = size + 10;
>  +udr->data_ref= av_buffer_alloc(udr->data_length);
>  +if (!udr->data_ref) {
>  +err = AVERROR(ENOMEM);
>  +goto fail;
>  +}
>  +udr->data = udr->data_ref->data;
>  +
>  +udr->itu_t_t35_country_code = 181;
>  +udr->data[0] = 0;
>  +udr->data[1] = 49;
>  +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
>  +udr->data[6] = 3;
>  +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
>  +udr->data[8] = 0;
>  +memcpy(udr->data + 9, data, size);
>  +udr->data[size + 9] = 0xff;
>  +
>  +err = ff_cbs_h264_add_sei_message(ctx->cbc, au,
> &payload);
>  +if (err < 0) {
>  +av_log(bsf, AV_LOG_ERROR, "Failed to add user data
> SEI "
>  +   "message to access unit.\n");
>  +av_buffer_unref(&udr->data_ref);
>  +goto fail;
>  +}
>  +}
>  +
>  +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
>  +for (i = 0; i < au->nb_units; i++) {
>  +H264RawSEI *sei;
>  +if (au->units[i].type != H264_NAL_SEI)
>  +continue;
>  +sei = au->units[i].content;
>  +
>  +for (j = 0; j < sei->payload_count; j++) {
>  +H264RawSEIUserDataRegistered *udr;
>  +uint32_t tag;
>  +uint8_t type_code, count;
>  +
>  +if (sei->payload[j].payload_type !=
>  +H264_SEI_TYPE_USER_DATA_REGISTERED)
>  +continue;
>  +udr = &sei->payload[j].payload.user_data_registered;
>  +tag = AV_RB32(udr->data + 2);
>  +type_code = udr->data[6];
>  +if (tag != MKBETAG('G', 'A', '9', '4') || type_code
> != 3)
>  +continue;
>  +
>  +if (ctx->a53_cc == REMOVE) {
>  +err = ff_cbs_h264_delete_sei_message(ctx->cbc,
> au,
>  +
>  &au->units[i], j);
>  +if (err < 0) {
>  +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
>  +   "A53 CC SEI message.\n");
>  +goto fail;
>  +}
>  +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
>  +
>  +--i;
>  +break;
>  +}
>  +
>  +// Extract.
>  +count = udr->data[7] & 0x1f;
>  +if (3 * count + 10 > udr->data_length) {
>  +av_log(bsf, AV_LOG_E

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Mark Thompson
On 12/03/18 15:10, Hendrik Leppkes wrote:
> On Mon, Mar 12, 2018 at 2:38 PM, Mark Thompson  wrote:
>> On 12/03/18 09:54, Hendrik Leppkes wrote:
>>> On Sun, Mar 11, 2018 at 7:30 PM, Mark Thompson  wrote:
 ---
  libavcodec/h264_metadata_bsf.c | 121 
 +
  1 file changed, 121 insertions(+)

 diff --git a/libavcodec/h264_metadata_bsf.c 
 b/libavcodec/h264_metadata_bsf.c
 index 36047887ca..d340c55990 100644
 --- a/libavcodec/h264_metadata_bsf.c
 +++ b/libavcodec/h264_metadata_bsf.c
 @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
  int display_orientation;
  double rotate;
  int flip;
 +
 +int a53_cc;
  } H264MetadataContext;


 @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
 AVPacket *out)
  int err, i, j, has_sps;
  uint8_t *displaymatrix_side_data = NULL;
  size_t displaymatrix_side_data_size = 0;
 +uint8_t *a53_side_data = NULL;
 +size_t a53_side_data_size = 0;

  err = ff_bsf_get_packet(bsf, &in);
  if (err < 0)
 @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
 AVPacket *out)
  }
  }

 +if (ctx->a53_cc == INSERT) {
 +uint8_t *data;
 +int size;
 +
 +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
 +if (data) {
 +H264RawSEIPayload payload = {
 +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
 +};
 +H264RawSEIUserDataRegistered *udr =
 +&payload.payload.user_data_registered;
 +
 +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n", 
 size);
 +
 +udr->data_length = size + 10;
 +udr->data_ref= av_buffer_alloc(udr->data_length);
 +if (!udr->data_ref) {
 +err = AVERROR(ENOMEM);
 +goto fail;
 +}
 +udr->data = udr->data_ref->data;
 +
 +udr->itu_t_t35_country_code = 181;
 +udr->data[0] = 0;
 +udr->data[1] = 49;
 +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
 +udr->data[6] = 3;
 +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
 +udr->data[8] = 0;
 +memcpy(udr->data + 9, data, size);
 +udr->data[size + 9] = 0xff;
 +
 +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
 +if (err < 0) {
 +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
 +   "message to access unit.\n");
 +av_buffer_unref(&udr->data_ref);
 +goto fail;
 +}
 +}
 +
 +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
 +for (i = 0; i < au->nb_units; i++) {
 +H264RawSEI *sei;
 +if (au->units[i].type != H264_NAL_SEI)
 +continue;
 +sei = au->units[i].content;
 +
 +for (j = 0; j < sei->payload_count; j++) {
 +H264RawSEIUserDataRegistered *udr;
 +uint32_t tag;
 +uint8_t type_code, count;
 +
 +if (sei->payload[j].payload_type !=
 +H264_SEI_TYPE_USER_DATA_REGISTERED)
 +continue;
 +udr = &sei->payload[j].payload.user_data_registered;
 +tag = AV_RB32(udr->data + 2);
 +type_code = udr->data[6];
 +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
 +continue;
 +
 +if (ctx->a53_cc == REMOVE) {
 +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
 + &au->units[i], 
 j);
 +if (err < 0) {
 +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
 +   "A53 CC SEI message.\n");
 +goto fail;
 +}
 +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
 +
 +--i;
 +break;
 +}
 +
 +// Extract.
 +count = udr->data[7] & 0x1f;
 +if (3 * count + 10 > udr->data_length) {
 +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed 
 caption "
 +   "data: count %d overflows length %zu.\n",
 +   count, udr->data_length);
 +continue;
>>>

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Hendrik Leppkes
On Mon, Mar 12, 2018 at 2:38 PM, Mark Thompson  wrote:
> On 12/03/18 09:54, Hendrik Leppkes wrote:
>> On Sun, Mar 11, 2018 at 7:30 PM, Mark Thompson  wrote:
>>> ---
>>>  libavcodec/h264_metadata_bsf.c | 121 
>>> +
>>>  1 file changed, 121 insertions(+)
>>>
>>> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
>>> index 36047887ca..d340c55990 100644
>>> --- a/libavcodec/h264_metadata_bsf.c
>>> +++ b/libavcodec/h264_metadata_bsf.c
>>> @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>>>  int display_orientation;
>>>  double rotate;
>>>  int flip;
>>> +
>>> +int a53_cc;
>>>  } H264MetadataContext;
>>>
>>>
>>> @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
>>> AVPacket *out)
>>>  int err, i, j, has_sps;
>>>  uint8_t *displaymatrix_side_data = NULL;
>>>  size_t displaymatrix_side_data_size = 0;
>>> +uint8_t *a53_side_data = NULL;
>>> +size_t a53_side_data_size = 0;
>>>
>>>  err = ff_bsf_get_packet(bsf, &in);
>>>  if (err < 0)
>>> @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
>>> AVPacket *out)
>>>  }
>>>  }
>>>
>>> +if (ctx->a53_cc == INSERT) {
>>> +uint8_t *data;
>>> +int size;
>>> +
>>> +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
>>> +if (data) {
>>> +H264RawSEIPayload payload = {
>>> +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
>>> +};
>>> +H264RawSEIUserDataRegistered *udr =
>>> +&payload.payload.user_data_registered;
>>> +
>>> +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n", 
>>> size);
>>> +
>>> +udr->data_length = size + 10;
>>> +udr->data_ref= av_buffer_alloc(udr->data_length);
>>> +if (!udr->data_ref) {
>>> +err = AVERROR(ENOMEM);
>>> +goto fail;
>>> +}
>>> +udr->data = udr->data_ref->data;
>>> +
>>> +udr->itu_t_t35_country_code = 181;
>>> +udr->data[0] = 0;
>>> +udr->data[1] = 49;
>>> +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
>>> +udr->data[6] = 3;
>>> +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
>>> +udr->data[8] = 0;
>>> +memcpy(udr->data + 9, data, size);
>>> +udr->data[size + 9] = 0xff;
>>> +
>>> +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
>>> +if (err < 0) {
>>> +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
>>> +   "message to access unit.\n");
>>> +av_buffer_unref(&udr->data_ref);
>>> +goto fail;
>>> +}
>>> +}
>>> +
>>> +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
>>> +for (i = 0; i < au->nb_units; i++) {
>>> +H264RawSEI *sei;
>>> +if (au->units[i].type != H264_NAL_SEI)
>>> +continue;
>>> +sei = au->units[i].content;
>>> +
>>> +for (j = 0; j < sei->payload_count; j++) {
>>> +H264RawSEIUserDataRegistered *udr;
>>> +uint32_t tag;
>>> +uint8_t type_code, count;
>>> +
>>> +if (sei->payload[j].payload_type !=
>>> +H264_SEI_TYPE_USER_DATA_REGISTERED)
>>> +continue;
>>> +udr = &sei->payload[j].payload.user_data_registered;
>>> +tag = AV_RB32(udr->data + 2);
>>> +type_code = udr->data[6];
>>> +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
>>> +continue;
>>> +
>>> +if (ctx->a53_cc == REMOVE) {
>>> +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
>>> + &au->units[i], j);
>>> +if (err < 0) {
>>> +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
>>> +   "A53 CC SEI message.\n");
>>> +goto fail;
>>> +}
>>> +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
>>> +
>>> +--i;
>>> +break;
>>> +}
>>> +
>>> +// Extract.
>>> +count = udr->data[7] & 0x1f;
>>> +if (3 * count + 10 > udr->data_length) {
>>> +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed caption 
>>> "
>>> +   "data: count %d overflows length %zu.\n",
>>> +   count, udr->data_length);
>>> +continue;
>>> +}
>>> +
>>> +av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu 
>>> bytes.\n", udr->data_length);
>>> +
>>> +err = av_reallocp(

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Mark Thompson
On 12/03/18 09:54, Hendrik Leppkes wrote:
> On Sun, Mar 11, 2018 at 7:30 PM, Mark Thompson  wrote:
>> ---
>>  libavcodec/h264_metadata_bsf.c | 121 
>> +
>>  1 file changed, 121 insertions(+)
>>
>> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
>> index 36047887ca..d340c55990 100644
>> --- a/libavcodec/h264_metadata_bsf.c
>> +++ b/libavcodec/h264_metadata_bsf.c
>> @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>>  int display_orientation;
>>  double rotate;
>>  int flip;
>> +
>> +int a53_cc;
>>  } H264MetadataContext;
>>
>>
>> @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
>> AVPacket *out)
>>  int err, i, j, has_sps;
>>  uint8_t *displaymatrix_side_data = NULL;
>>  size_t displaymatrix_side_data_size = 0;
>> +uint8_t *a53_side_data = NULL;
>> +size_t a53_side_data_size = 0;
>>
>>  err = ff_bsf_get_packet(bsf, &in);
>>  if (err < 0)
>> @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
>> AVPacket *out)
>>  }
>>  }
>>
>> +if (ctx->a53_cc == INSERT) {
>> +uint8_t *data;
>> +int size;
>> +
>> +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
>> +if (data) {
>> +H264RawSEIPayload payload = {
>> +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
>> +};
>> +H264RawSEIUserDataRegistered *udr =
>> +&payload.payload.user_data_registered;
>> +
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n", size);
>> +
>> +udr->data_length = size + 10;
>> +udr->data_ref= av_buffer_alloc(udr->data_length);
>> +if (!udr->data_ref) {
>> +err = AVERROR(ENOMEM);
>> +goto fail;
>> +}
>> +udr->data = udr->data_ref->data;
>> +
>> +udr->itu_t_t35_country_code = 181;
>> +udr->data[0] = 0;
>> +udr->data[1] = 49;
>> +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
>> +udr->data[6] = 3;
>> +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
>> +udr->data[8] = 0;
>> +memcpy(udr->data + 9, data, size);
>> +udr->data[size + 9] = 0xff;
>> +
>> +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
>> +if (err < 0) {
>> +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
>> +   "message to access unit.\n");
>> +av_buffer_unref(&udr->data_ref);
>> +goto fail;
>> +}
>> +}
>> +
>> +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
>> +for (i = 0; i < au->nb_units; i++) {
>> +H264RawSEI *sei;
>> +if (au->units[i].type != H264_NAL_SEI)
>> +continue;
>> +sei = au->units[i].content;
>> +
>> +for (j = 0; j < sei->payload_count; j++) {
>> +H264RawSEIUserDataRegistered *udr;
>> +uint32_t tag;
>> +uint8_t type_code, count;
>> +
>> +if (sei->payload[j].payload_type !=
>> +H264_SEI_TYPE_USER_DATA_REGISTERED)
>> +continue;
>> +udr = &sei->payload[j].payload.user_data_registered;
>> +tag = AV_RB32(udr->data + 2);
>> +type_code = udr->data[6];
>> +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
>> +continue;
>> +
>> +if (ctx->a53_cc == REMOVE) {
>> +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
>> + &au->units[i], j);
>> +if (err < 0) {
>> +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
>> +   "A53 CC SEI message.\n");
>> +goto fail;
>> +}
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
>> +
>> +--i;
>> +break;
>> +}
>> +
>> +// Extract.
>> +count = udr->data[7] & 0x1f;
>> +if (3 * count + 10 > udr->data_length) {
>> +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed caption "
>> +   "data: count %d overflows length %zu.\n",
>> +   count, udr->data_length);
>> +continue;
>> +}
>> +
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu bytes.\n", 
>> udr->data_length);
>> +
>> +err = av_reallocp(&a53_side_data,
>> +  a53_side_data_size + 3 * count);
>> +if (err)
>> +goto fail;
>> +memcpy(a53_side_dat

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Mark Thompson
On 12/03/18 07:19, Aman Gupta wrote:
> On Sun, Mar 11, 2018 at 11:30 AM, Mark Thompson  wrote:
> 
>> ---
>>  libavcodec/h264_metadata_bsf.c | 121 ++
>> +++
>>  1 file changed, 121 insertions(+)
>>
>> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_
>> bsf.c
>> index 36047887ca..d340c55990 100644
>> --- a/libavcodec/h264_metadata_bsf.c
>> +++ b/libavcodec/h264_metadata_bsf.c
>> @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>>  int display_orientation;
>>  double rotate;
>>  int flip;
>> +
>> +int a53_cc;
>>  } H264MetadataContext;
>>
>>
>> @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf,
>> AVPacket *out)
>>  int err, i, j, has_sps;
>>  uint8_t *displaymatrix_side_data = NULL;
>>  size_t displaymatrix_side_data_size = 0;
>> +uint8_t *a53_side_data = NULL;
>> +size_t a53_side_data_size = 0;
>>
>>  err = ff_bsf_get_packet(bsf, &in);
>>  if (err < 0)
>> @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf,
>> AVPacket *out)
>>  }
>>  }
>>
>> +if (ctx->a53_cc == INSERT) {
>> +uint8_t *data;
>> +int size;
>> +
>> +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
>> +if (data) {
>> +H264RawSEIPayload payload = {
>> +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
>> +};
>> +H264RawSEIUserDataRegistered *udr =
>> +&payload.payload.user_data_registered;
>> +
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n",
>> size);
>> +
>> +udr->data_length = size + 10;
>> +udr->data_ref= av_buffer_alloc(udr->data_length);
>> +if (!udr->data_ref) {
>> +err = AVERROR(ENOMEM);
>> +goto fail;
>> +}
>> +udr->data = udr->data_ref->data;
>> +
>> +udr->itu_t_t35_country_code = 181;
>> +udr->data[0] = 0;
>> +udr->data[1] = 49;
>> +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
>> +udr->data[6] = 3;
>> +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
>> +udr->data[8] = 0;
>> +memcpy(udr->data + 9, data, size);
>> +udr->data[size + 9] = 0xff;
>> +
>> +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
>> +if (err < 0) {
>> +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
>> +   "message to access unit.\n");
>> +av_buffer_unref(&udr->data_ref);
>> +goto fail;
>> +}
>> +}
>> +
>> +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
>> +for (i = 0; i < au->nb_units; i++) {
>> +H264RawSEI *sei;
>> +if (au->units[i].type != H264_NAL_SEI)
>> +continue;
>> +sei = au->units[i].content;
>> +
>> +for (j = 0; j < sei->payload_count; j++) {
>> +H264RawSEIUserDataRegistered *udr;
>> +uint32_t tag;
>> +uint8_t type_code, count;
>> +
>> +if (sei->payload[j].payload_type !=
>> +H264_SEI_TYPE_USER_DATA_REGISTERED)
>> +continue;
>> +udr = &sei->payload[j].payload.user_data_registered;
>> +tag = AV_RB32(udr->data + 2);
>> +type_code = udr->data[6];
>> +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
>> +continue;
>> +
>> +if (ctx->a53_cc == REMOVE) {
>> +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
>> + &au->units[i],
>> j);
>> +if (err < 0) {
>> +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
>> +   "A53 CC SEI message.\n");
>> +goto fail;
>> +}
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
> 
> +
>> +--i;
>> +break;
>> +}
>> +
>> +// Extract.
>> +count = udr->data[7] & 0x1f;
>> +if (3 * count + 10 > udr->data_length) {
>> +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed
>> caption "
>> +   "data: count %d overflows length %zu.\n",
>> +   count, udr->data_length);
>> +continue;
>> +}
>> +
>> +av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu
>> bytes.\n", udr->data_length);
>>
> 
> I assume these are WARNINGs from testing? Seems like TRACE or DEBUG would
> be fine.

Oops, yeah.  Removed this one and others.

(The filter probably does want some more logging to explain what it's doing (at 
VERB

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Devin Heitmueller

> Does extracting really make sense? Doesn't the data end up out of
> order and basically unusable?

For what it’s worth, I’ve got a video filter which extracts the A53 side data 
and saves it into an MCC file (Telestream MacCaption format).  If people think 
that’s something that would be useful, I’ll see about getting it upstreamed.

Devin
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Hendrik Leppkes
On Sun, Mar 11, 2018 at 7:30 PM, Mark Thompson  wrote:
> ---
>  libavcodec/h264_metadata_bsf.c | 121 
> +
>  1 file changed, 121 insertions(+)
>
> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
> index 36047887ca..d340c55990 100644
> --- a/libavcodec/h264_metadata_bsf.c
> +++ b/libavcodec/h264_metadata_bsf.c
> @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>  int display_orientation;
>  double rotate;
>  int flip;
> +
> +int a53_cc;
>  } H264MetadataContext;
>
>
> @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
> AVPacket *out)
>  int err, i, j, has_sps;
>  uint8_t *displaymatrix_side_data = NULL;
>  size_t displaymatrix_side_data_size = 0;
> +uint8_t *a53_side_data = NULL;
> +size_t a53_side_data_size = 0;
>
>  err = ff_bsf_get_packet(bsf, &in);
>  if (err < 0)
> @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
> AVPacket *out)
>  }
>  }
>
> +if (ctx->a53_cc == INSERT) {
> +uint8_t *data;
> +int size;
> +
> +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
> +if (data) {
> +H264RawSEIPayload payload = {
> +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
> +};
> +H264RawSEIUserDataRegistered *udr =
> +&payload.payload.user_data_registered;
> +
> +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n", size);
> +
> +udr->data_length = size + 10;
> +udr->data_ref= av_buffer_alloc(udr->data_length);
> +if (!udr->data_ref) {
> +err = AVERROR(ENOMEM);
> +goto fail;
> +}
> +udr->data = udr->data_ref->data;
> +
> +udr->itu_t_t35_country_code = 181;
> +udr->data[0] = 0;
> +udr->data[1] = 49;
> +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
> +udr->data[6] = 3;
> +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
> +udr->data[8] = 0;
> +memcpy(udr->data + 9, data, size);
> +udr->data[size + 9] = 0xff;
> +
> +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
> +if (err < 0) {
> +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
> +   "message to access unit.\n");
> +av_buffer_unref(&udr->data_ref);
> +goto fail;
> +}
> +}
> +
> +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
> +for (i = 0; i < au->nb_units; i++) {
> +H264RawSEI *sei;
> +if (au->units[i].type != H264_NAL_SEI)
> +continue;
> +sei = au->units[i].content;
> +
> +for (j = 0; j < sei->payload_count; j++) {
> +H264RawSEIUserDataRegistered *udr;
> +uint32_t tag;
> +uint8_t type_code, count;
> +
> +if (sei->payload[j].payload_type !=
> +H264_SEI_TYPE_USER_DATA_REGISTERED)
> +continue;
> +udr = &sei->payload[j].payload.user_data_registered;
> +tag = AV_RB32(udr->data + 2);
> +type_code = udr->data[6];
> +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
> +continue;
> +
> +if (ctx->a53_cc == REMOVE) {
> +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
> + &au->units[i], j);
> +if (err < 0) {
> +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
> +   "A53 CC SEI message.\n");
> +goto fail;
> +}
> +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
> +
> +--i;
> +break;
> +}
> +
> +// Extract.
> +count = udr->data[7] & 0x1f;
> +if (3 * count + 10 > udr->data_length) {
> +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed caption "
> +   "data: count %d overflows length %zu.\n",
> +   count, udr->data_length);
> +continue;
> +}
> +
> +av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu bytes.\n", 
> udr->data_length);
> +
> +err = av_reallocp(&a53_side_data,
> +  a53_side_data_size + 3 * count);
> +if (err)
> +goto fail;
> +memcpy(a53_side_data + a53_side_data_size,
> +   udr->data + 9, 3 * count);
> +a53_side_data_size += 3 * count;
> +}
> +}
> +}
> 

Re: [FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-12 Thread Aman Gupta
On Sun, Mar 11, 2018 at 11:30 AM, Mark Thompson  wrote:

> ---
>  libavcodec/h264_metadata_bsf.c | 121 ++
> +++
>  1 file changed, 121 insertions(+)
>
> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_
> bsf.c
> index 36047887ca..d340c55990 100644
> --- a/libavcodec/h264_metadata_bsf.c
> +++ b/libavcodec/h264_metadata_bsf.c
> @@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
>  int display_orientation;
>  double rotate;
>  int flip;
> +
> +int a53_cc;
>  } H264MetadataContext;
>
>
> @@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf,
> AVPacket *out)
>  int err, i, j, has_sps;
>  uint8_t *displaymatrix_side_data = NULL;
>  size_t displaymatrix_side_data_size = 0;
> +uint8_t *a53_side_data = NULL;
> +size_t a53_side_data_size = 0;
>
>  err = ff_bsf_get_packet(bsf, &in);
>  if (err < 0)
> @@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf,
> AVPacket *out)
>  }
>  }
>
> +if (ctx->a53_cc == INSERT) {
> +uint8_t *data;
> +int size;
> +
> +data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
> +if (data) {
> +H264RawSEIPayload payload = {
> +.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
> +};
> +H264RawSEIUserDataRegistered *udr =
> +&payload.payload.user_data_registered;
> +
> +av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n",
> size);
> +
> +udr->data_length = size + 10;
> +udr->data_ref= av_buffer_alloc(udr->data_length);
> +if (!udr->data_ref) {
> +err = AVERROR(ENOMEM);
> +goto fail;
> +}
> +udr->data = udr->data_ref->data;
> +
> +udr->itu_t_t35_country_code = 181;
> +udr->data[0] = 0;
> +udr->data[1] = 49;
> +AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
> +udr->data[6] = 3;
> +udr->data[7] = ((size / 3) & 0x1f) | 0x40;
> +udr->data[8] = 0;
> +memcpy(udr->data + 9, data, size);
> +udr->data[size + 9] = 0xff;
> +
> +err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
> +if (err < 0) {
> +av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
> +   "message to access unit.\n");
> +av_buffer_unref(&udr->data_ref);
> +goto fail;
> +}
> +}
> +
> +} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
> +for (i = 0; i < au->nb_units; i++) {
> +H264RawSEI *sei;
> +if (au->units[i].type != H264_NAL_SEI)
> +continue;
> +sei = au->units[i].content;
> +
> +for (j = 0; j < sei->payload_count; j++) {
> +H264RawSEIUserDataRegistered *udr;
> +uint32_t tag;
> +uint8_t type_code, count;
> +
> +if (sei->payload[j].payload_type !=
> +H264_SEI_TYPE_USER_DATA_REGISTERED)
> +continue;
> +udr = &sei->payload[j].payload.user_data_registered;
> +tag = AV_RB32(udr->data + 2);
> +type_code = udr->data[6];
> +if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
> +continue;
> +
> +if (ctx->a53_cc == REMOVE) {
> +err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
> + &au->units[i],
> j);
> +if (err < 0) {
> +av_log(bsf, AV_LOG_ERROR, "Failed to delete "
> +   "A53 CC SEI message.\n");
> +goto fail;
> +}
> +av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");

+
> +--i;
> +break;
> +}
> +
> +// Extract.
> +count = udr->data[7] & 0x1f;
> +if (3 * count + 10 > udr->data_length) {
> +av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed
> caption "
> +   "data: count %d overflows length %zu.\n",
> +   count, udr->data_length);
> +continue;
> +}
> +
> +av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu
> bytes.\n", udr->data_length);
>

I assume these are WARNINGs from testing? Seems like TRACE or DEBUG would
be fine.


> +
> +err = av_reallocp(&a53_side_data,
> +  a53_side_data_size + 3 * count);
> +if (err)
> +goto fail;
> +memcpy(a53_side_data + a53_side_data_size,
> +   udr->data + 9, 3 * count)

[FFmpeg-devel] [PATCH 4/8] h264_metadata: Add support for A/53 closed captions

2018-03-11 Thread Mark Thompson
---
 libavcodec/h264_metadata_bsf.c | 121 +
 1 file changed, 121 insertions(+)

diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index 36047887ca..d340c55990 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -77,6 +77,8 @@ typedef struct H264MetadataContext {
 int display_orientation;
 double rotate;
 int flip;
+
+int a53_cc;
 } H264MetadataContext;
 
 
@@ -225,6 +227,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket 
*out)
 int err, i, j, has_sps;
 uint8_t *displaymatrix_side_data = NULL;
 size_t displaymatrix_side_data_size = 0;
+uint8_t *a53_side_data = NULL;
+size_t a53_side_data_size = 0;
 
 err = ff_bsf_get_packet(bsf, &in);
 if (err < 0)
@@ -514,6 +518,104 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
AVPacket *out)
 }
 }
 
+if (ctx->a53_cc == INSERT) {
+uint8_t *data;
+int size;
+
+data = av_packet_get_side_data(in, AV_PKT_DATA_A53_CC, &size);
+if (data) {
+H264RawSEIPayload payload = {
+.payload_type = H264_SEI_TYPE_USER_DATA_REGISTERED,
+};
+H264RawSEIUserDataRegistered *udr =
+&payload.payload.user_data_registered;
+
+av_log(bsf, AV_LOG_WARNING, "A53 CC insert: %d bytes.\n", size);
+
+udr->data_length = size + 10;
+udr->data_ref= av_buffer_alloc(udr->data_length);
+if (!udr->data_ref) {
+err = AVERROR(ENOMEM);
+goto fail;
+}
+udr->data = udr->data_ref->data;
+
+udr->itu_t_t35_country_code = 181;
+udr->data[0] = 0;
+udr->data[1] = 49;
+AV_WB32(udr->data + 2, MKBETAG('G', 'A', '9', '4'));
+udr->data[6] = 3;
+udr->data[7] = ((size / 3) & 0x1f) | 0x40;
+udr->data[8] = 0;
+memcpy(udr->data + 9, data, size);
+udr->data[size + 9] = 0xff;
+
+err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload);
+if (err < 0) {
+av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI "
+   "message to access unit.\n");
+av_buffer_unref(&udr->data_ref);
+goto fail;
+}
+}
+
+} else if (ctx->a53_cc == REMOVE || ctx->a53_cc == EXTRACT) {
+for (i = 0; i < au->nb_units; i++) {
+H264RawSEI *sei;
+if (au->units[i].type != H264_NAL_SEI)
+continue;
+sei = au->units[i].content;
+
+for (j = 0; j < sei->payload_count; j++) {
+H264RawSEIUserDataRegistered *udr;
+uint32_t tag;
+uint8_t type_code, count;
+
+if (sei->payload[j].payload_type !=
+H264_SEI_TYPE_USER_DATA_REGISTERED)
+continue;
+udr = &sei->payload[j].payload.user_data_registered;
+tag = AV_RB32(udr->data + 2);
+type_code = udr->data[6];
+if (tag != MKBETAG('G', 'A', '9', '4') || type_code != 3)
+continue;
+
+if (ctx->a53_cc == REMOVE) {
+err = ff_cbs_h264_delete_sei_message(ctx->cbc, au,
+ &au->units[i], j);
+if (err < 0) {
+av_log(bsf, AV_LOG_ERROR, "Failed to delete "
+   "A53 CC SEI message.\n");
+goto fail;
+}
+av_log(bsf, AV_LOG_WARNING, "A53 CC remove!.\n");
+
+--i;
+break;
+}
+
+// Extract.
+count = udr->data[7] & 0x1f;
+if (3 * count + 10 > udr->data_length) {
+av_log(bsf, AV_LOG_ERROR, "Invalid A/53 closed caption "
+   "data: count %d overflows length %zu.\n",
+   count, udr->data_length);
+continue;
+}
+
+av_log(bsf, AV_LOG_WARNING, "A53 CC extract: %zu bytes.\n", 
udr->data_length);
+
+err = av_reallocp(&a53_side_data,
+  a53_side_data_size + 3 * count);
+if (err)
+goto fail;
+memcpy(a53_side_data + a53_side_data_size,
+   udr->data + 9, 3 * count);
+a53_side_data_size += 3 * count;
+}
+}
+}
+
 err = ff_cbs_write_packet(ctx->cbc, out, au);
 if (err < 0) {
 av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
@@ -535,6 +637,16 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
AVPacket *out)
 }
 displaymatrix_side_data = NULL;
 }
+if (a53_side_data) {