[FFmpeg-devel] [PATCH v6] libavformat/mxfenc: write package name metadata

2015-03-05 Thread Mark Reid
changes since v5
* use size >= UINT16_MAX/2 instead

Mark Reid (1):
  libavformat/mxfenc: write package name metadata

 libavformat/mxfenc.c  | 97 +--
 tests/ref/lavf/mxf|  6 +--
 tests/ref/lavf/mxf_d10|  2 +-
 tests/ref/lavf/mxf_opatom |  2 +-
 4 files changed, 91 insertions(+), 16 deletions(-)

-- 
2.2.1

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


[FFmpeg-devel] [PATCH v6] libavformat/mxfenc: write package name metadata

2015-03-05 Thread Mark Reid
---
 libavformat/mxfenc.c  | 97 +--
 tests/ref/lavf/mxf|  6 +--
 tests/ref/lavf/mxf_d10|  2 +-
 tests/ref/lavf/mxf_opatom |  2 +-
 4 files changed, 91 insertions(+), 16 deletions(-)

diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 7d35af4..898951c 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -624,14 +624,61 @@ static void mxf_write_preface(AVFormatContext *s)
 }
 
 /*
- * Write a local tag containing an ascii string as utf-16
+ * Returns the length of the UTF-16 string, in 16-bit characters, that would 
result
+ * from decoding the utf-8 string.
+ */
+static uint64_t mxf_utf16len(const char *utf8_str)
+{
+const uint8_t *q = utf8_str;
+uint64_t size = 0;
+while (*q) {
+uint32_t ch;
+GET_UTF8(ch, *q++, goto invalid;)
+if (ch < 0x1)
+size++;
+else
+size += 2;
+continue;
+invalid:
+av_log(NULL, AV_LOG_ERROR, "Invaid UTF8 sequence in mxf_utf16len\n\n");
+}
+size += 1;
+return size;
+}
+
+/*
+ * Returns the calculated length a local tag containing an utf-8 string as 
utf-16
+ */
+static int mxf_utf16_local_tag_length(const char *utf8_str)
+{
+uint64_t size;
+
+if (!utf8_str)
+return 0;
+
+size = mxf_utf16len(utf8_str);
+if (size >= UINT16_MAX/2) {
+av_log(NULL, AV_LOG_ERROR, "utf16 local tag size %"PRIx64" invalid 
(too large), ignoring\n", size);
+return 0;
+}
+
+return 4 + size * 2;
+}
+
+/*
+ * Write a local tag containing an utf-8 string as utf-16
  */
 static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char 
*value)
 {
-int i, size = strlen(value);
+uint64_t size = mxf_utf16len(value);
+
+if (size >= UINT16_MAX/2) {
+av_log(NULL, AV_LOG_ERROR, "utf16 local tag size %"PRIx64" invalid 
(too large), ignoring\n", size);
+return;
+}
+
 mxf_write_local_tag(pb, size*2, tag);
-for (i = 0; i < size; i++)
-avio_wb16(pb, value[i]);
+avio_put_str16be(pb, value);
 }
 
 static void mxf_write_identification(AVFormatContext *s)
@@ -648,7 +695,9 @@ static void mxf_write_identification(AVFormatContext *s)
 
 version = s->flags & AVFMT_FLAG_BITEXACT ?
 "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
-length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // 
utf-16
+length = 72 + mxf_utf16_local_tag_length(company) +
+  mxf_utf16_local_tag_length(product) +
+  mxf_utf16_local_tag_length(version);
 klv_encode_ber_length(pb, length);
 
 // write uid
@@ -659,7 +708,6 @@ static void mxf_write_identification(AVFormatContext *s)
 // write generation uid
 mxf_write_local_tag(pb, 16, 0x3C09);
 mxf_write_uuid(pb, Identification, 1);
-
 mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name
 mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name
 mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String
@@ -1092,20 +1140,21 @@ static void 
mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
 mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
 }
 
-static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
+static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType 
type, const char *package_name)
 {
 MXFContext *mxf = s->priv_data;
 AVIOContext *pb = s->pb;
 int i, track_count = s->nb_streams+1;
+int name_size = mxf_utf16_local_tag_length(package_name);
 
 if (type == MaterialPackage) {
 mxf_write_metadata_key(pb, 0x013600);
 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
-klv_encode_ber_length(pb, 92 + 16*track_count);
+klv_encode_ber_length(pb, 92 + name_size + (16*track_count));
 } else {
 mxf_write_metadata_key(pb, 0x013700);
 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
-klv_encode_ber_length(pb, 112 + 16*track_count); // 20 bytes length 
for descriptor reference
+klv_encode_ber_length(pb, 112 + name_size + (16*track_count)); // 20 
bytes length for descriptor reference
 }
 
 // write uid
@@ -1119,6 +1168,10 @@ static void mxf_write_package(AVFormatContext *s, enum 
MXFMetadataSetType type)
 mxf_write_umid(s, type == SourcePackage);
 PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
 
+// package name
+if (name_size)
+mxf_write_local_tag_utf16(pb, 0x4402, package_name);
+
 // package creation date
 mxf_write_local_tag(pb, 8, 0x4405);
 avio_wb64(pb, mxf->timestamp);
@@ -1187,11 +1240,33 @@ static int 
mxf_write_essence_container_data(AVFormatContext *s)
 
 static int mxf_write_header_metadata_sets(AVFormatContext *s)
 {
+const char *material_package_name = NULL;
+const char *file_package_name = NULL;
+AVDictionaryEntry *entry = NULL;
+AVStream *st = NULL;
+

Re: [FFmpeg-devel] [PATCH v6] libavformat/mxfenc: write package name metadata

2015-03-09 Thread Michael Niedermayer
On Thu, Mar 05, 2015 at 10:59:11AM -0800, Mark Reid wrote:
> ---
>  libavformat/mxfenc.c  | 97 
> +--
>  tests/ref/lavf/mxf|  6 +--
>  tests/ref/lavf/mxf_d10|  2 +-
>  tests/ref/lavf/mxf_opatom |  2 +-
>  4 files changed, 91 insertions(+), 16 deletions(-)

applied

thanks

[...]

-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Dictatorship naturally arises out of democracy, and the most aggravated
form of tyranny and slavery out of the most extreme liberty. -- Plato


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel