void DiscardDeint::filter(QQueue< FrameBuffer > &framesQueue) { int insertAt = addFramesToDeinterlace(framesQueue); while (!internalQueue.isEmpty()) { FrameBuffer dequeued = internalQueue.dequeue(); VideoFrame *videoFrame = VideoFrame::fromData(dequeued.data); const bool TFF = isTopFieldFirst(videoFrame); videoFrame->setNoInterlaced(); for (int p = 0; p < 3; ++p) { const int linesize = videoFrame->linesize[p]; quint8 *src = videoFrame->data[p]; quint8 *dst = videoFrame->data[p]; const int lines = (p ? h >> 2 : h >> 1) - 1; if (!TFF) { memcpy(dst, src + linesize, linesize); src += linesize; dst += linesize; } dst += linesize; src += linesize; for (int i = 0; i < lines; ++i) { VideoFilters::averageTwoLines(dst, src - linesize, src + linesize, linesize); src += linesize << 1; dst += linesize << 1; } if (TFF) memcpy(dst, src - linesize, linesize); } framesQueue.insert(insertAt++, dequeued); } }
bool DiscardDeint::filter(QQueue<FrameBuffer> &framesQueue) { addFramesToDeinterlace(framesQueue); if (!internalQueue.isEmpty()) { FrameBuffer dequeued = internalQueue.dequeue(); VideoFrame &videoFrame = dequeued.frame; const bool TFF = isTopFieldFirst(videoFrame); videoFrame.setNoInterlaced(); for (int p = 0; p < 3; ++p) { const int linesize = videoFrame.linesize[p]; quint8 *data = videoFrame.buffer[p].data(); const int lines = (videoFrame.size.getHeight(p) >> 1) - 1; if (!TFF) { memcpy(data, data + linesize, linesize); data += linesize; } data += linesize; for (int i = 0; i < lines; ++i) { VideoFilters::averageTwoLines(data, data - linesize, data + linesize, linesize); data += linesize << 1; } if (TFF) memcpy(data, data - linesize, linesize); } framesQueue.enqueue(dequeued); }
void BobDeint::filter( QQueue< FrameBuffer > &framesQueue ) { int insertAt = addFramesToDeinterlace( framesQueue ); while ( internalQueue.count() >= 2 ) { FrameBuffer dequeued = internalQueue.dequeue(); QByteArray videoFrameData2; VideoFrame *videoFrame1 = VideoFrame::fromData( dequeued.data ); VideoFrame *videoFrame2 = VideoFrame::create( videoFrameData2, w, h ); for ( int p = 0 ; p < 3 ; ++p ) { const int linesize = videoFrame1->linesize[ p ]; quint8 *src = videoFrame1->data[ p ] + linesize; quint8 *dst1 = videoFrame1->data[ p ]; quint8 *dst2 = videoFrame2->data[ p ]; memcpy( dst2, src, linesize ); //Copy second line into new frame (duplicate first line in new frame, simple deshake) dst2 += linesize; const int H = p ? h >> 2 : h >> 1; for ( int i = 0 ; i < H ; ++i ) { const bool notLast = i != H-1; memcpy( dst2, src, linesize ); dst2 += linesize; if ( notLast ) { VideoFilters::averageTwoLines( dst2, src, src + ( linesize << 1 ), linesize ); dst2 += linesize; } dst1 += linesize; if ( notLast ) VideoFilters::averageTwoLines( dst1, src - linesize, src + linesize, linesize ); else memcpy( dst1, src - linesize, linesize ); dst1 += linesize; src += linesize << 1; } if ( h & 1 ) //Duplicate last line for odd height memcpy( dst2, dst2 - linesize, linesize ); } const bool TFF = isTopFieldFirst( videoFrame1 ); videoFrame1->setNoInterlaced(); framesQueue.insert( insertAt++, FrameBuffer( TFF ? dequeued.data : videoFrameData2, dequeued.ts ) ); framesQueue.insert( insertAt++, FrameBuffer( !TFF ? dequeued.data : videoFrameData2, dequeued.ts + halfDelay( internalQueue.first(), dequeued ) ) ); } }
void BlendDeint::filter(QQueue< FrameBuffer > &framesQueue) { int insertAt = addFramesToDeinterlace(framesQueue); while (!internalQueue.isEmpty()) { FrameBuffer dequeued = internalQueue.dequeue(); VideoFrame *videoFrame = VideoFrame::fromData(dequeued.data); videoFrame->setNoInterlaced(); for (int p = 0; p < 3; ++p) { const int linesize = videoFrame->linesize[p]; quint8 *src = videoFrame->data[p] + linesize; quint8 *dst = videoFrame->data[p] + linesize; const int H = (p ? h >> 1 : h >> 0) - 2; for (int i = 0; i < H; ++i) { VideoFilters::averageTwoLines(dst, src, src + linesize, linesize); src += linesize; dst += linesize; } } framesQueue.insert(insertAt++, dequeued); } }