Mercurial > libavformat.hg
changeset 2558:74c1aa100084 libavformat
Add support for VP6A in flv.
Those files really contain 2 standard VP6 video streams:
- the "normal" video stream
- the alpha plan video stream (which is a standard
YV12 video with it's U an V plans all set to 0)
closes issue166
author | aurel |
---|---|
date | Tue, 18 Sep 2007 15:36:29 +0000 |
parents | 0c4febec2258 |
children | c57d3d6c8f44 |
files | flvdec.c |
diffstat | 1 files changed, 49 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/flvdec.c Tue Sep 18 08:26:10 2007 +0000 +++ b/flvdec.c Tue Sep 18 15:36:29 2007 +0000 @@ -26,6 +26,13 @@ #include "avformat.h" #include "flv.h" +typedef struct { + AVStream *alpha_stream; + int pts; + int flags; + int alpha_size; +} FLVContext; + static int flv_probe(AVProbeData *p) { const uint8_t *d; @@ -57,16 +64,32 @@ } static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { + FLVContext *flv = s->priv_data; AVCodecContext *vcodec = vstream->codec; switch(flv_codecid) { case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break; + case FLV_CODECID_VP6A : + if (!flv->alpha_stream) { + AVCodecContext *alpha_codec; + flv->alpha_stream = av_new_stream(s, 2); + if (flv->alpha_stream) { + av_set_pts_info(flv->alpha_stream, 24, 1, 1000); + alpha_codec = flv->alpha_stream->codec; + alpha_codec->codec_type = CODEC_TYPE_VIDEO; + alpha_codec->codec_id = CODEC_ID_VP6F; + alpha_codec->extradata_size = 1; + alpha_codec->extradata = av_malloc(1); + } + } case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; if(vcodec->extradata_size != 1) { vcodec->extradata_size = 1; vcodec->extradata = av_malloc(1); } vcodec->extradata[0] = get_byte(&s->pb); + if (flv->alpha_stream) + flv->alpha_stream->codec->extradata[0] = vcodec->extradata[0]; return 1; // 1 byte body size adjustment for flv_read_packet() default: av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); @@ -259,16 +282,26 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) { - int ret, i, type, size, pts, flags, is_audio, next, pos; + int ret, i, type, size, flags, is_audio, next, pos; + FLVContext *flv = s->priv_data; AVStream *st = NULL; + if (flv->alpha_stream && flv->alpha_size) { + is_audio = 0; + size = flv->alpha_size; + flv->alpha_size = 0; + flags = flv->flags; + st = flv->alpha_stream; + goto packet; + } + for(;;){ pos = url_ftell(&s->pb); url_fskip(&s->pb, 4); /* size of previous packet */ type = get_byte(&s->pb); size = get_be24(&s->pb); - pts = get_be24(&s->pb); -// av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, pts); + flv->pts = get_be24(&s->pb); +// av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, flv->pts); if (url_feof(&s->pb)) return AVERROR(EIO); url_fskip(&s->pb, 4); /* reserved */ @@ -314,7 +347,7 @@ continue; } if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) - av_add_index_entry(st, pos, pts, size, 0, AVINDEX_KEYFRAME); + av_add_index_entry(st, pos, flv->pts, size, 0, AVINDEX_KEYFRAME); break; } @@ -346,6 +379,16 @@ size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); } + if ((flags & FLV_VIDEO_CODECID_MASK) == FLV_CODECID_VP6A) { + int alpha_offset = get_be24(&s->pb); + if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) + av_add_index_entry(flv->alpha_stream, pos, flv->pts, size, + 0, AVINDEX_KEYFRAME); + flv->alpha_size = size - 3 - alpha_offset; + size = alpha_offset + 1; + flv->flags = flags; + } +packet: ret= av_get_packet(&s->pb, pkt, size - 1); if (ret <= 0) { return AVERROR(EIO); @@ -353,7 +396,7 @@ /* note: we need to modify the packet size here to handle the last packet */ pkt->size = ret; - pkt->pts = pts; + pkt->pts = flv->pts; pkt->stream_index = st->index; if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) @@ -381,7 +424,7 @@ AVInputFormat flv_demuxer = { "flv", "flv format", - 0, + sizeof(FLVContext), flv_probe, flv_read_header, flv_read_packet,