static PyObject * py_ogg_ogg_page_packets(PyObject *self, PyObject *args) { int size; int c_out; ogg_page * og; PyArg_ParseTuple(args, "s#", &og, &size); c_out = ogg_page_packets(og); return Py_BuildValue("i", c_out); };
static ChainState * validate_ogg_page (ogg_page * page) { gulong serialno; gint64 granule; ChainState *state; serialno = ogg_page_serialno (page); granule = ogg_page_granulepos (page); state = g_hash_table_lookup (eos_chain_states, GINT_TO_POINTER (serialno)); fail_if (ogg_page_packets (page) == 0 && granule != -1, "Must have granulepos -1 when page has no packets, has %" G_GINT64_FORMAT, granule); if (ogg_page_bos (page)) { fail_unless (state == NULL, "Extraneous BOS flag on chain %u", serialno); state = g_new0 (ChainState, 1); g_hash_table_insert (eos_chain_states, GINT_TO_POINTER (serialno), state); state->serialno = serialno; state->last_granule = granule; state->codec = get_page_codec (page); /* check for things like BOS ordering, etc */ switch (state->codec) { case CODEC_THEORA: /* check we have no vorbis/speex chains yet */ g_hash_table_foreach (eos_chain_states, (GHFunc) fail_if_audio, NULL); break; case CODEC_VORBIS: case CODEC_SPEEX: /* no checks (yet) */ break; case CODEC_UNKNOWN: default: break; } } else if (ogg_page_eos (page)) { fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno); state->eos = TRUE; } else { fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno); fail_unless (!state->eos, "Data after EOS flag on chain %u", serialno); } if (granule != -1) { fail_unless (granule >= state->last_granule, "Granulepos out-of-order for chain %u: old=%" G_GINT64_FORMAT ", new=" G_GINT64_FORMAT, serialno, state->last_granule, granule); state->last_granule = granule; } return state; }
void SndSysSpeexSoundData::Initialize() { ogg_sync_state oy; ogg_page og; ogg_packet op; ogg_stream_state os; // Process enough to get the header. ogg_sync_init(&oy); oy.data = m_DataStore.data; oy.storage = (int)m_DataStore.length; ogg_sync_wrote(&oy, (long)m_DataStore.length); ogg_sync_pageout(&oy, &og); ogg_stream_init(&os, ogg_page_serialno(&og)); ogg_stream_pagein(&os, &og); ogg_stream_packetout(&os, &op); SpeexHeader* header = speex_packet_to_header((char*)op.packet, op.bytes); m_SoundFormat.Channels = header->nb_channels; m_SoundFormat.Freq = header->rate; // Is there a better way to do this? // Get number of packets (-1 as the second contains misc info). int count = -1; while(ogg_sync_pageout(&oy, &og)==1) { ogg_stream_pagein(&os, &og); count += ogg_page_packets(&og); } m_FrameCount = header->frames_per_packet * count; // Free memory. speex_header_free(header); ogg_stream_clear(&os); // No need to call this again. m_bInfoReady=true; }
void CAOggFLACDecoder::InPacket(const void* inInputData, const AudioStreamPacketDescription* inPacketDescription) { if (!mCompressionInitialized) CODEC_THROW(kAudioCodecUnspecifiedError); ogg_page op; if (!WrapOggPage(&op, inInputData, inPacketDescription->mDataByteSize + inPacketDescription->mStartOffset, inPacketDescription->mStartOffset)) CODEC_THROW(kAudioCodecUnspecifiedError); dbg_printf("[ oFD] : [%08lx] InPacket() [%4.4s] %ld\n", (UInt32) this, (char *) (static_cast<const Byte*> (inInputData) + inPacketDescription->mStartOffset), ogg_page_pageno(&op)); ogg_packet opk; SInt32 packet_count = 0; int oret; AudioStreamPacketDescription flac_packet_desc = {0, 0, 0}; UInt32 page_packets = ogg_page_packets(&op); ogg_stream_pagein(&mO_st, &op); while ((oret = ogg_stream_packetout(&mO_st, &opk)) != 0) { if (oret < 0) { page_packets--; continue; } packet_count++; flac_packet_desc.mDataByteSize = opk.bytes; CAFLACDecoder::InPacket(opk.packet, &flac_packet_desc); } if (packet_count > 0) complete_pages += 1; mFramesBufferedList.push_back(OggPagePacket(packet_count, inPacketDescription->mVariableFramesInPacket)); }
static void _ready_page(StreamInfoPtr si) { UInt32 len = si->og.header_len + si->og.body_len; Float64 pos; if (si->og_buffer_size < len) { si->og_buffer = realloc(si->og_buffer, len); si->og_buffer_size = len; } BlockMoveData(si->og.header, si->og_buffer, si->og.header_len); BlockMoveData(si->og.body, si->og_buffer + si->og.header_len, si->og.body_len); si->og.header = si->og_buffer; si->og.body = si->og_buffer + si->og.header_len; si->og_ready = true; si->acc_packets -= ogg_page_packets(&si->og); if (ogg_page_granulepos(&si->og) != -1) { si->og_grpos = ogg_page_granulepos(&si->og); if (si->si_v.grpos_shift > 0) { /* with theora, si->og_grpos represents total number of frames */ ogg_int64_t frames = si->og_grpos >> si->si_v.grpos_shift; si->og_grpos = frames + si->og_grpos - (frames << si->si_v.grpos_shift); }
static int spx_read_header (SF_PRIVATE * psf) { static SpeexStereoState STEREO_INIT = SPEEX_STEREO_STATE_INIT ; OGG_PRIVATE* odata = psf->container_data ; SPX_PRIVATE* spx = psf->codec_data ; ogg_int64_t page_granule = 0 ; int stream_init = 0 ; int page_nb_packets = 0 ; int packet_count = 0 ; int enh_enabled = 1 ; int force_mode = -1 ; char * data ; int nb_read ; int lookahead ; printf ("%s %d\n", __func__, __LINE__) ; psf_log_printf (psf, "Speex header\n") ; odata->eos = 0 ; /* Reset ogg stuff which has already been used in src/ogg.c. */ ogg_stream_reset (&odata->ostream) ; ogg_sync_reset (&odata->osync) ; /* Seek to start of stream. */ psf_fseek (psf, 0, SEEK_SET) ; /* Initialize. */ ogg_sync_init (&odata->osync) ; speex_bits_init (&spx->bits) ; /* Set defaults. */ psf->sf.channels = -1 ; psf->sf.samplerate = 0 ; spx->stereo = STEREO_INIT ; /* Get a pointer to the ogg buffer and read data into it. */ data = ogg_sync_buffer (&odata->osync, OGG_SPX_READ_SIZE) ; nb_read = psf_fread (data, 1, OGG_SPX_READ_SIZE, psf) ; ogg_sync_wrote (&odata->osync, nb_read) ; /* Now we chew on Ogg packets. */ while (ogg_sync_pageout (&odata->osync, &odata->opage) == 1) { if (stream_init == 0) { ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ; stream_init = 1 ; } ; if (ogg_page_serialno (&odata->opage) != odata->ostream.serialno) { /* so all streams are read. */ ogg_stream_reset_serialno (&odata->ostream, ogg_page_serialno (&odata->opage)) ; } ; /*Add page to the bitstream*/ ogg_stream_pagein (&odata->ostream, &odata->opage) ; page_granule = ogg_page_granulepos (&odata->opage) ; page_nb_packets = ogg_page_packets (&odata->opage) ; /*Extract all available packets*/ while (odata->eos == 0 && ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1) { if (odata->opacket.bytes >= 8 && memcmp (odata->opacket.packet, "Speex ", 8) == 0) { spx->serialno = odata->ostream.serialno ; } ; if (spx->serialno == -1 || odata->ostream.serialno != spx->serialno) break ; if (packet_count == 0) { spx->state = spx_header_read (psf, &odata->opacket, enh_enabled, force_mode) ; if (! spx->state) break ; speex_decoder_ctl (spx->state, SPEEX_GET_LOOKAHEAD, &lookahead) ; if (spx->nframes == 0) spx->nframes = 1 ; } else if (packet_count == 1) { spx_print_comments ((const char*) odata->opacket.packet, odata->opacket.bytes) ; } else if (packet_count < 2 + spx->header.extra_headers) { /* Ignore extra headers */ } packet_count ++ ; } ; } ; psf_log_printf (psf, "End\n") ; psf_log_printf (psf, "packet_count %d\n", packet_count) ; psf_log_printf (psf, "page_nb_packets %d\n", page_nb_packets) ; psf_log_printf (psf, "page_granule %lld\n", page_granule) ; return 0 ; } /* spx_read_header */
int main(int argc, char **argv) { int c; int option_index = 0; char *inFile, *outFile; FILE *fin, *fout=NULL; short out[MAX_FRAME_SIZE]; short output[MAX_FRAME_SIZE]; int frame_size=0, granule_frame_size=0; void *st=NULL; CELTMode *mode=NULL; int packet_count=0; int stream_init = 0; int quiet = 0; ogg_int64_t page_granule=0, last_granule=0; int skip_samples=0, page_nb_packets; struct option long_options[] = { {"help", no_argument, NULL, 0}, {"quiet", no_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"version-short", no_argument, NULL, 0}, {"rate", required_argument, NULL, 0}, {"mono", no_argument, NULL, 0}, {"stereo", no_argument, NULL, 0}, {"packet-loss", required_argument, NULL, 0}, {0, 0, 0, 0} }; ogg_sync_state oy; ogg_page og; ogg_packet op; ogg_stream_state os; int enh_enabled; int nframes=2; int print_bitrate=0; int close_in=0; int eos=0; int forceMode=-1; int audio_size=0; float loss_percent=-1; int channels=-1; int rate=0; int extra_headers=0; int wav_format=0; int lookahead=0; int celt_serialno = -1; int firstpacket = 1; enh_enabled = 1; /*Process options*/ while(1) { c = getopt_long (argc, argv, "hvV", long_options, &option_index); if (c==-1) break; switch(c) { case 0: if (strcmp(long_options[option_index].name,"help")==0) { usage(); exit(0); } else if (strcmp(long_options[option_index].name,"quiet")==0) { quiet = 1; } else if (strcmp(long_options[option_index].name,"version")==0) { version(); exit(0); } else if (strcmp(long_options[option_index].name,"version-short")==0) { version_short(); exit(0); } else if (strcmp(long_options[option_index].name,"mono")==0) { channels=1; } else if (strcmp(long_options[option_index].name,"stereo")==0) { channels=2; } else if (strcmp(long_options[option_index].name,"rate")==0) { rate=atoi (optarg); } else if (strcmp(long_options[option_index].name,"packet-loss")==0) { loss_percent = atof(optarg); } break; case 'h': usage(); exit(0); break; case 'v': version(); exit(0); break; case 'V': print_bitrate=1; break; case '?': usage(); exit(1); break; } } if (argc-optind!=2 && argc-optind!=1) { usage(); exit(1); } inFile=argv[optind]; if (argc-optind==2) outFile=argv[optind+1]; else outFile = ""; wav_format = strlen(outFile)>=4 && ( strcmp(outFile+strlen(outFile)-4,".wav")==0 || strcmp(outFile+strlen(outFile)-4,".WAV")==0); /*Open input file*/ if (strcmp(inFile, "-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif fin=stdin; } else { fin = fopen(inFile, "rb"); if (!fin) { perror(inFile); exit(1); } close_in=1; } /*Init Ogg data struct*/ ogg_sync_init(&oy); /*Main decoding loop*/ while (1) { char *data; int i, nb_read; /*Get the ogg buffer for writing*/ data = ogg_sync_buffer(&oy, 200); /*Read bitstream from input file*/ nb_read = fread(data, sizeof(char), 200, fin); ogg_sync_wrote(&oy, nb_read); /*Loop for all complete pages we got (most likely only one)*/ while (ogg_sync_pageout(&oy, &og)==1) { if (stream_init == 0) { ogg_stream_init(&os, ogg_page_serialno(&og)); stream_init = 1; } if (ogg_page_serialno(&og) != os.serialno) { /* so all streams are read. */ ogg_stream_reset_serialno(&os, ogg_page_serialno(&og)); } /*Add page to the bitstream*/ ogg_stream_pagein(&os, &og); page_granule = ogg_page_granulepos(&og); page_nb_packets = ogg_page_packets(&og); if (page_granule>0 && frame_size) { /* FIXME: shift the granule values if --force-* is specified */ skip_samples = frame_size*(page_nb_packets*granule_frame_size*nframes - (page_granule-last_granule))/granule_frame_size; if (ogg_page_eos(&og)) skip_samples = -skip_samples; /*else if (!ogg_page_bos(&og)) skip_samples = 0;*/ } else { skip_samples = 0; } /*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/ last_granule = page_granule; /*Extract all available packets*/ while (!eos && ogg_stream_packetout(&os, &op) == 1 && op.bytes>=8) { if (!memcmp(op.packet, "CELT ", 8)) { celt_serialno = os.serialno; } if (celt_serialno == -1 || os.serialno != celt_serialno) break; /*If first packet, process as CELT header*/ if (packet_count==0) { st = process_header(&op, enh_enabled, &frame_size, &granule_frame_size, &rate, &nframes, forceMode, &channels, &lookahead, &extra_headers, quiet, &mode); if (!st) exit(1); if (!nframes) nframes=1; fout = out_file_open(outFile, rate, &channels); } else if (packet_count==1) { if (!quiet) print_comments((char*)op.packet, op.bytes); } else if (packet_count<=1+extra_headers) { /* Ignore extra headers */ } else { int lost=0; if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent) lost=1; /*End of stream condition*/ if (op.e_o_s && os.serialno == celt_serialno) /* don't care for anything except celt eos */ eos=1; { int ret; /*Decode frame*/ if (!lost) ret = celt_decode(st, (unsigned char*)op.packet, op.bytes, output); else ret = celt_decode(st, NULL, 0, output); /*for (i=0;i<frame_size*channels;i++) printf ("%d\n", (int)output[i]);*/ if (ret!=0) { fprintf (stderr, "Decoding error: corrupted stream?\n"); break; } if (print_bitrate) { celt_int32 tmp=op.bytes; char ch=13; fputc (ch, stderr); fprintf (stderr, "Bitrate in use: %d bytes/packet ", tmp); } /*Convert to short and save to output file*/ if (strlen(outFile)!=0) { for (i=0;i<frame_size*channels;i++) out[i]=le_short(output[i]); } else { for (i=0;i<frame_size*channels;i++) out[i]=output[i]; } { int frame_offset = 0; int new_frame_size = frame_size; /*printf ("packet %d %d\n", packet_no, skip_samples);*/ /*fprintf (stderr, "packet %d %d %d\n", packet_no, skip_samples, lookahead);*/ if (firstpacket == 1) { /*printf ("chopping first packet\n");*/ new_frame_size -= lookahead; frame_offset = lookahead; firstpacket = 0; } if (new_frame_size>0) { #if defined WIN32 || defined _WIN32 if (strlen(outFile)==0) WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels); else #endif fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout); audio_size+=sizeof(short)*new_frame_size*channels; } } } } packet_count++; } } if (feof(fin)) break; } if (fout && wav_format) { if (fseek(fout,4,SEEK_SET)==0) { int tmp; tmp = le_int(audio_size+36); fwrite(&tmp,4,1,fout); if (fseek(fout,32,SEEK_CUR)==0) { tmp = le_int(audio_size); fwrite(&tmp,4,1,fout); } else { fprintf (stderr, "First seek worked, second didn't\n"); } } else { fprintf (stderr, "Cannot seek on wave file, size will be incorrect\n"); } } if (st) { celt_decoder_destroy(st); celt_mode_destroy(mode); } else { fprintf (stderr, "This doesn't look like a CELT file\n"); } if (stream_init) ogg_stream_clear(&os); ogg_sync_clear(&oy); #if defined WIN32 || defined _WIN32 if (strlen(outFile)==0) WIN_Audio_close (); #endif if (close_in) fclose(fin); if (fout != NULL) fclose(fout); return 0; }
int writeFrame(uint8_t *framePcmBytes, unsigned int frameByteCount) { int cur_frame_size = frame_size; _packetId++; opus_int32 nb_samples = frameByteCount / 2; total_samples += nb_samples; if (nb_samples < frame_size) { op.e_o_s = 1; } else { op.e_o_s = 0; } int nbBytes = 0; if (nb_samples != 0) { uint8_t *paddedFrameBytes = framePcmBytes; int freePaddedFrameBytes = 0; if (nb_samples < cur_frame_size) { paddedFrameBytes = malloc(cur_frame_size * 2); freePaddedFrameBytes = 1; memcpy(paddedFrameBytes, framePcmBytes, frameByteCount); memset(paddedFrameBytes + nb_samples * 2, 0, cur_frame_size * 2 - nb_samples * 2); } nbBytes = opus_encode(_encoder, (opus_int16 *)paddedFrameBytes, cur_frame_size, _packet, max_frame_bytes / 10); if (freePaddedFrameBytes) { free(paddedFrameBytes); paddedFrameBytes = NULL; } if (nbBytes < 0) { LOGE("Encoding failed: %s. Aborting.", opus_strerror(nbBytes)); return 0; } enc_granulepos += cur_frame_size * 48000 / coding_rate; size_segments = (nbBytes + 255) / 255; min_bytes = min(nbBytes, min_bytes); } while ((((size_segments <= 255) && (last_segments + size_segments > 255)) || (enc_granulepos - last_granulepos > max_ogg_delay)) && ogg_stream_flush_fill(&os, &og, 255 * 255)) { if (ogg_page_packets(&og) != 0) { last_granulepos = ogg_page_granulepos(&og); } last_segments -= og.header[26]; int writtenPageBytes = writeOggPage(&og, _fileOs); if (writtenPageBytes != og.header_len + og.body_len) { LOGE("Error: failed writing data to output stream"); return 0; } bytes_written += writtenPageBytes; pages_out++; } op.packet = (unsigned char *)_packet; op.bytes = nbBytes; op.b_o_s = 0; op.granulepos = enc_granulepos; if (op.e_o_s) { op.granulepos = ((total_samples * 48000 + rate - 1) / rate) + header.preskip; } op.packetno = 2 + _packetId; ogg_stream_packetin(&os, &op); last_segments += size_segments; while ((op.e_o_s || (enc_granulepos + (frame_size * 48000 / coding_rate) - last_granulepos > max_ogg_delay) || (last_segments >= 255)) ? ogg_stream_flush_fill(&os, &og, 255 * 255) : ogg_stream_pageout_fill(&os, &og, 255 * 255)) { if (ogg_page_packets(&og) != 0) { last_granulepos = ogg_page_granulepos(&og); } last_segments -= og.header[26]; int writtenPageBytes = writeOggPage(&og, _fileOs); if (writtenPageBytes != og.header_len + og.body_len) { LOGE("Error: failed writing data to output stream"); return 0; } bytes_written += writtenPageBytes; pages_out++; } return 1; }
int AudioStreamPlaybackSpeex::mix(int16_t *p_buffer, int p_frames) { //printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs); //printf("playing %i, paused %i\n", (int)playing, (int)paused); if (!active || !playing || !data.size()) return 0; /* if (read_ofs >= data.size()) { if (loops) { reload(); ++loop_count; } else { return; }; }; */ int todo = p_frames; if (todo < page_size) { return 0; }; int eos = 0; while (todo > page_size) { int ret = 0; while ((todo > page_size && packets_available && !eos) || (ret = ogg_sync_pageout(&oy, &og)) == 1) { if (!packets_available) { /*Add page to the bitstream*/ ogg_stream_pagein(&os, &og); page_granule = ogg_page_granulepos(&og); page_nb_packets = ogg_page_packets(&og); packet_no = 0; if (page_granule > 0 && frame_size) { skip_samples = page_nb_packets * frame_size * nframes - (page_granule - last_granule); if (ogg_page_eos(&og)) skip_samples = -skip_samples; /*else if (!ogg_page_bos(&og)) skip_samples = 0;*/ } else { skip_samples = 0; } last_granule = page_granule; packets_available = true; } /*Extract all available packets*/ while (todo > page_size && !eos) { if (ogg_stream_packetout(&os, &op) != 1) { packets_available = false; break; } packet_no++; /*End of stream condition*/ if (op.e_o_s) eos = 1; /*Copy Ogg packet to Speex bitstream*/ speex_bits_read_from(&bits, (char *)op.packet, op.bytes); for (int j = 0; j != nframes; j++) { int16_t *out = p_buffer; int ret; /*Decode frame*/ ret = speex_decode_int(st, &bits, out); /*for (i=0;i<frame_size*channels;i++) printf ("%d\n", (int)output[i]);*/ if (ret == -1) { printf("decode returned -1\n"); break; }; if (ret == -2) { OS::get_singleton()->printerr("Decoding error: corrupted stream?\n"); break; } if (speex_bits_remaining(&bits) < 0) { OS::get_singleton()->printerr("Decoding overflow: corrupted stream?\n"); break; } //if (channels==2) // speex_decode_stereo_int(output, frame_size, &stereo); /*Convert to short and save to output file*/ for (int i = 0; i < frame_size * stream_channels; i++) { out[i] = le_short(out[i]); } { int new_frame_size = frame_size; /*printf ("packet %d %d\n", packet_no, skip_samples);*/ if (packet_no == 1 && j == 0 && skip_samples > 0) { /*printf ("chopping first packet\n");*/ new_frame_size -= skip_samples; } if (packet_no == page_nb_packets && skip_samples < 0) { int packet_length = nframes * frame_size + skip_samples; new_frame_size = packet_length - j * frame_size; if (new_frame_size < 0) new_frame_size = 0; if (new_frame_size > frame_size) new_frame_size = frame_size; /*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/ } p_buffer += new_frame_size * stream_channels; todo -= new_frame_size; } } }; }; //todo = get_todo(); //todo is still greater than page size, can write more if (todo > page_size || eos) { if (read_ofs < data.size()) { //char *buf; int nb_read = MIN(data.size() - read_ofs, READ_CHUNK); /*Get the ogg buffer for writing*/ char *ogg_dst = ogg_sync_buffer(&oy, nb_read); /*Read bitstream from input file*/ copymem(ogg_dst, &data[read_ofs], nb_read); read_ofs += nb_read; ogg_sync_wrote(&oy, nb_read); } else { if (loops) { reload(); ++loop_count; //break; } else { playing = false; unload(); break; }; } }; }; return p_frames - todo; };
void AudioStreamPlaybackSpeex::reload() { if (active) unload(); if (!data.size()) return; ogg_sync_init(&oy); speex_bits_init(&bits); read_ofs = 0; // char *buf; int packet_count = 0; int extra_headers = 0; int stream_init = 0; page_granule = 0; last_granule = 0; skip_samples = 0; page_nb_packets = 0; packets_available = false; packet_no = 0; int eos = 0; do { /*Get the ogg buffer for writing*/ int nb_read = MIN(data.size() - read_ofs, READ_CHUNK); char *ogg_dst = ogg_sync_buffer(&oy, nb_read); /*Read bitstream from input file*/ copymem(ogg_dst, &data[read_ofs], nb_read); read_ofs += nb_read; ogg_sync_wrote(&oy, nb_read); /*Loop for all complete pages we got (most likely only one)*/ while (ogg_sync_pageout(&oy, &og) == 1) { if (stream_init == 0) { ogg_stream_init(&os, ogg_page_serialno(&og)); stream_init = 1; } /*Add page to the bitstream*/ ogg_stream_pagein(&os, &og); page_granule = ogg_page_granulepos(&og); page_nb_packets = ogg_page_packets(&og); if (page_granule > 0 && frame_size) { skip_samples = page_nb_packets * frame_size * nframes - (page_granule - last_granule); if (ogg_page_eos(&og)) skip_samples = -skip_samples; /*else if (!ogg_page_bos(&og)) skip_samples = 0;*/ } else { skip_samples = 0; } last_granule = page_granule; /*Extract all available packets*/ while (!eos && ogg_stream_packetout(&os, &op) == 1) { /*If first packet, process as Speex header*/ if (packet_count == 0) { int rate = 0; int channels; st = process_header(&op, &frame_size, &rate, &nframes, &channels, &extra_headers); if (!nframes) nframes = 1; if (!st) { unload(); return; }; page_size = nframes * frame_size; stream_srate = rate; stream_channels = channels; stream_minbuff_size = page_size; } else if (packet_count == 1) { } else if (packet_count <= 1 + extra_headers) { /* Ignore extra headers */ }; }; ++packet_count; }; } while (packet_count <= extra_headers); active = true; }
static int init_vorbis(mm_file *mf, ogg_page *pg) { int pkts = 0; int res = 0; int rval = 0; vorbis_block *vo_blk = NULL; vorbis_info *vo_info = NULL; vorbis_comment vo_comm; ogg_packet pkt; ogg_stream_state stream; assert(mf); vo_info = (vorbis_info *)xmalloc(sizeof(*vo_info)); vorbis_info_init(vo_info); vorbis_comment_init(&vo_comm); ogg_stream_init(&stream, ogg_page_serialno(pg)); if (ogg_page_packets(pg) != 1 || ogg_page_granulepos(pg) != 0) { goto end; } if (ogg_stream_pagein(&stream, pg) < 0) /* should not happen */ { goto end; } /* * Three first packets must go successfully through the loop. */ for (pkts = 0; pkts < 3; ++pkts) { while ((res = ogg_stream_packetpeek(&stream, &pkt)) != 1) { if (res < 0 || get_page(mf, pg) <= 0 || ogg_stream_pagein(&stream, pg) < 0) { rval = -1; goto end; } } switch (vorbis_synthesis_headerin(vo_info, &vo_comm, &pkt)) { case 0: break; case OV_EBADHEADER: INFO1("bad vorbis header"); case OV_ENOTVORBIS: default: goto end; } /* decode successful so grab packet */ ogg_stream_packetout(&stream, &pkt); } /* maybe print something about comment or etc? */ mf->audio_ctx = (vorbis_dsp_state *)xmalloc(sizeof(*mf->audio_ctx)); mf->audio = (ogg_stream_state *)xmalloc(sizeof(*mf->audio)); vo_blk = (vorbis_block *)xmalloc(sizeof(*vo_blk)); memcpy(mf->audio, &stream, sizeof(stream)); vorbis_synthesis_init(mf->audio_ctx, vo_info); vorbis_block_init(mf->audio_ctx, vo_blk); mf->audio_info = vo_info; mf->audio_blk = vo_blk; rval = 1; end: vorbis_comment_clear(&vo_comm); if (rval <= 0) { ogg_stream_clear(&stream); vorbis_info_clear(vo_info); free(vo_info); } return rval; }
static int init_theora(mm_file *mf, ogg_page *pg) { int pkts = 0; int res = 0; int rval = 0; theora_info *th_info = NULL; theora_comment th_comm; ogg_packet pkt; ogg_stream_state stream; assert(mf); th_info = (theora_info *)xmalloc(sizeof(*mf->video_info)); theora_info_init(th_info); theora_comment_init(&th_comm); ogg_stream_init(&stream, ogg_page_serialno(pg)); if (ogg_page_packets(pg) != 1 || ogg_page_granulepos(pg) != 0) { goto end; } if (ogg_stream_pagein(&stream, pg)) /* should not happen */ { goto end; } /* Three first packets must go successfully through the loop. */ for (pkts = 0; pkts < 3; ++pkts) { while ((res = ogg_stream_packetpeek(&stream, &pkt)) != 1) { if (res < 0 || get_page(mf, pg) <= 0 || ogg_stream_pagein(&stream, pg) < 0) { rval = -1; goto end; } } switch (theora_decode_header(th_info, &th_comm, &pkt)) { case 0: break; case OC_VERSION: case OC_NEWPACKET: INFO1("incompatible theora file"); /* fall through */ case OC_BADHEADER: default: goto end; } /* decode successful so grab packet */ ogg_stream_packetout(&stream, &pkt); } mf->video_ctx = (theora_state *)xmalloc(sizeof(*mf->video_ctx)); mf->video = (ogg_stream_state *)xmalloc(sizeof(*mf->video)); memcpy(mf->video, &stream, sizeof(stream)); theora_decode_init(mf->video_ctx, th_info); mf->video_info = th_info; rval = 1; end: theora_comment_clear(&th_comm); if (rval <= 0) { ogg_stream_clear(&stream); theora_info_clear(th_info); free(th_info); mf->video_info = NULL; } return rval; }
int main () { ogg_sync_state oy; /* sync and verify incoming physical bitstream */ ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ ogg_packet op; /* one raw packet of data for decode */ struct stream *st = NULL; int r; char *buffer; int bytes; int eos = 0; int i; int bufferSize = 4096; r = ogg_sync_init(&oy); /* Now we can read pages */ assert(r == 0); while (1) { /* we repeat if the bitstream is chained */ /* submit a 4k block to the libogg sync layer */ buffer = ogg_sync_buffer(&oy, bufferSize); bytes = fread(buffer, 1, bufferSize, stdin); if (bytes == 0) { fprintf(stderr, "Got stdin EOF.\n"); r = 0; break; } r = ogg_sync_wrote(&oy, bytes); assert(r == 0); /* Get the first page. */ r = ogg_sync_pageout(&oy, &og); if (r == 0) { fprintf(stderr, "Need more data.\n"); continue; } else if (r < 1) { /* have we simply run out of data? If so, we're done. */ if (bytes < bufferSize) break; /* error case. Must not be Vorbis data */ fprintf(stderr, "Input does not appear to be an Ogg bitstream.\n"); r = 1; break; } assert(r == 1); /* Get the serial number and set up the rest of decode. */ /* serialno first; use it to set up a logical stream */ int serialno = ogg_page_serialno(&og); int packets = ogg_page_packets(&og); fprintf(stderr, "version: %d\n", ogg_page_version(&og)); fprintf(stderr, "continued: %d\n", ogg_page_continued(&og)); fprintf(stderr, "pageno: %ld\n", ogg_page_pageno(&og)); fprintf(stderr, "serialno: %d\n", serialno); fprintf(stderr, "packets: %d\n", packets); fprintf(stderr, "granulepos: %lld\n", ogg_page_granulepos(&og)); fprintf(stderr, "eos: %d\n", ogg_page_eos(&og)); fprintf(stderr, "bos: %d\n", ogg_page_bos(&og)); /* we need to get the correct "ogg_stream_state" struct based on the serialno */ struct stream *s = st; while (1) { if (s == NULL) { fprintf(stderr, "creating struct stream for %d\n", serialno); s = malloc(sizeof(struct stream)); s->next = NULL; s->serialno = serialno; ogg_stream_init(&s->os, serialno); if (st == NULL) { st = s; } else { /* have to set "s" to the last element of the "st" linked list */ struct stream *t = st; while (1) { if (t->next == NULL) { t->next = s; break; } else { t = t->next; } } } break; } if (s->serialno == serialno) { break; } s = s->next; } assert(s->serialno == serialno); fprintf(stderr, "using struct stream %d\n", s->serialno); /* holy shit that sucked... */ if (ogg_stream_pagein(&s->os, &og) < 0) { /* error; stream version mismatch perhaps */ fprintf(stderr, "Error reading page of Ogg bitstream data.\n"); r = 1; break; } /* iterate though the "packets" in the page */ for (i=0; i<packets; i++) { fprintf(stderr, " Reading packet %d.\n", i); r = ogg_stream_packetout(&s->os, &op); fprintf(stderr, " Reading packet result %d.\n", r); if (r != 1) { /* no page? must not be vorbis */ fprintf(stderr, " Error reading packet.\n"); r = 1; break; } /** * At this point, you'd pass the raw packet data to the vorbis decoder or * whatever your destination is.... */ fprintf(stderr, " bytes: %ld\n", op.bytes); fprintf(stderr, " b_o_s: %ld\n", op.b_o_s); fprintf(stderr, " e_o_s: %ld\n", op.e_o_s); fprintf(stderr, " granulepos: %lld\n", op.granulepos); fprintf(stderr, " packetno: %lld\n", op.packetno); } fprintf(stderr, "\n"); } /* OK, clean up the framer */ ogg_sync_clear(&oy); fprintf(stderr,"\nDone.\n"); return r; }
void OggOpusFile::EncodeChunks(void* pcmBuf, int numSamples, bool lastChunk) { int numFrames = numSamples/PCM_SAMPLES_IN_FRAME; bool flush = false; for(int j = 0; j < numFrames; j++) { if(j == (numFrames -1) && (lastChunk == true)) { flush =true; } nb_samples=PCM_SAMPLES_IN_FRAME;//make it 160 id++; int size_segments,cur_frame_size; ////frame_size=160 for 8k cur_frame_size=frame_size; /*Encode current frame*/ //Stereo: each pcm samples will have 2 short samples(L/R interlaced) so the num of bytes for each frame will be double to mono nbBytes=opus_multistream_encode (st, (short*)pcmBuf + (j*PCM_SAMPLES_IN_FRAME*chan), cur_frame_size, m_outBuf, max_frame_bytes); if(nbBytes<0){ fprintf(stderr, "Encoding failed: %s. Aborting.\n", opus_strerror(nbBytes)); return; } nb_encoded+=cur_frame_size; enc_granulepos+=cur_frame_size*48000/coding_rate; total_bytes+=nbBytes; size_segments=(nbBytes+255)/255; peak_bytes=IMAX(nbBytes,peak_bytes); min_bytes=IMIN(nbBytes,min_bytes); //printf("TotalByes:%d\n", total_bytes); /*Flush early if adding this packet would make us end up with a continued page which we wouldn't have otherwise.*/ while((((size_segments<=255)&&(last_segments+size_segments>255))|| (enc_granulepos-last_granulepos>max_ogg_delay)) && ogg_stream_flush_fill(&os, &og,255*255)){ if(ogg_page_packets(&og)!=0) last_granulepos=ogg_page_granulepos(&og); last_segments-=og.header[26]; ret=oe_write_page(&og); if(ret!=og.header_len+og.body_len){ fprintf(stderr,"Error: failed writing data to output stream\n"); exit(1); } bytes_written+=ret; pages_out++; } /*The downside of early reading is if the input is an exact multiple of the frame_size you'll get an extra frame that needs to get cropped off. The downside of late reading is added delay. If your ogg_delay is 120ms or less we'll assume you want the low delay behavior.*/ // if(max_ogg_delay>5760){ // nb_samples = inopt.read_samples(inopt.readdata,input,frame_size); // total_samples+=nb_samples; // if(nb_samples==0)op.e_o_s=1; // } else nb_samples=-1; op.packet=(unsigned char *)m_outBuf; op.bytes=nbBytes; op.b_o_s=0; op.granulepos=enc_granulepos; if(flush == true){ /*We compute the final GP as ceil(len*48k/input_rate)+preskip. When a resampling decoder does the matching floor((len-preskip)*input_rate/48k) conversion, the resulting output length will exactly equal the original input length when 0<input_rate<=48000.*/ op.granulepos=((original_samples*48000+rate-1)/rate)+header.preskip; } op.packetno=2+id; ogg_stream_packetin(&os, &op); last_segments+=size_segments; /*If the stream is over or we're sure that the delayed flush will fire, go ahead and flush now to avoid adding delay.*/ while(((flush == true) || (enc_granulepos+(frame_size*48000/coding_rate)-last_granulepos>max_ogg_delay)|| (last_segments>=255))? ogg_stream_flush_fill(&os, &og,255*255): ogg_stream_pageout_fill(&os, &og,255*255)){ if(ogg_page_packets(&og)!=0)last_granulepos=ogg_page_granulepos(&og); last_segments-=og.header[26]; ret=oe_write_page(&og); if(ret!=og.header_len+og.body_len){ fprintf(stderr,"Error: failed writing data to output stream\n"); exit(1); } bytes_written+=ret; pages_out++; } } }