Ejemplo n.º 1
0
static mlt_properties find_default_streams( mlt_properties meta_media, AVFormatContext *context, int *audio_index, int *video_index )
{
	int i;
	char key[200];

	mlt_properties_set_int( meta_media, "meta.media.nb_streams", context->nb_streams );

	// Allow for multiple audio and video streams in the file and select first of each (if available)
	for( i = 0; i < context->nb_streams; i++ )
	{
		// Get the codec context
		AVStream *stream = context->streams[ i ];
		if ( ! stream ) continue;
		AVCodecContext *codec_context = stream->codec;
		if ( ! codec_context ) continue;
		AVCodec *codec = avcodec_find_decoder( codec_context->codec_id );
		if ( ! codec ) continue;

		snprintf( key, sizeof(key), "meta.media.%d.stream.type", i );

		// Determine the type and obtain the first index of each type
		switch( codec_context->codec_type )
		{
			case CODEC_TYPE_VIDEO:
				if ( *video_index < 0 )
					*video_index = i;
				mlt_properties_set( meta_media, key, "video" );
				snprintf( key, sizeof(key), "meta.media.%d.stream.frame_rate", i );
				mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->r_frame_rate ) );
#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0)
				snprintf( key, sizeof(key), "meta.media.%d.stream.sample_aspect_ratio", i );
				mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->sample_aspect_ratio ) );
#endif
				snprintf( key, sizeof(key), "meta.media.%d.codec.pix_fmt", i );
				mlt_properties_set( meta_media, key, avcodec_get_pix_fmt_name( codec_context->pix_fmt ) );
				snprintf( key, sizeof(key), "meta.media.%d.codec.sample_aspect_ratio", i );
				mlt_properties_set_double( meta_media, key, av_q2d( codec_context->sample_aspect_ratio ) );
				break;
			case CODEC_TYPE_AUDIO:
				if ( *audio_index < 0 )
					*audio_index = i;
				mlt_properties_set( meta_media, key, "audio" );
#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(71<<8)+0))
				snprintf( key, sizeof(key), "meta.media.%d.codec.sample_fmt", i );
				mlt_properties_set( meta_media, key, avcodec_get_sample_fmt_name( codec_context->sample_fmt ) );
#endif
				snprintf( key, sizeof(key), "meta.media.%d.codec.sample_rate", i );
				mlt_properties_set_int( meta_media, key, codec_context->sample_rate );
				snprintf( key, sizeof(key), "meta.media.%d.codec.channels", i );
				mlt_properties_set_int( meta_media, key, codec_context->channels );
				break;
			default:
				break;
		}
// 		snprintf( key, sizeof(key), "meta.media.%d.stream.time_base", i );
// 		mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->time_base ) );
		snprintf( key, sizeof(key), "meta.media.%d.codec.name", i );
		mlt_properties_set( meta_media, key, codec->name );
#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(55<<8)+0))
		snprintf( key, sizeof(key), "meta.media.%d.codec.long_name", i );
		mlt_properties_set( meta_media, key, codec->long_name );
#endif
		snprintf( key, sizeof(key), "meta.media.%d.codec.bit_rate", i );
		mlt_properties_set_int( meta_media, key, codec_context->bit_rate );
// 		snprintf( key, sizeof(key), "meta.media.%d.codec.time_base", i );
// 		mlt_properties_set_double( meta_media, key, av_q2d( codec_context->time_base ) );
		snprintf( key, sizeof(key), "meta.media.%d.codec.profile", i );
		mlt_properties_set_int( meta_media, key, codec_context->profile );
		snprintf( key, sizeof(key), "meta.media.%d.codec.level", i );
		mlt_properties_set_int( meta_media, key, codec_context->level );
	}

	return meta_media;
}
Ejemplo n.º 2
0
/**
 * Gets the AVPacket stored in _packet, and decodes all the samples it can from it,
 * putting them in _buffer, the total number of bytes written begin stored in _dataSize.
 */
int AudioLoader::decodePacket() {
    /*
    E_DEBUG(EAlgorithm, "-----------------------------------------------------");
    E_DEBUG(EAlgorithm, "decoding packet of " << _packet.size << " bytes");
    E_DEBUG(EAlgorithm, "pts: " << _packet.pts << " - dts: " << _packet.dts); //" - pos: " << pkt->pos);
    E_DEBUG(EAlgorithm, "flags: " << _packet.flags);
    E_DEBUG(EAlgorithm, "duration: " << _packet.duration);
    */

    int len = 0;

    // buff is an offset in our output buffer, it points to where we should start
    // writing the next decoded samples
    int16_t* buff = _buffer;

#if !HAVE_SWRESAMPLE
    if (_audioConvert) { buff = _buff1; }
#endif

    // _dataSize gets the size of the buffer, in bytes
    _dataSize = FFMPEG_BUFFER_SIZE*sizeof(int16_t);

    // _dataSize  input = number of bytes available for write in buff
    //           output = number of bytes actually written (actual: S16 data)
    //E_DEBUG(EAlgorithm, "decode_audio_frame, available bytes in buffer = " << _dataSize);
    len = decode_audio_frame(_audioCtx, buff, &_dataSize, &_packet);

    if (len < 0) {
        // only print error msg when file is not an mp3, because mp3 streams can have tag
        // frames (id3v2?) which libavcodec tries to read as audio anyway, and we don't want
        // to print an error message for that...
        if (_audioCtx->codec_id == CODEC_ID_MP3) {
            E_DEBUG(EAlgorithm, "AudioLoader: invalid frame, probably an mp3 tag frame, skipping it");
        }
        else {
            E_WARNING("AudioLoader: error while decoding, skipping frame");
        }
        return 0;
    }

    if (_dataSize <= 0) {
        // No data yet, get more frames
        //cout << "no data yet, get more frames" << endl;
        _dataSize = 0;
        return 0;
    }

#if !HAVE_SWRESAMPLE
    if (_audioConvert) {
        // this assumes that all audio is interleaved in the first channel
        // it works as we're only doing sample format conversion, but we
        // should be very careful
        const void* ibuf[6] = { buff };
              void* obuf[6] = { _buff2 };
        int istride[6]      = { av_get_bytes_per_sample(_audioCtx->sample_fmt) };
        int ostride[6]      = { av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)     };
        int totalsamples    = _dataSize / istride[0]; // == num_samp_per_channel * num_channels

        if (av_audio_convert(_audioConvert, obuf, ostride, ibuf, istride, totalsamples) < 0) {
            ostringstream msg;
            msg << "AudioLoader: Error converting "
                << " from " << avcodec_get_sample_fmt_name(_audioCtx->sample_fmt)
                << " to "   << avcodec_get_sample_fmt_name(SAMPLE_FMT_S16);
            throw EssentiaException(msg);
        }

        // when entering the current block, dataSize contained the size in bytes
        // that the audio was taking in its native format. Now it needs to be set
        // to the size of the audio we're returning, after conversion
        _dataSize = totalsamples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
        memcpy(_buffer, _buff2, _dataSize);
    }
#endif

    if (len != _packet.size) {
        // FIXME: investigate why this happens and whether it is a big issue
        //        (looks like it only loses silent samples at the end of files)

        // more than 1 frame in a packet, happens a lot with flac for instance...
        E_WARNING("AudioLoader: more than 1 frame in packet, dropping remaining bytes...");
        E_WARNING("at sample index: " << output("audio").totalProduced());
        E_WARNING("decoded samples: " << len);
        E_WARNING("packet size: " << _packet.size);
    }

    return len;
}