This updated patch registers the 'uncv' tag in the isom_tags.c
ff_codec_movvideo_tags[] list. However, I still need to specify the tag
with the "-tag:v uncv" option. I hoped this change would set 'uncv' as the
default tag for raw mp4 video, but I'm not sure what the issue is.

I'm also looking into passing FATE and adding additional test cases to
cover this new code. The documentation is helpful, but there's still a
steep learning curve to get all this put together.

Any help would be greatly appreciated.

On Sat, Oct 12, 2024 at 1:59 AM Tomas Härdin <g...@haerdin.se> wrote:

> ons 2024-10-09 klockan 20:08 -0600 skrev Devon Sookhoo:
> > Sounds good, I'll look into adding rawvideo to the list of
> > movcodec_tags.
> >
> > Looking at the AVPixFmtDescriptor, I noticed: AVComponentDescriptor
> > comp[4]; Does this line limit the component count to only four?
> > Encoding
> > video with many components is an important use case.
>
> I am aware of no pixel format with more than 4 components so probably.
> I've never seen hyperspectral imagery used in this project. I've worked
> with it before though
>
> > Complex pixels are used in applications that involve both amplitude
> > and
> > phase information, particularly in signal processing and imaging
> > techniques
> > where the Fourier transform is frequently applied. Examples include
> > Synthetic Aperture Radar (SAR), MRI scans, and radio astronomy.
>
> Yep, suspected as much
>
> /Tomas
> _______________________________________________
> 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".
>
From c5211cba38f3ec4d64c6c07304a2d947d033ca82 Mon Sep 17 00:00:00 2001
From: dukesook <devonsookhoo14@gmail.com>
Date: Tue, 24 Sep 2024 12:27:31 -0600
Subject: [PATCH] Encode RGB interleaved 8 bit uncompressed mp4

---
 libavcodec/rawenc.c     | 18 +++++++++
 libavformat/isom_tags.c |  1 +
 libavformat/movenc.c    | 88 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 8c577006d9..abb4a46886 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -77,6 +77,24 @@ static int raw_encode(AVCodecContext *avctx, AVPacket *pkt,
             AV_WB64(&pkt->data[8 * x], v << 48 | v >> 16);
         }
     }
+    else if (avctx->codec_tag == AV_RL32("uncv") && ret > 0 &&
+            frame->format == AV_PIX_FMT_RGB24) {
+        int x, y;
+        uint8_t *dst = pkt->data;
+        uint8_t *src = frame->data[0];
+
+        for (y = 0; y < frame->height; y++) {
+            for (x = 0; x < frame->width; x++) {
+                dst[0] = src[0];  // Red component
+                dst[1] = src[1];  // Green component
+                dst[2] = src[2];  // Blue component
+                src += 3;
+                dst += 3;
+            }
+            src += frame->linesize[0] - frame->width * 3;
+        }
+    }
+
     *got_packet = 1;
     return 0;
 }
