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.

>  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?

> +    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

> +            break;
> +    }
> +    if (st->id != 2) {
> +        st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
> +        if (!st)
> +            goto out;
> +        st->codec->codec_id = CODEC_ID_TEXT;
> +    }
> +
> +    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.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to