oggpacket.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:5k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: oggpacket.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "vorbis.h"
  25. #include "tremor/ogg.h"
  26. #include "tremor/ivorbiscodec.h"
  27. typedef struct oggpacket
  28. {
  29. codec Codec;
  30. vorbis_info     Info;
  31. vorbis_comment  Comment;
  32. ogg_reference OggRef;
  33. ogg_buffer OggBuffer;
  34. ogg_packet      OggPacket;
  35. } oggpacket;
  36. static bool_t SynthesisHeader(oggpacket* p)
  37. {
  38. ++p->OggPacket.packetno;
  39. p->OggPacket.b_o_s = p->OggPacket.packetno == 0;
  40. p->OggPacket.bytes = p->OggPacket.packet->length;
  41. return vorbis_synthesis_headerin(&p->Info,&p->Comment,&p->OggPacket) >= 0;
  42. }
  43. static int Process( oggpacket* p, const packet* Packet, const flowstate* State )
  44. {
  45. if (Packet)
  46. {
  47. p->OggBuffer.data = (uint8_t*)Packet->Data[0];
  48. p->OggPacket.bytes = p->OggRef.length = p->OggBuffer.size = Packet->Length;
  49. ++p->OggPacket.packetno;
  50. p->Codec.Packet.RefTime = Packet->RefTime;
  51. p->Codec.Packet.Key = Packet->Key;
  52. Packet = &p->Codec.Packet;
  53. }
  54. return p->Codec.Out.Process(p->Codec.Out.Pin.Node,Packet,State);
  55. }
  56. static int UpdateInput( oggpacket* p )
  57. {
  58. vorbis_comment_clear(&p->Comment);
  59. vorbis_info_clear(&p->Info);
  60. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  61. {
  62. int i,j,n;
  63. if (p->Codec.In.Format.ExtraLength < 1 || !p->Codec.In.Format.Extra)
  64. return ERR_INVALID_DATA;
  65. p->Codec.Packet.Data[0] = &p->OggPacket;
  66. p->Codec.Packet.Length = sizeof(p->OggPacket);
  67. vorbis_info_init(&p->Info);
  68. vorbis_comment_init(&p->Comment);
  69. memset(&p->OggPacket,0,sizeof(ogg_packet));
  70. p->OggBuffer.data = (uint8_t*) p->Codec.In.Format.Extra;
  71. p->OggBuffer.size = p->Codec.In.Format.ExtraLength;
  72. p->OggBuffer.refcount = 1;
  73. p->OggRef.buffer = &p->OggBuffer;
  74. p->OggRef.next = NULL;
  75. p->OggPacket.packet = &p->OggRef;
  76. p->OggPacket.packetno = -1; 
  77. n = p->OggBuffer.data[0];
  78. i = 1+n;
  79. j = 1;
  80. while (p->OggPacket.packetno < 3 && n>=j)
  81. {
  82. p->OggRef.begin = i;
  83. p->OggRef.length = 0;
  84. do
  85. {
  86. p->OggRef.length += p->OggBuffer.data[j];
  87. }
  88. while (p->OggBuffer.data[j++] == 255 && n>=j);
  89. i += p->OggRef.length;
  90. if (i > p->OggBuffer.size)
  91. return ERR_INVALID_DATA;
  92. if (!SynthesisHeader(p) && p->OggPacket.packetno==0)
  93. return ERR_INVALID_DATA;
  94. }
  95. if (p->OggPacket.packetno < 3)
  96. {
  97. p->OggRef.begin = i;
  98. p->OggRef.length = p->OggBuffer.size - i; 
  99. SynthesisHeader(p);
  100. }
  101. if (p->Codec.Comment.Node)
  102. for (i=0;i<p->Comment.comments;++i)
  103. {
  104. tchar_t Comment[256];
  105. StrToTcs(Comment,TSIZEOF(Comment),p->Comment.user_comments[i]);
  106. p->Codec.Comment.Node->Set(p->Codec.Comment.Node,p->Codec.Comment.No,Comment,sizeof(Comment));
  107. }
  108. PacketFormatClear(&p->Codec.Out.Format);
  109. p->Codec.Out.Format.Type = PACKET_AUDIO;
  110. p->Codec.Out.Format.Format.Audio.Format = AUDIOFMT_VORBIS_INTERNAL_VIDEO;
  111. p->Codec.Out.Format.Extra = &p->Info;
  112. p->Codec.Out.Format.ExtraLength = -1;
  113. p->Codec.In.Format.ByteRate = p->Codec.Out.Format.ByteRate = p->Info.bitrate_nominal >> 3;
  114. p->Codec.In.Format.Format.Audio.SampleRate = p->Codec.Out.Format.Format.Audio.SampleRate = p->Info.rate;
  115. p->Codec.In.Format.Format.Audio.Channels = p->Codec.Out.Format.Format.Audio.Channels = p->Info.channels;
  116. p->OggPacket.b_o_s = 0;
  117. p->OggPacket.packetno = 0;
  118. p->OggRef.begin = 0;
  119. p->Codec.In.Process = (packetprocess)Process;
  120. }
  121. return ERR_NONE;
  122. }
  123. static int Create(oggpacket* p)
  124. {
  125. p->Codec.UseComment = 1;
  126. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  127. return ERR_NONE;
  128. }
  129. static const nodedef OGGPacket =
  130. {
  131. sizeof(oggpacket),
  132. OGGPACKET_ID,
  133. CODEC_CLASS,
  134. PRI_DEFAULT,
  135. (nodecreate)Create,
  136. };
  137. void OGGPacket_Init()
  138. {
  139. NodeRegisterClass(&OGGPacket);
  140. }
  141. void OGGPacket_Done()
  142. {
  143. NodeUnRegisterClass(OGGPACKET_ID);
  144. }