void CMMALVideo::Reset(void) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__); if (m_dec_input && m_dec_input->is_enabled) mmal_port_disable(m_dec_input); if (m_deint_connection && m_deint_connection->is_enabled) mmal_connection_disable(m_deint_connection); if (m_dec_output && m_dec_output->is_enabled) mmal_port_disable(m_dec_output); if (!m_finished) { if (m_dec_input) mmal_port_enable(m_dec_input, dec_input_port_cb); if (m_deint_connection) mmal_connection_enable(m_deint_connection); if (m_dec_output) mmal_port_enable(m_dec_output, dec_output_port_cb_static); } // blow all ready video frames bool old_drop_state = m_drop_state; SetDropState(true); pthread_mutex_lock(&m_output_mutex); while(!m_dts_queue.empty()) m_dts_queue.pop(); while (!m_demux_queue.empty()) m_demux_queue.pop(); m_demux_queue_length = 0; pthread_mutex_unlock(&m_output_mutex); if (!old_drop_state) SetDropState(false); if (!m_finished) SendCodecConfigData(); m_startframe = false; m_decoderPts = DVD_NOPTS_VALUE; m_droppedPics = 0; m_decode_frame_number = 1; m_preroll = !m_hints.stills && (m_speed == DVD_PLAYSPEED_NORMAL || m_speed == DVD_PLAYSPEED_PAUSE); }
bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVideoPtr myself) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s::%s usemmal:%d software:%d %dx%d", CLASSNAME, __func__, CSettings::Get().GetBool("videoplayer.usemmal"), hints.software, hints.width, hints.height); // we always qualify even if DVDFactoryCodec does this too. if (!CSettings::Get().GetBool("videoplayer.usemmal") || hints.software) return false; m_hints = hints; MMAL_STATUS_T status; MMAL_PARAMETER_BOOLEAN_T error_concealment; m_myself = myself; m_decoded_width = hints.width; m_decoded_height = hints.height; // use aspect in stream if available if (m_hints.forced_aspect) m_aspect_ratio = m_hints.aspect; else m_aspect_ratio = 0.0; switch (hints.codec) { case AV_CODEC_ID_H264: // H.264 m_codingType = MMAL_ENCODING_H264; m_pFormatName = "mmal-h264"; break; case AV_CODEC_ID_H263: case AV_CODEC_ID_MPEG4: // MPEG-4, DivX 4/5 and Xvid compatible m_codingType = MMAL_ENCODING_MP4V; m_pFormatName = "mmal-mpeg4"; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: // MPEG-2 m_codingType = MMAL_ENCODING_MP2V; m_pFormatName = "mmal-mpeg2"; break; case AV_CODEC_ID_VP6: // this form is encoded upside down // fall through case AV_CODEC_ID_VP6F: case AV_CODEC_ID_VP6A: // VP6 m_codingType = MMAL_ENCODING_VP6; m_pFormatName = "mmal-vp6"; break; case AV_CODEC_ID_VP8: // VP8 m_codingType = MMAL_ENCODING_VP8; m_pFormatName = "mmal-vp8"; break; case AV_CODEC_ID_THEORA: // theora m_codingType = MMAL_ENCODING_THEORA; m_pFormatName = "mmal-theora"; break; case AV_CODEC_ID_MJPEG: case AV_CODEC_ID_MJPEGB: // mjpg m_codingType = MMAL_ENCODING_MJPEG; m_pFormatName = "mmal-mjpg"; break; case AV_CODEC_ID_VC1: case AV_CODEC_ID_WMV3: // VC-1, WMV9 m_codingType = MMAL_ENCODING_WVC1; m_pFormatName = "mmal-vc1"; break; default: CLog::Log(LOGERROR, "%s::%s : Video codec unknown: %x", CLASSNAME, __func__, hints.codec); return false; break; } if ( (m_codingType == MMAL_ENCODING_MP2V && !g_RBP.GetCodecMpg2() ) || (m_codingType == MMAL_ENCODING_WVC1 && !g_RBP.GetCodecWvc1() ) ) { CLog::Log(LOGWARNING, "%s::%s Codec %s is not supported", CLASSNAME, __func__, m_pFormatName); return false; } // initialize mmal. status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &m_dec); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to create MMAL decoder component %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status)); return false; } m_dec->control->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(m_dec->control, dec_control_port_cb_static); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder control port %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status)); return false; } m_dec_input = m_dec->input[0]; m_dec_input->format->type = MMAL_ES_TYPE_VIDEO; m_dec_input->format->encoding = m_codingType; if (m_hints.width && m_hints.height) { m_dec_input->format->es->video.crop.width = m_hints.width; m_dec_input->format->es->video.crop.height = m_hints.height; m_dec_input->format->es->video.width = ALIGN_UP(m_hints.width, 32); m_dec_input->format->es->video.height = ALIGN_UP(m_hints.height, 16); } m_dec_input->format->flags |= MMAL_ES_FORMAT_FLAG_FRAMED; error_concealment.hdr.id = MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT; error_concealment.hdr.size = sizeof(MMAL_PARAMETER_BOOLEAN_T); error_concealment.enable = MMAL_FALSE; status = mmal_port_parameter_set(m_dec_input, &error_concealment.hdr); if (status != MMAL_SUCCESS) CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, NUM_BUFFERS); if (status != MMAL_SUCCESS) CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); status = mmal_port_format_commit(m_dec_input); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to commit format for decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); return false; } m_dec_input->buffer_size = m_dec_input->buffer_size_recommended; m_dec_input->buffer_num = m_dec_input->buffer_num_recommended; m_dec_input->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(m_dec_input, dec_input_port_cb); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status)); return false; } m_dec_output = m_dec->output[0]; // set up initial decoded frame format - will likely change from this m_dec_output->format->encoding = MMAL_ENCODING_OPAQUE; mmal_format_copy(m_es_format, m_dec_output->format); status = mmal_port_format_commit(m_dec_output); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to commit decoder output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_dec_output->buffer_size = m_dec_output->buffer_size_min; m_dec_output->buffer_num = m_dec_output->buffer_num_recommended; m_dec_output->userdata = (struct MMAL_PORT_USERDATA_T *)this; status = mmal_port_enable(m_dec_output, dec_output_port_cb_static); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } status = mmal_component_enable(m_dec); if (status != MMAL_SUCCESS) { CLog::Log(LOGERROR, "%s::%s Failed to enable decoder component %s (status=%x %s)", CLASSNAME, __func__, m_dec->name, status, mmal_status_to_string(status)); return false; } m_dec_input_pool = mmal_pool_create(m_dec_input->buffer_num, m_dec_input->buffer_size); if (!m_dec_input_pool) { CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } m_dec_output_pool = mmal_pool_create(m_dec_output->buffer_num, m_dec_output->buffer_size); if(!m_dec_output_pool) { CLog::Log(LOGERROR, "%s::%s Failed to create pool for decode output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status)); return false; } if (!SendCodecConfigData()) return false; m_drop_state = false; m_startframe = false; return true; }