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