PageRenderTime 206ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/working/avcodec_to_widget_9/t_generator.cpp

http://mingw-lib.googlecode.com/
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
  1. // $URL: http://mingw-lib.googlecode.com/svn/trunk/working/avcodec_to_widget_9/t_generator.cpp $
  2. // $Rev: 319 $
  3. // $Author: akio.miyoshi $
  4. // $Date:: 2010-07-31 11:47:06 +0200#$
  5. #include "t_generator.h"
  6. #include "t_box_player_ctx.h"
  7. void T_Generator::breakTimer()
  8. {
  9. m_base_msecs = -1;
  10. m_base_bytes = 0;
  11. }
  12. qint64 T_Generator::elapsed()
  13. {
  14. QAudioOutput *v_output = m_player_ctx->m_audioOutput;
  15. QAudioFormat v_format = v_output->format();
  16. qint64 v_bytesWaiting = (v_output->bufferSize() - v_output->bytesFree());
  17. if(v_bytesWaiting == 0)
  18. {
  19. return -1;
  20. }
  21. if(m_base_msecs < 0)
  22. {
  23. return -1;
  24. }
  25. qint64 v_bytesPlayed = m_out_read_size - v_bytesWaiting;
  26. qint64 v_msecsDelta =
  27. ((qint64)1000)
  28. * (v_bytesPlayed - m_base_bytes)
  29. / ( v_format.channels() * v_format.sampleSize() / 8 )
  30. / v_format.frequency();
  31. qint64 v_msecs = m_base_msecs + v_msecsDelta;
  32. return v_msecs;
  33. }
  34. // In qaudiooutput_win32_p.cpp
  35. // QAudioOutputPrivate::deviceReady() seek() backwards
  36. // (when part of the final read() data could not be written to the sound device)
  37. // Generator::m_audio_last_read (=QByteArray) holds final read() data to handle
  38. // this case.
  39. bool T_Generator::seek(qint64 pos)
  40. {
  41. qint64 v_curr_pos = this->pos();
  42. qint64 v_seek_len = v_curr_pos - pos;
  43. //qDebug() << "[Generator::seek()]" << v_seek_len << m_audio_last_read.size();
  44. if(v_seek_len <= 0)
  45. {
  46. qDebug() << "=====>seek() error (1)";
  47. return false;
  48. }
  49. m_max_seek_size = qMax(m_max_seek_size, v_seek_len);
  50. if(v_seek_len > m_audio_last_read.size())
  51. {
  52. qDebug() << "=====>seek() error (2)";
  53. m_out_read_size -= m_audio_last_read.size();
  54. m_audio_data_left.prepend(m_audio_last_read);
  55. m_audio_data_left.clear();
  56. return false;
  57. }
  58. m_out_read_size -= v_seek_len;
  59. m_audio_data_left.prepend(p_pop_back(m_audio_last_read, v_seek_len));
  60. //qDebug() << "=====>seek() ok";
  61. return true;
  62. }
  63. qint64 T_Generator::readData(char *data, qint64 len)
  64. {
  65. //qDebug() << "[Generator::readData()]" << "[this->pos()]" << this->pos() << "[len]" << len;
  66. Q_ASSERT(len%2==0);
  67. //[m_max_seek_size]
  68. m_max_seek_size = qMax(m_max_seek_size, len);
  69. //[left_len, read_len]
  70. qint64 prec_len = 0;
  71. qint64 need_len = len;
  72. //[pop from m_audio_data_left]
  73. QByteArray v_result = p_pop_front(m_audio_data_left, need_len);
  74. need_len -= v_result.size();
  75. prec_len += v_result.size();
  76. //[decode packet if needed]
  77. if(need_len>0)
  78. {
  79. QByteArray v_packet_bytes = p_readPacket(prec_len, need_len);
  80. need_len -= v_packet_bytes.size();
  81. prec_len += v_packet_bytes.size();
  82. v_result.append(v_packet_bytes);
  83. }
  84. //qDebug() << "[Generator::readData()]" << read_len << v_result.size();
  85. Q_ASSERT(prec_len==v_result.size());
  86. //[save bytes beyond capacity => m_audio_data_left]
  87. if(v_result.size() > len)
  88. {
  89. m_audio_data_left.append(p_pop_back(v_result, v_result.size()-len));
  90. }
  91. //[append the result bytes => m_audio_last_read (prepare for possible seek()-ing backwards)]
  92. m_audio_last_read.append(v_result);
  93. //[reduce m_audio_last_read's size => m_max_seek_size]
  94. if(m_audio_last_read.size() > m_max_seek_size)
  95. {
  96. m_audio_last_read = m_audio_last_read.right(m_max_seek_size);
  97. }
  98. //Q_ASSERT(v_result.size()<=len);
  99. m_out_read_size += v_result.size(); //add to m_out_read_size before padding zero.
  100. #if 0x0
  101. if(v_result.size()<len)
  102. {
  103. //need padding zerro
  104. this->breakTimer();
  105. QByteArray v_pad(len-v_result.size(), (char)0);
  106. v_result.append(v_pad);
  107. }
  108. #endif
  109. //qDebug() << "[Generator::readData()]" << len << v_result.size();
  110. memcpy(data, v_result.constData(), v_result.size());
  111. return v_result.size();
  112. }
  113. QByteArray T_Generator::p_readPacket(qint64 prec_len, qint64 need_len)
  114. {
  115. //[seek lock]
  116. T_RecursiveLocked *v_seek_mutex = m_player_ctx->seekManager();
  117. if(!v_seek_mutex->tryLockForRead())
  118. {
  119. return QByteArray();
  120. }
  121. QReadLocker v_seek_locker(v_seek_mutex);
  122. Q_UNUSED(v_seek_locker);
  123. v_seek_mutex->unlock();
  124. //
  125. if(!m_player_ctx->m_stopwatch.isActive())
  126. {
  127. return QByteArray();
  128. }
  129. //
  130. if(m_player_ctx->m_audio.packet_queue.size()>0 && m_player_ctx->m_audio.packet_queue.head()->isNull())
  131. {
  132. //m_player_ctx->m_audio.packet_queue.dequeue();
  133. return QByteArray();
  134. }
  135. //[left_len, read_len]
  136. qint64 read_len = 0;
  137. QByteArray v_result;
  138. if(need_len>0 && m_player_ctx->m_audio.packet_queue.size()>0)
  139. {
  140. QSharedPointer<T_AV_Packet> v_head_packet = m_player_ctx->m_audio.packet_queue.head();
  141. m_base_bytes = m_out_read_size + prec_len;
  142. m_base_msecs = v_head_packet->timing();
  143. }
  144. while(need_len>0 && m_player_ctx->m_audio.packet_queue.size()>0)
  145. {
  146. QSharedPointer<T_AV_Packet> v_head_packet = m_player_ctx->m_audio.packet_queue.head();
  147. QByteArray v_audio_byes = v_head_packet->decodeAudio();
  148. need_len -= v_audio_byes.size();
  149. read_len += v_audio_byes.size();
  150. v_result.append(v_audio_byes);
  151. /*delete*/ m_player_ctx->m_audio.packet_queue.dequeue();
  152. }
  153. //qDebug() << "[Generator::p_readPacket()]" << "read_len" << v_result.size();
  154. Q_ASSERT(read_len==v_result.size());
  155. // v_result.size() might exceed wanted_len.
  156. return v_result;
  157. }
  158. QByteArray T_Generator::p_pop_front(QByteArray &a_bytes, int a_maxlen)
  159. {
  160. int v_len = qMin(a_maxlen, a_bytes.size());
  161. QByteArray v_pop = a_bytes.left(v_len);
  162. a_bytes = a_bytes.right(a_bytes.size()-v_len);
  163. return v_pop;
  164. }
  165. QByteArray T_Generator::p_pop_back(QByteArray &a_bytes, int a_maxlen)
  166. {
  167. int v_len = qMin(a_maxlen, a_bytes.size());
  168. QByteArray v_pop = a_bytes.right(v_len);
  169. a_bytes = a_bytes.left(a_bytes.size()-v_len);
  170. return v_pop;
  171. }