void DefaultReader::readHeader() {
			av_metadata_conv( this->pFormatContext_.get(), NULL, this->pFormatContext_->iformat->metadata_conv );
			AVMetadataTag * mt = NULL;
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "title", NULL, 0 ) ) ) {
				this->setTitle( mt->value );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "author", NULL, 0 ) ) ) {
				this->setArtist( mt->value );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "copyright", NULL, 0 ) ) ) {
				this->setCopyright( mt->value );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "comment", NULL, 0 ) ) ) {
				this->setComment( mt->value );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "album", NULL, 0 ) ) ) {
				this->setAlbum( mt->value );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "year", NULL, 0 ) ) ) {
				this->setYear( std::atoi( mt->value ) );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "track", NULL, 0 ) ) ) {
				this->setIndex( std::atoi( mt->value ) );
			}
			if( ( mt = av_metadata_get( this->pFormatContext_->metadata, "genre", NULL, 0 ) ) ) {
				this->setGenre( mt->value );
			}
		}
示例#2
0
static void show_format(AVFormatContext *fmt_ctx)
{
    AVMetadataTag *tag = NULL;
    char val_str[128];

    printf("[FORMAT]\n");

    printf("filename=%s\n",         fmt_ctx->filename);
    printf("nb_streams=%d\n",       fmt_ctx->nb_streams);
    printf("format_name=%s\n",      fmt_ctx->iformat->name);
    printf("format_long_name=%s\n", fmt_ctx->iformat->long_name);
    printf("start_time=%s\n",       time_value_string(val_str, sizeof(val_str), fmt_ctx->start_time,
                                                      &AV_TIME_BASE_Q));
    printf("duration=%s\n",         time_value_string(val_str, sizeof(val_str), fmt_ctx->duration,
                                                      &AV_TIME_BASE_Q));
    printf("size=%s\n",             value_string(val_str, sizeof(val_str), fmt_ctx->file_size,
                                                 unit_byte_str));
    printf("bit_rate=%s\n",         value_string(val_str, sizeof(val_str), fmt_ctx->bit_rate,
                                                 unit_bit_per_second_str));

    if (convert_tags)
        av_metadata_conv(fmt_ctx, NULL, fmt_ctx->iformat->metadata_conv);
    while ((tag = av_metadata_get(fmt_ctx->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX)))
        printf("TAG:%s=%s\n", tag->key, tag->value);

    printf("[/FORMAT]\n");
}
示例#3
0
                        void File::initializeMediaProperties() {
#ifdef HAVE_AVFORMAT
                            av_register_all();
                            AVFormatContext* ctx;
                            if ((av_open_input_file(&ctx, getPath(), NULL, 0, NULL) == 0) && (av_find_stream_info(ctx) >= 0)) {
                                
                                // duration
                                if (ctx->duration != AV_NOPTS_VALUE)
                                    duration = strdup(Utils::timeToString(ctx->duration / AV_TIME_BASE).c_str());
                                // bitrate
                                if (ctx->bit_rate > 0)
                                    bitrate = ctx->bit_rate / 8;

                                for (unsigned int i = 0; i < ctx->nb_streams; i++) {
                                    // samplerate
                                    if(samplerate <= 0)
                                        samplerate = ctx->streams[i]->codec->sample_rate;
                                    // channels
                                    if(channels <= 0)
                                        channels = ctx->streams[i]->codec->channels;
                                    // width
                                    if(width <= 0)
                                        width = ctx->streams[i]->codec->width;
                                    // height
                                    if(height <= 0)
                                        height = ctx->streams[i]->codec->height;
                                    if ((samplerate > 0) && (channels > 0) && (width > 0) && (height > 0))
                                        i = ctx->nb_streams;
                                }

#if LIBAVFORMAT_VERSION_INT < (53<<16)
                                // title
                                if(ctx->title != NULL)
                                    title = strdup(ctx->title);
                                // artist
                                if(ctx->author != NULL)
                                    author = strdup(ctx->author);
                                // album
                                if(ctx->album != NULL)
                                    album = strdup(ctx->album);
                                // genre
                                if(ctx->genre != NULL)
                                    genre = strdup(ctx->genre);
                                // description / comment
                                if(ctx->comment != NULL)
                                    comment = strdup(ctx->comment);
                                // track number
                                if(ctx->track > 0)
                                    track = ctx->track;
                                // date / year
                                if(ctx->year > 0)
                                    year = ctx->year;
#else
                                av_metadata_conv(ctx, NULL, ctx->iformat->metadata_conv);
                                AVMetadataTag *mtitle, *mauthor, *malbum, *mgenre, *mcomment, *mtrack, *myear;
                                mtitle = av_metadata_get(ctx->metadata, "title", NULL, 0);
                                mauthor = av_metadata_get(ctx->metadata, "author", NULL, 0);
                                malbum = av_metadata_get(ctx->metadata, "album", NULL, 0);
                                mgenre = av_metadata_get(ctx->metadata, "genre", NULL, 0);
                                mcomment = av_metadata_get(ctx->metadata, "comment", NULL, 0);
                                mtrack = av_metadata_get(ctx->metadata, "track", NULL, 0);
                                myear = av_metadata_get(ctx->metadata, "year", NULL, 0);
                                // title
                                if(mtitle != NULL)
                                    title = strdup(mtitle->value);
                                // artist
                                if(mauthor != NULL)
                                    author = strdup(mauthor->value);
                                // album
                                if(malbum != NULL)
                                    album = strdup(malbum->value);
                                // genre
                                if(mgenre != NULL)
                                    genre = strdup(mgenre->value);
                                // description / comment
                                if(mcomment != NULL)
                                    comment = strdup(mcomment->value);
                                // track number
                                if(mtrack != NULL)
                                    track = Utils::stringToInteger(mtrack->value);
                                // date / year
                                if(myear != NULL)
                                    year = Utils::stringToInteger(myear->value);
#endif //LIBAVFORMAT_VERSION_INT
                            }
                            av_close_input_file(ctx);
#endif //HAVE_AVFORMAT
                        }
