Пример #1
0
VORBISFORMAT2 *CLAVFAudioHelper::CreateVorbis2(const AVStream *avstream, ULONG *size) {
    BYTE *p = avstream->codec->extradata;
    std::vector<int> sizes;
    // read the number of blocks, and then the sizes of the individual blocks
    for(BYTE n = *p++; n > 0; n--) {
        int size = 0;
        // Xiph Lacing
        do {
            size += *p;
        }
        while (*p++ == 0xFF);
        sizes.push_back(size);
    }

    int totalsize = 0;
    for(unsigned int i = 0; i < sizes.size(); i++)
        totalsize += sizes[i];

    // Get the size of the last block
    sizes.push_back(avstream->codec->extradata_size - (int)(p - avstream->codec->extradata) - totalsize);
    totalsize += sizes[sizes.size()-1];

    // 3 blocks is the currently valid Vorbis format
    if(sizes.size() == 3) {
        VORBISFORMAT2* pvf2 = (VORBISFORMAT2*)CoTaskMemAlloc(sizeof(VORBISFORMAT2) + totalsize);
        if (!pvf2)
            return nullptr;
        memset(pvf2, 0, sizeof(VORBISFORMAT2));

        pvf2->Channels = avstream->codec->channels;
        pvf2->SamplesPerSec = avstream->codec->sample_rate;
        pvf2->BitsPerSample = get_bits_per_sample(avstream->codec);

        BYTE *p2 = (BYTE *)pvf2 + sizeof(VORBISFORMAT2);
        for(unsigned int i = 0; i < sizes.size(); p += sizes[i], p2 += sizes[i], i++) {
            memcpy(p2, p, pvf2->HeaderSize[i] = sizes[i]);
        }

        *size = sizeof(VORBISFORMAT2) + totalsize;
        return pvf2;
    }
    *size = 0;
    return nullptr;
}
Пример #2
0
WAVEFORMATEX *CLAVFAudioHelper::CreateWVFMTEX(const AVStream *avstream, ULONG *size) {
    WAVEFORMATEX *wvfmt = (WAVEFORMATEX *)CoTaskMemAlloc(sizeof(WAVEFORMATEX) + avstream->codec->extradata_size);
    if (!wvfmt)
        return nullptr;
    memset(wvfmt, 0, sizeof(WAVEFORMATEX));

    wvfmt->wFormatTag = avstream->codec->codec_tag;

    wvfmt->nChannels = avstream->codec->channels ? avstream->codec->channels : 2;
    wvfmt->nSamplesPerSec = avstream->codec->sample_rate ? avstream->codec->sample_rate : 48000;
    wvfmt->nAvgBytesPerSec = (DWORD)(avstream->codec->bit_rate / 8);

    if(avstream->codec->codec_id == AV_CODEC_ID_AAC || avstream->codec->codec_id == AV_CODEC_ID_AAC_LATM) {
        wvfmt->wBitsPerSample = 0;
        wvfmt->nBlockAlign = 1;
    } else {
        wvfmt->wBitsPerSample = get_bits_per_sample(avstream->codec);

        if ( avstream->codec->block_align > 0 ) {
            wvfmt->nBlockAlign = avstream->codec->block_align;
        } else {
            if ( wvfmt->wBitsPerSample == 0 ) {
                DbgOutString(L"BitsPerSample is 0, no good!");
            }
            wvfmt->nBlockAlign = (WORD)(wvfmt->nChannels * av_get_bytes_per_sample(avstream->codec->sample_fmt));
        }
    }
    if (!wvfmt->nAvgBytesPerSec)
        wvfmt->nAvgBytesPerSec = (wvfmt->nSamplesPerSec * wvfmt->nChannels * wvfmt->wBitsPerSample) >> 3;

    if (avstream->codec->extradata_size > 0) {
        wvfmt->cbSize = avstream->codec->extradata_size;
        memcpy((BYTE *)wvfmt + sizeof(WAVEFORMATEX), avstream->codec->extradata, avstream->codec->extradata_size);
    }

    *size = sizeof(WAVEFORMATEX) + avstream->codec->extradata_size;
    return wvfmt;
}
Пример #3
0
std::string lavf_get_stream_description(AVStream *pStream)
{
  AVCodecContext *enc = pStream->codec;

  std::string codec_name = get_codec_name(enc);

  const char *lang = get_stream_language(pStream);
  std::string sLanguage;

  if(lang) {
    sLanguage = ProbeLangForLanguage(lang);
    if (sLanguage.empty()) {
      sLanguage = lang;
    }
  }

  char *title = nullptr;
  if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "title", nullptr, 0)) {
    title = dictEntry->value;
  } else if (AVDictionaryEntry *dictEntry = av_dict_get(pStream->metadata, "handler_name", nullptr, 0)) {
    title = dictEntry->value;
    if (strcmp(title, "GPAC ISO Video Handler") == 0 || strcmp(title, "VideoHandler") == 0|| strcmp(title, "GPAC ISO Audio Handler") == 0 || strcmp(title, "GPAC Streaming Text Handler") == 0)
      title = nullptr;
  }

  // Empty titles are rather useless
  if (title && strlen(title) == 0)
    title = nullptr;

  int bitrate = get_bit_rate(enc);

  std::ostringstream buf;
  switch(enc->codec_type) {
  case AVMEDIA_TYPE_VIDEO:
    buf << "V: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Pixel Format
    if (enc->pix_fmt != AV_PIX_FMT_NONE) {
      buf << ", " << av_get_pix_fmt_name(enc->pix_fmt);
    }
    // Dimensions
    if (enc->width) {
      buf << ", " << enc->width << "x" << enc->height;
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_AUDIO:
    buf << "A: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Sample Rate
    if (enc->sample_rate) {
      buf << ", " << enc->sample_rate << " Hz";
    }
    if (enc->channels) {
      // Get channel layout
      char channel[32];
      av_get_channel_layout_string(channel, 32, enc->channels, enc->channel_layout);
      buf << ", " << channel;
    }
    // Sample Format
    if (show_sample_fmt(enc->codec_id) && get_bits_per_sample(enc, true)) {
      if (enc->sample_fmt == AV_SAMPLE_FMT_FLT || enc->sample_fmt == AV_SAMPLE_FMT_DBL) {
        buf << ", fp";
      } else {
        buf << ", s";
      }
      buf << get_bits_per_sample(enc, true);
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    // Flags
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_SUBTITLE:
    buf << "S: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    if (title || lang) {
      buf << ")";
    }
    // Subtitle flags
    buf << format_flags(pStream->disposition);
    break;
  default:
    buf << "Unknown: Stream #" << pStream->index;
    break;
  }

  return buf.str();
}
Пример #4
0
std::string lavf_get_stream_description(const AVStream *pStream)
{
  AVCodecParameters *par = pStream->codecpar;

  std::string codec_name = get_codec_name(par);

  const char *lang = get_stream_language(pStream);
  std::string sLanguage;

  if(lang) {
    sLanguage = ProbeLangForLanguage(lang);
    if (sLanguage.empty()) {
      sLanguage = lang;
    }
  }

  const char * title = lavf_get_stream_title(pStream);

  // Empty titles are rather useless
  if (title && strlen(title) == 0)
    title = nullptr;

  int64_t bitrate = get_bit_rate(par);

  std::ostringstream buf;
  switch(par->codec_type) {
  case AVMEDIA_TYPE_VIDEO:
    buf << "V: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Pixel Format
    if (const char *pix_fmt = av_get_pix_fmt_name((AVPixelFormat)par->format)) {
      buf << ", " << pix_fmt;
    }
    // Dimensions
    if (par->width) {
      buf << ", " << par->width << "x" << par->height;
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    if (par->codec_id == AV_CODEC_ID_H264 && par->profile == FF_PROFILE_H264_STEREO_HIGH) {
      AVDictionaryEntry *entry = av_dict_get(pStream->metadata, "stereo_mode", nullptr, 0);
      if (entry && strcmp(entry->value, "mvc_lr") == 0)
        buf << ", lr";
      else if (entry && strcmp(entry->value, "mvc_rl") == 0)
        buf << ", rl";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_AUDIO:
    buf << "A: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    // Sample Rate
    if (par->sample_rate) {
      buf << ", " << par->sample_rate << " Hz";
    }
    if (par->channels) {
      // Get channel layout
      char channel[32];
      av_get_channel_layout_string(channel, 32, par->channels, par->channel_layout);
      buf << ", " << channel;
    }
    // Sample Format
    if (show_sample_fmt(par) && get_bits_per_sample(par, true)) {
      if (par->format == AV_SAMPLE_FMT_FLT || par->format == AV_SAMPLE_FMT_DBL) {
        buf << ", fp";
      } else {
        buf << ", s";
      }
      buf << get_bits_per_sample(par, true);
    }
    // Bitrate
    if (bitrate > 0) {
      buf << ", " << (bitrate / 1000) << " kb/s";
    }
    // Closing tag
    if (title || lang) {
      buf << ")";
    }
    // Flags
    buf << format_flags(pStream->disposition);
    break;
  case AVMEDIA_TYPE_SUBTITLE:
    buf << "S: ";
    // Title/Language
    if (title && lang) {
      buf << title << " [" << lang << "] (";
    } else if (title) {
      // Print either title or lang
      buf << title << " (";
    } else if (lang) {
      buf << sLanguage << " [" << lang << "] (";
    }
    // Codec
    buf << codec_name;
    if (title || lang) {
      buf << ")";
    }
    // Subtitle flags
    buf << format_flags(pStream->disposition);
    break;
  default:
    buf << "Unknown: Stream #" << pStream->index;
    break;
  }

  return buf.str();
}