/working/avcodec_to_widget_9/t_generator.cpp
C++ | 179 lines | 141 code | 8 blank | 30 comment | 16 complexity | 7984bb065e87b30324fb48562d14c9cf MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, MPL-2.0-no-copyleft-exception
- // $URL: http://mingw-lib.googlecode.com/svn/trunk/working/avcodec_to_widget_9/t_generator.cpp $
- // $Rev: 319 $
- // $Author: akio.miyoshi $
- // $Date:: 2010-07-31 11:47:06 +0200#$
-
- #include "t_generator.h"
- #include "t_box_player_ctx.h"
-
- void T_Generator::breakTimer()
- {
- m_base_msecs = -1;
- m_base_bytes = 0;
- }
-
- qint64 T_Generator::elapsed()
- {
- QAudioOutput *v_output = m_player_ctx->m_audioOutput;
- QAudioFormat v_format = v_output->format();
- qint64 v_bytesWaiting = (v_output->bufferSize() - v_output->bytesFree());
- if(v_bytesWaiting == 0)
- {
- return -1;
- }
- if(m_base_msecs < 0)
- {
- return -1;
- }
- qint64 v_bytesPlayed = m_out_read_size - v_bytesWaiting;
- qint64 v_msecsDelta =
- ((qint64)1000)
- * (v_bytesPlayed - m_base_bytes)
- / ( v_format.channels() * v_format.sampleSize() / 8 )
- / v_format.frequency();
- qint64 v_msecs = m_base_msecs + v_msecsDelta;
- return v_msecs;
- }
-
- // In qaudiooutput_win32_p.cpp
- // QAudioOutputPrivate::deviceReady() seek() backwards
- // (when part of the final read() data could not be written to the sound device)
- // Generator::m_audio_last_read (=QByteArray) holds final read() data to handle
- // this case.
- bool T_Generator::seek(qint64 pos)
- {
- qint64 v_curr_pos = this->pos();
- qint64 v_seek_len = v_curr_pos - pos;
- //qDebug() << "[Generator::seek()]" << v_seek_len << m_audio_last_read.size();
- if(v_seek_len <= 0)
- {
- qDebug() << "=====>seek() error (1)";
- return false;
- }
- m_max_seek_size = qMax(m_max_seek_size, v_seek_len);
- if(v_seek_len > m_audio_last_read.size())
- {
- qDebug() << "=====>seek() error (2)";
- m_out_read_size -= m_audio_last_read.size();
- m_audio_data_left.prepend(m_audio_last_read);
- m_audio_data_left.clear();
- return false;
- }
- m_out_read_size -= v_seek_len;
- m_audio_data_left.prepend(p_pop_back(m_audio_last_read, v_seek_len));
- //qDebug() << "=====>seek() ok";
- return true;
- }
-
- qint64 T_Generator::readData(char *data, qint64 len)
- {
- //qDebug() << "[Generator::readData()]" << "[this->pos()]" << this->pos() << "[len]" << len;
- Q_ASSERT(len%2==0);
- //[m_max_seek_size]
- m_max_seek_size = qMax(m_max_seek_size, len);
- //[left_len, read_len]
- qint64 prec_len = 0;
- qint64 need_len = len;
- //[pop from m_audio_data_left]
- QByteArray v_result = p_pop_front(m_audio_data_left, need_len);
- need_len -= v_result.size();
- prec_len += v_result.size();
- //[decode packet if needed]
- if(need_len>0)
- {
- QByteArray v_packet_bytes = p_readPacket(prec_len, need_len);
- need_len -= v_packet_bytes.size();
- prec_len += v_packet_bytes.size();
- v_result.append(v_packet_bytes);
- }
- //qDebug() << "[Generator::readData()]" << read_len << v_result.size();
- Q_ASSERT(prec_len==v_result.size());
- //[save bytes beyond capacity => m_audio_data_left]
- if(v_result.size() > len)
- {
- m_audio_data_left.append(p_pop_back(v_result, v_result.size()-len));
- }
- //[append the result bytes => m_audio_last_read (prepare for possible seek()-ing backwards)]
- m_audio_last_read.append(v_result);
- //[reduce m_audio_last_read's size => m_max_seek_size]
- if(m_audio_last_read.size() > m_max_seek_size)
- {
- m_audio_last_read = m_audio_last_read.right(m_max_seek_size);
- }
- //Q_ASSERT(v_result.size()<=len);
- m_out_read_size += v_result.size(); //add to m_out_read_size before padding zero.
- #if 0x0
- if(v_result.size()<len)
- {
- //need padding zerro
- this->breakTimer();
- QByteArray v_pad(len-v_result.size(), (char)0);
- v_result.append(v_pad);
- }
- #endif
- //qDebug() << "[Generator::readData()]" << len << v_result.size();
- memcpy(data, v_result.constData(), v_result.size());
- return v_result.size();
- }
-
- QByteArray T_Generator::p_readPacket(qint64 prec_len, qint64 need_len)
- {
- //[seek lock]
- T_RecursiveLocked *v_seek_mutex = m_player_ctx->seekManager();
- if(!v_seek_mutex->tryLockForRead())
- {
- return QByteArray();
- }
- QReadLocker v_seek_locker(v_seek_mutex);
- Q_UNUSED(v_seek_locker);
- v_seek_mutex->unlock();
- //
- if(!m_player_ctx->m_stopwatch.isActive())
- {
- return QByteArray();
- }
- //
- if(m_player_ctx->m_audio.packet_queue.size()>0 && m_player_ctx->m_audio.packet_queue.head()->isNull())
- {
- //m_player_ctx->m_audio.packet_queue.dequeue();
- return QByteArray();
- }
- //[left_len, read_len]
- qint64 read_len = 0;
- QByteArray v_result;
- if(need_len>0 && m_player_ctx->m_audio.packet_queue.size()>0)
- {
- QSharedPointer<T_AV_Packet> v_head_packet = m_player_ctx->m_audio.packet_queue.head();
- m_base_bytes = m_out_read_size + prec_len;
- m_base_msecs = v_head_packet->timing();
- }
- while(need_len>0 && m_player_ctx->m_audio.packet_queue.size()>0)
- {
- QSharedPointer<T_AV_Packet> v_head_packet = m_player_ctx->m_audio.packet_queue.head();
- QByteArray v_audio_byes = v_head_packet->decodeAudio();
- need_len -= v_audio_byes.size();
- read_len += v_audio_byes.size();
- v_result.append(v_audio_byes);
- /*delete*/ m_player_ctx->m_audio.packet_queue.dequeue();
- }
- //qDebug() << "[Generator::p_readPacket()]" << "read_len" << v_result.size();
- Q_ASSERT(read_len==v_result.size());
- // v_result.size() might exceed wanted_len.
- return v_result;
- }
-
- QByteArray T_Generator::p_pop_front(QByteArray &a_bytes, int a_maxlen)
- {
- int v_len = qMin(a_maxlen, a_bytes.size());
- QByteArray v_pop = a_bytes.left(v_len);
- a_bytes = a_bytes.right(a_bytes.size()-v_len);
- return v_pop;
- }
-
- QByteArray T_Generator::p_pop_back(QByteArray &a_bytes, int a_maxlen)
- {
- int v_len = qMin(a_maxlen, a_bytes.size());
- QByteArray v_pop = a_bytes.right(v_len);
- a_bytes = a_bytes.left(a_bytes.size()-v_len);
- return v_pop;
- }