1
0

header_mpg.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include <windows.h>
  2. #include "header_mpg.h"
  3. #include <bfc/platform/types.h>
  4. static int frameratecode2framerate[16] = {
  5. 0,
  6. // Official mpeg1/2 framerates:
  7. 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001, 60*10000,
  8. // libmpeg3's "Unofficial economy rates":
  9. 1*10000,5*10000,10*10000,12*10000,15*10000,0,0
  10. };
  11. static const int gaSampleRate[3][4] =
  12. {
  13. {44100, 48000, 32000, 0}, // MPEG-1
  14. {22050, 24000, 16000, 0}, // MPEG-2
  15. {11025, 12000, 8000, 0}, // MPEG-2.5
  16. };
  17. static const int gaBitrate[2][3][15] =
  18. {
  19. {
  20. // MPEG-1
  21. { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448}, // Layer 1
  22. { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384}, // Layer 2
  23. { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}, // Layer 3
  24. },
  25. {
  26. // MPEG-2, MPEG-2.5
  27. { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, // Layer 1
  28. { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, // Layer 2
  29. { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, // Layer 3
  30. },
  31. };
  32. #define MPEG_SYNCWORD 0x7ff
  33. #define MPEG1 0
  34. #define MPEG2 1
  35. #define MPEG25 2
  36. #define MODE_MONO 3
  37. HeaderMpg::HeaderMpg() : fh(INVALID_HANDLE_VALUE)
  38. {
  39. memset(buf, 0, sizeof(buf));
  40. pbuf = end = 0;
  41. m_BitrateNdx = m_SampleRateNdx = m_Layer = m_Id = m_Mode =
  42. m_Idex = video_bitrate = audio_bitrate = 0;
  43. }
  44. int HeaderMpg::mp3headerFromInt(unsigned long dwHdrBits)
  45. {
  46. // header fields
  47. int m_Syncword;
  48. /*int m_CrcCheck;
  49. int m_Padding;
  50. int m_Private;
  51. int m_ModeExt;
  52. int m_Copyright;
  53. int m_Original;
  54. int m_Emphasis;*/
  55. // calculated data
  56. int m_HeaderValid;
  57. // read header fields
  58. m_Syncword = (dwHdrBits >> 21) & 0x000007ff;
  59. m_Idex = (dwHdrBits >> 20) & 0x00000001;
  60. m_Id = (dwHdrBits >> 19) & 0x00000001;
  61. m_Layer = 4 -((dwHdrBits >> 17) & 0x00000003);
  62. //m_CrcCheck = !((dwHdrBits >> 16) & 0x00000001);
  63. m_BitrateNdx = (dwHdrBits >> 12) & 0x0000000f;
  64. m_SampleRateNdx = (dwHdrBits >> 10) & 0x00000003;
  65. /*m_Padding = (dwHdrBits >> 9) & 0x00000001;
  66. m_Private = (dwHdrBits >> 8) & 0x00000001;*/
  67. m_Mode = (dwHdrBits >> 6) & 0x00000003;
  68. /*m_ModeExt = (dwHdrBits >> 4) & 0x00000003;
  69. m_Copyright = (dwHdrBits >> 3) & 0x00000001;
  70. m_Original = (dwHdrBits >> 2) & 0x00000001;
  71. m_Emphasis = (dwHdrBits ) & 0x00000003;*/
  72. // check if header is valid
  73. /* if (
  74. (m_Syncword != MPEG_SYNCWORD) ||
  75. #ifndef SYNC_ALL_LAYERS
  76. (m_Layer != 3 ) ||
  77. #else
  78. (m_Layer == 4 ) ||
  79. #endif
  80. (m_BitrateNdx == 15 ) ||
  81. (m_BitrateNdx == 0 ) ||
  82. (m_SampleRateNdx == 3 ) ||
  83. (m_Idex == 0 && m_Layer != 3 ) ||
  84. (m_Idex == 0 && m_Id == 1 && m_Layer == 3)
  85. )*/
  86. if (
  87. (m_Syncword != MPEG_SYNCWORD) ||
  88. (m_Layer == 4 ) ||
  89. (m_BitrateNdx == 15 ) ||
  90. (m_BitrateNdx == 0 ) ||
  91. (m_SampleRateNdx == 3 ) ||
  92. (m_Idex == 0 && m_Layer != 3 ) ||
  93. (m_Idex == 0 && m_Id == 1 ) ||
  94. (m_Idex == 0 && m_BitrateNdx>8 )
  95. )
  96. {
  97. m_HeaderValid = 0;
  98. // ResetMembers();
  99. }
  100. else
  101. {
  102. m_HeaderValid = 1;
  103. // SetMembers();
  104. }
  105. return m_HeaderValid;
  106. }
  107. static __int64 FileSize64(HANDLE file)
  108. {
  109. LARGE_INTEGER position;
  110. position.QuadPart=0;
  111. position.LowPart = GetFileSize(file, (LPDWORD)&position.HighPart);
  112. if (position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
  113. return INVALID_FILE_SIZE;
  114. else
  115. return position.QuadPart;
  116. }
  117. int HeaderMpg::getInfos(const wchar_t *filename, bool metadata)
  118. {
  119. fh = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  120. if(fh==INVALID_HANDLE_VALUE) return 0;
  121. int ret=decodeHeader();
  122. if(ret) {
  123. int l=MulDiv(video_bitrate+audio_bitrate,2048,2018);
  124. l/=8;
  125. int64_t flen = FileSize64(fh);
  126. if(l)
  127. length=(int)((flen*1000ull) / (int64_t)l);
  128. }
  129. CloseHandle(fh);
  130. return ret;
  131. }
  132. int HeaderMpg::decodeHeader()
  133. {
  134. DWORD bytesRead = 0;
  135. memset(buf,0,sizeof(buf));
  136. end=buf+sizeof(buf);
  137. ReadFile(fh, &buf, sizeof(buf), &bytesRead, NULL);
  138. pbuf=buf;
  139. while(1) {
  140. int code;
  141. code=sync_packet();
  142. if(!code) return 1;
  143. switch(code) {
  144. case 0x1b3: {
  145. if(has_video) break;
  146. pbuf+=4;
  147. if ((pbuf[6] & 0x20) != 0x20){
  148. //printf("missing marker bit!\n");
  149. //return 1; /* missing marker_bit */
  150. break;
  151. }
  152. int height = (pbuf[0] << 16) | (pbuf[1] << 8) | pbuf[2];
  153. video_w = (height >> 12);
  154. video_h = (height & 0xfff);
  155. int width = ((height >> 12) + 15) & ~15;
  156. height = ((height & 0xfff) + 15) & ~15;
  157. if ((width > 768) || (height > 576)){
  158. //printf("size restrictions for MP@ML or MPEG1 exceeded! (%dx%d)\n",width,height);
  159. // return 1; /* size restrictions for MP@ML or MPEG1 */
  160. break;
  161. }
  162. has_video=true;
  163. int bitrate=(pbuf[4]<<10)|(pbuf[5]<<2)|(pbuf[6]>>6);
  164. if(bitrate==262143) {
  165. //variable bitrate
  166. //has_video=false;
  167. break;
  168. }
  169. bitrate=bitrate*2/5;
  170. video_bitrate=bitrate*1000;
  171. break;
  172. }
  173. case 0x1be: {
  174. // padding stream
  175. pbuf+=4;
  176. int s=pbuf[0]<<8|pbuf[1];
  177. pbuf+=2+s;
  178. break;
  179. }
  180. }
  181. if(code>=0x1c0 && code<=0x1df) {
  182. pbuf+=4;
  183. int len=pbuf[0]<<8|pbuf[1];
  184. pbuf+=2;
  185. pbuf+=5;
  186. if (len > (end-pbuf))
  187. return 0;
  188. // decode mpeg audio header
  189. while(--len) {
  190. if(mp3headerFromInt((pbuf[0]<<24)|(pbuf[1]<<16)|(pbuf[2]<<8)|pbuf[3])) {
  191. has_audio=true;
  192. audio_bps=16;
  193. int m_MpegVersion = m_Id==1 ? MPEG1 : (m_Idex==1?MPEG2 : MPEG25);
  194. audio_nch = m_Mode == MODE_MONO ? 1:2;
  195. audio_srate = gaSampleRate[m_MpegVersion][m_SampleRateNdx];
  196. audio_bitrate = gaBitrate[m_MpegVersion==MPEG1?0:1][m_Layer-1][m_BitrateNdx] * 1000;
  197. break;
  198. }
  199. pbuf++;
  200. }
  201. }
  202. if(has_audio && has_video) return 1;
  203. pbuf++;
  204. }
  205. return 1;
  206. }