From 2d8591c27e2dc582a7020e2580e16278dbfbddff Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 9 Apr 2011 15:49:51 +0200 Subject: make containers pass palette change in AVPacket Signed-off-by: Luca Barbato --- libavformat/asf.h | 2 ++ libavformat/asfdec.c | 21 +++++++++++++++------ libavformat/avidec.c | 24 +++++++++++------------- libavformat/idcin.c | 17 +++++++++++------ libavformat/ipmovie.c | 23 +++++++++++++++-------- libavformat/isom.h | 2 ++ libavformat/mov.c | 20 +++++++++++++++----- 7 files changed, 71 insertions(+), 38 deletions(-) (limited to 'libavformat') diff --git a/libavformat/asf.h b/libavformat/asf.h index b56345993d..b72445def9 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -44,6 +44,8 @@ typedef struct { uint16_t stream_language_index; + int palette_changed; + uint32_t palette[256]; } ASFStream; typedef uint8_t ff_asf_guid[16]; diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 30828ad6ff..36e9efad75 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -365,15 +365,14 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) /* This is true for all paletted codecs implemented in ffmpeg */ if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { int av_unused i; - st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); #if HAVE_BIGENDIAN for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); + asf_st->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); #else - memcpy(st->codec->palctrl->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); + memcpy(asf_st->palette, st->codec->extradata, + FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); #endif - st->codec->palctrl->palette_changed = 1; + asf_st->palette_changed = 1; } st->codec->codec_tag = tag1; @@ -966,6 +965,17 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->pkt.stream_index = asf->stream_index; asf_st->pkt.pos = asf_st->packet_pos= asf->packet_pos; + if (asf_st->pkt.data && asf_st->palette_changed) { + uint8_t *pal; + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, + AVPALETTE_SIZE); + if (!pal) { + av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n"); + } else { + memcpy(pal, asf_st->palette, AVPALETTE_SIZE); + asf_st->palette_changed = 0; + } + } //printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & AV_PKT_FLAG_KEY, //s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO, asf->packet_obj_size); @@ -1127,7 +1137,6 @@ static int asf_read_close(AVFormatContext *s) asf_reset_header(s); for(i=0;inb_streams;i++) { AVStream *st = s->streams[i]; - av_free(st->codec->palctrl); } return 0; } diff --git a/libavformat/avidec.c b/libavformat/avidec.c index ec3aa9335a..c7bbf422b7 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -590,15 +590,14 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) /* This code assumes that extradata contains only palette. */ /* This is true for all paletted codecs implemented in FFmpeg. */ if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); #if HAVE_BIGENDIAN for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); + ast->pal[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]); #else - memcpy(st->codec->palctrl->palette, st->codec->extradata, + memcpy(ast->pal, st->codec->extradata, FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); #endif - st->codec->palctrl->palette_changed = 1; + ast->has_pal = 1; } print_tag("video", tag1, 0); @@ -932,14 +931,14 @@ resync: return err; if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){ - void *ptr= av_realloc(pkt->data, pkt->size + 4*256 + FF_INPUT_BUFFER_PADDING_SIZE); - if(ptr){ - ast->has_pal=0; - pkt->size += 4*256; - pkt->data= ptr; - memcpy(pkt->data + pkt->size - 4*256, ast->pal, 4*256); - }else - av_log(s, AV_LOG_ERROR, "Failed to append palette\n"); + uint8_t *pal; + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); + if(!pal){ + av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n"); + }else{ + memcpy(pal, ast->pal, AVPALETTE_SIZE); + ast->has_pal = 0; + } } if (CONFIG_DV_DEMUXER && avi->dv_demux) { @@ -1340,7 +1339,6 @@ static int avi_read_close(AVFormatContext *s) for(i=0;inb_streams;i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; - av_free(st->codec->palctrl); if (ast) { if (ast->sub_ctx) { av_freep(&ast->sub_ctx->pb); diff --git a/libavformat/idcin.c b/libavformat/idcin.c index e6883c7d94..04ae687c6c 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -86,8 +86,6 @@ typedef struct IdcinDemuxContext { int audio_present; int64_t pts; - - AVPaletteControl palctrl; } IdcinDemuxContext; static int idcin_probe(AVProbeData *p) @@ -172,8 +170,6 @@ static int idcin_read_header(AVFormatContext *s, if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) return AVERROR(EIO); - /* save a reference in order to transport the palette */ - st->codec->palctrl = &idcin->palctrl; /* if sample rate is 0, assume no audio */ if (sample_rate) { @@ -226,6 +222,7 @@ static int idcin_read_packet(AVFormatContext *s, int palette_scale; unsigned char r, g, b; unsigned char palette_buffer[768]; + uint32_t palette[256]; if (s->pb->eof_reached) return AVERROR(EIO); @@ -236,7 +233,6 @@ static int idcin_read_packet(AVFormatContext *s, return AVERROR(EIO); } else if (command == 1) { /* trigger a palette change */ - idcin->palctrl.palette_changed = 1; if (avio_read(pb, palette_buffer, 768) != 768) return AVERROR(EIO); /* scale the palette as necessary */ @@ -251,7 +247,7 @@ static int idcin_read_packet(AVFormatContext *s, r = palette_buffer[i * 3 ] << palette_scale; g = palette_buffer[i * 3 + 1] << palette_scale; b = palette_buffer[i * 3 + 2] << palette_scale; - idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b); + palette[i] = (r << 16) | (g << 8) | (b); } } @@ -262,6 +258,15 @@ static int idcin_read_packet(AVFormatContext *s, ret= av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; + if (command == 1) { + uint8_t *pal; + + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, + AVPALETTE_SIZE); + if (ret < 0) + return ret; + memcpy(pal, palette, AVPALETTE_SIZE); + } pkt->stream_index = idcin->video_stream_index; pkt->pts = idcin->pts; } else { diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index e1d08df1f3..e3215d3b79 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -97,6 +97,8 @@ typedef struct IPMVEContext { unsigned int video_width; unsigned int video_height; int64_t video_pts; + uint32_t palette[256]; + int has_palette; unsigned int audio_bits; unsigned int audio_channels; @@ -116,8 +118,6 @@ typedef struct IPMVEContext { int64_t next_chunk_offset; - AVPaletteControl palette_control; - } IPMVEContext; static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, @@ -162,6 +162,17 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; + if (s->has_palette) { + uint8_t *pal; + + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, + AVPALETTE_SIZE); + if (pal) { + memcpy(pal, s->palette, AVPALETTE_SIZE); + s->has_palette = 0; + } + } + pkt->pos= s->decode_map_chunk_offset; avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; @@ -456,10 +467,9 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, r = scratch[j++] * 4; g = scratch[j++] * 4; b = scratch[j++] * 4; - s->palette_control.palette[i] = (r << 16) | (g << 8) | (b); + s->palette[i] = (r << 16) | (g << 8) | (b); } - /* indicate a palette change */ - s->palette_control.palette_changed = 1; + s->has_palette = 1; break; case OPCODE_SET_PALETTE_COMPRESSED: @@ -573,9 +583,6 @@ static int ipmovie_read_header(AVFormatContext *s, st->codec->height = ipmovie->video_height; st->codec->bits_per_coded_sample = ipmovie->video_bpp; - /* palette considerations */ - st->codec->palctrl = &ipmovie->palette_control; - if (ipmovie->audio_type) { st = av_new_stream(s, 0); if (!st) diff --git a/libavformat/isom.h b/libavformat/isom.h index fba49635d6..48e0bcf9e2 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -123,6 +123,8 @@ typedef struct MOVStreamContext { int width; ///< tkhd width int height; ///< tkhd height int dts_shift; ///< dts shift when ctts is negative + uint32_t palette[256]; + int has_palette; } MOVStreamContext; typedef struct MOVContext { diff --git a/libavformat/mov.c b/libavformat/mov.c index 61ceaac351..bd8cf031e0 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1027,7 +1027,6 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) unsigned int color_start, color_count, color_end; unsigned char r, g, b; - st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl)); if (color_greyscale) { int color_index, color_dec; /* compute the greyscale palette */ @@ -1037,7 +1036,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) color_dec = 256 / (color_count - 1); for (j = 0; j < color_count; j++) { r = g = b = color_index; - st->codec->palctrl->palette[j] = + sc->palette[j] = (r << 16) | (g << 8) | (b); color_index -= color_dec; if (color_index < 0) @@ -1058,7 +1057,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) r = color_table[j * 3 + 0]; g = color_table[j * 3 + 1]; b = color_table[j * 3 + 2]; - st->codec->palctrl->palette[j] = + sc->palette[j] = (r << 16) | (g << 8) | (b); } } else { @@ -1080,12 +1079,12 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) avio_r8(pb); b = avio_r8(pb); avio_r8(pb); - st->codec->palctrl->palette[j] = + sc->palette[j] = (r << 16) | (g << 8) | (b); } } } - st->codec->palctrl->palette_changed = 1; + sc->has_palette = 1; } } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { int bits_per_sample, flags; @@ -2433,6 +2432,17 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) ret = av_get_packet(sc->pb, pkt, sample->size); if (ret < 0) return ret; + if (sc->has_palette) { + uint8_t *pal; + + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); + if (!pal) { + av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n"); + } else { + memcpy(pal, sc->palette, AVPALETTE_SIZE); + sc->has_palette = 0; + } + } #if CONFIG_DV_DEMUXER if (mov->dv_demux && sc->dv_audio_container) { dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size); -- cgit v1.2.3