[FFmpeg-devel] [PATCH] libavcodec/mpeg12dec: extract embedded CC of particular type only

2022-04-27 Thread Ivan Baykalov
Some streams contain closed caption data embedded using several wrapping
types. For example stream can contain CC wrapped as ATSC A53 packets +
the same data wrapped as SCTE-20 packets. Prior to the patch CC data was
extracted from both types of packets, so it gave duplicated character
pairs on the output.

Now we calculate some statistics which CC types appear more often in the
stream and extract the data from a single type only. If at some point
the other CC type becomes more active, we switch to this new type.

Fixes ticket #9724.
---
 libavcodec/mpeg12dec.c | 44 ++
 1 file changed, 44 insertions(+)

diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index e9bde48f7a..f7e54ef0a9 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -58,6 +58,14 @@
 
 #define A53_MAX_CC_COUNT 2000
 
+typedef enum CcType {
+CC_TYPE_UNKNOWN = -1,
+CC_TYPE_A53 = 0,
+CC_TYPE_SCTE20,
+CC_TYPE_DVD,
+CC_TYPE_COUNT
+} CcType;
+
 typedef struct Mpeg1Context {
 MpegEncContext mpeg_enc_ctx;
 int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
@@ -81,6 +89,7 @@ typedef struct Mpeg1Context {
 int first_slice;
 int extradata_decoded;
 int64_t timecode_frame_start;  /*< GOP timecode frame start number, in non 
drop frame format */
+int cc_packet_count[CC_TYPE_COUNT];
 } Mpeg1Context;
 
 #define MB_TYPE_ZERO_MV   0x2000
@@ -2198,6 +2207,32 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
 return 0;
 }
 
+static int cc_type_is_selected(Mpeg1Context *s1, CcType type)
+{
+int max = 0;
+int max_index = -1;
+int sum = 0;
+av_assert0(type >= 0 && type < CC_TYPE_COUNT);
+s1->cc_packet_count[type]++;
+
+for (int i = 0; i < CC_TYPE_COUNT; i++) {
+if (s1->cc_packet_count[i] > max) {
+max = s1->cc_packet_count[i];
+max_index = i;
+}
+sum += s1->cc_packet_count[i];
+}
+
+if (sum < 2 || sum > 20) {
+// reset statistics, but give some advantage to the current selection
+// to avoid frequent switching between the types
+memset(s1->cc_packet_count, 0, sizeof(s1->cc_packet_count));
+s1->cc_packet_count[max_index] = 2;
+}
+
+return type == max_index;
+}
+
 static int mpeg_decode_a53_cc(AVCodecContext *avctx,
   const uint8_t *p, int buf_size)
 {
@@ -2217,6 +2252,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
 if (new_size > 3*A53_MAX_CC_COUNT)
 return AVERROR(EINVAL);
 
+if (!cc_type_is_selected(s1, CC_TYPE_A53))
+return 0;
+
 ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
 if (ret >= 0)
 memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * 
UINT64_C(3));
@@ -2240,6 +2278,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
 if (new_size > 3*A53_MAX_CC_COUNT)
 return AVERROR(EINVAL);
 
