Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 3 Jun 2012 22:33:42 +0000 (00:33 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 3 Jun 2012 22:33:42 +0000 (00:33 +0200)
* qatar/master:
  librtmp: return AVERROR_UNKNOWN instead of -1.
  librtmp: don't abuse a variable for two unrelated things.
  librtmp: add rtmp_app and rtmp_playpath private options.
  bmv: add stricter checks for invalid decoded length
  avpacket: fix duplicating side data.
  flv: support stream text data as onTextData

Conflicts:
libavcodec/bmv.c
libavformat/flvdec.c
libavformat/flvenc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/avpacket.c
libavcodec/bmv.c
libavformat/flvdec.c
libavformat/flvenc.c
libavformat/librtmp.c

Simple merge
Simple merge
@@@ -62,6 -66,17 +62,21 @@@ static int flv_probe(AVProbeData *p
      return 0;
  }
  
 -static AVStream *create_stream(AVFormatContext *s, int tag, int codec_type)
 -{
++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;
+     st->codec->codec_type = codec_type;
++    if(s->nb_streams>=3 ||(   s->nb_streams==2
++                           && s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA
++                           && s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA))
++        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
++
+     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
@@@ -298,13 -313,14 +313,19 @@@ static int amf_parse_object(AVFormatCon
                  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 (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 &&
 +           ((!acodec && !strcmp(key, "audiocodecid")) ||
 +            (!vcodec && !strcmp(key, "videocodecid"))))
 +                s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
 +
          if (!strcmp(key, "duration")        ||
              !strcmp(key, "filesize")        ||
              !strcmp(key, "width")           ||
@@@ -403,11 -407,9 +409,11 @@@ static int flv_read_header(AVFormatCont
              return AVERROR(ENOMEM);
      }
      if(flags & FLV_HEADER_FLAG_HASAUDIO){
-         if(!create_stream(s, FLV_STREAM_TYPE_AUDIO))
+         if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
              return AVERROR(ENOMEM);
      }
 +    // Flag doesn't indicate whether or not there is script-data present. Must
 +    // create that stream if it's encountered.
  
      offset = avio_rb32(s->pb);
      avio_seek(s->pb, offset, SEEK_SET);
@@@ -547,12 -601,14 +612,13 @@@ static int flv_read_packet(AVFormatCont
              break;
      }
      if(i == s->nb_streams){
 -        av_log(s, AV_LOG_ERROR, "invalid stream\n");
 -        st = create_stream(s, is_audio,
 -             is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
 -        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
 +        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,
++             (int[]){AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA}[stream_type]);
      }
 -    av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
 -    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
 -       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
 +    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
 +    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
 +       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
         || st->discard >= AVDISCARD_ALL
         ){
          avio_seek(s->pb, next, SEEK_SET);
@@@ -292,23 -305,12 +309,28 @@@ static int flv_write_header(AVFormatCon
          put_amf_double(pb, audio_enc->codec_tag);
      }
  
+     if (data_enc) {
+         put_amf_string(pb, "datastream");
+         put_amf_double(pb, 0.0);
+     }
      while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
 +        if(   !strcmp(tag->key, "width")
 +            ||!strcmp(tag->key, "height")
 +            ||!strcmp(tag->key, "videodatarate")
 +            ||!strcmp(tag->key, "framerate")
 +            ||!strcmp(tag->key, "videocodecid")
 +            ||!strcmp(tag->key, "audiodatarate")
 +            ||!strcmp(tag->key, "audiosamplerate")
 +            ||!strcmp(tag->key, "audiosamplesize")
 +            ||!strcmp(tag->key, "stereo")
 +            ||!strcmp(tag->key, "audiocodecid")
 +            ||!strcmp(tag->key, "duration")
 +            ||!strcmp(tag->key, "onMetaData")
 +        ){
 +            av_log(s, AV_LOG_DEBUG, "ignoring metadata for %s\n", tag->key);
 +            continue;
 +        }
          put_amf_string(pb, tag->key);
          avio_w8(pb, AMF_DATA_TYPE_STRING);
          put_amf_string(pb, tag->value);
@@@ -432,16 -436,16 +456,15 @@@ static int flv_write_packet(AVFormatCon
          assert(size);
  
          avio_w8(pb, FLV_TAG_TYPE_AUDIO);
-     } else {
-         // In-band flv metadata ("scriptdata")
-         assert(enc->codec_type == AVMEDIA_TYPE_DATA);
+         break;
 -
+     case AVMEDIA_TYPE_DATA:
          avio_w8(pb, FLV_TAG_TYPE_META);
-         flags_size = 0;
-         flags = 0;
+         break;
+     default:
+         return AVERROR(EINVAL);
      }
 -    if (enc->codec_id == CODEC_ID_H264) {
 -        /* check if extradata looks like MP4 */
 +    if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
 +        /* check if extradata looks like mp4 formated */
          if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
              if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
                  return -1;
      avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
      avio_wb24(pb,flv->reserved);
  
-     if(flags_size)
-         avio_w8(pb,flags);
+     if (enc->codec_type == AVMEDIA_TYPE_DATA) {
+         int data_size;
+         int metadata_size_pos = avio_tell(pb);
+         avio_w8(pb, AMF_DATA_TYPE_STRING);
+         put_amf_string(pb, "onTextData");
+         avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
+         avio_wb32(pb, 2);
+         put_amf_string(pb, "type");
+         avio_w8(pb, AMF_DATA_TYPE_STRING);
+         put_amf_string(pb, "Text");
+         put_amf_string(pb, "text");
+         avio_w8(pb, AMF_DATA_TYPE_STRING);
+         put_amf_string(pb, pkt->data);
+         put_amf_string(pb, "");
+         avio_w8(pb, AMF_END_OF_OBJECT);
+         /* write total size of tag */
+         data_size = avio_tell(pb) - metadata_size_pos;
+         avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
+         avio_wb24(pb, data_size);
+         avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
+         avio_wb32(pb, data_size + 11);
+     } else {
+     avio_w8(pb,flags);
      if (enc->codec_id == CODEC_ID_VP6)
          avio_w8(pb,0);
 -    if (enc->codec_id == CODEC_ID_VP6F)
 +    if (enc->codec_id == CODEC_ID_VP6F || enc->codec_id == CODEC_ID_VP6A)
          avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
      else if (enc->codec_id == CODEC_ID_AAC)
          avio_w8(pb,1); // AAC raw
Simple merge