bool ThumbFinder::getFrameImage(bool needKeyFrame, int64_t requiredPTS) { AVPacket pkt; AVFrame orig; AVFrame retbuf; memset(&orig, 0, sizeof(AVFrame)); memset(&retbuf, 0, sizeof(AVFrame)); av_init_packet(&pkt); int frameFinished = 0; int keyFrame; int frameCount = 0; bool gotKeyFrame = false; while (av_read_frame(m_inputFC, &pkt) >= 0 && !frameFinished) { if (pkt.stream_index == m_videostream) { frameCount++; keyFrame = pkt.flags & AV_PKT_FLAG_KEY; if (m_startPTS == -1 && pkt.dts != AV_NOPTS_VALUE) { m_startPTS = pkt.dts; m_frameTime = pkt.duration; } if (keyFrame) gotKeyFrame = true; if (!gotKeyFrame && needKeyFrame) { av_packet_unref(&pkt); continue; } if (m_firstIFramePTS == -1) m_firstIFramePTS = pkt.dts; av_frame_unref(m_frame); frameFinished = 0; int ret = avcodec_receive_frame(m_codecCtx, m_frame); if (ret == 0) frameFinished = 1; if (ret == 0 || ret == AVERROR(EAGAIN)) ret = avcodec_send_packet(m_codecCtx, &pkt); if (requiredPTS != -1 && pkt.dts != AV_NOPTS_VALUE && pkt.dts < requiredPTS) frameFinished = false; m_currentPTS = pkt.dts; } av_packet_unref(&pkt); } if (frameFinished) { av_image_fill_arrays(retbuf.data, retbuf.linesize, m_outputbuf, AV_PIX_FMT_RGB32, m_frameWidth, m_frameHeight, IMAGE_ALIGN); AVFrame *tmp = m_frame; m_deinterlacer->DeinterlaceSingle(tmp, tmp); m_copy.Copy(&retbuf, AV_PIX_FMT_RGB32, tmp, m_codecCtx->pix_fmt, m_frameWidth, m_frameHeight); QImage img(m_outputbuf, m_frameWidth, m_frameHeight, QImage::Format_RGB32); QByteArray ffile = m_frameFile.toLocal8Bit(); if (!img.save(ffile.constData(), "JPEG")) { LOG(VB_GENERAL, LOG_ERR, "Failed to save thumb: " + m_frameFile); } if (m_updateFrame) { MythImage *mimage = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage(); mimage->Assign(img); m_frameImage->SetImage(mimage); mimage->DecrRef(); } updateCurrentPos(); } return true; }
bool ThumbFinder::getFrameImage(bool needKeyFrame, int64_t requiredPTS) { AVPacket pkt; AVPicture orig; AVPicture retbuf; bzero(&orig, sizeof(AVPicture)); bzero(&retbuf, sizeof(AVPicture)); av_init_packet(&pkt); int frameFinished = 0; int keyFrame; int frameCount = 0; bool gotKeyFrame = false; while (av_read_frame(m_inputFC, &pkt) >= 0 && !frameFinished) { if (pkt.stream_index == m_videostream) { frameCount++; keyFrame = pkt.flags & PKT_FLAG_KEY; if (m_startPTS == -1 && pkt.dts != (int64_t)AV_NOPTS_VALUE) { m_startPTS = pkt.dts; m_frameTime = pkt.duration; } if (keyFrame) gotKeyFrame = true; if (!gotKeyFrame && needKeyFrame) { av_free_packet(&pkt); continue; } if (m_firstIFramePTS == -1) m_firstIFramePTS = pkt.dts; avcodec_decode_video2(m_codecCtx, m_frame, &frameFinished, &pkt); if (requiredPTS != -1 && pkt.dts != (int64_t)AV_NOPTS_VALUE && pkt.dts < requiredPTS) frameFinished = false; m_currentPTS = pkt.dts; } av_free_packet(&pkt); } if (frameFinished) { avpicture_fill(&retbuf, m_outputbuf, PIX_FMT_RGB32, m_frameWidth, m_frameHeight); avpicture_deinterlace((AVPicture*)m_frame, (AVPicture*)m_frame, m_codecCtx->pix_fmt, m_frameWidth, m_frameHeight); myth_sws_img_convert( &retbuf, PIX_FMT_RGB32, (AVPicture*) m_frame, m_codecCtx->pix_fmt, m_frameWidth, m_frameHeight); QImage img(m_outputbuf, m_frameWidth, m_frameHeight, QImage::Format_RGB32); QByteArray ffile = m_frameFile.toLocal8Bit(); if (!img.save(ffile.constData(), "JPEG")) { VERBOSE(VB_IMPORTANT, "Failed to save thumb: " + m_frameFile); } if (m_updateFrame) { if (m_image) { m_image->DownRef(); m_image = NULL; } m_image = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage(); m_image->Assign(img); m_image->UpRef(); m_frameImage->SetImage(m_image); } updateCurrentPos(); } return true; }