Commit 4c050429 authored by Joseph Wecker's avatar Joseph Wecker Committed by Michael Niedermayer

flvdec: Properly decoding in-band metadata packets as data frames.

parent c054f116
...@@ -284,13 +284,12 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst ...@@ -284,13 +284,12 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
AMFDataType type; AMFDataType type;
AVStream *stream, *astream, *vstream; AVStream *stream, *astream, *vstream, *dstream;
AVIOContext *ioc; AVIOContext *ioc;
int i; int i;
char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
astream = NULL; vstream = astream = dstream = NULL;
vstream = NULL;
ioc = s->pb; ioc = s->pb;
//first object needs to be "onMetaData" string //first object needs to be "onMetaData" string
...@@ -301,8 +300,9 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { ...@@ -301,8 +300,9 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
//find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
for(i = 0; i < s->nb_streams; i++) { for(i = 0; i < s->nb_streams; i++) {
stream = s->streams[i]; stream = s->streams[i];
if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream; if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream; else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) dstream = stream;
} }
//parse the second object (we want a mixed array) //parse the second object (we want a mixed array)
...@@ -322,6 +322,7 @@ static AVStream *create_stream(AVFormatContext *s, int stream_type){ ...@@ -322,6 +322,7 @@ static AVStream *create_stream(AVFormatContext *s, int stream_type){
case FLV_STREAM_TYPE_DATA: case FLV_STREAM_TYPE_DATA:
st->codec->codec_type = AVMEDIA_TYPE_DATA; st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id = CODEC_ID_NONE; // Going to rely on copy for now st->codec->codec_id = CODEC_ID_NONE; // Going to rely on copy for now
av_log(s, AV_LOG_DEBUG, "Data stream created\n");
} }
av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
return st; return st;
...@@ -379,7 +380,8 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) ...@@ -379,7 +380,8 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
{ {
FLVContext *flv = s->priv_data; FLVContext *flv = s->priv_data;
int ret, i, type, size, flags, stream_type; int ret, i, type, size, flags;
int stream_type=-1;
int64_t next, pos; int64_t next, pos;
int64_t dts, pts = AV_NOPTS_VALUE; int64_t dts, pts = AV_NOPTS_VALUE;
AVStream *st = NULL; AVStream *st = NULL;
...@@ -415,12 +417,10 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -415,12 +417,10 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
if (size > 13+1+4 && dts == 0) { if (size > 13+1+4 && dts == 0) {
// Header-type metadata stuff // Header-type metadata stuff
flv_read_metabody(s, next); flv_read_metabody(s, next);
} else if (dts != 0) {
// Script-data
stream_type=FLV_STREAM_TYPE_VIDEO;
goto skip; goto skip;
} else if (dts != 0) {
// TODO: Parse / set stuff, etc. // Script-data "special" metadata frames - don't skip
stream_type=FLV_STREAM_TYPE_DATA;
} else { } else {
goto skip; goto skip;
} }
...@@ -441,7 +441,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -441,7 +441,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
break; break;
} }
if(i == s->nb_streams){ if(i == s->nb_streams){
av_log(s, AV_LOG_ERROR, "invalid stream\n"); av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
st= create_stream(s, stream_type); st= create_stream(s, stream_type);
s->ctx_flags &= ~AVFMTCTX_NOHEADER; s->ctx_flags &= ~AVFMTCTX_NOHEADER;
} }
...@@ -540,7 +540,9 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -540,7 +540,9 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts; pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
pkt->stream_index = st->index; pkt->stream_index = st->index;
if ((stream_type == FLV_STREAM_TYPE_AUDIO) || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) if ( stream_type == FLV_STREAM_TYPE_AUDIO ||
(flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
stream_type == FLV_STREAM_TYPE_DATA)
pkt->flags |= AV_PKT_FLAG_KEY; pkt->flags |= AV_PKT_FLAG_KEY;
leave: leave:
......
...@@ -2119,6 +2119,8 @@ static int has_codec_parameters(AVCodecContext *avctx) ...@@ -2119,6 +2119,8 @@ static int has_codec_parameters(AVCodecContext *avctx)
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE; val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE;
break; break;
case AVMEDIA_TYPE_DATA:
if(avctx->codec_id == CODEC_ID_NONE) return 1;
default: default:
val = 1; val = 1;
break; break;
......
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