diff mbox series

[FFmpeg-devel,1/3] closed caption decoder: accept and decode a new codec type of 'raw 608 byte pairs'

Message ID CAL1QdWc4m+E2Ks4VJXvzq+vuBkqpOOMzyWTn0Gh2B-HVE-XAfg@mail.gmail.com
State New
Headers show
Series [FFmpeg-devel,1/3] closed caption decoder: accept and decode a new codec type of 'raw 608 byte pairs'
Related show

Checks

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

Commit Message

Roger Pack April 28, 2020, 6:15 a.m. UTC
I needed this in order to be able to parse raw analog TV closed
caption byte pairs (analog line 21 CC's).

Signed-off-by: rogerdpack <rogerpack2005@gmail.com>
---
 configure                 |   1 +
 libavcodec/Makefile       |   2 +-
 libavcodec/allcodecs.c    |   1 +
 libavcodec/ccaption_dec.c | 117 ++++++++++++++++++++++++++------------
 libavcodec/codec_desc.c   |   7 +++
 libavcodec/codec_id.h     |   1 +
 libavcodec/version.h      |   4 +-
 7 files changed, 93 insertions(+), 40 deletions(-)

Comments

Michael Niedermayer April 28, 2020, 5:32 p.m. UTC | #1
On Tue, Apr 28, 2020 at 12:15:19AM -0600, Roger Pack wrote:
> I needed this in order to be able to parse raw analog TV closed
> caption byte pairs (analog line 21 CC's).

>  configure                 |    1 
>  libavcodec/Makefile       |    2 
>  libavcodec/allcodecs.c    |    1 
>  libavcodec/ccaption_dec.c |  117 +++++++++++++++++++++++++++++++---------------
>  libavcodec/codec_desc.c   |    7 ++
>  libavcodec/codec_id.h     |    1 
>  libavcodec/version.h      |    4 -
>  7 files changed, 93 insertions(+), 40 deletions(-)
> c9153590e5f167e41910d867639eb887164e28d2  0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> From: rogerdpack <rogerpack2005@gmail.com>
> Date: Tue, 28 Apr 2020 05:15:15 +0000
> Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
>  type of 'raw 608 byte pairs'

breaks fate

TEST    sub-cc-realtime
--- ./tests/ref/fate/sub-cc-realtime	2020-04-28 15:43:10.506887112 +0200
+++ tests/data/fate/sub-cc-realtime	2020-04-28 19:31:37.164407976 +0200
@@ -1,42 +0,0 @@
-[Script Info]
-; Script generated by FFmpeg/Lavc
-ScriptType: v4.00+
-PlayResX: 384
-PlayResY: 288
-
-[V4+ Styles]
-Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
-Style: Default,Monospace,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,3,1,0,2,10,10,10,0
-
-[Events]
-Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
-Dialogue: 0,0:00:14.14,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}(
-Dialogue: 0,0:00:15.47,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} in
-Dialogue: 0,0:00:15.92,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inau
-Dialogue: 0,0:00:16.36,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudi
-Dialogue: 0,0:00:16.81,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudibl
-Dialogue: 0,0:00:17.25,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible 
-Dialogue: 0,0:00:17.70,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible ra
-Dialogue: 0,0:00:18.14,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radi
-Dialogue: 0,0:00:18.59,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio 
-Dialogue: 0,0:00:19.03,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio ch
-Dialogue: 0,0:00:19.48,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio chat
-Dialogue: 0,0:00:19.92,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio chatte
-Dialogue: 0,0:00:20.36,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio chatter
-Dialogue: 0,0:00:21.70,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,44)}({\i1} inaudible radio chatter{\i0} )
-Dialogue: 0,0:00:42.61,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>>
-Dialogue: 0,0:00:43.05,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> S
-Dialogue: 0,0:00:43.50,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Saf
-Dialogue: 0,0:00:43.94,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safet
-Dialogue: 0,0:00:44.39,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety 
-Dialogue: 0,0:00:44.83,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety re
-Dialogue: 0,0:00:45.28,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety rema
-Dialogue: 0,0:00:45.72,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remain
-Dialogue: 0,0:00:46.17,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains 
-Dialogue: 0,0:00:46.61,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains ou
-Dialogue: 0,0:00:47.06,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our 
-Dialogue: 0,0:00:47.50,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our nu
-Dialogue: 0,0:00:47.95,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our numb
-Dialogue: 0,0:00:48.39,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our number
-Dialogue: 0,0:00:48.84,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our number o
-Dialogue: 0,0:00:49.28,9:59:59.99,Default,,0,0,0,,{\an7}{\pos(38,28)}({\i1} inaudible radio chatter{\i0} )\N{\an7}{\pos(38,44)}>> Safety remains our number one
Test sub-cc-realtime failed. Look at tests/data/fate/sub-cc-realtime.err for details.
tests/Makefile:254: recipe for target 'fate-sub-cc-realtime' failed
make: *** [fate-sub-cc-realtime] Error 1

[...]
Roger Pack April 30, 2020, 5:23 a.m. UTC | #2
> > c9153590e5f167e41910d867639eb887164e28d2  0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> > From: rogerdpack <rogerpack2005@gmail.com>
> > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
> >  type of 'raw 608 byte pairs'
>
> breaks fate
>
> TEST    sub-cc-realtime
> --- ./tests/ref/fate/sub-cc-realtime    2020-04-28 15:43:10.506887112 +0200
> +++ tests/data/fate/sub-cc-realtime     2020-04-28 19:31:37.164407976 +0200

OK I believe to have fixed that, see the latest attached.  Plus a few
more aesthetic cleanups to boot.

Thanks!
Kieran Kunhya April 30, 2020, 9:58 a.m. UTC | #3
On Thu, 30 Apr 2020 at 07:22, Roger Pack <rogerdpack2@gmail.com> wrote:

> > > c9153590e5f167e41910d867639eb887164e28d2
> 0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> > > From: rogerdpack <rogerpack2005@gmail.com>
> > > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > > Subject: [PATCH 1/3] closed caption decoder: accept and decode a new
> codec
> > >  type of 'raw 608 byte pairs'
>

How does this content exist? Are you defining your own file format with the
byte pairs?

Kieran
Roger Pack May 1, 2020, 3:59 a.m. UTC | #4
On Thu, Apr 30, 2020 at 4:30 AM Kieran Kunhya <kierank@obe.tv> wrote:
>
> On Thu, 30 Apr 2020 at 07:22, Roger Pack <rogerdpack2@gmail.com> wrote:
>
> > > > c9153590e5f167e41910d867639eb887164e28d2
> > 0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > > > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> > > > From: rogerdpack <rogerpack2005@gmail.com>
> > > > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > > > Subject: [PATCH 1/3] closed caption decoder: accept and decode a new
> > codec
> > > >  type of 'raw 608 byte pairs'
> >
>
> How does this content exist? Are you defining your own file format with the
> byte pairs?

It's transmitted as "raw byte pairs" by analog TV broadcast in the US.
https://en.wikipedia.org/wiki/EIA-608 has  details.

I believe it transmits  one closed caption character (or control code)
per frame (basically a single byte pair on "line 21") so it can do 30
closed caption chars/second.  Anyway that's where it's originating
from.  Good question :)

Thanks!
Kieran Kunhya May 1, 2020, 6:22 a.m. UTC | #5
On Fri, 1 May 2020 at 04:59, Roger Pack <rogerdpack2@gmail.com> wrote:

> On Thu, Apr 30, 2020 at 4:30 AM Kieran Kunhya <kierank@obe.tv> wrote:
> >
> > On Thu, 30 Apr 2020 at 07:22, Roger Pack <rogerdpack2@gmail.com> wrote:
> >
> > > > > c9153590e5f167e41910d867639eb887164e28d2
> > > 0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > > > > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00
> 2001
> > > > > From: rogerdpack <rogerpack2005@gmail.com>
> > > > > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > > > > Subject: [PATCH 1/3] closed caption decoder: accept and decode a
> new
> > > codec
> > > > >  type of 'raw 608 byte pairs'
> > >
> >
> > How does this content exist? Are you defining your own file format with
> the
> > byte pairs?
>
> It's transmitted as "raw byte pairs" by analog TV broadcast in the US.
> https://en.wikipedia.org/wiki/EIA-608 has  details.
>
> I believe it transmits  one closed caption character (or control code)
> per frame (basically a single byte pair on "line 21") so it can do 30
> closed caption chars/second.  Anyway that's where it's originating
> from.  Good question :)
>

Yes, but these byte pairs are usually in a container or exist in an
analogue waveform.
Have you defined your own format of "raw byte pairs"? That doesn't exist in
the wild as far as I know.

Kieran
Roger Pack May 2, 2020, 4:10 a.m. UTC | #6
On Fri, May 1, 2020 at 12:22 AM Kieran Kunhya <kierank@obe.tv> wrote:
>
> On Fri, 1 May 2020 at 04:59, Roger Pack <rogerdpack2@gmail.com> wrote:
>
> > On Thu, Apr 30, 2020 at 4:30 AM Kieran Kunhya <kierank@obe.tv> wrote:
> > >
> > > On Thu, 30 Apr 2020 at 07:22, Roger Pack <rogerdpack2@gmail.com> wrote:
> > >
> > > > > > c9153590e5f167e41910d867639eb887164e28d2
> > > > 0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > > > > > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00
> > 2001
> > > > > > From: rogerdpack <rogerpack2005@gmail.com>
> > > > > > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > > > > > Subject: [PATCH 1/3] closed caption decoder: accept and decode a
> > new
> > > > codec
> > > > > >  type of 'raw 608 byte pairs'
> > > >
> > >
> > > How does this content exist? Are you defining your own file format with
> > the
> > > byte pairs?
> >
> > It's transmitted as "raw byte pairs" by analog TV broadcast in the US.
> > https://en.wikipedia.org/wiki/EIA-608 has  details.
> >
> > I believe it transmits  one closed caption character (or control code)
> > per frame (basically a single byte pair on "line 21") so it can do 30
> > closed caption chars/second.  Anyway that's where it's originating
> > from.  Good question :)
> >
>
> Yes, but these byte pairs are usually in a container or exist in an
> analogue waveform.

It's from analogue waveform, it gets pulled out by the analog TV
decoder card into the byte pairs.
The container is basically "which frame" the line 21 data happened to
come in with.  It comes in with two bytes/frame.
It comes in with a timestamp given by (I presume) the timestamp of the
frame it accompanies as a pin in directshow (in windows).

Directshow with the tuner card presents the line 21 data as "VBI
packets" (with a header specifying which portion of the VBI it comes
from, line 21 "odd" or line 21 "even"), and a timestamp.

There is another directshow filter that basically filters out the VBI
data and passes on just the "raw byte pairs" for a given CC stream.
See attached, but only concentrate on the "VBI Codec" filter box.  It
presents  two "CC" pins, the first of which we accept the byte pairs
from (with patch 3/3) [1]

So it's an analog standard, which directshow handles this way, and
it's converted to byte pairs.

> Have you defined your own format of "raw byte pairs"? That doesn't exist in
> the wild as far as I know.

The "format" is normal EIA 608
https://en.wikipedia.org/wiki/EIA-608
The "characters" section.
There was already a codec named "AV_CODEC_ID_EIA_608", but it was
really EIA 608 encapsulated within an EIA 708 stream, so I went with a
new name.  The existing 608 decoder already decoded the "byte pairs"
internally I just needed to be able to access it without the
encapsulation for this particular input.
In the analog stream they "come in" on the line 21 data as EIA byte
pairs.  No 708 encapsulation, hence me calling it "raw"
(AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS).
So it seems standard.

Cheers.

-roger-

[1] If you care about the nitty gritty, here's the media types that
the pins present:

VBI pin:
Media type: MEDIATYPE_VBI {F72A76E1-EB0A-11D0-ACE4-0000C0CC16BA}
Subtype: KSDATAFORMAT_SUBTYPE_RAW8 {CA20D9A0-3E3E-11D1-9BF9-00C04FBBDEBF}
Format type: {F72A76E0-EB0A-11D0-ACE4-0000C0CC16BA}

CC pin:
Media type: MEDIATYPE_AUXLine21Data {670AEA80-3A82-11D0-B79B-00AA003767A7}
Subtype: MEDIASUBTYPE_Line21_BytePair {6E8D4A22-310C-11D0-B79A-00AA003767A7}
Format type: FORMAT_None {0F6417D6-C318-11D0-A43F-00A0C9223196}
Roger Pack May 5, 2020, 2:38 p.m. UTC | #7
Bump...

On Wed, Apr 29, 2020 at 11:23 PM Roger Pack <rogerdpack2@gmail.com> wrote:
>
> > > c9153590e5f167e41910d867639eb887164e28d2  0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> > > From: rogerdpack <rogerpack2005@gmail.com>
> > > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > > Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
> > >  type of 'raw 608 byte pairs'
> >
> > breaks fate
> >
> > TEST    sub-cc-realtime
> > --- ./tests/ref/fate/sub-cc-realtime    2020-04-28 15:43:10.506887112 +0200
> > +++ tests/data/fate/sub-cc-realtime     2020-04-28 19:31:37.164407976 +0200
>
> OK I believe to have fixed that, see the latest attached.  Plus a few
> more aesthetic cleanups to boot.
>
> Thanks!
Anton Khirnov May 7, 2020, 12:32 p.m. UTC | #8
Quoting Roger Pack (2020-04-28 08:15:19)
> From 5d7c12a3f703e794e1092087355bc9523d5f4d93 Mon Sep 17 00:00:00 2001
> From: rogerdpack <rogerpack2005@gmail.com>
> Date: Tue, 28 Apr 2020 05:15:15 +0000
> Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
>  type of 'raw 608 byte pairs'
> 
> Signed-off-by: rogerdpack <rogerpack2005@gmail.com>
> ---
> diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
> index e7d6e059db..805e18758b 100644
> --- a/libavcodec/codec_id.h
> +++ b/libavcodec/codec_id.h
> @@ -513,6 +513,7 @@ enum AVCodecID {
>  
>      AV_CODEC_ID_MICRODVD   = 0x17800,
>      AV_CODEC_ID_EIA_608,
> +    AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,

You can't just add new IDs in the middle of the table, it changes the
IDs of all the following codecs which breaks ABI.
Add it to the end of the subtitle block.
Paul B Mahol May 7, 2020, 1:06 p.m. UTC | #9
Is it just me, or the coded id is too much verbose?

On 5/7/20, Anton Khirnov <anton@khirnov.net> wrote:
> Quoting Roger Pack (2020-04-28 08:15:19)
>> From 5d7c12a3f703e794e1092087355bc9523d5f4d93 Mon Sep 17 00:00:00 2001
>> From: rogerdpack <rogerpack2005@gmail.com>
>> Date: Tue, 28 Apr 2020 05:15:15 +0000
>> Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
>>  type of 'raw 608 byte pairs'
>>
>> Signed-off-by: rogerdpack <rogerpack2005@gmail.com>
>> ---
>> diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
>> index e7d6e059db..805e18758b 100644
>> --- a/libavcodec/codec_id.h
>> +++ b/libavcodec/codec_id.h
>> @@ -513,6 +513,7 @@ enum AVCodecID {
>>
>>      AV_CODEC_ID_MICRODVD   = 0x17800,
>>      AV_CODEC_ID_EIA_608,
>> +    AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
>
> You can't just add new IDs in the middle of the table, it changes the
> IDs of all the following codecs which breaks ABI.
> Add it to the end of the subtitle block.
>
> --
> Anton Khirnov
> _______________________________________________
> 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 080d93a129..8a0a6cce7c 100755
--- a/configure
+++ b/configure
@@ -2681,6 +2681,7 @@  bink_decoder_select="blockdsp hpeldsp"
 binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs"
 binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs"
 cavs_decoder_select="blockdsp golomb h264chroma idctdsp qpeldsp videodsp"
+ccaption_raw_608_decoder_select="ccaption_decoder"
 clearvideo_decoder_select="idctdsp"
 cllc_decoder_select="bswapdsp"
 comfortnoise_encoder_select="lpc"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 28076c2c83..006eb40107 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -246,6 +246,7 @@  OBJS-$(CONFIG_C93_DECODER)             += c93.o
 OBJS-$(CONFIG_CAVS_DECODER)            += cavs.o cavsdec.o cavsdsp.o \
                                           cavsdata.o
 OBJS-$(CONFIG_CCAPTION_DECODER)        += ccaption_dec.o ass.o
+OBJS-$(CONFIG_CCAPTION_RAW_608_DECODER)        += ccaption_dec.o ass.o
 OBJS-$(CONFIG_CDGRAPHICS_DECODER)      += cdgraphics.o
 OBJS-$(CONFIG_CDTOONS_DECODER)         += cdtoons.o
 OBJS-$(CONFIG_CDXL_DECODER)            += cdxl.o
@@ -463,7 +464,6 @@  OBJS-$(CONFIG_MP3ON4FLOAT_DECODER)     += mpegaudiodec_float.o mpeg4audio.o
 OBJS-$(CONFIG_MPC7_DECODER)            += mpc7.o mpc.o
 OBJS-$(CONFIG_MPC8_DECODER)            += mpc8.o mpc.o
 OBJS-$(CONFIG_MPEGVIDEO_DECODER)       += mpeg12dec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12dec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG1VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o
 OBJS-$(CONFIG_MPEG1_CUVID_DECODER)     += cuviddec.o
 OBJS-$(CONFIG_MPEG1_V4L2M2M_DECODER)   += v4l2_m2m_dec.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 54d40ebdbc..b78f58cb4c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -645,6 +645,7 @@  extern AVCodec ff_ssa_decoder;
 extern AVCodec ff_ass_encoder;
 extern AVCodec ff_ass_decoder;
 extern AVCodec ff_ccaption_decoder;
+extern AVCodec ff_ccaption_raw_608_decoder;
 extern AVCodec ff_dvbsub_encoder;
 extern AVCodec ff_dvbsub_decoder;
 extern AVCodec ff_dvdsub_encoder;
diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c
index bf3563a0bc..07091f4572 100644
--- a/libavcodec/ccaption_dec.c
+++ b/libavcodec/ccaption_dec.c
@@ -341,43 +341,53 @@  static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch)
 }
 
 /**
- * This function after validating parity bit, also remove it from data pair.
- * The first byte doesn't pass parity, we replace it with a solid blank
- * and process the pair.
- * If the second byte doesn't pass parity, it returns INVALIDDATA
- * user can ignore the whole pair and pass the other pair.
+ * This function accepts a byte pair [EIA 608 first byte, EIA 608 second byte]
+ * checks both for parity and strips parity on success.
+ * If the first byte doesn't pass parity, replace it with a solid blank
+ * and process the pair anyway.
+ * Returns failure for parity failure or "no data" (padding bytes).
+ */
+static int validate_eia_608_byte_pair(uint8_t *cc_data_pair) {
+    if (!av_parity(cc_data_pair[1])) {
+        return AVERROR_INVALIDDATA;
+    }
+    if (!av_parity(cc_data_pair[0])) {
+        cc_data_pair[0]=0x7F; // solid blank
+    }
+    if ((cc_data_pair[0] & 0x7F) == 0 && (cc_data_pair[1] & 0x7F) == 0) {
+        return AVERROR_INVALIDDATA; // padding bytes
+    }
+    /* remove parity bit */
+    cc_data_pair[0] &= 0x7F;
+    cc_data_pair[1] &= 0x7F;
+    return 0;
+}
+
+/**
+ * This function accepts "cc_data_pair" = [708 header byte, EIA 608 first byte, EIA 608 second byte]
+ * This function after validating parity bits, also removes parity bits them from 608 data pair.
  */
 static int validate_cc_data_pair(uint8_t *cc_data_pair)
 {
+    int ret;
     uint8_t cc_valid = (*cc_data_pair & 4) >>2;
     uint8_t cc_type = *cc_data_pair & 3;
 
     if (!cc_valid)
         return AVERROR_INVALIDDATA;
 
-    // if EIA-608 data then verify parity.
-    if (cc_type==0 || cc_type==1) {
-        if (!av_parity(cc_data_pair[2])) {
-            return AVERROR_INVALIDDATA;
-        }
-        if (!av_parity(cc_data_pair[1])) {
-            cc_data_pair[1]=0x7F;
-        }
-    }
-
-    //Skip non-data
-    if ((cc_data_pair[0] == 0xFA || cc_data_pair[0] == 0xFC || cc_data_pair[0] == 0xFD)
-         && (cc_data_pair[1] & 0x7F) == 0 && (cc_data_pair[2] & 0x7F) == 0)
-        return AVERROR_PATCHWELCOME;
-
-    //skip 708 data
+    // skip 708 data, we only support "608 over 708" not native 708
     if (cc_type == 3 || cc_type == 2)
+    {
         return AVERROR_PATCHWELCOME;
+    }
 
-    /* remove parity bit */
-    cc_data_pair[1] &= 0x7F;
-    cc_data_pair[2] &= 0x7F;
-
+    // Must be EIA-608 data, verify parity.
+    if (cc_type==0 || cc_type==1) {
+      if (ret = validate_eia_608_byte_pair(cc_data_pair + 1)) {
+          return ret;
+      }
+    }
     return 0;
 }
 
@@ -756,6 +766,8 @@  static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
     int len = avpkt->size;
     int ret = 0;
     int i;
+    int stride;
+    int raw_608 = avctx->codec_id == AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS;
 
     av_fast_padded_malloc(&ctx->pktbuf, &ctx->pktbuf_size, len);
     if (!ctx->pktbuf) {
@@ -764,16 +776,27 @@  static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
     }
     memcpy(ctx->pktbuf, avpkt->data, len);
     bptr = ctx->pktbuf;
-
-    for (i  = 0; i < len; i += 3) {
-        uint8_t cc_type = *(bptr + i) & 3;
-        if (validate_cc_data_pair(bptr + i))
-            continue;
-        /* ignoring data field 1 */
-        if(cc_type == 1)
-            continue;
-        else
-            process_cc608(ctx, start_time, *(bptr + i + 1) & 0x7f, *(bptr + i + 2) & 0x7f);
+    if (raw_608) {
+        stride = 2; // expect 2 byte "per packet"
+    }
+    for (i = 0; i < len; i += stride) {
+	if (raw_608) {
+            if (validate_eia_608_byte_pair(bptr)) {
+                continue;
+	    }
+	    process_cc608(ctx, start_time, *(bptr + i), *(bptr + i + 1));
+	} else {
+          // look for 608 over 708 bytes
+          uint8_t cc_type = *(bptr + i) & 3;
+          if (validate_cc_data_pair(bptr + i))
+              continue;
+          /* ignore NTSC_CC_FIELD_2 (cc_type 1) for now */
+          if (cc_type == 1)
+              continue;
+          else {
+              process_cc608(ctx, start_time, *(bptr + i + 1), *(bptr + i + 2));
+	  }
+	}
 
         if (!ctx->buffer_changed)
             continue;
@@ -781,7 +804,7 @@  static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
 
         if (*ctx->buffer.str || ctx->real_time)
         {
-            ff_dlog(ctx, "cdp writing data (%s)\n",ctx->buffer.str);
+            ff_dlog(ctx, "writing data (%s)\n",ctx->buffer.str);
             ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL);
             if (ret < 0)
                 return ret;
@@ -829,9 +852,16 @@  static const AVClass ccaption_dec_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
+static const AVClass ccaption_raw_608_dec_class = {
+    .class_name = "Closed caption Decoder Raw 608",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_ccaption_decoder = {
     .name           = "cc_dec",
-    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 / CEA-708)"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 over CEA-708)"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_EIA_608,
     .priv_data_size = sizeof(CCaptionSubContext),
@@ -841,3 +871,16 @@  AVCodec ff_ccaption_decoder = {
     .decode         = decode,
     .priv_class     = &ccaption_dec_class,
 };
+
+AVCodec ff_ccaption_raw_608_decoder = {
+    .name           = "cc_raw_608_dec",
+    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 raw byte pairs)"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
+    .priv_data_size = sizeof(CCaptionSubContext),
+    .init           = init_decoder,
+    .close          = close_decoder,
+    .flush          = flush_decoder,
+    .decode         = decode,
+    .priv_class     = &ccaption_raw_608_dec_class,
+};
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 93433b5a27..c706a5ba08 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3173,6 +3173,13 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"),
         .props     = AV_CODEC_PROP_TEXT_SUB,
     },
+    {
+        .id        = AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "eia_608_raw_byte_pairs",
+        .long_name = NULL_IF_CONFIG_SMALL("EIA-608 closed captions raw byte pairs"),
+        .props     = AV_CODEC_PROP_TEXT_SUB,
+    },
     {
         .id        = AV_CODEC_ID_EIA_608,
         .type      = AVMEDIA_TYPE_SUBTITLE,
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index e7d6e059db..805e18758b 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -513,6 +513,7 @@  enum AVCodecID {
 
     AV_CODEC_ID_MICRODVD   = 0x17800,
     AV_CODEC_ID_EIA_608,
+    AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
     AV_CODEC_ID_JACOSUB,
     AV_CODEC_ID_SAMI,
     AV_CODEC_ID_REALTEXT,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 3de16c884c..552129e0a3 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@ 
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR  82
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MINOR  83
+#define LIBAVCODEC_VERSION_MICRO  100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
-- 
2.17.1