Commit 342e2d5f authored by aurel's avatar aurel

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)


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@10527 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 1252ab84
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
#include "avformat.h" #include "avformat.h"
#include "flv.h" #include "flv.h"
typedef struct {
AVStream *alpha_stream;
int pts;
int flags;
int alpha_size;
} FLVContext;
static int flv_probe(AVProbeData *p) static int flv_probe(AVProbeData *p)
{ {
const uint8_t *d; const uint8_t *d;
...@@ -57,16 +64,32 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_c ...@@ -57,16 +64,32 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_c
} }
static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) {
FLVContext *flv = s->priv_data;
AVCodecContext *vcodec = vstream->codec; AVCodecContext *vcodec = vstream->codec;
switch(flv_codecid) { switch(flv_codecid) {
case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; 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_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 ; case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ;
if(vcodec->extradata_size != 1) { if(vcodec->extradata_size != 1) {
vcodec->extradata_size = 1; vcodec->extradata_size = 1;
vcodec->extradata = av_malloc(1); vcodec->extradata = av_malloc(1);
} }
vcodec->extradata[0] = get_byte(&s->pb); 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() return 1; // 1 byte body size adjustment for flv_read_packet()
default: default:
av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
...@@ -259,16 +282,26 @@ static int flv_read_header(AVFormatContext *s, ...@@ -259,16 +282,26 @@ static int flv_read_header(AVFormatContext *s,
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) 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; 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(;;){ for(;;){
pos = url_ftell(&s->pb); pos = url_ftell(&s->pb);
url_fskip(&s->pb, 4); /* size of previous packet */ url_fskip(&s->pb, 4); /* size of previous packet */
type = get_byte(&s->pb); type = get_byte(&s->pb);
size = get_be24(&s->pb); size = get_be24(&s->pb);
pts = get_be24(&s->pb); flv->pts = get_be24(&s->pb);
// av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, pts); // av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, flv->pts);
if (url_feof(&s->pb)) if (url_feof(&s->pb))
return AVERROR(EIO); return AVERROR(EIO);
url_fskip(&s->pb, 4); /* reserved */ url_fskip(&s->pb, 4); /* reserved */
...@@ -314,7 +347,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -314,7 +347,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
continue; continue;
} }
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) 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; break;
} }
...@@ -346,6 +379,16 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -346,6 +379,16 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); 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); ret= av_get_packet(&s->pb, pkt, size - 1);
if (ret <= 0) { if (ret <= 0) {
return AVERROR(EIO); return AVERROR(EIO);
...@@ -353,7 +396,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -353,7 +396,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
/* note: we need to modify the packet size here to handle the last /* note: we need to modify the packet size here to handle the last
packet */ packet */
pkt->size = ret; pkt->size = ret;
pkt->pts = pts; pkt->pts = flv->pts;
pkt->stream_index = st->index; pkt->stream_index = st->index;
if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
...@@ -381,7 +424,7 @@ static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp ...@@ -381,7 +424,7 @@ static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
AVInputFormat flv_demuxer = { AVInputFormat flv_demuxer = {
"flv", "flv",
"flv format", "flv format",
0, sizeof(FLVContext),
flv_probe, flv_probe,
flv_read_header, flv_read_header,
flv_read_packet, flv_read_packet,
......
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