diff options
author | Mats Peterson <matsp888@yahoo.com> | 2016-02-26 05:07:28 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-02-27 01:28:48 +0100 |
commit | 9a2778082121ea44d06a2f00f822ea99109c7fd8 (patch) | |
tree | 5e006268dff2cb8e28f3c58a7ae2a8d80c864615 | |
parent | 42c5e1cc2ad95c88b5234ff9927c5adfae028896 (diff) | |
download | ffmpeg-9a2778082121ea44d06a2f00f822ea99109c7fd8.tar.gz |
lavf/movenc: Add palette to video sample description
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/movenc.c | 64 | ||||
-rw-r--r-- | libavformat/movenc.h | 5 |
2 files changed, 67 insertions, 2 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index b9c0f7ae67..e0223b223b 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1711,10 +1711,30 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr avio_write(pb, compressor_name, 31); if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample) - avio_wb16(pb, track->enc->bits_per_coded_sample); + avio_wb16(pb, track->enc->bits_per_coded_sample | + (track->enc->pix_fmt == AV_PIX_FMT_GRAY8 ? 0x20 : 0)); else avio_wb16(pb, 0x18); /* Reserved */ - avio_wb16(pb, 0xffff); /* Reserved */ + + if (track->is_unaligned_qt_rgb && track->enc->pix_fmt == AV_PIX_FMT_PAL8) { + int i; + avio_wb16(pb, 0); /* Color table ID */ + avio_wb32(pb, 0); /* Color table seed */ + avio_wb16(pb, 0x8000); /* Color table flags */ + avio_wb16(pb, 255); /* Color table size (zero-relative) */ + for (i = 0; i < 256; i++) { + uint32_t rgb = AV_RL32(&track->palette[i]); + uint16_t r = (rgb >> 16) & 0xff; + uint16_t g = (rgb >> 8) & 0xff; + uint16_t b = rgb & 0xff; + avio_wb16(pb, 0); + avio_wb16(pb, (r << 8) | r); + avio_wb16(pb, (g << 8) | g); + avio_wb16(pb, (b << 8) | b); + } + } else + avio_wb16(pb, 0xffff); /* Reserved */ + if (track->tag == MKTAG('m','p','4','v')) mov_write_esds_tag(pb, track); else if (track->enc->codec_id == AV_CODEC_ID_H263) @@ -4703,6 +4723,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) } else { int i; MOVMuxContext *mov = s->priv_data; + MOVTrack *trk = &mov->tracks[pkt->stream_index]; if (!pkt->size) return mov_write_single_packet(s, pkt); /* Passthrough. */ @@ -4739,6 +4760,31 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) } } + if (trk->is_unaligned_qt_rgb) { + const uint8_t *data = pkt->data; + int size = pkt->size; + int64_t bpc = trk->enc->bits_per_coded_sample != 15 ? trk->enc->bits_per_coded_sample : 16; + int expected_stride = ((trk->enc->width * bpc + 15) >> 4)*2; + int ret = ff_reshuffle_raw_rgb(s, &pkt, trk->enc, expected_stride); + if (ret < 0) + return ret; + if (ret == CONTAINS_PAL && !trk->pal_done) { + int pal_size = 1 << trk->enc->bits_per_coded_sample; + memset(trk->palette, 0, AVPALETTE_SIZE); + memcpy(trk->palette, data + size - 4*pal_size, 4*pal_size); + trk->pal_done++; + } else if (trk->enc->pix_fmt == AV_PIX_FMT_GRAY8 || + trk->enc->pix_fmt == AV_PIX_FMT_MONOBLACK) { + for (i = 0; i < pkt->size; i++) + pkt->data[i] = ~pkt->data[i]; + } + if (ret) { + ret = mov_write_single_packet(s, pkt); + av_packet_free(&pkt); + return ret; + } + } + return mov_write_single_packet(s, pkt); } } @@ -5249,6 +5295,20 @@ static int mov_write_header(AVFormatContext *s) "WARNING codec timebase is very high. If duration is too long,\n" "file may not be playable by quicktime. Specify a shorter timebase\n" "or choose different container.\n"); + if (track->mode == MODE_MOV && + track->enc->codec_id == AV_CODEC_ID_RAWVIDEO && + track->tag == MKTAG('r','a','w',' ')) { + enum AVPixelFormat pix_fmt = track->enc->pix_fmt; + if (pix_fmt == AV_PIX_FMT_NONE && track->enc->bits_per_coded_sample == 1) + pix_fmt = AV_PIX_FMT_MONOWHITE; + track->is_unaligned_qt_rgb = + pix_fmt == AV_PIX_FMT_RGB24 || + pix_fmt == AV_PIX_FMT_BGR24 || + pix_fmt == AV_PIX_FMT_PAL8 || + pix_fmt == AV_PIX_FMT_GRAY8 || + pix_fmt == AV_PIX_FMT_MONOWHITE || + pix_fmt == AV_PIX_FMT_MONOBLACK; + } } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { track->timescale = st->codec->sample_rate; if (!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) { diff --git a/libavformat/movenc.h b/libavformat/movenc.h index deb90fe2a7..44caff9711 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -152,6 +152,11 @@ typedef struct MOVTrack { void *eac3_priv; MOVMuxCencContext cenc; + + uint32_t palette[AVPALETTE_COUNT]; + int pal_done; + + int is_unaligned_qt_rgb; } MOVTrack; typedef enum { |