---
libavformat/movenc.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 91 insertions(+), 4 deletions(-)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 2ae3475..3f1e65b 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -308,7 +308,9 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack
*track) // Basic
// the following fields is made of 6 bits to identify the streamtype (4
for video, 5 for audio)
// plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
- if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+ if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
+ avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
+ else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
avio_w8(pb, 0x15); // flags (= Audiostream)
else
avio_w8(pb, 0x11); // flags (= Visualstream)
@@ -759,6 +761,7 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack
*track)
else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag =
MKTAG('v','c','-','1');
else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag =
MKTAG('m','p','4','v');
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag =
MKTAG('m','p','4','a');
+ else if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE) tag =
MKTAG('m','p','4','s');
return tag;
}
@@ -981,6 +984,21 @@ static int mov_write_subtitle_tag(AVIOContext *pb,
MOVTrack *track)
return update_size(pb, pos);
}
+static int mov_write_subpic_tag(AVIOContext *pb, MOVTrack *track)
+{
+ int64_t pos = avio_tell(pb);
+
+ avio_wb32(pb, 0); /* size */
+ avio_wl32(pb, track->tag); // store it byteswapped
+ avio_wb32(pb, 0); /* Reserved */
+ avio_wb16(pb, 0); /* Reserved */
+ avio_wb16(pb, 1); /* Data-reference index */
+
+ mov_write_esds_tag(pb, track);
+
+ return update_size(pb, pos);
+}
+
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
{
AVRational sar;
@@ -1116,6 +1134,8 @@ static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack
*track)
mov_write_video_tag(pb, track);
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
mov_write_audio_tag(pb, track);
+ else if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
+ mov_write_subpic_tag(pb, track);
else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
mov_write_subtitle_tag(pb, track);
else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
@@ -1307,6 +1327,7 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack
*track)
descr = "SoundHandler";
} else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
+ if (track->tag == MKTAG('m','p','4','s')) hdlr_type = "subp";
else hdlr_type = "text";
descr = "SubtitleHandler";
} else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
@@ -3175,6 +3196,68 @@ static void mov_free(AVFormatContext *s)
av_freep(&mov->tracks);
}
+static uint32_t rgb_to_yuv(uint32_t rgb)
+{
+ uint8_t r, g, b;
+ int y, cb, cr;
+
+ r = (rgb >> 16) & 0xFF;
+ g = (rgb >> 8) & 0xFF;
+ b = (rgb ) & 0xFF;
+
+ y = av_clip_uint8( 16. + 0.257 * r + 0.504 * g + 0.098 * b);
+ cb = av_clip_uint8(128. - 0.148 * r - 0.291 * g + 0.439 * b);
+ cr = av_clip_uint8(128. + 0.439 * r - 0.368 * g - 0.071 * b);
+
+ return (y << 16) | (cr << 8) | cb;
+}
+
+static int mov_rewrite_dvd_sub_extradata(MOVTrack *track, AVStream *st)
+{
+ int i, width, height;
+ int have_palette, have_size;
+ uint32_t palette[16];
+ char *cur;
+
+ if (!st->codec->extradata || !st->codec->extradata_size)
+ return AVERROR_INVALIDDATA;
+
+ cur = st->codec->extradata;
+ while (*cur) {
+ if (strncmp("palette:", cur, 8) == 0) {
+ int i;
+ char *p = cur + 8;
+ for (i = 0; i < 16; i++) {
+ palette[i] = rgb_to_yuv(strtoul(p, &p, 16));
+ while (*p == ',' || av_isspace(*p))
+ p++;
+ }
+ have_palette = 1;
+ } else if (!strncmp("size:", cur, 5)) {
+ if (sscanf(cur + 5, "%dx%d", &width, &height) != 2) {
+ return AVERROR_INVALIDDATA;
+ }
+ have_size = 1;
+ }
+ if (have_palette && have_size)
+ break;
+ cur += strcspn(cur, "\n\r");
+ cur += strspn(cur, "\n\r");
+ }
+ if (!have_palette || !have_size)
+ return AVERROR_INVALIDDATA;
+
+ track->vos_data = av_malloc(16*4);
+ for (i = 0; i < 16; i++) {
+ AV_WB32(track->vos_data + i * 4, palette[i]);
+ }
+ track->vos_len = 16 * 4;
+ st->codec->width = width;
+ st->codec->height = track->height = height;
+
+ return 0;
+}
+
static int mov_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
@@ -3331,9 +3414,13 @@ static int mov_write_header(AVFormatContext *s)
/* copy extradata if it exists */
if (st->codec->extradata_size) {
- track->vos_len = st->codec->extradata_size;
- track->vos_data = av_malloc(track->vos_len);
- memcpy(track->vos_data, st->codec->extradata, track->vos_len);
+ if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
+ mov_rewrite_dvd_sub_extradata(track, st);
+ else {
+ track->vos_len = st->codec->extradata_size;
+ track->vos_data = av_malloc(track->vos_len);
+ memcpy(track->vos_data, st->codec->extradata, track->vos_len);
+ }
}
}
--
1.8.5.3
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel