1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

lavc: add smpte436m_to_eia608 bitstream filter

Signed-off-by: Jacob Lifshay <programmerjake@gmail.com>
This commit is contained in:
Jacob Lifshay
2025-07-22 23:17:37 -07:00
parent 1c85a3832a
commit aa5b9db7bd
5 changed files with 97 additions and 0 deletions

1
configure vendored
View File

@@ -3539,6 +3539,7 @@ h264_redundant_pps_bsf_select="cbs_h264"
hevc_metadata_bsf_select="cbs_h265"
mjpeg2jpeg_bsf_select="jpegtables"
mpeg2_metadata_bsf_select="cbs_mpeg2"
smpte436m_to_eia608_bsf_select="smpte_436m"
trace_headers_bsf_select="cbs cbs_vp8"
vp9_metadata_bsf_select="cbs_vp9"
vvc_metadata_bsf_select="cbs_h266"

View File

@@ -948,6 +948,11 @@ ffmpeg -i INPUT -c:a copy -bsf:a setts=pts=DTS out.mkv
Log basic packet information. Mainly useful for testing, debugging,
and development.
@section smpte436m_to_eia608
Convert from a @code{SMPTE_436M_ANC} data stream to a @code{EIA_608} stream,
extracting the closed captions from CTA-708 CDP VANC packets, and ignoring all other data.
@anchor{text2movsub}
@section text2movsub

View File

@@ -61,6 +61,7 @@ extern const FFBitStreamFilter ff_prores_metadata_bsf;
extern const FFBitStreamFilter ff_remove_extradata_bsf;
extern const FFBitStreamFilter ff_setts_bsf;
extern const FFBitStreamFilter ff_showinfo_bsf;
extern const FFBitStreamFilter ff_smpte436m_to_eia608_bsf;
extern const FFBitStreamFilter ff_text2movsub_bsf;
extern const FFBitStreamFilter ff_trace_headers_bsf;
extern const FFBitStreamFilter ff_truehd_core_bsf;

View File

@@ -38,6 +38,7 @@ OBJS-$(CONFIG_PRORES_METADATA_BSF) += bsf/prores_metadata.o
OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += bsf/remove_extradata.o
OBJS-$(CONFIG_SETTS_BSF) += bsf/setts.o
OBJS-$(CONFIG_SHOWINFO_BSF) += bsf/showinfo.o
OBJS-$(CONFIG_SMPTE436M_TO_EIA608_BSF) += bsf/smpte436m_to_eia608.o
OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += bsf/movsub.o
OBJS-$(CONFIG_TRACE_HEADERS_BSF) += bsf/trace_headers.o
OBJS-$(CONFIG_TRUEHD_CORE_BSF) += bsf/truehd_core.o

View File

@@ -0,0 +1,89 @@
/*
* MXF SMPTE-436M ANC to EIA-608 bitstream filter
* Copyright (c) 2025 Jacob Lifshay
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "bsf.h"
#include "bsf_internal.h"
#include "codec_id.h"
#include "libavcodec/smpte_436m.h"
#include "libavutil/error.h"
static av_cold int ff_smpte436m_to_eia608_init(AVBSFContext *ctx)
{
ctx->par_out->codec_type = AVMEDIA_TYPE_SUBTITLE;
ctx->par_out->codec_id = AV_CODEC_ID_EIA_608;
return 0;
}
static int ff_smpte436m_to_eia608_filter(AVBSFContext *ctx, AVPacket *out)
{
AVPacket *in;
int ret = ff_bsf_get_packet(ctx, &in);
if (ret < 0)
return ret;
AVSmpte436mAncIterator iter;
ret = av_smpte_436m_anc_iter_init(&iter, in->data, in->size);
if (ret < 0)
goto fail;
AVSmpte436mCodedAnc coded_anc;
while ((ret = av_smpte_436m_anc_iter_next(&iter, &coded_anc)) >= 0) {
AVSmpte291mAnc8bit anc;
ret = av_smpte_291m_anc_8bit_decode(
&anc, coded_anc.payload_sample_coding, coded_anc.payload_sample_count, coded_anc.payload, ctx);
if (ret < 0)
goto fail;
ret = av_smpte_291m_anc_8bit_extract_cta_708(&anc, NULL, ctx);
if (ret == AVERROR(EAGAIN))
continue;
if (ret < 0)
goto fail;
int cc_count = ret;
ret = av_new_packet(out, 3 * cc_count);
if (ret < 0)
goto fail;
ret = av_packet_copy_props(out, in);
if (ret < 0)
goto fail;
// verified it won't fail by running it above
av_smpte_291m_anc_8bit_extract_cta_708(&anc, out->data, ctx);
return 0;
}
if (ret != AVERROR_EOF)
return ret;
ret = AVERROR(EAGAIN);
fail:
if (ret < 0)
av_packet_unref(out);
av_packet_free(&in);
return ret;
}
const FFBitStreamFilter ff_smpte436m_to_eia608_bsf = {
.p.name = "smpte436m_to_eia608",
.p.codec_ids = (const enum AVCodecID[]){ AV_CODEC_ID_SMPTE_436M_ANC, AV_CODEC_ID_NONE },
.init = ff_smpte436m_to_eia608_init,
.filter = ff_smpte436m_to_eia608_filter,
};