mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
movenc: Add dvd subtitle support
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
parent
85698be461
commit
6adf3bc42e
@ -309,7 +309,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)
|
// 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)
|
// 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)
|
avio_w8(pb, 0x15); // flags (= Audiostream)
|
||||||
else
|
else
|
||||||
avio_w8(pb, 0x11); // flags (= Visualstream)
|
avio_w8(pb, 0x11); // flags (= Visualstream)
|
||||||
@ -760,6 +762,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_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_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_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;
|
return tag;
|
||||||
}
|
}
|
||||||
@ -976,7 +979,9 @@ static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
avio_wb16(pb, 0); /* Reserved */
|
avio_wb16(pb, 0); /* Reserved */
|
||||||
avio_wb16(pb, 1); /* Data-reference index */
|
avio_wb16(pb, 1); /* Data-reference index */
|
||||||
|
|
||||||
if (track->enc->extradata_size)
|
if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
|
||||||
|
mov_write_esds_tag(pb, track);
|
||||||
|
else if (track->enc->extradata_size)
|
||||||
avio_write(pb, track->enc->extradata, track->enc->extradata_size);
|
avio_write(pb, track->enc->extradata, track->enc->extradata_size);
|
||||||
|
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
@ -1308,6 +1313,7 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
descr = "SoundHandler";
|
descr = "SoundHandler";
|
||||||
} else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
} else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||||
if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
|
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";
|
else hdlr_type = "text";
|
||||||
descr = "SubtitleHandler";
|
descr = "SubtitleHandler";
|
||||||
} else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
|
} else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
|
||||||
@ -3178,6 +3184,69 @@ static void mov_free(AVFormatContext *s)
|
|||||||
av_freep(&mov->tracks);
|
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_create_dvd_sub_decoder_specific_info(MOVTrack *track,
|
||||||
|
AVStream *st)
|
||||||
|
{
|
||||||
|
int i, width = 720, height = 480;
|
||||||
|
int have_palette = 0, have_size = 0;
|
||||||
|
uint32_t palette[16];
|
||||||
|
char *cur = st->codec->extradata;
|
||||||
|
|
||||||
|
while (cur && *cur) {
|
||||||
|
if (strncmp("palette:", cur, 8) == 0) {
|
||||||
|
int i, count;
|
||||||
|
count = sscanf(cur + 8,
|
||||||
|
"%06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, "
|
||||||
|
"%06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x",
|
||||||
|
&palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
|
||||||
|
&palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
|
||||||
|
&palette[ 8], &palette[ 9], &palette[10], &palette[11],
|
||||||
|
&palette[12], &palette[13], &palette[14], &palette[15]);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
palette[i] = rgb_to_yuv(palette[i]);
|
||||||
|
}
|
||||||
|
have_palette = 1;
|
||||||
|
} else if (!strncmp("size:", cur, 5)) {
|
||||||
|
sscanf(cur + 5, "%dx%d", &width, &height);
|
||||||
|
have_size = 1;
|
||||||
|
}
|
||||||
|
if (have_palette && have_size)
|
||||||
|
break;
|
||||||
|
cur += strcspn(cur, "\n\r");
|
||||||
|
cur += strspn(cur, "\n\r");
|
||||||
|
}
|
||||||
|
if (have_palette) {
|
||||||
|
track->vos_data = av_malloc(16*4);
|
||||||
|
if (!track->vos_data)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
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)
|
static int mov_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
@ -3334,9 +3403,13 @@ static int mov_write_header(AVFormatContext *s)
|
|||||||
|
|
||||||
/* copy extradata if it exists */
|
/* copy extradata if it exists */
|
||||||
if (st->codec->extradata_size) {
|
if (st->codec->extradata_size) {
|
||||||
track->vos_len = st->codec->extradata_size;
|
if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
|
||||||
track->vos_data = av_malloc(track->vos_len);
|
mov_create_dvd_sub_decoder_specific_info(track, st);
|
||||||
memcpy(track->vos_data, st->codec->extradata, track->vos_len);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user