Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .vp6 files may contain two video streams: one for the primary video
- stream and another for the alpha mask. The file format uses identical
- data structures for both streams.
- Signed-off-by: Peter Ross <pross@xvid.org>
- ---
- libavformat/electronicarts.c | 136 +++++++++++++++++++++++++------------------
- 1 file changed, 80 insertions(+), 56 deletions(-)
- diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
- index d999a0b..1c35e2d 100644
- --- a/libavformat/electronicarts.c
- +++ b/libavformat/electronicarts.c
- @@ -59,18 +59,25 @@
- #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
- #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
- #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
- +#define AVhd_TAG MKTAG('A', 'V', 'h', 'd')
- +#define AV0K_TAG MKTAG('A', 'V', '0', 'K')
- +#define AV0F_TAG MKTAG('A', 'V', '0', 'F')
- #define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
- #define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV I-frame */
- #define AVP6_TAG MKTAG('A', 'V', 'P', '6')
- -typedef struct EaDemuxContext {
- - int big_endian;
- -
- - enum AVCodecID video_codec;
- +typedef struct VideoProperties {
- + enum AVCodecID codec;
- AVRational time_base;
- int width, height;
- int nb_frames;
- - int video_stream_index;
- + int stream_index;
- +} VideoProperties;
- +
- +typedef struct EaDemuxContext {
- + int big_endian;
- +
- + VideoProperties video, alpha;
- enum AVCodecID audio_codec;
- int audio_stream_index;
- @@ -302,46 +309,43 @@ static void process_audio_header_sead(AVFormatContext *s)
- ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
- }
- -static void process_video_header_mdec(AVFormatContext *s)
- +static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
- {
- - EaDemuxContext *ea = s->priv_data;
- AVIOContext *pb = s->pb;
- avio_skip(pb, 4);
- - ea->width = avio_rl16(pb);
- - ea->height = avio_rl16(pb);
- - ea->time_base = (AVRational) { 1, 15 };
- - ea->video_codec = AV_CODEC_ID_MDEC;
- + video->width = avio_rl16(pb);
- + video->height = avio_rl16(pb);
- + video->time_base = (AVRational) { 1, 15 };
- + video->codec = AV_CODEC_ID_MDEC;
- }
- -static int process_video_header_vp6(AVFormatContext *s)
- +static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
- {
- - EaDemuxContext *ea = s->priv_data;
- - AVIOContext *pb = s->pb;
- + AVIOContext *pb = s->pb;
- avio_skip(pb, 8);
- - ea->nb_frames = avio_rl32(pb);
- + video->nb_frames = avio_rl32(pb);
- avio_skip(pb, 4);
- - ea->time_base.den = avio_rl32(pb);
- - ea->time_base.num = avio_rl32(pb);
- - if (ea->time_base.den <= 0 || ea->time_base.num <= 0) {
- + video->time_base.den = avio_rl32(pb);
- + video->time_base.num = avio_rl32(pb);
- + if (video->time_base.den <= 0 || video->time_base.num <= 0) {
- av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
- return AVERROR_INVALIDDATA;
- }
- - ea->video_codec = AV_CODEC_ID_VP6;
- + video->codec = AV_CODEC_ID_VP6;
- return 1;
- }
- -static void process_video_header_cmv(AVFormatContext *s)
- +static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
- {
- - EaDemuxContext *ea = s->priv_data;
- int fps;
- avio_skip(s->pb, 10);
- fps = avio_rl16(s->pb);
- if (fps)
- - ea->time_base = (AVRational) { 1, fps };
- - ea->video_codec = AV_CODEC_ID_CMV;
- + video->time_base = (AVRational) { 1, fps };
- + video->codec = AV_CODEC_ID_CMV;
- }
- /* Process EA file header.
- @@ -353,7 +357,7 @@ static int process_ea_header(AVFormatContext *s)
- AVIOContext *pb = s->pb;
- int i;
- - for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
- + for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
- uint64_t startpos = avio_tell(pb);
- int err = 0;
- @@ -395,40 +399,44 @@ static int process_ea_header(AVFormatContext *s)
- break;
- case MVIh_TAG:
- - process_video_header_cmv(s);
- + process_video_header_cmv(s, &ea->video);
- break;
- case kVGT_TAG:
- - ea->video_codec = AV_CODEC_ID_TGV;
- + ea->video.codec = AV_CODEC_ID_TGV;
- break;
- case mTCD_TAG:
- - process_video_header_mdec(s);
- + process_video_header_mdec(s, &ea->video);
- break;
- case MPCh_TAG:
- - ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
- + ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
- break;
- case pQGT_TAG:
- case TGQs_TAG:
- - ea->video_codec = AV_CODEC_ID_TGQ;
- - ea->time_base = (AVRational) { 1, 15 };
- + ea->video.codec = AV_CODEC_ID_TGQ;
- + ea->video.time_base = (AVRational) { 1, 15 };
- break;
- case pIQT_TAG:
- - ea->video_codec = AV_CODEC_ID_TQI;
- - ea->time_base = (AVRational) { 1, 15 };
- + ea->video.codec = AV_CODEC_ID_TQI;
- + ea->video.time_base = (AVRational) { 1, 15 };
- break;
- case MADk_TAG:
- - ea->video_codec = AV_CODEC_ID_MAD;
- + ea->video.codec = AV_CODEC_ID_MAD;
- avio_skip(pb, 6);
- - ea->time_base = (AVRational) { avio_rl16(pb), 1000 };
- + ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
- break;
- case MVhd_TAG:
- - err = process_video_header_vp6(s);
- + err = process_video_header_vp6(s, &ea->video);
- + break;
- +
- + case AVhd_TAG:
- + err = process_video_header_vp6(s, &ea->alpha);
- break;
- }
- @@ -458,6 +466,7 @@ static int ea_probe(AVProbeData *p)
- case MADk_TAG:
- case MPCh_TAG:
- case MVhd_TAG:
- + case AVhd_TAG:
- case MVIh_TAG:
- case AVP6_TAG:
- break;
- @@ -474,6 +483,34 @@ static int ea_probe(AVProbeData *p)
- return AVPROBE_SCORE_MAX;
- }
- +static int init_video_stream(AVFormatContext *s, VideoProperties *video)
- +{
- + AVStream *st;
- +
- + if (!video->codec)
- + return 0;
- +
- + /* initialize the video decoder stream */
- + st = avformat_new_stream(s, NULL);
- + if (!st)
- + return AVERROR(ENOMEM);
- + video->stream_index = st->index;
- + st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- + st->codec->codec_id = video->codec;
- + // parsing is necessary to make FFmpeg generate correct timestamps
- + if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
- + st->need_parsing = AVSTREAM_PARSE_HEADERS;
- + st->codec->codec_tag = 0; /* no fourcc */
- + st->codec->width = video->width;
- + st->codec->height = video->height;
- + st->duration = st->nb_frames = video->nb_frames;
- + if (video->time_base.num)
- + avpriv_set_pts_info(st, 64, video->time_base.num, video->time_base.den);
- + st->r_frame_rate =
- + st->avg_frame_rate = av_inv_q(video->time_base);
- + return 0;
- +}
- +
- static int ea_read_header(AVFormatContext *s)
- {
- EaDemuxContext *ea = s->priv_data;
- @@ -482,26 +519,8 @@ static int ea_read_header(AVFormatContext *s)
- if (process_ea_header(s)<=0)
- return AVERROR(EIO);
- - if (ea->video_codec) {
- - /* initialize the video decoder stream */
- - st = avformat_new_stream(s, NULL);
- - if (!st)
- - return AVERROR(ENOMEM);
- - ea->video_stream_index = st->index;
- - st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- - st->codec->codec_id = ea->video_codec;
- - // parsing is necessary to make FFmpeg generate correct timestamps
- - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
- - st->need_parsing = AVSTREAM_PARSE_HEADERS;
- - st->codec->codec_tag = 0; /* no fourcc */
- - st->codec->width = ea->width;
- - st->codec->height = ea->height;
- - st->duration = st->nb_frames = ea->nb_frames;
- - if (ea->time_base.num)
- - avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
- - st->r_frame_rate =
- - st->avg_frame_rate = av_inv_q(ea->time_base);
- - }
- + if (init_video_stream(s, &ea->video) || init_video_stream(s, &ea->alpha))
- + return AVERROR(ENOMEM);
- if (ea->audio_codec) {
- if (ea->num_channels <= 0 || ea->num_channels > 2) {
- @@ -661,10 +680,12 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
- goto get_video_packet;
- case MV0K_TAG:
- + case AV0K_TAG:
- case MPCh_TAG:
- case pIQT_TAG:
- key = AV_PKT_FLAG_KEY;
- case MV0F_TAG:
- + case AV0F_TAG:
- get_video_packet:
- if (!chunk_size)
- continue;
- @@ -678,7 +699,10 @@ get_video_packet:
- break;
- }
- partial_packet = chunk_type == MVIh_TAG;
- - pkt->stream_index = ea->video_stream_index;
- + if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
- + pkt->stream_index = ea->alpha.stream_index;
- + else
- + pkt->stream_index = ea->video.stream_index;
- pkt->flags |= key;
- packet_read = 1;
- break;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement