From f320fb894c695044ef15239d27844d9ac01c9d16 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 15:45:47 -0500 Subject: 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. --- libavformat/bethsoftvid.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 2c8a980730..23c6d1dfdb 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -32,6 +32,8 @@ #include "internal.h" #include "libavcodec/bethsoftvideo.h" +#define BVID_PALETTE_SIZE 3 * 256 + typedef struct BVID_DemuxContext { int nframes; @@ -43,6 +45,7 @@ typedef struct BVID_DemuxContext /** video presentation time stamp. * delay = 16 milliseconds * (global_delay + per_frame_delay) */ int video_pts; + uint8_t *palette; int is_finished; @@ -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->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 return vidbuf_nbytes; fail: @@ -185,14 +196,18 @@ static int vid_read_packet(AVFormatContext *s, block_type = avio_r8(pb); switch(block_type){ case PALETTE_BLOCK: - avio_seek(pb, -1, SEEK_CUR); // include block type - ret_value = av_get_packet(pb, pkt, 3 * 256 + 1); - if(ret_value != 3 * 256 + 1){ - av_free_packet(pkt); + if (vid->palette) { + av_log(s, AV_LOG_WARNING, "discarding unused palette\n"); + av_freep(&vid->palette); + } + 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); } - pkt->stream_index = 0; - return ret_value; + return vid_read_packet(s, pkt); case FIRST_AUDIO_BLOCK: avio_rl16(pb); @@ -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 = { .name = "bethsoftvid", .long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"), @@ -229,4 +251,5 @@ AVInputFormat ff_bethsoftvid_demuxer = { .read_probe = vid_probe, .read_header = vid_read_header, .read_packet = vid_read_packet, + .read_close = vid_read_close, }; -- cgit v1.2.3 From 17b115591fae28b995973e0792260632d6d8dfc7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 18:46:38 -0500 Subject: bethsoftvid: fix read_packet() return codes. Use proper AVERROR codes, and return 0 for no error. --- libavformat/bethsoftvid.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 23c6d1dfdb..e755f83a7e 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -109,6 +109,7 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, int bytes_copied = 0; int position; unsigned int vidbuf_capacity; + int ret = 0; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) @@ -124,8 +125,10 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ - if(avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) + if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { + ret = AVERROR(EIO); goto fail; + } vidbuf_nbytes += 2; } @@ -141,8 +144,10 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code){ // plain sequence - if(avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) + if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { + ret = AVERROR(EIO); goto fail; + } vidbuf_nbytes += code; } bytes_copied += code & 0x7F; @@ -152,12 +157,14 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, avio_seek(pb, -1, SEEK_CUR); break; } - if(bytes_copied > npixels) + if (bytes_copied > npixels) { + ret = AVERROR_INVALIDDATA; goto fail; + } } while(code); // copy data into packet - if(av_new_packet(pkt, vidbuf_nbytes) < 0) + if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); @@ -175,10 +182,10 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, } vid->nframes--; // used to check if all the frames were read - return vidbuf_nbytes; + return 0; fail: av_free(vidbuf_start); - return -1; + return ret; } static int vid_read_packet(AVFormatContext *s, @@ -216,9 +223,14 @@ static int vid_read_packet(AVFormatContext *s, s->streams[1]->codec->bit_rate = s->streams[1]->codec->channels * s->streams[1]->codec->sample_rate * s->streams[1]->codec->bits_per_coded_sample; case AUDIO_BLOCK: audio_length = avio_rl16(pb); - ret_value = av_get_packet(pb, pkt, audio_length); + if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { + if (ret_value < 0) + return ret_value; + av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); + return AVERROR(EIO); + } pkt->stream_index = 1; - return ret_value != audio_length ? AVERROR(EIO) : ret_value; + return 0; case VIDEO_P_FRAME: case VIDEO_YOFF_P_FRAME: @@ -233,7 +245,8 @@ static int vid_read_packet(AVFormatContext *s, return AVERROR(EIO); default: av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", - block_type, block_type, block_type); return -1; + block_type, block_type, block_type); + return AVERROR_INVALIDDATA; } } -- cgit v1.2.3 From 05e4ae833ce9be39880c98a0cfb27edce4722bab Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 18:48:32 -0500 Subject: bethsoftvid: set packet key frame flag for audio and I-frame video packets. Fixes avconv video stream copy of bethsoft video, which was skipping all video frames unless the copyinkf option was used. --- libavformat/bethsoftvid.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index e755f83a7e..b01f73a558 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -172,6 +172,8 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, pkt->pos = position; pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream pkt->pts = vid->video_pts; + if (block_type == VIDEO_I_FRAME) + pkt->flags |= AV_PKT_FLAG_KEY; /* if there is a new palette available, add it to packet side data */ if (vid->palette) { @@ -230,6 +232,7 @@ static int vid_read_packet(AVFormatContext *s, return AVERROR(EIO); } pkt->stream_index = 1; + pkt->flags |= AV_PKT_FLAG_KEY; return 0; case VIDEO_P_FRAME: -- cgit v1.2.3 From 9546f331c6723d046f302da15acaa0ed52c03866 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 18:58:54 -0500 Subject: bethsoftvid: Set video packet duration instead of accumulating pts. --- libavformat/bethsoftvid.c | 12 +++++------- tests/ref/fate/bethsoft-vid | 41 ++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 28 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index b01f73a558..10be7d2521 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -42,9 +42,6 @@ typedef struct BVID_DemuxContext * to free, unofficial documentation) */ int bethsoft_global_delay; - /** video presentation time stamp. - * delay = 16 milliseconds * (global_delay + per_frame_delay) */ - int video_pts; uint8_t *palette; int is_finished; @@ -76,6 +73,7 @@ static int vid_read_header(AVFormatContext *s) stream = avformat_new_stream(s, NULL); if (!stream) return AVERROR(ENOMEM); + stream->start_time = 0; avpriv_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; stream->codec->codec_id = CODEC_ID_BETHSOFTVID; @@ -107,7 +105,7 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, int vidbuf_nbytes = 0; int code; int bytes_copied = 0; - int position; + int position, duration; unsigned int vidbuf_capacity; int ret = 0; @@ -120,8 +118,8 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, vidbuf_start[vidbuf_nbytes++] = block_type; - // get the video delay (next int16), and set the presentation time - vid->video_pts += vid->bethsoft_global_delay + avio_rl16(pb); + // get the current packet duration + duration = vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ @@ -171,7 +169,7 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, pkt->pos = position; pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream - pkt->pts = vid->video_pts; + pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid index 7abc9952d8..e6b1451e39 100644 --- a/tests/ref/fate/bethsoft-vid +++ b/tests/ref/fate/bethsoft-vid @@ -5,13 +5,13 @@ 1, 740, 740, 740, 1480, 0x20a92bd4 0, 4, 4, 1, 192000, 0x01a6cf45 1, 1480, 1480, 925, 1850, 0xa9e48a74 -0, 9, 9, 1, 192000, 0xd07d57e9 +0, 8, 8, 1, 192000, 0xd07d57e9 1, 2405, 2405, 740, 1480, 0x23ecd018 0, 13, 13, 1, 192000, 0x3cb1dff5 1, 3145, 3145, 740, 1480, 0x206bb915 0, 17, 17, 1, 192000, 0xd1aaa8fb 1, 3885, 3885, 925, 1850, 0xb0e10e75 -0, 22, 22, 1, 192000, 0x75f526cd +0, 21, 21, 1, 192000, 0x75f526cd 1, 4810, 4810, 740, 1480, 0x8d9baedd 0, 26, 26, 1, 192000, 0x0f673577 1, 5550, 5550, 740, 1480, 0xb802aae1 @@ -19,13 +19,13 @@ 1, 6290, 6290, 740, 1480, 0xecd7b5cc 0, 34, 34, 1, 192000, 0x81e6b7f7 1, 7030, 7030, 925, 1850, 0x16861355 -0, 39, 39, 1, 192000, 0x1f45ce61 +0, 38, 38, 1, 192000, 0x1f45ce61 1, 7955, 7955, 740, 1480, 0xa51690bd 0, 43, 43, 1, 192000, 0x5a0772a6 1, 8695, 8695, 740, 1480, 0xdd0b90d1 0, 47, 47, 1, 192000, 0xf78732b3 1, 9435, 9435, 925, 1850, 0x3ce6e333 -0, 52, 52, 1, 192000, 0x8427f9e5 +0, 51, 51, 1, 192000, 0x8427f9e5 1, 10360, 10360, 740, 1480, 0xf8ce8ea3 0, 56, 56, 1, 192000, 0x40473f11 1, 11100, 11100, 740, 1480, 0xda4597af @@ -33,13 +33,13 @@ 1, 11840, 11840, 740, 1480, 0x918f7cb3 0, 64, 64, 1, 192000, 0x136b9516 1, 12580, 12580, 925, 1850, 0xca6edb15 -0, 69, 69, 1, 192000, 0x138d11ae +0, 68, 68, 1, 192000, 0x138d11ae 1, 13505, 13505, 740, 1480, 0xba279597 0, 73, 73, 1, 192000, 0x063dbff3 1, 14245, 14245, 740, 1480, 0xc5a38a9e 0, 77, 77, 1, 192000, 0x5280852f 1, 14985, 14985, 925, 1850, 0x8147eef5 -0, 82, 82, 1, 192000, 0x99943a8f +0, 81, 81, 1, 192000, 0x99943a8f 1, 15910, 15910, 740, 1480, 0xce2c7cb5 0, 86, 86, 1, 192000, 0x0330a728 1, 16650, 16650, 740, 1480, 0x4282819f @@ -47,13 +47,13 @@ 1, 17390, 17390, 740, 1480, 0xbdbb8da6 0, 94, 94, 1, 192000, 0xfd436343 1, 18130, 18130, 925, 1850, 0xdbbeea10 -0, 99, 99, 1, 192000, 0xc323fcfe +0, 98, 98, 1, 192000, 0xc323fcfe 1, 19055, 19055, 740, 1480, 0xbe6a77c2 0, 103, 103, 1, 192000, 0x2a1530a0 1, 19795, 19795, 740, 1480, 0xa85c75b2 0, 107, 107, 1, 192000, 0xbd43bb60 1, 20535, 20535, 925, 1850, 0xa45bde21 -0, 112, 112, 1, 192000, 0xa47f5eab +0, 111, 111, 1, 192000, 0xa47f5eab 1, 21460, 21460, 740, 1480, 0x84aa7895 0, 116, 116, 1, 192000, 0xff17f5f7 1, 22200, 22200, 740, 1480, 0x147f7d9f @@ -61,13 +61,13 @@ 1, 22940, 22940, 740, 1480, 0xc8e77b85 0, 124, 124, 1, 192000, 0xb8782cc4 1, 23680, 23680, 925, 1850, 0x10d4d81b -0, 129, 129, 1, 192000, 0x92975b8b +0, 128, 128, 1, 192000, 0x92975b8b 1, 24605, 24605, 740, 1480, 0xb4ae8bb1 0, 133, 133, 1, 192000, 0xf42a64d6 1, 25345, 25345, 740, 1480, 0x3ef782a5 0, 137, 137, 1, 192000, 0x2cc7077d 1, 26085, 26085, 925, 1850, 0xdeebda14 -0, 142, 142, 1, 192000, 0x00080cc8 +0, 141, 141, 1, 192000, 0x00080cc8 1, 27010, 27010, 740, 1480, 0x4c7e7bbb 0, 146, 146, 1, 192000, 0x584b48f3 1, 27750, 27750, 740, 1480, 0x0e0e9198 @@ -75,13 +75,13 @@ 1, 28490, 28490, 740, 1480, 0x5c1f819f 0, 154, 154, 1, 192000, 0x60158422 1, 29230, 29230, 925, 1850, 0x0e4cf6ff -0, 159, 159, 1, 192000, 0xd7fb89e6 +0, 158, 158, 1, 192000, 0xd7fb89e6 1, 30155, 30155, 740, 1480, 0x374388a7 0, 163, 163, 1, 192000, 0x97f1c76a 1, 30895, 30895, 740, 1480, 0xed729389 0, 167, 167, 1, 192000, 0x46c4bb9e 1, 31635, 31635, 925, 1850, 0xe0f1e43f -0, 172, 172, 1, 192000, 0xd32f9b66 +0, 171, 171, 1, 192000, 0xd32f9b66 1, 32560, 32560, 740, 1480, 0x3b27839a 0, 176, 176, 1, 192000, 0x74f43886 1, 33300, 33300, 740, 1480, 0xe6287e94 @@ -89,13 +89,13 @@ 1, 34040, 34040, 740, 1480, 0x7e0d84b5 0, 184, 184, 1, 192000, 0xb5ac0a58 1, 34780, 34780, 925, 1850, 0xf08bebf7 -0, 189, 189, 1, 192000, 0xcc572b31 +0, 188, 188, 1, 192000, 0xcc572b31 1, 35705, 35705, 740, 1480, 0x94cf73a0 0, 193, 193, 1, 192000, 0xb1739d26 1, 36445, 36445, 740, 1480, 0xfef384ae 0, 197, 197, 1, 192000, 0x73da5473 1, 37185, 37185, 925, 1850, 0x3b93e0f7 -0, 202, 202, 1, 192000, 0x5f79f5bc +0, 201, 201, 1, 192000, 0x5f79f5bc 1, 38110, 38110, 740, 1480, 0x28d27bae 0, 206, 206, 1, 192000, 0x0affc0a0 1, 38850, 38850, 740, 1480, 0x94d57da5 @@ -103,13 +103,13 @@ 1, 39590, 39590, 740, 1480, 0xc9327db5 0, 214, 214, 1, 192000, 0x309b41bc 1, 40330, 40330, 925, 1850, 0xe781f604 -0, 219, 219, 1, 192000, 0xd42b6424 +0, 218, 218, 1, 192000, 0xd42b6424 1, 41255, 41255, 740, 1480, 0x752f8c5b 0, 223, 223, 1, 192000, 0x4795c948 1, 41995, 41995, 740, 1480, 0x30068032 0, 227, 227, 1, 192000, 0xbc1a3a8b 1, 42735, 42735, 925, 1850, 0x7895023e -0, 232, 232, 1, 192000, 0x16529c5b +0, 231, 231, 1, 192000, 0x16529c5b 1, 43660, 43660, 740, 1480, 0xa1e0a6e1 0, 236, 236, 1, 192000, 0x6b1b31ba 1, 44400, 44400, 740, 1480, 0x6af4b500 @@ -117,13 +117,13 @@ 1, 45140, 45140, 740, 1480, 0xc26ea4c7 0, 244, 244, 1, 192000, 0xe6ea9866 1, 45880, 45880, 925, 1850, 0x16a72419 -0, 249, 249, 1, 192000, 0x102c6076 +0, 248, 248, 1, 192000, 0x102c6076 1, 46805, 46805, 740, 1480, 0x1794aacc 0, 253, 253, 1, 192000, 0xb29f527a 1, 47545, 47545, 740, 1480, 0x2ecad8d0 0, 257, 257, 1, 192000, 0x040b4eee 1, 48285, 48285, 925, 1850, 0x2e645e07 -0, 262, 262, 1, 192000, 0x92574f4a +0, 261, 261, 1, 192000, 0x92574f4a 1, 49210, 49210, 740, 1480, 0x1c54dfe7 0, 266, 266, 1, 192000, 0x1e8acdce 1, 49950, 49950, 740, 1480, 0xbd35feec @@ -131,14 +131,13 @@ 1, 50690, 50690, 740, 1480, 0x419403d6 0, 274, 274, 1, 192000, 0xb62e9776 1, 51430, 51430, 925, 1850, 0x78699d2a -0, 279, 279, 1, 192000, 0xed37a08e +0, 278, 278, 1, 192000, 0xed37a08e 1, 52355, 52355, 740, 1480, 0x74ec68e0 0, 283, 283, 1, 192000, 0xc0719912 1, 53095, 53095, 740, 1480, 0x76af64d9 0, 287, 287, 1, 192000, 0x24cf7a7e 1, 53835, 53835, 925, 1850, 0x5a303d1a -0, 292, 292, 1, 192000, 0x0307f62f +0, 291, 291, 1, 192000, 0x0307f62f 1, 54760, 54760, 537, 1074, 0x142ce7ba 0, 296, 296, 1, 192000, 0x79b7417b 1, 55297, 55297, 925, 1850, 0x7ff682f7 -1, 56222, 56222, 740, 1480, 0xc33867e6 -- cgit v1.2.3 From 773ff823dac3da733c251b4cb1cc95b3b7e03001 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 19:50:37 -0500 Subject: bethsoftvid: add audio stream only after getting the first audio packet This avoids initializing a stream with dummy values or when the file does not contain audio. Also set duration for audio packets, using the sample rate as the time base. --- libavformat/bethsoftvid.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 10be7d2521..1092299874 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -34,14 +34,18 @@ #define BVID_PALETTE_SIZE 3 * 256 +#define DEFAULT_SAMPLE_RATE 11111 + typedef struct BVID_DemuxContext { int nframes; + int sample_rate; /**< audio sample rate */ /** delay value between frames, added to individual frame delay. * custom units, which will be added to other custom units (~=16ms according * to free, unofficial documentation) */ int bethsoft_global_delay; - + int video_index; /**< video stream index */ + int audio_index; /**< audio stream index */ uint8_t *palette; int is_finished; @@ -73,6 +77,7 @@ static int vid_read_header(AVFormatContext *s) stream = avformat_new_stream(s, NULL); if (!stream) return AVERROR(ENOMEM); + vid->video_index = stream->index; stream->start_time = 0; avpriv_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; @@ -83,16 +88,9 @@ static int vid_read_header(AVFormatContext *s) vid->bethsoft_global_delay = avio_rl16(pb); avio_rl16(pb); - // done with video codec, set up audio codec - stream = avformat_new_stream(s, NULL); - if (!stream) - return AVERROR(ENOMEM); - stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - stream->codec->codec_id = CODEC_ID_PCM_U8; - stream->codec->channels = 1; - stream->codec->sample_rate = 11025; - stream->codec->bits_per_coded_sample = 8; - stream->codec->bit_rate = stream->codec->channels * stream->codec->sample_rate * stream->codec->bits_per_coded_sample; + // wait until the first audio packet to create the audio stream + vid->audio_index = -1; + s->ctx_flags |= AVFMTCTX_NOHEADER; return 0; } @@ -168,7 +166,7 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, av_free(vidbuf_start); pkt->pos = position; - pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream + pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; @@ -219,9 +217,22 @@ static int vid_read_packet(AVFormatContext *s, case FIRST_AUDIO_BLOCK: avio_rl16(pb); // soundblaster DAC used for sample rate, as on specification page (link above) - s->streams[1]->codec->sample_rate = 1000000 / (256 - avio_r8(pb)); - s->streams[1]->codec->bit_rate = s->streams[1]->codec->channels * s->streams[1]->codec->sample_rate * s->streams[1]->codec->bits_per_coded_sample; + vid->sample_rate = 1000000 / (256 - avio_r8(pb)); case AUDIO_BLOCK: + if (vid->audio_index < 0) { + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + vid->audio_index = st->index; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_PCM_U8; + st->codec->channels = 1; + st->codec->bits_per_coded_sample = 8; + st->codec->sample_rate = vid->sample_rate; + st->codec->bit_rate = 8 * st->codec->sample_rate; + st->start_time = 0; + avpriv_set_pts_info(st, 64, 1, vid->sample_rate); + } audio_length = avio_rl16(pb); if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { if (ret_value < 0) @@ -229,7 +240,8 @@ static int vid_read_packet(AVFormatContext *s, av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); return AVERROR(EIO); } - pkt->stream_index = 1; + pkt->stream_index = vid->audio_index; + pkt->duration = audio_length; pkt->flags |= AV_PKT_FLAG_KEY; return 0; -- cgit v1.2.3 From c9fdf3241a96f01496facea9249b3965fa2df653 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 Jan 2012 20:24:30 -0500 Subject: bethsoftvid: synchronize video timestamps with audio sample rate According to unofficial documentation, the video rate is locked to the audio sample rate. This results in proper synchronization of audio and video timestamps from the demuxer. This only works if the first audio packet occurs before the first video packet or the audio sample rate is the default rate of 11111 Hz, both of which are true for all samples in our archive. --- libavformat/bethsoftvid.c | 47 +++++++++------ tests/ref/fate/bethsoft-vid | 141 ++++++++++++++++++++++---------------------- 2 files changed, 100 insertions(+), 88 deletions(-) (limited to 'libavformat/bethsoftvid.c') diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c index 1092299874..3e6ec5fa6d 100644 --- a/libavformat/bethsoftvid.c +++ b/libavformat/bethsoftvid.c @@ -40,6 +40,8 @@ typedef struct BVID_DemuxContext { int nframes; int sample_rate; /**< audio sample rate */ + int width; /**< video width */ + int height; /**< video height */ /** delay value between frames, added to individual frame delay. * custom units, which will be added to other custom units (~=16ms according * to free, unofficial documentation) */ @@ -65,7 +67,6 @@ static int vid_read_header(AVFormatContext *s) { BVID_DemuxContext *vid = s->priv_data; AVIOContext *pb = s->pb; - AVStream *stream; /* load main header. Contents: * bytes: 'V' 'I' 'D' @@ -73,23 +74,15 @@ static int vid_read_header(AVFormatContext *s) */ avio_skip(pb, 5); vid->nframes = avio_rl16(pb); - - stream = avformat_new_stream(s, NULL); - if (!stream) - return AVERROR(ENOMEM); - vid->video_index = stream->index; - stream->start_time = 0; - avpriv_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps - stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - stream->codec->codec_id = CODEC_ID_BETHSOFTVID; - stream->codec->width = avio_rl16(pb); - stream->codec->height = avio_rl16(pb); - stream->codec->pix_fmt = PIX_FMT_PAL8; + vid->width = avio_rl16(pb); + vid->height = avio_rl16(pb); vid->bethsoft_global_delay = avio_rl16(pb); avio_rl16(pb); - // wait until the first audio packet to create the audio stream + // wait until the first packet to create each stream + vid->video_index = -1; vid->audio_index = -1; + vid->sample_rate = DEFAULT_SAMPLE_RATE; s->ctx_flags |= AVFMTCTX_NOHEADER; return 0; @@ -97,15 +90,34 @@ static int vid_read_header(AVFormatContext *s) #define BUFFER_PADDING_SIZE 1000 static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, - uint8_t block_type, AVFormatContext *s, int npixels) + uint8_t block_type, AVFormatContext *s) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; - int position, duration; + int position, duration, npixels; unsigned int vidbuf_capacity; int ret = 0; + AVStream *st; + + if (vid->video_index < 0) { + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + vid->video_index = st->index; + if (vid->audio_index < 0) { + av_log_ask_for_sample(s, "No audio packet before first video " + "packet. Using default video time base.\n"); + } + avpriv_set_pts_info(st, 64, 185, vid->sample_rate); + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->codec_id = CODEC_ID_BETHSOFTVID; + st->codec->width = vid->width; + st->codec->height = vid->height; + } + st = s->streams[vid->video_index]; + npixels = st->codec->width * st->codec->height; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) @@ -248,8 +260,7 @@ static int vid_read_packet(AVFormatContext *s, case VIDEO_P_FRAME: case VIDEO_YOFF_P_FRAME: case VIDEO_I_FRAME: - return read_frame(vid, pb, pkt, block_type, s, - s->streams[0]->codec->width * s->streams[0]->codec->height); + return read_frame(vid, pb, pkt, block_type, s); case EOF_BLOCK: if(vid->nframes != 0) diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid index e6b1451e39..394d7e93ea 100644 --- a/tests/ref/fate/bethsoft-vid +++ b/tests/ref/fate/bethsoft-vid @@ -1,143 +1,144 @@ -#tb 0: 1/60 +#tb 0: 12/553 #tb 1: 1/11111 0, 0, 0, 1, 192000, 0x00000000 1, 0, 0, 740, 1480, 0x00000000 +0, 3, 3, 1, 192000, 0x01a6cf45 1, 740, 740, 740, 1480, 0x20a92bd4 -0, 4, 4, 1, 192000, 0x01a6cf45 +0, 6, 6, 1, 192000, 0xd07d57e9 1, 1480, 1480, 925, 1850, 0xa9e48a74 -0, 8, 8, 1, 192000, 0xd07d57e9 1, 2405, 2405, 740, 1480, 0x23ecd018 -0, 13, 13, 1, 192000, 0x3cb1dff5 +0, 10, 10, 1, 192000, 0x3cb1dff5 +0, 13, 13, 1, 192000, 0xd1aaa8fb 1, 3145, 3145, 740, 1480, 0x206bb915 -0, 17, 17, 1, 192000, 0xd1aaa8fb +0, 16, 16, 1, 192000, 0x75f526cd 1, 3885, 3885, 925, 1850, 0xb0e10e75 -0, 21, 21, 1, 192000, 0x75f526cd 1, 4810, 4810, 740, 1480, 0x8d9baedd -0, 26, 26, 1, 192000, 0x0f673577 +0, 20, 20, 1, 192000, 0x0f673577 +0, 23, 23, 1, 192000, 0x897b6781 1, 5550, 5550, 740, 1480, 0xb802aae1 -0, 30, 30, 1, 192000, 0x897b6781 +0, 26, 26, 1, 192000, 0x81e6b7f7 1, 6290, 6290, 740, 1480, 0xecd7b5cc -0, 34, 34, 1, 192000, 0x81e6b7f7 +0, 29, 29, 1, 192000, 0x1f45ce61 1, 7030, 7030, 925, 1850, 0x16861355 -0, 38, 38, 1, 192000, 0x1f45ce61 1, 7955, 7955, 740, 1480, 0xa51690bd -0, 43, 43, 1, 192000, 0x5a0772a6 +0, 33, 33, 1, 192000, 0x5a0772a6 +0, 36, 36, 1, 192000, 0xf78732b3 1, 8695, 8695, 740, 1480, 0xdd0b90d1 -0, 47, 47, 1, 192000, 0xf78732b3 +0, 39, 39, 1, 192000, 0x8427f9e5 1, 9435, 9435, 925, 1850, 0x3ce6e333 -0, 51, 51, 1, 192000, 0x8427f9e5 1, 10360, 10360, 740, 1480, 0xf8ce8ea3 -0, 56, 56, 1, 192000, 0x40473f11 +0, 43, 43, 1, 192000, 0x40473f11 +0, 46, 46, 1, 192000, 0x173ceebe 1, 11100, 11100, 740, 1480, 0xda4597af -0, 60, 60, 1, 192000, 0x173ceebe +0, 49, 49, 1, 192000, 0x136b9516 1, 11840, 11840, 740, 1480, 0x918f7cb3 -0, 64, 64, 1, 192000, 0x136b9516 +0, 52, 52, 1, 192000, 0x138d11ae 1, 12580, 12580, 925, 1850, 0xca6edb15 -0, 68, 68, 1, 192000, 0x138d11ae +0, 56, 56, 1, 192000, 0x063dbff3 1, 13505, 13505, 740, 1480, 0xba279597 -0, 73, 73, 1, 192000, 0x063dbff3 +0, 59, 59, 1, 192000, 0x5280852f 1, 14245, 14245, 740, 1480, 0xc5a38a9e -0, 77, 77, 1, 192000, 0x5280852f +0, 62, 62, 1, 192000, 0x99943a8f 1, 14985, 14985, 925, 1850, 0x8147eef5 -0, 81, 81, 1, 192000, 0x99943a8f 1, 15910, 15910, 740, 1480, 0xce2c7cb5 -0, 86, 86, 1, 192000, 0x0330a728 +0, 66, 66, 1, 192000, 0x0330a728 +0, 69, 69, 1, 192000, 0x5d35467d 1, 16650, 16650, 740, 1480, 0x4282819f -0, 90, 90, 1, 192000, 0x5d35467d +0, 72, 72, 1, 192000, 0xfd436343 1, 17390, 17390, 740, 1480, 0xbdbb8da6 -0, 94, 94, 1, 192000, 0xfd436343 +0, 75, 75, 1, 192000, 0xc323fcfe 1, 18130, 18130, 925, 1850, 0xdbbeea10 -0, 98, 98, 1, 192000, 0xc323fcfe +0, 79, 79, 1, 192000, 0x2a1530a0 1, 19055, 19055, 740, 1480, 0xbe6a77c2 -0, 103, 103, 1, 192000, 0x2a1530a0 +0, 82, 82, 1, 192000, 0xbd43bb60 1, 19795, 19795, 740, 1480, 0xa85c75b2 -0, 107, 107, 1, 192000, 0xbd43bb60 +0, 85, 85, 1, 192000, 0xa47f5eab 1, 20535, 20535, 925, 1850, 0xa45bde21 -0, 111, 111, 1, 192000, 0xa47f5eab +0, 89, 89, 1, 192000, 0xff17f5f7 1, 21460, 21460, 740, 1480, 0x84aa7895 -0, 116, 116, 1, 192000, 0xff17f5f7 +0, 92, 92, 1, 192000, 0xb4140b55 1, 22200, 22200, 740, 1480, 0x147f7d9f -0, 120, 120, 1, 192000, 0xb4140b55 +0, 95, 95, 1, 192000, 0xb8782cc4 1, 22940, 22940, 740, 1480, 0xc8e77b85 -0, 124, 124, 1, 192000, 0xb8782cc4 +0, 98, 98, 1, 192000, 0x92975b8b 1, 23680, 23680, 925, 1850, 0x10d4d81b -0, 128, 128, 1, 192000, 0x92975b8b +0, 102, 102, 1, 192000, 0xf42a64d6 1, 24605, 24605, 740, 1480, 0xb4ae8bb1 -0, 133, 133, 1, 192000, 0xf42a64d6 +0, 105, 105, 1, 192000, 0x2cc7077d 1, 25345, 25345, 740, 1480, 0x3ef782a5 -0, 137, 137, 1, 192000, 0x2cc7077d +0, 108, 108, 1, 192000, 0x00080cc8 1, 26085, 26085, 925, 1850, 0xdeebda14 -0, 141, 141, 1, 192000, 0x00080cc8 +0, 112, 112, 1, 192000, 0x584b48f3 1, 27010, 27010, 740, 1480, 0x4c7e7bbb -0, 146, 146, 1, 192000, 0x584b48f3 +0, 115, 115, 1, 192000, 0xd68f57da 1, 27750, 27750, 740, 1480, 0x0e0e9198 -0, 150, 150, 1, 192000, 0xd68f57da +0, 118, 118, 1, 192000, 0x60158422 1, 28490, 28490, 740, 1480, 0x5c1f819f -0, 154, 154, 1, 192000, 0x60158422 +0, 121, 121, 1, 192000, 0xd7fb89e6 1, 29230, 29230, 925, 1850, 0x0e4cf6ff -0, 158, 158, 1, 192000, 0xd7fb89e6 +0, 125, 125, 1, 192000, 0x97f1c76a 1, 30155, 30155, 740, 1480, 0x374388a7 -0, 163, 163, 1, 192000, 0x97f1c76a +0, 128, 128, 1, 192000, 0x46c4bb9e 1, 30895, 30895, 740, 1480, 0xed729389 -0, 167, 167, 1, 192000, 0x46c4bb9e +0, 131, 131, 1, 192000, 0xd32f9b66 1, 31635, 31635, 925, 1850, 0xe0f1e43f -0, 171, 171, 1, 192000, 0xd32f9b66 +0, 135, 135, 1, 192000, 0x74f43886 1, 32560, 32560, 740, 1480, 0x3b27839a -0, 176, 176, 1, 192000, 0x74f43886 +0, 138, 138, 1, 192000, 0x3c4e47df 1, 33300, 33300, 740, 1480, 0xe6287e94 -0, 180, 180, 1, 192000, 0x3c4e47df +0, 141, 141, 1, 192000, 0xb5ac0a58 1, 34040, 34040, 740, 1480, 0x7e0d84b5 -0, 184, 184, 1, 192000, 0xb5ac0a58 +0, 144, 144, 1, 192000, 0xcc572b31 1, 34780, 34780, 925, 1850, 0xf08bebf7 -0, 188, 188, 1, 192000, 0xcc572b31 +0, 148, 148, 1, 192000, 0xb1739d26 1, 35705, 35705, 740, 1480, 0x94cf73a0 -0, 193, 193, 1, 192000, 0xb1739d26 +0, 151, 151, 1, 192000, 0x73da5473 1, 36445, 36445, 740, 1480, 0xfef384ae -0, 197, 197, 1, 192000, 0x73da5473 +0, 154, 154, 1, 192000, 0x5f79f5bc 1, 37185, 37185, 925, 1850, 0x3b93e0f7 -0, 201, 201, 1, 192000, 0x5f79f5bc +0, 158, 158, 1, 192000, 0x0affc0a0 1, 38110, 38110, 740, 1480, 0x28d27bae -0, 206, 206, 1, 192000, 0x0affc0a0 +0, 161, 161, 1, 192000, 0x2b4d5c1c 1, 38850, 38850, 740, 1480, 0x94d57da5 -0, 210, 210, 1, 192000, 0x2b4d5c1c +0, 164, 164, 1, 192000, 0x309b41bc 1, 39590, 39590, 740, 1480, 0xc9327db5 -0, 214, 214, 1, 192000, 0x309b41bc +0, 167, 167, 1, 192000, 0xd42b6424 1, 40330, 40330, 925, 1850, 0xe781f604 -0, 218, 218, 1, 192000, 0xd42b6424 +0, 171, 171, 1, 192000, 0x4795c948 1, 41255, 41255, 740, 1480, 0x752f8c5b -0, 223, 223, 1, 192000, 0x4795c948 +0, 174, 174, 1, 192000, 0xbc1a3a8b 1, 41995, 41995, 740, 1480, 0x30068032 -0, 227, 227, 1, 192000, 0xbc1a3a8b +0, 177, 177, 1, 192000, 0x16529c5b 1, 42735, 42735, 925, 1850, 0x7895023e -0, 231, 231, 1, 192000, 0x16529c5b +0, 181, 181, 1, 192000, 0x6b1b31ba 1, 43660, 43660, 740, 1480, 0xa1e0a6e1 -0, 236, 236, 1, 192000, 0x6b1b31ba +0, 184, 184, 1, 192000, 0x569182ce 1, 44400, 44400, 740, 1480, 0x6af4b500 -0, 240, 240, 1, 192000, 0x569182ce +0, 187, 187, 1, 192000, 0xe6ea9866 1, 45140, 45140, 740, 1480, 0xc26ea4c7 -0, 244, 244, 1, 192000, 0xe6ea9866 +0, 190, 190, 1, 192000, 0x102c6076 1, 45880, 45880, 925, 1850, 0x16a72419 -0, 248, 248, 1, 192000, 0x102c6076 +0, 194, 194, 1, 192000, 0xb29f527a 1, 46805, 46805, 740, 1480, 0x1794aacc -0, 253, 253, 1, 192000, 0xb29f527a +0, 197, 197, 1, 192000, 0x040b4eee 1, 47545, 47545, 740, 1480, 0x2ecad8d0 -0, 257, 257, 1, 192000, 0x040b4eee +0, 200, 200, 1, 192000, 0x92574f4a 1, 48285, 48285, 925, 1850, 0x2e645e07 -0, 261, 261, 1, 192000, 0x92574f4a +0, 204, 204, 1, 192000, 0x1e8acdce 1, 49210, 49210, 740, 1480, 0x1c54dfe7 -0, 266, 266, 1, 192000, 0x1e8acdce +0, 207, 207, 1, 192000, 0x1becf516 1, 49950, 49950, 740, 1480, 0xbd35feec -0, 270, 270, 1, 192000, 0x1becf516 +0, 210, 210, 1, 192000, 0xb62e9776 1, 50690, 50690, 740, 1480, 0x419403d6 -0, 274, 274, 1, 192000, 0xb62e9776 +0, 213, 213, 1, 192000, 0xed37a08e 1, 51430, 51430, 925, 1850, 0x78699d2a -0, 278, 278, 1, 192000, 0xed37a08e +0, 217, 217, 1, 192000, 0xc0719912 1, 52355, 52355, 740, 1480, 0x74ec68e0 -0, 283, 283, 1, 192000, 0xc0719912 +0, 220, 220, 1, 192000, 0x24cf7a7e 1, 53095, 53095, 740, 1480, 0x76af64d9 -0, 287, 287, 1, 192000, 0x24cf7a7e +0, 223, 223, 1, 192000, 0x0307f62f 1, 53835, 53835, 925, 1850, 0x5a303d1a -0, 291, 291, 1, 192000, 0x0307f62f +0, 227, 227, 1, 192000, 0x79b7417b 1, 54760, 54760, 537, 1074, 0x142ce7ba -0, 296, 296, 1, 192000, 0x79b7417b 1, 55297, 55297, 925, 1850, 0x7ff682f7 +0, 230, 230, 1, 192000, 0x468d8db4 -- cgit v1.2.3