Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] libavformat/usmdec: add support for HCA stream decryption
@ 2025-06-24  6:19 Pavel Roslyy
  2025-06-24  6:25 ` Pavel Roslyy
  0 siblings, 1 reply; 2+ messages in thread
From: Pavel Roslyy @ 2025-06-24  6:19 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Pavel Roslyy

---
 libavformat/usmdec.c | 53 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/libavformat/usmdec.c b/libavformat/usmdec.c
index fd28e935ce..c5f2e208df 100644
--- a/libavformat/usmdec.c
+++ b/libavformat/usmdec.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/opt.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
@@ -47,10 +48,14 @@ typedef struct USMChannel {
 } USMChannel;
 
 typedef struct USMDemuxContext {
+    const AVClass *class;
     USMChannel ch[4][256];
     int nb_channels[4];
     uint8_t *header;
     unsigned header_size;
+    int64_t hca_keyl;
+    int64_t hca_keyh;
+    int hca_subkey;
 } USMDemuxContext;
 
 static int usm_probe(const AVProbeData *p)
@@ -314,6 +319,7 @@ static int64_t parse_chunk(AVFormatContext *s, AVIOContext *pb,
                     par->sample_rate = ch->rate.num;
                     par->ch_layout.nb_channels = ch->nb_channels;
                     st->duration = ch->duration;
+                    get_extradata = 1;
                     break;
                 }
 
@@ -323,7 +329,6 @@ static int64_t parse_chunk(AVFormatContext *s, AVIOContext *pb,
                 avpriv_set_pts_info(st, 64, ch->rate.den, ch->rate.num);
 
                 ffstream(st)->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
-                get_extradata = ch->codec_id == AV_CODEC_ID_ADPCM_ADX;
                 ch->extradata_pos = avio_tell(pb);
             }
 
@@ -333,10 +338,29 @@ static int64_t parse_chunk(AVFormatContext *s, AVIOContext *pb,
 
             pkt_size = chunk_size - (ret - chunk_start) - padding_size;
             if (get_extradata) {
-                if ((ret = ff_get_extradata(s, st->codecpar, pb, pkt_size)) < 0)
+                AVCodecParameters *par;
+                par = st->codecpar;
+
+                // HCA decoder expects last 10 bytes to contain decryption keys
+                int key_buf = ch->codec_id == AV_CODEC_ID_HCA ? 10 : 0;
+                ret = ff_alloc_extradata(par, pkt_size + key_buf);
+                if (ret < 0)
                     return ret;
+
+                ret = avio_read(pb, par->extradata, pkt_size);
+                if (ret < pkt_size) {
+                    av_freep(&par->extradata);
+                    par->extradata_size = 0;
+                    return AVERROR(EIO);
+                }
+
+                if (ch->codec_id == AV_CODEC_ID_HCA) {
+                    AV_WB32(par->extradata + par->extradata_size - 10, usm->hca_keyh);
+                    AV_WB32(par->extradata + par->extradata_size -  6, usm->hca_keyl);
+                    AV_WB16(par->extradata + par->extradata_size -  2, usm->hca_subkey);
+                }
             } else {
-                if (ret == ch->extradata_pos && ch->codec_id == AV_CODEC_ID_ADPCM_ADX) {
+                if (ret == ch->extradata_pos && ch->type == AVMEDIA_TYPE_AUDIO) {
                     avio_skip(pb, pkt_size);
                     ret = 0;
                 } else {
@@ -416,10 +440,33 @@ static int usm_read_close(AVFormatContext *s)
     return 0;
 }
 
+#define OFFSET(x) offsetof(USMDemuxContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption usm_options[] = {
+    { "hca_lowkey",
+        "Low key used for handling CRI HCA streams", OFFSET(hca_keyl),
+        AV_OPT_TYPE_INT64, {.i64=0}, .min = 0, .max = UINT32_MAX, .flags = FLAGS, },
+    { "hca_highkey",
+        "High key used for handling CRI HCA streams", OFFSET(hca_keyh),
+        AV_OPT_TYPE_INT64, {.i64=0}, .min = 0, .max = UINT32_MAX, .flags = FLAGS, },
+    { "hca_subkey",
+        "Subkey used for handling CRI HCA streams", OFFSET(hca_subkey),
+        AV_OPT_TYPE_INT, {.i64=0}, .min = 0, .max = UINT16_MAX, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass usm_class = {
+    .class_name = "usm",
+    .item_name  = av_default_item_name,
+    .option     = usm_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 const FFInputFormat ff_usm_demuxer = {
     .p.name         = "usm",
     .p.long_name    = NULL_IF_CONFIG_SMALL("CRI USM"),
     .p.extensions   = "usm",
+    .p.priv_class   = &usm_class,
     .p.flags        = AVFMT_GENERIC_INDEX | AVFMT_NO_BYTE_SEEK | AVFMT_NOBINSEARCH,
     .priv_data_size = sizeof(USMDemuxContext),
     .read_probe     = usm_probe,
-- 
2.49.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-06-24  6:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-24  6:19 [FFmpeg-devel] [PATCH] libavformat/usmdec: add support for HCA stream decryption Pavel Roslyy
2025-06-24  6:25 ` Pavel Roslyy

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git