+if (!cc_type_is_selected(s1, CC_TYPE_SCTE20))
+return 0;
+
 ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
 if (ret >= 0) {
 uint8_t field, cc1, cc2;
@@ -2310,6 +2351,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
 if (new_size > 3*A53_MAX_CC_COUNT)
 return AVERROR(EINVAL);
 
+if (!cc_type_is_selected(s1, CC_TYPE_DVD))
+return 0;
+
 ret = av_buffer_realloc(&s1->a53_buf_ref, new_size);
 if (ret >= 0) {
 uint8_t field1 = !!(p[4] & 0x80);
-- 
2.35.1

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] libavformat/isom: Add more language mappings

2022-04-27 Thread Ivan Baykalov
mov_mdhd_language_map table doesn't contain ISO 639 codes for some of
the languages. I added a few which have no contradictory mappings

Fixes ticket #9743
---
 libavformat/isom.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavformat/isom.c b/libavformat/isom.c
index e6569dfb68..2bc240ed5c 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -119,9 +119,9 @@ static const char mov_mdhd_language_map[][4] = {
 "hun",/*  26 Hungarian */
 "est",/*  27 Estonian */
 "lav",/*  28 Latvian */
-   "",/*  29 Sami */
+"smi",/*  29 Sami */
 "fo ",/*  30 Faroese */
-   "",/*  31 Farsi */
+"per",/*  31 Farsi */
 "rus",/*  32 Russian */
 "chi",/*  33 Simplified Chinese */
"",/*  34 Flemish */
@@ -166,7 +166,7 @@ static const char mov_mdhd_language_map[][4] = {
 "kan",/*  73 Kannada */
 "tam",/*  74 Tamil */
 "tel",/*  75 Telugu */
-   "",/*  76 Sinhala */
+"sin",/*  76 Sinhala */
 "bur",/*  77 Burmese */
 "khm",/*  78 Khmer */
 "lao",/*  79 Lao */
@@ -180,9 +180,9 @@ static const char mov_mdhd_language_map[][4] = {
 "orm",/*  87 Oromo */
 "som",/*  88 Somali */
 "swa",/*  89 Swahili */
-   "",/*  90 Kinyarwanda */
+"kin",/*  90 Kinyarwanda */
 "run",/*  91 Rundi */
-   "",/*  92 Nyanja */
+"nya",/*  92 Nyanja */
 "mlg",/*  93 Malagasy */
 "epo",/*  94 Esperanto */
"",/*  95  */
-- 
2.35.1

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] libavformat/isom: Add more language mappings

2022-06-06 Thread Ivan Baykalov
Ping

ср, 27 апр. 2022 г. в 18:00, Ivan Baykalov <4ru...@gmail.com>:

> mov_mdhd_language_map table doesn't contain ISO 639 codes for some of
> the languages. I added a few which have no contradictory mappings
>
> Fixes ticket #9743
> ---
>  libavformat/isom.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/libavformat/isom.c b/libavformat/isom.c
> index e6569dfb68..2bc240ed5c 100644
> --- a/libavformat/isom.c
> +++ b/libavformat/isom.c
> @@ -119,9 +119,9 @@ static const char mov_mdhd_language_map[][4] = {
>  "hun",/*  26 Hungarian */
>  "est",/*  27 Estonian */
>  "lav",/*  28 Latvian */
> -   "",/*  29 Sami */
> +"smi",/*  29 Sami */
>  "fo ",/*  30 Faroese */
> -   "",/*  31 Farsi */
> +"per",/*  31 Farsi */
>  "rus",/*  32 Russian */
>  "chi",/*  33 Simplified Chinese */
> "",/*  34 Flemish */
> @@ -166,7 +166,7 @@ static const char mov_mdhd_language_map[][4] = {
>  "kan",/*  73 Kannada */
>  "tam",/*  74 Tamil */
>  "tel",/*  75 Telugu */
> -   "",/*  76 Sinhala */
> +"sin",/*  76 Sinhala */
>  "bur",/*  77 Burmese */
>  "khm",/*  78 Khmer */
>  "lao",/*  79 Lao */
> @@ -180,9 +180,9 @@ static const char mov_mdhd_language_map[][4] = {
>  "orm",/*  87 Oromo */
>  "som",/*  88 Somali */
>  "swa",/*  89 Swahili */
> -   "",/*  90 Kinyarwanda */
> +"kin",/*  90 Kinyarwanda */
>  "run",/*  91 Rundi */
> -   "",/*  92 Nyanja */
> +"nya",/*  92 Nyanja */
>  "mlg",/*  93 Malagasy */
>  "epo",/*  94 Esperanto */
> "",/*  95  */
> --
> 2.35.1
>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avformat/mov: read PCM audio configuration box ('pcmC') if available

2022-06-07 Thread Ivan Baykalov
For ipcm and fpcm streams, big-endian format is the default, but it can be 
changed
with additional 'pcmC' sub-atom of audio sample description.

Details can be found in ISO/IEC 23003-5:2020

Fixes ticket #9763
Fixes ticket #9790
---
 libavformat/mov.c | 60 +++
 1 file changed, 60 insertions(+)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index d7be593a86..f71a470d9c 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7567,6 +7567,65 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 return atom.size;
 }
 
+static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+int version, format_flags, pcm_sample_size;
+AVStream *st;
+
+if (atom.size < 6) {
+av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
+return AVERROR_INVALIDDATA;
+}
+
+version = avio_r8(pb);
+if (version) {
+av_log(c->fc, AV_LOG_WARNING, "Unsupported pcmC box version %d\n", 
version);
+return 0;
+}
+
+avio_rb24(pb);  // flags
+
+if (c->fc->nb_streams < 1)
+return 0;
+st = c->fc->streams[c->fc->nb_streams-1];
+if (!st || !st->codecpar)
+return 0;
+
+format_flags = avio_r8(pb);
+if (format_flags == 1) { // indicates little-endian format. If not 
present, big-endian format is used
+if (st->codecpar->codec_tag == MKTAG('i','p','c','m')) {
+switch (st->codecpar->codec_id) {
+case AV_CODEC_ID_PCM_S16BE:
+st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
+break;
+case AV_CODEC_ID_PCM_S24BE:
+st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
+break;
+case AV_CODEC_ID_PCM_S32BE:
+st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
+break;
+}
+}
+else if (st->codecpar->codec_tag == MKTAG('f','p','c','m')) {
+switch (st->codecpar->codec_id) {
+case AV_CODEC_ID_PCM_F32BE:
+st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
+break;
+case AV_CODEC_ID_PCM_F64BE:
+st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
+break;
+}
+}
+}
+
+pcm_sample_size = avio_r8(pb);
+if (pcm_sample_size != st->codecpar->bits_per_coded_sample) {
+av_log(c->fc, AV_LOG_WARNING, "Unexpected pcmC sample size (%d vs 
%d)\n", pcm_sample_size, st->codecpar->bits_per_coded_sample);
+}
+
+return 0;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -7670,6 +7729,7 @@ static const MOVParseTableEntry mov_default_parse_table[] 
= {
 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
 { MKTAG('i','l','o','c'), mov_read_iloc },
+{ MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
 { 0, NULL }
 };
 
-- 
2.35.1

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] libavformat/movenc.c: Fix avg_frame_rate inversion on timecode track writing

2020-11-08 Thread Ivan Baykalov
When mov_create_timecode_track function is executed,
track->st->avg_frame_rate becomes inverted due to
track->st->avg_frame_rate = av_inv_q(rate);

, where "rate" is frame per second here.

I didn't find any obvious negative effect of this operation, but this may
lead to some misunderstanding. In particular, it's hard to say why number
of frames per second could be calculated as

nb_frames  = ROUNDED_DIV(track->st->avg_frame_rate.den,
track->st->avg_frame_rate.num);

---

 libavformat/movenc.c | 6 +++---

 1 file changed, 3 insertions(+), 3 deletions(-)



diff --git a/libavformat/movenc.c b/libavformat/movenc.c index
fea8a86192..e06c902c84 100644

--- a/libavformat/movenc.c

+++ b/libavformat/movenc.c

@@ -2352,8 +2352,8 @@ static int mov_write_tmcd_tag(AVIOContext *pb,
MOVTrack *track)

 return AVERROR(EINVAL);

 #endif

 } else {

-frame_duration = av_rescale(track->timescale,
track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);

-nb_frames  = ROUNDED_DIV(track->st->avg_frame_rate.den,
track->st->avg_frame_rate.num);

+frame_duration = av_rescale(track->timescale,
track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);

+nb_frames  = ROUNDED_DIV(track->st->avg_frame_rate.num,
track->st->avg_frame_rate.den);

 }



 if (nb_frames > 255) {

@@ -6190,7 +6190,7 @@ static int mov_create_timecode_track(AVFormatContext
*s, int index, int src_inde

 return AVERROR(ENOMEM);

 track->par->codec_type = AVMEDIA_TYPE_DATA;

 track->par->codec_tag  = track->tag;

-track->st->avg_frame_rate = av_inv_q(rate);

+track->st->avg_frame_rate = rate;



 /* the tmcd track just contains one packet with the frame number */

 AV_WB32(pkt.data, tc.start);

--

2.28.0.windows.1
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".