int
scan_metadata_ffmpeg(char *file, struct media_file_info *mfi)
{
  AVFormatContext *ctx;
  const struct metadata_map *extra_md_map;
  enum CodecID codec_id;
  enum CodecID video_codec_id;
  enum CodecID audio_codec_id;
  AVStream *video_stream;
  AVStream *audio_stream;
  int mdcount;
  int i;
  int ret;

  ctx = NULL;

#if LIBAVFORMAT_VERSION_MAJOR >= 53 || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR >= 3)
  ret = avformat_open_input(&ctx, file, NULL, NULL);
#else
  ret = av_open_input_file(&ctx, file, NULL, 0, NULL);
#endif
  if (ret != 0)
    {
      DPRINTF(E_WARN, L_SCAN, "Cannot open media file '%s': %s\n", file, strerror(AVUNERROR(ret)));

      return -1;
    }

  ret = av_find_stream_info(ctx);
  if (ret < 0)
    {
      DPRINTF(E_WARN, L_SCAN, "Cannot get stream info: %s\n", strerror(AVUNERROR(ret)));

      av_close_input_file(ctx);
      return -1;
    }

#if 0
  /* Dump input format as determined by ffmpeg */
# if LIBAVFORMAT_VERSION_MAJOR >= 52 || (LIBAVFORMAT_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 101)
  av_dump_format(ctx, 0, file, 0);
# else
  dump_format(ctx, 0, file, FALSE);
# endif
#endif

  DPRINTF(E_DBG, L_SCAN, "File has %d streams\n", ctx->nb_streams);

  /* Extract codec IDs, check for video */
  video_codec_id = CODEC_ID_NONE;
  video_stream = NULL;

  audio_codec_id = CODEC_ID_NONE;
  audio_stream = NULL;

  for (i = 0; i < ctx->nb_streams; i++)
    {
      switch (ctx->streams[i]->codec->codec_type)
	{
#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 64)
	  case AVMEDIA_TYPE_VIDEO:
#else
	  case CODEC_TYPE_VIDEO:
#endif
	    if (!video_stream)
	      {
		DPRINTF(E_DBG, L_SCAN, "File has video (stream %d)\n", i);

		mfi->has_video = 1;
		video_stream = ctx->streams[i];
		video_codec_id = video_stream->codec->codec_id;
	      }
	    break;

#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 64)
	  case AVMEDIA_TYPE_AUDIO:
#else
	  case CODEC_TYPE_AUDIO:
#endif
	    if (!audio_stream)
	      {
		audio_stream = ctx->streams[i];
		audio_codec_id = audio_stream->codec->codec_id;
	      } 
	    break;

	  default:
	    break;
	}
    }

  if (audio_codec_id == CODEC_ID_NONE)
    {
      DPRINTF(E_DBG, L_SCAN, "File has no audio streams, discarding\n");

      av_close_input_file(ctx);
      return -1;
    }

  /* Common media information */
  if (ctx->duration > 0)
    mfi->song_length = ctx->duration / (AV_TIME_BASE / 1000); /* ms */

  if (ctx->bit_rate > 0)
    mfi->bitrate = ctx->bit_rate / 1000;
  else if (ctx->duration > AV_TIME_BASE) /* guesstimate */
    mfi->bitrate = ((mfi->file_size * 8) / (ctx->duration / AV_TIME_BASE)) / 1000;

  DPRINTF(E_DBG, L_SCAN, "Duration %d ms, bitrate %d kbps\n", mfi->song_length, mfi->bitrate);

  /* Get some more information on the audio stream */
  if (audio_stream)
    {
      if (audio_stream->codec->sample_rate != 0)
	mfi->samplerate = audio_stream->codec->sample_rate;

      /* Try sample format first */
#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 4)
      mfi->bits_per_sample = 8 * av_get_bytes_per_sample(audio_stream->codec->sample_fmt);
#elif LIBAVCODEC_VERSION_MAJOR >= 53
      mfi->bits_per_sample = av_get_bits_per_sample_fmt(audio_stream->codec->sample_fmt);
#else
      mfi->bits_per_sample = av_get_bits_per_sample_format(audio_stream->codec->sample_fmt);
#endif
      if (mfi->bits_per_sample == 0)
	{
	  /* Try codec */
	  mfi->bits_per_sample = av_get_bits_per_sample(audio_codec_id);
	}

      DPRINTF(E_DBG, L_SCAN, "samplerate %d, bps %d\n", mfi->samplerate, mfi->bits_per_sample);
    }

  /* Check codec */
  extra_md_map = NULL;
  codec_id = (mfi->has_video) ? video_codec_id : audio_codec_id;
  switch (codec_id)
    {
      case CODEC_ID_AAC:
	DPRINTF(E_DBG, L_SCAN, "AAC\n");
	mfi->type = strdup("m4a");
	mfi->codectype = strdup("mp4a");
	mfi->description = strdup("AAC audio file");
	break;

      case CODEC_ID_ALAC:
	DPRINTF(E_DBG, L_SCAN, "ALAC\n");
	mfi->type = strdup("m4a");
	mfi->codectype = strdup("alac");
	mfi->description = strdup("AAC audio file");
	break;

      case CODEC_ID_FLAC:
	DPRINTF(E_DBG, L_SCAN, "FLAC\n");
	mfi->type = strdup("flac");
	mfi->codectype = strdup("flac");
	mfi->description = strdup("FLAC audio file");

	extra_md_map = md_map_vorbis;
	break;

      case CODEC_ID_MUSEPACK7:
      case CODEC_ID_MUSEPACK8:
	DPRINTF(E_DBG, L_SCAN, "Musepack\n");
	mfi->type = strdup("mpc");
	mfi->codectype = strdup("mpc");
	mfi->description = strdup("Musepack audio file");
	break;

      case CODEC_ID_MPEG4: /* Video */
      case CODEC_ID_H264:
	DPRINTF(E_DBG, L_SCAN, "MPEG4 video\n");
	mfi->type = strdup("m4v");
	mfi->codectype = strdup("mp4v");
	mfi->description = strdup("MPEG-4 video file");

	extra_md_map = md_map_tv;
	break;

      case CODEC_ID_MP3:
	DPRINTF(E_DBG, L_SCAN, "MP3\n");
	mfi->type = strdup("mp3");
	mfi->codectype = strdup("mpeg");
	mfi->description = strdup("MPEG audio file");

	extra_md_map = md_map_id3;
	break;

      case CODEC_ID_VORBIS:
	DPRINTF(E_DBG, L_SCAN, "VORBIS\n");
	mfi->type = strdup("ogg");
	mfi->codectype = strdup("ogg");
	mfi->description = strdup("Ogg Vorbis audio file");

	extra_md_map = md_map_vorbis;
	break;

      case CODEC_ID_WMAVOICE:
	DPRINTF(E_DBG, L_SCAN, "WMA Voice\n");
	mfi->type = strdup("wma");
	mfi->codectype = strdup("wmav");
	mfi->description = strdup("WMA audio file");
	break;

      case CODEC_ID_WMAPRO:
	DPRINTF(E_DBG, L_SCAN, "WMA Pro\n");
	mfi->type = strdup("wmap");
	mfi->codectype = strdup("wma");
	mfi->description = strdup("WMA audio file");
	break;

      case CODEC_ID_WMALOSSLESS:
	DPRINTF(E_DBG, L_SCAN, "WMA Lossless\n");
	mfi->type = strdup("wma");
	mfi->codectype = strdup("wmal");
	mfi->description = strdup("WMA audio file");
	break;

      case CODEC_ID_WMAV1:
      case CODEC_ID_WMAV2:
	DPRINTF(E_DBG, L_SCAN, "WMA V1/V2\n");
	mfi->type = strdup("wma");
	mfi->codectype = strdup("wma");
	mfi->description = strdup("WMA audio file");
	break;

      case CODEC_ID_PCM_S16LE ... CODEC_ID_PCM_F64LE:
	if (strcmp(ctx->iformat->name, "aiff") == 0)
	  {
	    DPRINTF(E_DBG, L_SCAN, "AIFF\n");
	    mfi->type = strdup("aif");
	    mfi->codectype = strdup("aif");
	    mfi->description = strdup("AIFF audio file");
	    break;
	  }
	else if (strcmp(ctx->iformat->name, "wav") == 0)
	  {
	    DPRINTF(E_DBG, L_SCAN, "WAV\n");
	    mfi->type = strdup("wav");
	    mfi->codectype = strdup("wav");
	    mfi->description = strdup("WAV audio file");
	    break;
	  }
	/* WARNING: will fallthrough to default case, don't move */
	/* FALLTHROUGH */

      default:
	DPRINTF(E_DBG, L_SCAN, "Unknown codec 0x%x (video: %s), format %s (%s)\n",
		codec_id, (mfi->has_video) ? "yes" : "no", ctx->iformat->name, ctx->iformat->long_name);
	mfi->type = strdup("unkn");
	mfi->codectype = strdup("unkn");
	if (mfi->has_video)
	  {
	    mfi->description = strdup("Unknown video file format");
	    extra_md_map = md_map_tv;
	  }
	else
	  mfi->description = strdup("Unknown audio file format");
	break;
    }

  mdcount = 0;

  if ((!ctx->metadata) && (!audio_stream->metadata)
      && (video_stream && !video_stream->metadata))
    {
      DPRINTF(E_WARN, L_SCAN, "ffmpeg reports no metadata\n");

      goto skip_extract;
    }

  if (extra_md_map)
    {
      ret = extract_metadata(mfi, ctx, audio_stream, video_stream, extra_md_map);
      mdcount += ret;

      DPRINTF(E_DBG, L_SCAN, "Picked up %d tags with extra md_map\n", ret);
    }

#if LIBAVFORMAT_VERSION_MAJOR < 53
  av_metadata_conv(ctx, NULL, ctx->iformat->metadata_conv);
#endif

  ret = extract_metadata(mfi, ctx, audio_stream, video_stream, md_map_generic);
  mdcount += ret;

  DPRINTF(E_DBG, L_SCAN, "Picked up %d tags with generic md_map, %d tags total\n", ret, mdcount);

  /* fix up TV metadata */
  if (mfi->media_kind == 10)
    {
      /* I have no idea why this is, but iTunes reports a media kind of 64 for stik==10 (?!) */
      mfi->media_kind = 64;
    }
  /* Unspecified video files are "Movies", media_kind 2 */
  else if (mfi->has_video == 1)
    {
      mfi->media_kind = 2;
    }

 skip_extract:
  if (mdcount == 0)
    {
      /* ffmpeg doesn't support FLAC nor Musepack metadata,
       * and is buggy for some WMA variants, so fall back to the
       * legacy format-specific parsers until it gets fixed */
      if ((codec_id == CODEC_ID_WMAPRO)
	  || (codec_id == CODEC_ID_WMAVOICE)
	  || (codec_id == CODEC_ID_WMALOSSLESS))
	{
	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy WMA scanner\n");

	  av_close_input_file(ctx);
	  return (scan_get_wmainfo(file, mfi) ? 0 : -1);
	}
#ifdef FLAC
      else if (codec_id == CODEC_ID_FLAC)
	{
	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy FLAC scanner\n");

	  av_close_input_file(ctx);
	  return (scan_get_flacinfo(file, mfi) ? 0 : -1);
	}
#endif /* FLAC */
#ifdef MUSEPACK
      else if ((codec_id == CODEC_ID_MUSEPACK7)
	       || (codec_id == CODEC_ID_MUSEPACK8))
	{
	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy Musepack scanner\n");

	  av_close_input_file(ctx);
	  return (scan_get_mpcinfo(file, mfi) ? 0 : -1);
	}
#endif /* MUSEPACK */
      else
	DPRINTF(E_WARN, L_SCAN, "Could not extract any metadata\n");
    }

  /* Just in case there's no title set ... */
  if (mfi->title == NULL)
    mfi->title = strdup(mfi->fname);

  /* All done */
  av_close_input_file(ctx);

  return 0;
}
static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
    AVFormatContext *avfc;
    AVFormatParameters ap;
    const AVOption *opt;
    AVMetadataTag *t = NULL;
    lavf_priv_t *priv= demuxer->priv;
    int i;
    //start_time = 0.0;
    char mp_filename[256]="mp:";
    memset(&ap, 0, sizeof(AVFormatParameters));

    //demux_lavf_find_geodata(demuxer);

    stream_seek(demuxer->stream, 0);

    int filepos=stream_tell(demuxer->stream);
    
    avfc = avformat_alloc_context();

    if (opt_cryptokey)
        parse_cryptokey(avfc, opt_cryptokey);
    if (user_correct_pts != 0)
        avfc->flags |= AVFMT_FLAG_GENPTS;
    /* if (index_mode == 0) */
    /*     avfc->flags |= AVFMT_FLAG_IGNIDX; */

    ap.prealloced_context = 1;
#if 0
    if(opt_probesize) {
        opt = av_set_int(avfc, "probesize", opt_probesize);
        if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", opt_probesize);
    }
    if(opt_analyzeduration) {
        opt = av_set_int(avfc, "analyzeduration", opt_analyzeduration * AV_TIME_BASE);
        if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option analyzeduration to %u\n", opt_analyzeduration);
    }

    if(opt_avopt){
        if(parse_avopts(avfc, opt_avopt) < 0){
            mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", opt_avopt);
            return NULL;
        }
    }
#endif
    if(demuxer->stream->url) {
        if (!strncmp(demuxer->stream->url, "ffmpeg://rtsp:", 14))
            av_strlcpy(mp_filename, demuxer->stream->url + 9, sizeof(mp_filename));
        else
            av_strlcat(mp_filename, demuxer->stream->url, sizeof(mp_filename));
    } else
        av_strlcat(mp_filename, "foobar.dummy", sizeof(mp_filename));

    priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
                                 demuxer, mp_read, NULL, mp_seek);
    priv->pb->read_seek = mp_read_seek;
    priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
    filepos=stream_tell(demuxer->stream);
    if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
        mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
        return NULL;
    }
    filepos=stream_tell(demuxer->stream);
    priv->avfc= avfc;
    if(av_find_stream_info(avfc) < 0){
        mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
        return NULL;
    }
    filepos=stream_tell(demuxer->stream);
    if(!strncmp(avfc->iformat->name,"aac",4))
      get_aac_duration(demuxer,avfc);

    if(!strncmp(avfc->iformat->name,"mp3",4))
       priv->avfc->duration = get_mp3_duration(demuxer) * AV_TIME_BASE;

    /* Add metadata. */
    av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
    while((t = av_metadata_get(avfc->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))){
        demux_info_add(demuxer, t->key, t->value);
    }

    for(i=0; i < avfc->nb_chapters; i++) {
        AVChapter *c = avfc->chapters[i];
        uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
        uint64_t end   = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
        t = av_metadata_get(c->metadata, "title", NULL, 0);
        demuxer_add_chapter(demuxer, t ? t->value : NULL, start, end);
    }
    demuxer->ttaflag = 0;
    for(i=0; i<avfc->nb_streams; i++)
        handle_stream(demuxer, avfc, i);
    if(demuxer->matroflag && !demuxer->ttaflag)
      return NULL;
    if(avfc->nb_programs) {
        int p;
        for (p = 0; p < avfc->nb_programs; p++) {
            AVProgram *program = avfc->programs[p];
            t = av_metadata_get(program->metadata, "title", NULL, 0);
            mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
        }
    }

    mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
    mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
    if(!priv->audio_streams) demuxer->audio->id=-2;  // nosound