diff --git a/libavformat/isom_tags.c b/libavformat/isom_tags.c
index 5dd72d570e..ffdb412ee6 100644
--- a/libavformat/isom_tags.c
+++ b/libavformat/isom_tags.c
@@ -29,6 +29,7 @@
 const AVCodecTag ff_codec_movvideo_tags[] = {
 /*  { AV_CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
 
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('u', 'n', 'c', 'v') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* uncompressed RGB */
     { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* uncompressed YUV422 */
     { AV_CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* uncompressed 8-bit 4:2:2 */
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index d20e45cf81..1e85b06b64 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2602,6 +2602,90 @@ static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
     return update_size(pb, pos);
 }
 
+static int mov_write_uncC_component(AVIOContext *pb, uint16_t index, uint8_t bit_depth, uint8_t format, uint8_t align_size) {
+    avio_wb16(pb, index);
+    avio_w8(pb, bit_depth-1);
+    avio_w8(pb, format); // 0 = unsigned integer. 1 = floating point. 2 = complex
+    avio_w8(pb, align_size);
+    return 0;
+}
+
+static int mov_write_uncC_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) {
+    int64_t pos = avio_tell(pb);
+    uint8_t version = 0x0;
+    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
+    const uint32_t nb_components = (uint32_t) pixdesc->nb_components;
+    uint8_t bit_depth = 8; // TODO: Read correct bit depth
+                           // track->par->bits_per_coded_sample;
+                           // track->par->bits_per_raw_sample;
+
+    avio_wb32(pb, 0); /* size */
+    ffio_wfourcc(pb, "uncC");
+
+    avio_w8(pb, 0x00);       // Flags
+    avio_wb24(pb, 0x000000); // Version
+
+    avio_wb32(pb, 0x00000000); // profile
+
+    if (version == 1) {
+
+    }
+    else if (version == 0) {
+        avio_wb32(pb, nb_components);
+        for (uint32_t i = 0; i < nb_components; i++) {
+            mov_write_uncC_component(pb, i, bit_depth, 0x00, 0x00);
+        }
+
+        avio_w8(pb, 0x00); //sampling_type. 0 = No subsampling
+        avio_w8(pb, 0x01); //interleave_type. 0 = Planar, 1 = interleaved
+        avio_w8(pb, 0x00); //block_size;
+
+        // Pixel Layout Flags
+        // bit(1) components_little_endian;
+        // bit(1) block_pad_last;
+        // bit(1) block_little_endian;
+        // bit(1) block_reversed;
+        // bit(1) pad_unknown;
+        // bit(3) reserved = 0;
+        avio_w8(pb, 0X00);
+
+        avio_wb32(pb, 0x00000000); // pixel_size;
+        avio_wb32(pb, 0x00000000); // row_align_size;
+        avio_wb32(pb, 0x00000000); // tile_align_size;
+        avio_wb32(pb, 0x00000000); // num_tile_cols_minus_one;
+        avio_wb32(pb, 0x00000000); // num_tile_rows_minus_one;
+    }
+    return update_size(pb, pos);
+}
+
+static int mov_write_cmpd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) {
+    
+    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
+    const uint32_t nb_components = (uint32_t) pixdesc->nb_components;
+    int pix_fmt = track->par->format;
+    int64_t start_position = avio_tell(pb);
+
+    avio_wb32(pb, 0); // size
+    ffio_wfourcc(pb, "cmpd");
+    avio_wb32(pb, nb_components);
+
+    if (pix_fmt == AV_PIX_FMT_RGB24) {
+        if (nb_components != 3) {
+            av_log(s, AV_LOG_ERROR, "RGB24 format must have 3 components\n");
+            return 0;
+        }
+        avio_wb16(pb, 0x4); // Red
+        avio_wb16(pb, 0x5); // Green
+        avio_wb16(pb, 0x6); // Blue
+    }
+    else {
+        av_log(s, AV_LOG_ERROR, "Pixel format not implemented yet\n");
+        return 0;
+    }
+
+    return update_size(pb, start_position);
+}
+
 static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
 {
     int ret = AVERROR_BUG;
@@ -2727,6 +2811,9 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
     } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
         if (track->par->codec_tag == MKTAG('R','1','0','k'))
             mov_write_dpxe_tag(pb, track);
+    } else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO) {
+        mov_write_uncC_tag(s, pb, mov, track);
+        mov_write_cmpd_tag(s, pb, mov, track);
     } else if (track->vos_len > 0)
         mov_write_glbl_tag(pb, track);
 
@@ -8580,6 +8667,7 @@ static const AVCodecTag codec_mp4_tags[] = {
     { AV_CODEC_ID_MOV_TEXT,        MKTAG('t', 'x', '3', 'g') },
     { AV_CODEC_ID_BIN_DATA,        MKTAG('g', 'p', 'm', 'd') },
     { AV_CODEC_ID_MPEGH_3D_AUDIO,  MKTAG('m', 'h', 'm', '1') },
+    { AV_CODEC_ID_RAWVIDEO,        MKTAG('u', 'n', 'c', 'v') },
     { AV_CODEC_ID_TTML,            MOV_MP4_TTML_TAG          },
     { AV_CODEC_ID_TTML,            MOV_ISMV_TTML_TAG         },
 
-- 
2.34.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".

Reply via email to