On 12/05/12 09:59, Anton Khirnov wrote:
>
> On Wed, 9 May 2012 14:35:58 -0700, Luca Barbato <[email protected]> wrote:
>> Adobe specifies onTextData as the standard message to use to deliver
>> text information.
>> ---
>
> First of all, I'd appreciate it if you could split the muxer and demuxer
> parts.
I can do but would be sort of pointless.
>> libavformat/flvdec.c | 102
>> ++++++++++++++++++++++++++++++++++++++++++-------
>> libavformat/flvenc.c | 77 ++++++++++++++++++++++++++++++++-----
>> 2 files changed, 153 insertions(+), 26 deletions(-)
>>
>> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
>> index 7c4b792..d2e9fdd 100644
>> --- a/libavformat/flvdec.c
>> +++ b/libavformat/flvdec.c
>> @@ -66,6 +66,17 @@ static int flv_probe(AVProbeData *p)
>> return 0;
>> }
>>
>> +static AVStream *create_stream(AVFormatContext *s, int tag, int codec_type)
>> +{
>> + AVStream *st = avformat_new_stream(s, NULL);
>> + if (!st)
>> + return NULL;
>> + st->id = tag;
>
> I don't really like this abuse of id to store demuxer private
> information. Can't you just check for AVMEDIA_TYPE_DATA?
tag is used in a strange way in flv, I might try to fix it later and see
if we can support multistream flv later (that is the XXX)
>> + st->codec->codec_type = codec_type;
>> + avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
>> + return st;
>> +}
>> +
>> static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
>> AVCodecContext *acodec, int flv_codecid) {
>> switch(flv_codecid) {
>> //no distinction between S16 and S8 PCM codec flags
>> @@ -302,6 +313,12 @@ static int amf_parse_object(AVFormatContext *s,
>> AVStream *astream, AVStream *vst
>> vcodec->bit_rate = num_val * 1024.0;
>> else if (!strcmp(key, "audiodatarate") && acodec && 0 <=
>> (int)(num_val * 1024.0))
>> acodec->bit_rate = num_val * 1024.0;
>> + else if (!strcmp(key, "datastream")) {
>> + AVStream *st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
>> + if (!st)
>> + return AVERROR(ENOMEM);
>> + st->codec->codec_id = CODEC_ID_TEXT;
>> + }
>> }
>>
>> if (!strcmp(key, "duration") ||
>> @@ -344,7 +361,14 @@ static int flv_read_metabody(AVFormatContext *s,
>> int64_t next_pos) {
>>
>> //first object needs to be "onMetaData" string
>> type = avio_r8(ioc);
>> - if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer,
>> sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData"))
>> + if (type != AMF_DATA_TYPE_STRING ||
>> + amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
>> + return -1;
>> +
>> + if (!strcmp(buffer, "onTextData"))
>> + return 1;
>> +
>> + if (strcmp(buffer, "onMetaData"))
>> return -1;
>>
>> //find the streams now so that amf_parse_object doesn't need to do the
>> lookup every time it is called.
>> @@ -361,16 +385,6 @@ static int flv_read_metabody(AVFormatContext *s,
>> int64_t next_pos) {
>> return 0;
>> }
>>
>> -static AVStream *create_stream(AVFormatContext *s, int is_audio){
>> - AVStream *st = avformat_new_stream(s, NULL);
>> - if (!st)
>> - return NULL;
>> - st->id = is_audio;
>> - st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO :
>> AVMEDIA_TYPE_VIDEO;
>> - avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
>> - return st;
>> -}
>> -
>> static int flv_read_header(AVFormatContext *s)
>> {
>> int offset, flags;
>> @@ -389,11 +403,11 @@ static int flv_read_header(AVFormatContext *s)
>> s->ctx_flags |= AVFMTCTX_NOHEADER;
>>
>> if(flags & FLV_HEADER_FLAG_HASVIDEO){
>> - if(!create_stream(s, 0))
>> + if(!create_stream(s, 0, AVMEDIA_TYPE_VIDEO))
>> return AVERROR(ENOMEM);
>> }
>> if(flags & FLV_HEADER_FLAG_HASAUDIO){
>> - if(!create_stream(s, 1))
>> + if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
>> return AVERROR(ENOMEM);
>> }
>>
>> @@ -453,6 +467,61 @@ static void clear_index_entries(AVFormatContext *s,
>> int64_t pos)
>> }
>> }
>>
>> +
>> +static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
>> + int64_t dts, int64_t next)
>> +{
>> + AVIOContext *pb = s->pb;
>> + AVStream *st = NULL;
>> + AMFDataType type;
>> + char buf[20];
>> + int codec_id;
>> + int length;
>> + int ret = AVERROR_INVALIDDATA, i;
>> +
>> + type = avio_r8(pb);
>> + if (type == AMF_DATA_TYPE_MIXEDARRAY)
>> + avio_seek(pb, 4, SEEK_CUR);
>> + else if (type != AMF_DATA_TYPE_OBJECT)
>> + goto out;
>> + amf_get_string(pb, buf, sizeof(buf));
>> + if (strcmp(buf,"type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
>> + goto out;
>> + amf_get_string(pb, buf, sizeof(buf));
>> + //FIXME parse it as codec_id
>> + amf_get_string(pb, buf, sizeof(buf));
>> + if (strcmp(buf,"text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
>> + goto out;
>> + length = avio_rb16(pb);
>> + ret = av_get_packet(s->pb, pkt, length);
>> + if (ret < 0) {
>> + ret = AVERROR(EIO);
>> + goto out;
>> + }
>> +
>> + for(i=0;i<s->nb_streams;i++) {
>> + st = s->streams[i];
>> + if (st->id == 2) //XXX
>
> Exactly. Please fix the XXX
> also some spaces in for() would help
Supporting multiple streams is ortogonal.
>> + pkt->size = ret;
>> + pkt->dts = dts;
>> + pkt->pts = dts;
>> + pkt->stream_index = st->index;
>> + pkt->flags |= AV_PKT_FLAG_KEY;
>
> Extra karma for vertical alignment.
Good point, I have a full cleanup patch slated for later.
lu
--
Luca Barbato
Gentoo/linux
http://dev.gentoo.org/~lu_zero
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel