Commit f320fb89 authored by Justin Ruggles's avatar Justin Ruggles

bethsoftvid: pass palette in side data instead of in a separate packet.

Update FATE reference to account for now non-existent palette packet.
This also fixes the FATE test if frame data is not initialized in
get_buffer(), so update comment in avconv accordingly.
parent f3a094f2
...@@ -449,7 +449,7 @@ static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf) ...@@ -449,7 +449,7 @@ static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)
/* XXX this shouldn't be needed, but some tests break without this line /* XXX this shouldn't be needed, but some tests break without this line
* those decoders are buggy and need to be fixed. * those decoders are buggy and need to be fixed.
* the following tests fail: * the following tests fail:
* bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
*/ */
memset(buf->base[0], 128, ret); memset(buf->base[0], 128, ret);
......
...@@ -71,14 +71,23 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, ...@@ -71,14 +71,23 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
uint8_t * dst; uint8_t * dst;
uint8_t * frame_end; uint8_t * frame_end;
int remaining = avctx->width; // number of bytes remaining on a line int remaining = avctx->width; // number of bytes remaining on a line
const int wrap_to_next_line = vid->frame.linesize[0] - avctx->width; int wrap_to_next_line;
int code; int code, ret;
int yoffset; int yoffset;
if (avctx->reget_buffer(avctx, &vid->frame)) { if (avctx->reget_buffer(avctx, &vid->frame)) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1; return -1;
} }
wrap_to_next_line = vid->frame.linesize[0] - avctx->width;
if (avpkt->side_data_elems > 0 &&
avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) {
bytestream2_init(&vid->g, avpkt->side_data[0].data,
avpkt->side_data[0].size);
if ((ret = set_palette(vid)) < 0)
return ret;
}
bytestream2_init(&vid->g, avpkt->data, avpkt->size); bytestream2_init(&vid->g, avpkt->data, avpkt->size);
dst = vid->frame.data[0]; dst = vid->frame.data[0];
...@@ -86,7 +95,6 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, ...@@ -86,7 +95,6 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
switch(block_type = bytestream2_get_byte(&vid->g)){ switch(block_type = bytestream2_get_byte(&vid->g)){
case PALETTE_BLOCK: { case PALETTE_BLOCK: {
int ret;
*data_size = 0; *data_size = 0;
if ((ret = set_palette(vid)) < 0) { if ((ret = set_palette(vid)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error reading palette\n"); av_log(avctx, AV_LOG_ERROR, "error reading palette\n");
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "internal.h" #include "internal.h"
#include "libavcodec/bethsoftvideo.h" #include "libavcodec/bethsoftvideo.h"
#define BVID_PALETTE_SIZE 3 * 256
typedef struct BVID_DemuxContext typedef struct BVID_DemuxContext
{ {
int nframes; int nframes;
...@@ -43,6 +45,7 @@ typedef struct BVID_DemuxContext ...@@ -43,6 +45,7 @@ typedef struct BVID_DemuxContext
/** video presentation time stamp. /** video presentation time stamp.
* delay = 16 milliseconds * (global_delay + per_frame_delay) */ * delay = 16 milliseconds * (global_delay + per_frame_delay) */
int video_pts; int video_pts;
uint8_t *palette;
int is_finished; int is_finished;
...@@ -163,6 +166,14 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, ...@@ -163,6 +166,14 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,
pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream
pkt->pts = vid->video_pts; pkt->pts = vid->video_pts;
/* if there is a new palette available, add it to packet side data */
if (vid->palette) {
uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
BVID_PALETTE_SIZE);
memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
av_freep(&vid->palette);
}
vid->nframes--; // used to check if all the frames were read vid->nframes--; // used to check if all the frames were read
return vidbuf_nbytes; return vidbuf_nbytes;
fail: fail:
...@@ -185,14 +196,18 @@ static int vid_read_packet(AVFormatContext *s, ...@@ -185,14 +196,18 @@ static int vid_read_packet(AVFormatContext *s,
block_type = avio_r8(pb); block_type = avio_r8(pb);
switch(block_type){ switch(block_type){
case PALETTE_BLOCK: case PALETTE_BLOCK:
avio_seek(pb, -1, SEEK_CUR); // include block type if (vid->palette) {
ret_value = av_get_packet(pb, pkt, 3 * 256 + 1); av_log(s, AV_LOG_WARNING, "discarding unused palette\n");
if(ret_value != 3 * 256 + 1){ av_freep(&vid->palette);
av_free_packet(pkt); }
vid->palette = av_malloc(BVID_PALETTE_SIZE);
if (!vid->palette)
return AVERROR(ENOMEM);
if (avio_read(pb, vid->palette, BVID_PALETTE_SIZE) != BVID_PALETTE_SIZE) {
av_freep(&vid->palette);
return AVERROR(EIO); return AVERROR(EIO);
} }
pkt->stream_index = 0; return vid_read_packet(s, pkt);
return ret_value;
case FIRST_AUDIO_BLOCK: case FIRST_AUDIO_BLOCK:
avio_rl16(pb); avio_rl16(pb);
...@@ -222,6 +237,13 @@ static int vid_read_packet(AVFormatContext *s, ...@@ -222,6 +237,13 @@ static int vid_read_packet(AVFormatContext *s,
} }
} }
static int vid_read_close(AVFormatContext *s)
{
BVID_DemuxContext *vid = s->priv_data;
av_freep(&vid->palette);
return 0;
}
AVInputFormat ff_bethsoftvid_demuxer = { AVInputFormat ff_bethsoftvid_demuxer = {
.name = "bethsoftvid", .name = "bethsoftvid",
.long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"), .long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"),
...@@ -229,4 +251,5 @@ AVInputFormat ff_bethsoftvid_demuxer = { ...@@ -229,4 +251,5 @@ AVInputFormat ff_bethsoftvid_demuxer = {
.read_probe = vid_probe, .read_probe = vid_probe,
.read_header = vid_read_header, .read_header = vid_read_header,
.read_packet = vid_read_packet, .read_packet = vid_read_packet,
.read_close = vid_read_close,
}; };
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment