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; }
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; }