//    else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
    if(!priv->video_streams){
        if(!priv->audio_streams){
	    mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
            return NULL;
        }
        demuxer->video->id=-2; // audio-only
    } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;

    filepos=stream_tell(demuxer->stream);

    int j=0;
    AVCodecContext *codec;
    AVCodec *avc;
    demuxer->audio_info = malloc(100*avfc->nb_streams);
    for(i=0; i<avfc->nb_streams; i++){
      if(demuxer->a_streams[i]){
	char *info = malloc(100);
	codec= ((AVStream *)avfc->streams[i])->codec;
	avc = avcodec_find_decoder(codec->codec_id);
	char *cn = avc ? avc->name : "unknown";
	char *codec_name = malloc(100);
	strncpy(codec_name,cn,100);
	
	if((codec_name[0]=='d')&&(codec_name[1]=='c')&&(codec_name[2]=='a'))
	  strncpy(codec_name,"dts",100);
	int a;
	for(a=0;codec_name[a];a++) 
	  if(codec_name[a]>='a'&&codec_name[a]<='z')
	    codec_name[a]-=32; 
	sprintf(info, "%s(%dHz %dCh)--%d", codec_name,codec->sample_rate, codec->channels, i);
	free(codec_name);
	memcpy(demuxer->audio_info+j*100,info, 100);
	j++;
	free(info);
	info = NULL;
      }
    }

    j = 0;
    demuxer->sub_info = malloc(100*avfc->nb_streams);
    for(i=0; i<avfc->nb_streams; i++){
      if(demuxer->s_streams[i]){
	char *info = malloc(100);
	AVStream *st= avfc->streams[i];
	AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
	codec= st->codec;
        if (lang && lang->value)
	  strcpy(info, lang->value);
	else
	  strcpy(info, "unknown");
	sprintf(info, "%s--%d", info,i);
	memcpy(demuxer->sub_info+j*100,info, 100);
	j++;
	free(info);
	info = NULL;
      }
    }

    if(AV_NOPTS_VALUE == priv->avfc->start_time){
        LOGW("priv->avfc->start_time = AV_NOPTS_VALUE");
        demuxer->start_time = 0;
    }else{
        demuxer->start_time = priv->avfc->start_time;
    }

    return demuxer;
}