Exemple #1
0
BOOL player_impl::open(const char *movie, int media_type, int render_type)
{
    // 如果未关闭原来的媒体, 则先关闭.
    if (m_avplay || m_source)
        close();

    // 未创建窗口, 无法播放, 返回失败.
    if (!IsWindow(m_hwnd))
        return FALSE;

    char filename[MAX_PATH];
    int len = strlen(movie) + 1;

    strcpy(filename, movie);

    uint64_t file_lentgh = 0;
    if (media_type == MEDIA_TYPE_FILE || media_type == MEDIA_TYPE_BT)
    {
        file_lentgh = file_size(movie);
        if (file_lentgh < 0)
        {
            ::logger("get file size failed!\n");
            return FALSE;
        }
    }

    do {
        // 创建avplay.
        m_avplay = alloc_avplay_context();
        if (!m_avplay)
        {
            ::logger("allocate avplay context failed!\n");
            break;
        }

        // 根据打开的文件类型, 创建不同媒体源.
        if (media_type == MEDIA_TYPE_FILE)
        {
            len = strlen(filename);
            m_source = alloc_media_source(MEDIA_TYPE_FILE, filename, len + 1, file_lentgh);
            if (!m_source)
            {
                ::logger("allocate media source failed, type is file.\n");
                break;
            }

            // 插入到媒体列表.
            m_media_list.insert(std::make_pair(filename, filename));

            // 初始化文件媒体源.
            init_file_source(m_source);
        }

        if (media_type == MEDIA_TYPE_BT)
        {
            // 先读取bt种子数据, 然后作为附加数据保存到媒体源.
            FILE *fp = fopen(filename, "r+b");
            if (!fp)
            {
                ::logger("open torrent file \'%s\' failed!\n", filename);
                break;
            }
            char *torrent_data = (char*)malloc(file_lentgh);
            int readbytes = fread(torrent_data, 1, file_lentgh, fp);
            if (readbytes != file_lentgh)
            {
                ::logger("read torrent file \'%s\' failed!\n", filename);
                break;
            }
            m_source = alloc_media_source(MEDIA_TYPE_BT, torrent_data, file_lentgh, 0);
            if (!m_source)
            {
                ::logger("allocate media source failed, type is torrent.\n");
                break;
            }

            free(torrent_data);

            // 初始化torrent媒体源.
            init_torrent_source(m_source);
        }

        if (media_type == MEDIA_TYPE_HTTP)
        {
            len = strlen(filename) + 1;
            m_source = alloc_media_source(MEDIA_TYPE_HTTP, filename, len, 0);
            if (!m_source)
            {
                ::logger("allocate media source failed, type is http.\n");
                break;
            }

            // 插入到媒体列表.
            m_media_list.insert(std::make_pair(filename, filename));
        }

        if (media_type == MEDIA_TYPE_RTSP)
        {
            len = strlen(filename) + 1;
            m_source = alloc_media_source(MEDIA_TYPE_RTSP, filename, len, 0);
            if (!m_source)
            {
                ::logger("allocate media source failed, type is rtsp.\n");
                break;
            }

            // 插入到媒体列表.
            m_media_list.insert(std::make_pair(filename, filename));
        }

        // 初始化avplay.
        if (initialize(m_avplay, m_source) != 0)
        {
            ::logger("initialize avplay failed!\n");
            break;
        }

        // 如果是bt类型, 则在此得到视频文件列表, 并添加到m_media_list.
        if (media_type == MEDIA_TYPE_BT)
        {
            int i = 0;
            media_info *media = m_source->media;
            for (; i < m_source->media_size; i++)
            {
                std::string name;
                name = media->name;
                m_media_list.insert(std::make_pair(filename, name));
            }
        }

        // 分配音频和视频的渲染器.
        m_audio = alloc_audio_render();
        if (!m_audio)
        {
            ::logger("allocate audio render failed!\n");
            break;
        }

        m_video = alloc_video_render(m_hwnd);
        if (!m_video)
        {
            ::logger("allocate video render failed!\n");
            break;
        }

        // 初始化音频和视频渲染器.
        init_audio(m_audio);
        init_video(m_video);

        // 配置音频视频渲染器.
        configure(m_avplay, m_video, VIDEO_RENDER);
        configure(m_avplay, m_audio, AUDIO_RENDER);

        // 得到视频宽高.
        m_video_width = av_width(m_avplay);
        m_video_height = av_height(m_avplay);

        // 打开视频实时码率和帧率计算.
        enable_calc_frame_rate(m_avplay);
        enable_calc_bit_rate(m_avplay);

        return TRUE;

    } while (0);

    if (m_avplay)
        free_avplay_context(m_avplay);
    m_avplay = NULL;
    if (m_source)
        free_media_source(m_source);
    if (m_audio)
        free_audio_render(m_audio);
    if (m_video)
        free_video_render(m_video);

    ::logger("open avplay failed!\n");

    return FALSE;
}
Exemple #2
0
bool youku_demux::open(boost::any ctx)
{
	av_register_all();
	avformat_network_init();

	// 得到传入的参数.
	m_youku_demux_data = boost::any_cast<youku_demux_data>(ctx);
	BOOST_ASSERT(m_youku_demux_data.type == MEDIA_TYPE_YK);

	// 初始化youku的source.
	m_source_ctx = alloc_media_source(MEDIA_TYPE_YK,
		m_youku_demux_data.youku_url.c_str(), m_youku_demux_data.youku_url.size(), 0);

	// 创建m_format_ctx.
	m_format_ctx = avformat_alloc_context();
	if (!m_format_ctx)
		goto FAILED_FLG;

	// 设置参数.
	m_format_ctx->flags = AVFMT_FLAG_GENPTS;
	m_format_ctx->interrupt_callback.callback = decode_interrupt_cb;
	m_format_ctx->interrupt_callback.opaque = (void*)this;

	m_source_ctx->init_source = yk_init_source;
	m_source_ctx->read_data = yk_read_data;
	m_source_ctx->read_seek = yk_read_seek;
	m_source_ctx->close = yk_close;
	m_source_ctx->destory = yk_destory;

	// 如果初始化失败.
	if (m_source_ctx->init_source(m_source_ctx) < 0)
		goto FAILED_FLG;

	int ret = 0;
	AVInputFormat *iformat = NULL;
	m_io_buffer = (unsigned char*)av_malloc(IO_BUFFER_SIZE);
	if (!m_io_buffer)
	{
		std::cerr << "Create buffer failed!\n";
		goto FAILED_FLG;
	}

	// 分配io上下文.
	m_avio_ctx = avio_alloc_context(m_io_buffer,
		IO_BUFFER_SIZE, 0, (void*)this, read_data, NULL, seek_data);
	if (!m_avio_ctx)
	{
		std::cerr << "Create io context failed!\n";
		goto FAILED_FLG;
	}
	m_avio_ctx->write_flag = 0;

	ret = av_probe_input_buffer(m_avio_ctx, &iformat, "", NULL, 0, 0);
	if (ret < 0)
	{
		std::cerr << "av_probe_input_buffer call failed!\n";
		goto FAILED_FLG;
	}

	// 打开输入媒体流.
	m_format_ctx->pb = m_avio_ctx;
	ret = avformat_open_input(&m_format_ctx, "", iformat, NULL);
	if (ret < 0)
	{
		std::cerr << "av_open_input_stream call failed!\n";
		goto FAILED_FLG;
	}

	ret = avformat_find_stream_info(m_format_ctx, NULL);
	if (ret < 0)
		goto FAILED_FLG;

FAILED_FLG:
	// 遇到出错, 释放各种资源.
	if (m_source_ctx)
	{
		free_media_source(m_source_ctx);
		m_source_ctx = NULL;
	}
	if (m_format_ctx)
	{
		avformat_close_input(&m_format_ctx);
		m_format_ctx = NULL;
	}

	return false;
}