*buffer = NULL;
int64_t time_us = -1;
MediaSource::ReadOptions::SeekMode mode;
-
+
if (options && options->getSeekTo(&time_us, &mode))
{
#if defined(DEBUG_VERBOSE)
p->in_mutex.unlock();
return VC_ERROR;
}
-
+
std::map<int64_t,Frame*>::iterator it = p->in_queue.begin();
frame = it->second;
ret = frame->status;
: CThread("CStageFrightDecodeThread")
, p(priv)
{}
-
+
void OnStartup()
{
#if defined(DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, "%s: entering decode thread\n", CLASSNAME);
#endif
}
-
+
void OnExit()
{
#if defined(DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, "%s: exited decode thread\n", CLASSNAME);
#endif
}
-
+
void Process()
{
Frame* frame;
#endif
p->cur_frame = NULL;
frame = (Frame*)malloc(sizeof(Frame));
- if (!frame)
+ if (!frame)
{
decode_done = 1;
continue;
}
frame->status = p->decoder->read(&frame->medbuf, &readopt);
readopt.clearSeekTo();
-
+
if (frame->status == OK)
{
if (!frame->medbuf->graphicBuffer().get()) // hw buffers
else
{
CLog::Log(LOGERROR, "%s - decoding error (%d)\n", CLASSNAME,frame->status);
- decode_done = 1;
if (frame->medbuf)
frame->medbuf->release();
frame->medbuf = NULL;
+ free(frame);
+ continue;
}
if (frame->format == RENDER_FMT_EGLIMG)
if (!p->eglInitialized)
{
p->InitializeEGL(frame->width, frame->height);
- }
+ }
else if (p->texwidth != frame->width || p->texheight != frame->height)
{
p->UninitializeEGL();
if (p->free_queue.empty())
{
CLog::Log(LOGERROR, "%s::%s - Error: No free output buffers\n", CLASSNAME, __func__);
- if (frame->medbuf)
+ if (frame->medbuf)
frame->medbuf->release();
free(frame);
continue;
- }
+ }
ANativeWindowBuffer* graphicBuffer = frame->medbuf->graphicBuffer()->getNativeBuffer();
native_window_set_buffers_timestamp(p->mVideoNativeWindow.get(), frame->pts * 1000);
glUniform1i(p->mTexSamplerHandle, 0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, p->mVideoTextureId);
-
+
GLfloat texMatrix[16];
// const GLfloat texMatrix[] = {
// 1, 0, 0, 0,
p->out_mutex.unlock();
}
while (!decode_done && !m_bStop);
-
+
if (p->eglInitialized)
p->UninitializeEGL();
-
+
}
};
if (g_advancedSettings.m_stagefrightConfig.useSwRenderer)
p->quirks |= QuirkSWRender;
-
+
sp<MetaData> outFormat;
int32_t cropLeft, cropTop, cropRight, cropBottom;
//Vector<String8> matchingCodecs;
goto fail;
}
- p->mVideoNativeWindow = NULL;
if ((p->quirks & QuirkSWRender) == 0)
- {
p->InitStagefrightSurface();
- native_window_api_connect(p->mVideoNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
- }
-
+
p->decoder = OMXCodec::Create(p->client->interface(), p->meta,
false, p->source, NULL,
OMXCodec::kHardwareCodecsOnly | (p->quirks & QuirkSWRender ? OMXCodec::kClientNeedsFramebuffer : 0),
if (outFormat->findCString(kKeyDecoderComponent, &component))
{
CLog::Log(LOGDEBUG, "%s::%s - component: %s\n", CLASSNAME, __func__, component);
-
+
//Blacklist
- if (!strncmp(component, "OMX.Nvidia.mp4.decode", 21) && g_advancedSettings.m_stagefrightConfig.useMP4codec != 1)
+ if (!strncmp(component, "OMX.google", 10))
{
- // Has issues with some XVID encoded MP4. Only fails after actual decoding starts...
- CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (MP4)");
+ // On some platforms, software decoders are returned anyway
+ CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (software)");
goto fail;
-
}
- else if (!strncmp(component, "OMX.rk.", 7))
+ else if (!strncmp(component, "OMX.Nvidia.mp4.decode", 21) && g_advancedSettings.m_stagefrightConfig.useMP4codec != 1)
{
- if (g_advancedSettings.m_stagefrightConfig.useAVCcodec != 1 && g_advancedSettings.m_stagefrightConfig.useMP4codec != 1)
- {
- if (p->width % 32 != 0 || p->height % 16 != 0)
- {
- // Buggy. Hard crash on non MOD16 height videos and stride errors for non MOD32 width
- CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (MOD16)");
- goto fail;
-
- }
- }
+ // Has issues with some XVID encoded MP4. Only fails after actual decoding starts...
+ CLog::Log(LOGERROR, "%s::%s - %s\n", CLASSNAME, __func__,"Blacklisted component (MP4)");
+ goto fail;
}
}
p->videoStride = p->width;
if (!outFormat->findInt32(kKeySliceHeight, &p->videoSliceHeight))
p->videoSliceHeight = p->height;
-
+
for (int i=0; i<INBUFCOUNT; ++i)
{
p->inbuf[i] = new MediaBuffer(300000);
p->inbuf[i]->setObserver(p);
}
-
+
p->decode_thread = new CStageFrightDecodeThread(p);
p->decode_thread->Create(true /*autodelete*/);
Frame *frame;
int demuxer_bytes = iSize;
uint8_t *demuxer_content = pData;
+ int ret = 0;
if (demuxer_content)
{
frame->pts = (dts != DVD_NOPTS_VALUE) ? pts_dtoi(dts) : ((pts != DVD_NOPTS_VALUE) ? pts_dtoi(pts) : 0);
else
frame->pts = (pts != DVD_NOPTS_VALUE) ? pts_dtoi(pts) : ((dts != DVD_NOPTS_VALUE) ? pts_dtoi(dts) : 0);
+
+ // No valid pts? libstagefright asserts on this.
+ if (frame->pts < 0)
+ {
+ free(frame);
+ return ret;
+ }
+
frame->medbuf = p->getBuffer(demuxer_bytes);
if (!frame->medbuf)
{
free(frame);
return VC_ERROR;
}
+
fast_memcpy(frame->medbuf->data(), demuxer_content, demuxer_bytes);
frame->medbuf->meta_data()->clear();
frame->medbuf->meta_data()->setInt64(kKeyTime, frame->pts);
-
+
p->in_mutex.lock();
p->framecount++;
p->in_queue.insert(std::pair<int64_t, Frame*>(p->framecount, frame));
p->in_mutex.unlock();
}
- int ret = 0;
if (p->inputBufferAvailable() && p->in_queue.size() < INBUFCOUNT)
ret |= VC_BUFFER;
else
#if defined(DEBUG_VERBOSE)
CLog::Log(LOGDEBUG, ">>> pic dts:%f, pts:%llu, img:%p, tm:%d\n", pDvdVideoPicture->dts, frame->pts, pDvdVideoPicture->eglimg, XbmcThreads::SystemClockMillis() - time);
#endif
- }
+ }
else if (pDvdVideoPicture->format == RENDER_FMT_YUV420P)
- {
+ {
pDvdVideoPicture->color_range = 0;
pDvdVideoPicture->color_matrix = 4;
frame->medbuf->release();
free(frame);
}
-
+
if (p->decoder_component)
free(&p->decoder_component);