closedcaption: move cc_data->cdp to shared file
Used by both ccconverter and cccombiner Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3211>
This commit is contained in:
parent
9f1b54f6ee
commit
fde92ec43f
@ -22,8 +22,15 @@
|
|||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <gst/base/base.h>
|
||||||
|
|
||||||
#include "ccutils.h"
|
#include "ccutils.h"
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT ccutils_debug_cat
|
||||||
|
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
|
typedef struct cdp_fps_entry cdp_fps_entry;
|
||||||
|
|
||||||
static const struct cdp_fps_entry cdp_fps_table[] = {
|
static const struct cdp_fps_entry cdp_fps_table[] = {
|
||||||
{0x1f, 24000, 1001, 25, 22, 3 /* FIXME: alternating max cea608 count! */ },
|
{0x1f, 24000, 1001, 25, 22, 3 /* FIXME: alternating max cea608 count! */ },
|
||||||
{0x2f, 24, 1, 25, 22, 2},
|
{0x2f, 24, 1, 25, 22, 2},
|
||||||
@ -57,3 +64,119 @@ cdp_fps_entry_from_id (guint8 id)
|
|||||||
}
|
}
|
||||||
return &null_fps_entry;
|
return &null_fps_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Converts raw CEA708 cc_data and an optional timecode into CDP */
|
||||||
|
guint
|
||||||
|
convert_cea708_cc_data_to_cdp (GstObject * dbg_obj, GstCCCDPMode cdp_mode,
|
||||||
|
guint16 cdp_hdr_sequence_cntr, const guint8 * cc_data, guint cc_data_len,
|
||||||
|
guint8 * cdp, guint cdp_len, const GstVideoTimeCode * tc,
|
||||||
|
const cdp_fps_entry * fps_entry)
|
||||||
|
{
|
||||||
|
GstByteWriter bw;
|
||||||
|
guint8 flags, checksum;
|
||||||
|
guint i, len;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dbg_obj, "writing out cdp packet from cc_data with "
|
||||||
|
"length %u", cc_data_len);
|
||||||
|
|
||||||
|
gst_byte_writer_init_with_data (&bw, cdp, cdp_len, FALSE);
|
||||||
|
gst_byte_writer_put_uint16_be_unchecked (&bw, 0x9669);
|
||||||
|
/* Write a length of 0 for now */
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
||||||
|
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, fps_entry->fps_idx);
|
||||||
|
|
||||||
|
if (cc_data_len / 3 > fps_entry->max_cc_count) {
|
||||||
|
GST_WARNING_OBJECT (dbg_obj, "Too many cc_data triplets for framerate: %u. "
|
||||||
|
"Truncating to %u", cc_data_len / 3, fps_entry->max_cc_count);
|
||||||
|
cc_data_len = 3 * fps_entry->max_cc_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* caption_service_active */
|
||||||
|
flags = 0x02;
|
||||||
|
|
||||||
|
/* ccdata_present */
|
||||||
|
if ((cdp_mode & GST_CC_CDP_MODE_CC_DATA))
|
||||||
|
flags |= 0x40;
|
||||||
|
|
||||||
|
/* time_code_present */
|
||||||
|
if ((cdp_mode & GST_CC_CDP_MODE_TIME_CODE) && tc && tc->config.fps_n > 0)
|
||||||
|
flags |= 0x80;
|
||||||
|
|
||||||
|
/* reserved */
|
||||||
|
flags |= 0x01;
|
||||||
|
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, flags);
|
||||||
|
|
||||||
|
gst_byte_writer_put_uint16_be_unchecked (&bw, cdp_hdr_sequence_cntr);
|
||||||
|
|
||||||
|
if ((cdp_mode & GST_CC_CDP_MODE_TIME_CODE) && tc && tc->config.fps_n > 0) {
|
||||||
|
guint8 u8;
|
||||||
|
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0x71);
|
||||||
|
/* reserved 11 - 2 bits */
|
||||||
|
u8 = 0xc0;
|
||||||
|
/* tens of hours - 2 bits */
|
||||||
|
u8 |= ((tc->hours / 10) & 0x3) << 4;
|
||||||
|
/* units of hours - 4 bits */
|
||||||
|
u8 |= (tc->hours % 10) & 0xf;
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
||||||
|
|
||||||
|
/* reserved 1 - 1 bit */
|
||||||
|
u8 = 0x80;
|
||||||
|
/* tens of minutes - 3 bits */
|
||||||
|
u8 |= ((tc->minutes / 10) & 0x7) << 4;
|
||||||
|
/* units of minutes - 4 bits */
|
||||||
|
u8 |= (tc->minutes % 10) & 0xf;
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
||||||
|
|
||||||
|
/* field flag - 1 bit */
|
||||||
|
u8 = tc->field_count < 2 ? 0x00 : 0x80;
|
||||||
|
/* tens of seconds - 3 bits */
|
||||||
|
u8 |= ((tc->seconds / 10) & 0x7) << 4;
|
||||||
|
/* units of seconds - 4 bits */
|
||||||
|
u8 |= (tc->seconds % 10) & 0xf;
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
||||||
|
|
||||||
|
/* drop frame flag - 1 bit */
|
||||||
|
u8 = (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) ? 0x80 :
|
||||||
|
0x00;
|
||||||
|
/* reserved0 - 1 bit */
|
||||||
|
/* tens of frames - 2 bits */
|
||||||
|
u8 |= ((tc->frames / 10) & 0x3) << 4;
|
||||||
|
/* units of frames 4 bits */
|
||||||
|
u8 |= (tc->frames % 10) & 0xf;
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cdp_mode & GST_CC_CDP_MODE_CC_DATA)) {
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0x72);
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | fps_entry->max_cc_count);
|
||||||
|
gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len);
|
||||||
|
while (fps_entry->max_cc_count > cc_data_len / 3) {
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0xfa);
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
||||||
|
cc_data_len += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0x74);
|
||||||
|
gst_byte_writer_put_uint16_be_unchecked (&bw, cdp_hdr_sequence_cntr);
|
||||||
|
/* We calculate the checksum afterwards */
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
||||||
|
|
||||||
|
len = gst_byte_writer_get_pos (&bw);
|
||||||
|
gst_byte_writer_set_pos (&bw, 2);
|
||||||
|
gst_byte_writer_put_uint8_unchecked (&bw, len);
|
||||||
|
|
||||||
|
checksum = 0;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
checksum += cdp[i];
|
||||||
|
}
|
||||||
|
checksum &= 0xff;
|
||||||
|
checksum = 256 - checksum;
|
||||||
|
cdp[len - 1] = checksum;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
@ -19,12 +19,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
#ifndef __CCUTILS_H__
|
#ifndef __CCUTILS_H__
|
||||||
#define __CCUTILS_H__
|
#define __CCUTILS_H__
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_EXTERN(ccutils_debug_cat);
|
||||||
|
|
||||||
struct cdp_fps_entry
|
struct cdp_fps_entry
|
||||||
{
|
{
|
||||||
guint8 fps_idx; /* value stored in cdp */
|
guint8 fps_idx; /* value stored in cdp */
|
||||||
@ -41,6 +44,22 @@ const struct cdp_fps_entry * cdp_fps_entry_from_id (guint8 id);
|
|||||||
|
|
||||||
extern const struct cdp_fps_entry null_fps_entry;
|
extern const struct cdp_fps_entry null_fps_entry;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_CC_CDP_MODE_TIME_CODE = (1<<0),
|
||||||
|
GST_CC_CDP_MODE_CC_DATA = (1<<1),
|
||||||
|
GST_CC_CDP_MODE_CC_SVC_INFO = (1<<2)
|
||||||
|
} GstCCCDPMode;
|
||||||
|
|
||||||
|
guint convert_cea708_cc_data_to_cdp (GstObject * dbg_obj,
|
||||||
|
GstCCCDPMode cdp_mode,
|
||||||
|
guint16 cdp_hdr_sequence_cntr,
|
||||||
|
const guint8 * cc_data,
|
||||||
|
guint cc_data_len,
|
||||||
|
guint8 * cdp,
|
||||||
|
guint cdp_len,
|
||||||
|
const GstVideoTimeCode * tc,
|
||||||
|
const struct cdp_fps_entry *fps_entry);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -192,108 +192,22 @@ done:
|
|||||||
|
|
||||||
#define MAX_CDP_PACKET_LEN 256
|
#define MAX_CDP_PACKET_LEN 256
|
||||||
#define MAX_CEA608_LEN 32
|
#define MAX_CEA608_LEN 32
|
||||||
|
#define CDP_MODE (GST_CC_CDP_MODE_CC_DATA | GST_CC_CDP_MODE_TIME_CODE)
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
make_cdp (GstCCCombiner * self, const guint8 * cc_data, guint cc_data_len,
|
make_cdp (GstCCCombiner * self, const guint8 * cc_data, guint cc_data_len,
|
||||||
const struct cdp_fps_entry *fps_entry, const GstVideoTimeCode * tc)
|
const struct cdp_fps_entry *fps_entry, const GstVideoTimeCode * tc)
|
||||||
{
|
{
|
||||||
GstByteWriter bw;
|
guint len;
|
||||||
guint8 flags, checksum;
|
|
||||||
guint i, len;
|
|
||||||
GstBuffer *ret = gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
GstBuffer *ret = gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
||||||
GstMapInfo map;
|
GstMapInfo map;
|
||||||
|
|
||||||
gst_buffer_map (ret, &map, GST_MAP_WRITE);
|
gst_buffer_map (ret, &map, GST_MAP_WRITE);
|
||||||
|
|
||||||
gst_byte_writer_init_with_data (&bw, map.data, MAX_CDP_PACKET_LEN, FALSE);
|
len = convert_cea708_cc_data_to_cdp (GST_OBJECT (self), CDP_MODE,
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, 0x9669);
|
self->cdp_hdr_sequence_cntr, cc_data, cc_data_len, map.data, map.size,
|
||||||
/* Write a length of 0 for now */
|
tc, fps_entry);
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, fps_entry->fps_idx);
|
|
||||||
|
|
||||||
/* caption_service_active */
|
|
||||||
flags = 0x02;
|
|
||||||
|
|
||||||
/* ccdata_present */
|
|
||||||
flags |= 0x40;
|
|
||||||
|
|
||||||
if (tc && tc->config.fps_n > 0)
|
|
||||||
flags |= 0x80;
|
|
||||||
|
|
||||||
/* reserved */
|
|
||||||
flags |= 0x01;
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, flags);
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr);
|
|
||||||
|
|
||||||
if (tc && tc->config.fps_n > 0) {
|
|
||||||
guint8 u8;
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x71);
|
|
||||||
/* reserved 11 - 2 bits */
|
|
||||||
u8 = 0xc0;
|
|
||||||
/* tens of hours - 2 bits */
|
|
||||||
u8 |= ((tc->hours / 10) & 0x3) << 4;
|
|
||||||
/* units of hours - 4 bits */
|
|
||||||
u8 |= (tc->hours % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* reserved 1 - 1 bit */
|
|
||||||
u8 = 0x80;
|
|
||||||
/* tens of minutes - 3 bits */
|
|
||||||
u8 |= ((tc->minutes / 10) & 0x7) << 4;
|
|
||||||
/* units of minutes - 4 bits */
|
|
||||||
u8 |= (tc->minutes % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* field flag - 1 bit */
|
|
||||||
u8 = tc->field_count < 2 ? 0x00 : 0x80;
|
|
||||||
/* tens of seconds - 3 bits */
|
|
||||||
u8 |= ((tc->seconds / 10) & 0x7) << 4;
|
|
||||||
/* units of seconds - 4 bits */
|
|
||||||
u8 |= (tc->seconds % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* drop frame flag - 1 bit */
|
|
||||||
u8 = (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) ? 0x80 :
|
|
||||||
0x00;
|
|
||||||
/* reserved0 - 1 bit */
|
|
||||||
/* tens of frames - 2 bits */
|
|
||||||
u8 |= ((tc->frames / 10) & 0x3) << 4;
|
|
||||||
/* units of frames 4 bits */
|
|
||||||
u8 |= (tc->frames % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x72);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | fps_entry->max_cc_count);
|
|
||||||
gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len);
|
|
||||||
while (fps_entry->max_cc_count > cc_data_len / 3) {
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0xfa);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
|
||||||
cc_data_len += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x74);
|
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr);
|
|
||||||
self->cdp_hdr_sequence_cntr++;
|
self->cdp_hdr_sequence_cntr++;
|
||||||
/* We calculate the checksum afterwards */
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
|
||||||
|
|
||||||
len = gst_byte_writer_get_pos (&bw);
|
|
||||||
gst_byte_writer_set_pos (&bw, 2);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, len);
|
|
||||||
|
|
||||||
checksum = 0;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
checksum += map.data[i];
|
|
||||||
}
|
|
||||||
checksum &= 0xff;
|
|
||||||
checksum = 256 - checksum;
|
|
||||||
map.data[len - 1] = checksum;
|
|
||||||
|
|
||||||
gst_buffer_unmap (ret, &map);
|
gst_buffer_unmap (ret, &map);
|
||||||
|
|
||||||
|
@ -80,11 +80,11 @@ static GType
|
|||||||
gst_cc_converter_cdp_mode_get_type (void)
|
gst_cc_converter_cdp_mode_get_type (void)
|
||||||
{
|
{
|
||||||
static const GFlagsValue values[] = {
|
static const GFlagsValue values[] = {
|
||||||
{GST_CC_CONVERTER_CDP_MODE_TIME_CODE,
|
{GST_CC_CDP_MODE_TIME_CODE,
|
||||||
"Store time code information in CDP packets", "time-code"},
|
"Store time code information in CDP packets", "time-code"},
|
||||||
{GST_CC_CONVERTER_CDP_MODE_CC_DATA, "Store CC data in CDP packets",
|
{GST_CC_CDP_MODE_CC_DATA, "Store CC data in CDP packets",
|
||||||
"cc-data"},
|
"cc-data"},
|
||||||
{GST_CC_CONVERTER_CDP_MODE_CC_SVC_INFO,
|
{GST_CC_CDP_MODE_CC_SVC_INFO,
|
||||||
"Store CC service information in CDP packets", "cc-svc-info"},
|
"Store CC service information in CDP packets", "cc-svc-info"},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
@ -1104,122 +1104,19 @@ fit_and_scale_cc_data (GstCCConverter * self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts raw CEA708 cc_data and an optional timecode into CDP */
|
|
||||||
static guint
|
static guint
|
||||||
convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
|
convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
|
||||||
const guint8 * cc_data, guint cc_data_len, guint8 * cdp, guint cdp_len,
|
const guint8 * cc_data, guint cc_data_len, guint8 * cdp, guint cdp_len,
|
||||||
const GstVideoTimeCode * tc, const struct cdp_fps_entry *fps_entry)
|
const GstVideoTimeCode * tc, const struct cdp_fps_entry *fps_entry)
|
||||||
{
|
{
|
||||||
GstByteWriter bw;
|
guint ret;
|
||||||
guint8 flags, checksum;
|
|
||||||
guint i, len;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "writing out cdp packet from cc_data with length %u",
|
ret = convert_cea708_cc_data_to_cdp (GST_OBJECT (self),
|
||||||
cc_data_len);
|
(GstCCCDPMode) self->cdp_mode, self->cdp_hdr_sequence_cntr, cc_data,
|
||||||
|
cc_data_len, cdp, cdp_len, tc, fps_entry);
|
||||||
gst_byte_writer_init_with_data (&bw, cdp, cdp_len, FALSE);
|
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, 0x9669);
|
|
||||||
/* Write a length of 0 for now */
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, fps_entry->fps_idx);
|
|
||||||
|
|
||||||
if (cc_data_len / 3 > fps_entry->max_cc_count) {
|
|
||||||
GST_WARNING_OBJECT (self, "Too many cc_data triplets for framerate: %u. "
|
|
||||||
"Truncating to %u", cc_data_len / 3, fps_entry->max_cc_count);
|
|
||||||
cc_data_len = 3 * fps_entry->max_cc_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* caption_service_active */
|
|
||||||
flags = 0x02;
|
|
||||||
|
|
||||||
/* ccdata_present */
|
|
||||||
if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_CC_DATA))
|
|
||||||
flags |= 0x40;
|
|
||||||
|
|
||||||
/* time_code_present */
|
|
||||||
if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_TIME_CODE) && tc
|
|
||||||
&& tc->config.fps_n > 0)
|
|
||||||
flags |= 0x80;
|
|
||||||
|
|
||||||
/* reserved */
|
|
||||||
flags |= 0x01;
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, flags);
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr);
|
|
||||||
|
|
||||||
if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_TIME_CODE) && tc
|
|
||||||
&& tc->config.fps_n > 0) {
|
|
||||||
guint8 u8;
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x71);
|
|
||||||
/* reserved 11 - 2 bits */
|
|
||||||
u8 = 0xc0;
|
|
||||||
/* tens of hours - 2 bits */
|
|
||||||
u8 |= ((tc->hours / 10) & 0x3) << 4;
|
|
||||||
/* units of hours - 4 bits */
|
|
||||||
u8 |= (tc->hours % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* reserved 1 - 1 bit */
|
|
||||||
u8 = 0x80;
|
|
||||||
/* tens of minutes - 3 bits */
|
|
||||||
u8 |= ((tc->minutes / 10) & 0x7) << 4;
|
|
||||||
/* units of minutes - 4 bits */
|
|
||||||
u8 |= (tc->minutes % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* field flag - 1 bit */
|
|
||||||
u8 = tc->field_count < 2 ? 0x00 : 0x80;
|
|
||||||
/* tens of seconds - 3 bits */
|
|
||||||
u8 |= ((tc->seconds / 10) & 0x7) << 4;
|
|
||||||
/* units of seconds - 4 bits */
|
|
||||||
u8 |= (tc->seconds % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
|
|
||||||
/* drop frame flag - 1 bit */
|
|
||||||
u8 = (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) ? 0x80 :
|
|
||||||
0x00;
|
|
||||||
/* reserved0 - 1 bit */
|
|
||||||
/* tens of frames - 2 bits */
|
|
||||||
u8 |= ((tc->frames / 10) & 0x3) << 4;
|
|
||||||
/* units of frames 4 bits */
|
|
||||||
u8 |= (tc->frames % 10) & 0xf;
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_CC_DATA)) {
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x72);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | fps_entry->max_cc_count);
|
|
||||||
gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len);
|
|
||||||
while (fps_entry->max_cc_count > cc_data_len / 3) {
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0xfa);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
|
|
||||||
cc_data_len += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0x74);
|
|
||||||
gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr);
|
|
||||||
self->cdp_hdr_sequence_cntr++;
|
self->cdp_hdr_sequence_cntr++;
|
||||||
/* We calculate the checksum afterwards */
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, 0);
|
|
||||||
|
|
||||||
len = gst_byte_writer_get_pos (&bw);
|
return ret;
|
||||||
gst_byte_writer_set_pos (&bw, 2);
|
|
||||||
gst_byte_writer_put_uint8_unchecked (&bw, len);
|
|
||||||
|
|
||||||
checksum = 0;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
checksum += cdp[i];
|
|
||||||
}
|
|
||||||
checksum &= 0xff;
|
|
||||||
checksum = 256 - checksum;
|
|
||||||
cdp[len - 1] = checksum;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts CDP into raw CEA708 cc_data */
|
/* Converts CDP into raw CEA708 cc_data */
|
||||||
|
@ -31,12 +31,16 @@
|
|||||||
#include "gstline21dec.h"
|
#include "gstline21dec.h"
|
||||||
#include "gstceaccoverlay.h"
|
#include "gstceaccoverlay.h"
|
||||||
#include "gstline21enc.h"
|
#include "gstline21enc.h"
|
||||||
|
#include "ccutils.h"
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
closedcaption_init (GstPlugin * plugin)
|
closedcaption_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (ccutils_debug_cat, "ccutils", 0,
|
||||||
|
"Closed caption utilities");
|
||||||
|
|
||||||
ret |= GST_ELEMENT_REGISTER (cccombiner, plugin);
|
ret |= GST_ELEMENT_REGISTER (cccombiner, plugin);
|
||||||
ret |= GST_ELEMENT_REGISTER (ccconverter, plugin);
|
ret |= GST_ELEMENT_REGISTER (ccconverter, plugin);
|
||||||
ret |= GST_ELEMENT_REGISTER (ccextractor, plugin);
|
ret |= GST_ELEMENT_REGISTER (ccextractor, plugin);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user