static int noop_test_encode () { theora_info ti; theora_state th; INFO ("+ Initializing theora_info struct"); theora_info_init (&ti); INFO ("+ Setting a 16x16 frame"); ti.width = 16; ti.height = 16; INFO ("+ Setting a 1:1 frame rate"); ti.fps_numerator = 1; ti.fps_denominator = 1; INFO ("+ Initializing theora_state for encoding"); if (theora_encode_init (&th, &ti) != OC_DISABLED) { INFO ("+ Clearing theora_state"); theora_clear (&th); } INFO ("+ Clearing theora_info struct"); theora_info_clear (&ti); return 0; }
void Cin_OGM_Shutdown() { #ifdef USE_CIN_XVID int status; status = shutdown_xvid(); if (status) Com_Printf("[Xvid]Decore RELEASE problem, return value %d\n", status); #endif #ifdef USE_CIN_THEORA theora_clear(&g_ogm.th_state); theora_comment_clear(&g_ogm.th_comment); theora_info_clear(&g_ogm.th_info); #endif if(g_ogm.outputBuffer) free(g_ogm.outputBuffer); g_ogm.outputBuffer = NULL; vorbis_dsp_clear(&g_ogm.vd); vorbis_comment_clear(&g_ogm.vc); vorbis_info_clear(&g_ogm.vi); /* must be called last (comment from vorbis example code) */ ogg_stream_clear(&g_ogm.os_audio); ogg_stream_clear(&g_ogm.os_video); ogg_sync_clear(&g_ogm.oy); FS_FCloseFile(g_ogm.ogmFile); g_ogm.ogmFile = 0; }
void DGVideo::unload() { if (_isLoaded) { _isLoaded = false; _state = DGVideoInitial; _theoraInfo->videobuf_ready = 0; _theoraInfo->videobuf_granulepos -= 1; _theoraInfo->videobuf_time = 0; if (_theoraInfo->theora_p) { // Rewind and reset fseek(_handle, (long)_theoraInfo->bos * 8, SEEK_SET); ogg_stream_reset(&_theoraInfo->to); ogg_stream_clear(&_theoraInfo->to); theora_clear(&_theoraInfo->td); theora_comment_clear(&_theoraInfo->tc); theora_info_clear(&_theoraInfo->ti); } ogg_sync_clear(&_theoraInfo->oy); _theoraInfo->theora_p = 0; free(_currentFrame.data); fclose(_handle); } }
static void theora_end(stream_processor *stream) { misc_theora_info *inf = stream->data; long minutes, seconds, milliseconds; double bitrate, time; /* This should be lastgranulepos - startgranulepos, or something like that*/ ogg_int64_t iframe=inf->lastgranulepos>>inf->ti.granule_shift; ogg_int64_t pframe=inf->lastgranulepos-(iframe<<inf->ti.granule_shift); time = (double)(iframe+pframe) / ((float)inf->ti.fps_numerator/(float)inf->ti.fps_denominator); minutes = (long)time / 60; seconds = (long)time - minutes*60; milliseconds = (long)((time - minutes*60 - seconds)*1000); bitrate = inf->bytes*8 / time / 1000.0; #ifdef _WIN32 info(_("Theora stream %d:\n" "\tTotal data length: %I64d bytes\n" "\tPlayback length: %ldm:%02ld.%03lds\n" "\tAverage bitrate: %f kb/s\n"), stream->num,inf->bytes, minutes, seconds, milliseconds, bitrate); #else info(_("Theora stream %d:\n" "\tTotal data length: %lld bytes\n" "\tPlayback length: %ldm:%02ld.%03lds\n" "\tAverage bitrate: %f kb/s\n"), stream->num,inf->bytes, minutes, seconds, milliseconds, bitrate); #endif theora_comment_clear(&inf->tc); theora_info_clear(&inf->ti); free(stream->data); }
static void dec_uninit(MSFilter *f){ DecState *s=(DecState*)f->data; if (s->yuv!=NULL) freemsg(s->yuv); if (s->curframe!=NULL) freemsg(s->curframe); theora_info_clear(&s->tinfo); ms_free(s); }
static void theora_decode_clear(theora_state *_td){ if(_td->i!=NULL)theora_info_clear(_td->i); #ifdef _TH_DEBUG_ fclose(debugout); debugout=NULL; #endif memset(_td,0,sizeof(*_td)); }
static void enc_postprocess(MSFilter *f){ EncState *s=(EncState*)f->data; theora_clear(&s->tstate); theora_info_clear(&s->tinfo); if (s->packed_conf) { freemsg(s->packed_conf); s->packed_conf=NULL; } }
void TheoraClose() { ogg_stream_clear ( &m_StreamState ); theora_clear ( &m_State ); theora_comment_clear ( &m_Comment ); theora_info_clear ( &m_Info ); ogg_sync_clear ( &m_SyncState ); fclose( m_File ); }
/***************************************************************************** * CloseDecoder: theora decoder destruction *****************************************************************************/ static void CloseDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys = p_dec->p_sys; theora_info_clear( &p_sys->ti ); theora_comment_clear( &p_sys->tc ); free( p_sys ); }
void theora_clear(theora_state *_th){ /*Provide compatibility with mixed encoder and decoder shared lib versions.*/ if(_th->internal_decode!=NULL){ (*((oc_state_dispatch_vtbl *)_th->internal_decode)->clear)(_th); } if(_th->internal_encode!=NULL){ (*((oc_state_dispatch_vtbl *)_th->internal_encode)->clear)(_th); } if(_th->i!=NULL)theora_info_clear(_th->i); memset(_th,0,sizeof(*_th)); }
/* * uninit driver */ static void uninit(sh_video_t *sh) { theora_struct_t *context = (theora_struct_t *)sh->context; if (context) { theora_info_clear(&context->inf); theora_comment_clear(&context->cc); theora_clear (&context->st); free (context); } }
int mm_close(mm_file *mf) { assert(mf); if (mf->file) { fclose(mf->file); mf->file = NULL; } if (mf->audio) { ogg_stream_destroy(mf->audio); mf->audio = NULL; } if (mf->video) { ogg_stream_destroy(mf->video); mf->video = NULL; } if (mf->video_ctx) { theora_clear(mf->video_ctx); free(mf->video_ctx); mf->video_ctx = NULL; } if (mf->video_info) { theora_info_clear(mf->video_info); free(mf->video_info); mf->video_info = NULL; } if (mf->audio_blk) { vorbis_block_clear(mf->audio_blk); free(mf->audio_blk); mf->audio_blk = NULL; } if (mf->audio_ctx) { vorbis_dsp_clear(mf->audio_ctx); free(mf->audio_ctx); mf->audio_ctx = NULL; } if (mf->audio_info) { vorbis_info_clear(mf->audio_info); free(mf->audio_info); mf->audio_info = NULL; } ogg_sync_clear(&mf->sync); return 0; }
static GF_Err THEO_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) { THEORACTX(); if (ctx->ES_ID != ES_ID) return GF_BAD_PARAM; theora_clear(&ctx->td); theora_info_clear(&ctx->ti); theora_comment_clear(&ctx->tc); ctx->ES_ID = 0; return GF_OK; }
static void theora_enc_finalize (GObject * object) { GstTheoraEnc *enc = GST_THEORA_ENC (object); GST_DEBUG_OBJECT (enc, "Finalizing"); theora_clear (&enc->state); theora_comment_clear (&enc->comment); theora_info_clear (&enc->info); G_OBJECT_CLASS (parent_class)->finalize (object); }
bool Oggeyman::shutdown() { // shutdown in the reverse order of intialization theora_clear(&theo_state); ogg_stream_clear(&ogg_theora_stream_state); theora_comment_clear(&theo_comment); theora_info_clear(&theo_info); ogg_sync_clear(&overall_sync_state); if (infptr) fclose(infptr); return true; }
static void altheora_close(APEG_LAYER *layer) { ALOGG_INFO *info = layer->ogg_info; if(info && (layer->stream.flags&APEG_THEORA_VIDEO)) { theora_clear(&info->tstate); theora_info_clear(&info->tinfo); theora_comment_clear(&info->tcomment); ogg_stream_clear(&info->ostream[0]); layer->stream.flags &= ~APEG_THEORA_VIDEO; } }
static GstStateChangeReturn theora_enc_change_state (GstElement * element, GstStateChange transition) { GstTheoraEnc *enc; GstStateChangeReturn ret; enc = GST_THEORA_ENC (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state"); theora_info_init (&enc->info); theora_comment_init (&enc->comment); enc->packetno = 0; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = parent_class->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state"); theora_clear (&enc->state); theora_comment_clear (&enc->comment); theora_info_clear (&enc->info); theora_enc_clear (enc); enc->initialised = FALSE; break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; }
void OggFree(OggData *data) { if (data->audio) { ogg_stream_clear(&data->astream); vorbis_block_clear(&data->vblock); vorbis_dsp_clear(&data->vdsp); vorbis_comment_clear(&data->vcomment); vorbis_info_clear(&data->vinfo); } #ifdef USE_THEORA if (data->video) { ogg_stream_clear(&data->vstream); theora_comment_clear(&data->tcomment); theora_info_clear(&data->tinfo); theora_clear(&data->tstate); } #endif ogg_sync_clear(&data->sync); }
static int noop_test_encode () { theora_info ti; theora_state th; INFO ("+ Initializing theora_info struct"); theora_info_init (&ti); INFO ("+ Initializing theora_state for encoding"); if (theora_encode_init (&th, &ti) != OC_DISABLED) { INFO ("+ Clearing theora_state"); theora_clear (&th); } INFO ("+ Clearing theora_info struct"); theora_info_clear (&ti); return 0; }
static int noop_test_decode () { theora_info ti; theora_state th; INFO ("+ Initializing theora_info struct"); theora_info_init (&ti); INFO ("+ Initializing theora_state for decoding"); theora_decode_init (&th, &ti); INFO ("+ Clearing theora_state"); theora_clear (&th); INFO ("+ Clearing theora_info struct"); theora_info_clear (&ti); return 0; }
static GstStateChangeReturn theora_dec_change_state (GstElement * element, GstStateChange transition) { GstTheoraDec *dec = GST_THEORA_DEC (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: theora_info_init (&dec->info); theora_comment_init (&dec->comment); GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE in READY->PAUSED"); dec->have_header = FALSE; gst_theora_dec_reset (dec); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = parent_class->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: theora_clear (&dec->state); theora_comment_clear (&dec->comment); theora_info_clear (&dec->info); gst_theora_dec_reset (dec); break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; }
void OGV_StopVideo(cinematic_t *cin) { if (cin->data) { theora_clear(&g_ogm->th_state); theora_comment_clear(&g_ogm->th_comment); theora_info_clear(&g_ogm->th_info); vorbis_dsp_clear(&g_ogm->vd); vorbis_comment_clear(&g_ogm->vc); vorbis_info_clear(&g_ogm->vi); /* must be called last (comment from vorbis example code) */ ogg_stream_clear(&g_ogm->os_audio); ogg_stream_clear(&g_ogm->os_video); ogg_sync_clear(&g_ogm->oy); Com_Dealloc(cin->data); cin->data = NULL; } }
void theora_clear(theora_state *t){ if(t){ CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode); PB_INSTANCE *pbi=(PB_INSTANCE *)(t->internal_decode); if (cpi) theora_encoder_clear (cpi); if(pbi){ theora_info_clear(&pbi->info); ClearHuffmanSet(pbi); ClearFragmentInfo(pbi); ClearFrameInfo(pbi); ClearPBInstance(pbi); _ogg_free(t->internal_decode); } t->internal_encode=NULL; t->internal_decode=NULL; } }
static int encode_init(AVCodecContext* avc_context) { theora_info t_info; theora_comment t_comment; ogg_packet o_packet; unsigned int offset; TheoraContext *h = avc_context->priv_data; /* Set up the theora_info struct */ theora_info_init( &t_info ); t_info.width = avc_context->width; t_info.height = avc_context->height; t_info.frame_width = avc_context->width; t_info.frame_height = avc_context->height; t_info.offset_x = 0; t_info.offset_y = 0; /* Swap numerator and denominator as time_base in AVCodecContext gives the * time period between frames, but theora_info needs the framerate. */ t_info.fps_numerator = avc_context->time_base.den; t_info.fps_denominator = avc_context->time_base.num; if (avc_context->sample_aspect_ratio.num != 0) { t_info.aspect_numerator = avc_context->sample_aspect_ratio.num; t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; } else { t_info.aspect_numerator = 1; t_info.aspect_denominator = 1; } t_info.colorspace = OC_CS_UNSPECIFIED; t_info.pixelformat = OC_PF_420; t_info.target_bitrate = avc_context->bit_rate; t_info.keyframe_frequency = avc_context->gop_size; t_info.keyframe_frequency_force = avc_context->gop_size; t_info.keyframe_mindistance = avc_context->keyint_min; t_info.quality = 0; t_info.quick_p = 1; t_info.dropframes_p = 0; t_info.keyframe_auto_p = 1; t_info.keyframe_data_target_bitrate = t_info.target_bitrate * 1.5; t_info.keyframe_auto_threshold = 80; t_info.noise_sensitivity = 1; t_info.sharpness = 0; /* Now initialise libtheora */ if (theora_encode_init( &(h->t_state), &t_info ) != 0) { av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); return -1; } /* Clear up theora_info struct */ theora_info_clear( &t_info ); /* Output first header packet consisting of theora header, comment, and tables. Each one is prefixed with a 16bit size, then they are concatenated together into ffmpeg's extradata. */ offset = 0; /* Header */ theora_encode_header( &(h->t_state), &o_packet ); if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) { return -1; } /* Comment */ theora_comment_init( &t_comment ); theora_encode_comment( &t_comment, &o_packet ); if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) { return -1; } /* Tables */ theora_encode_tables( &(h->t_state), &o_packet ); if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) { return -1; } /* Clear up theora_comment struct */ theora_comment_clear( &t_comment ); /* Set up the output AVFrame */ avc_context->coded_frame= avcodec_alloc_frame(); return 0; }
int OggInit(CFile *f, OggData *data) { ogg_packet packet; int num_vorbis; #ifdef USE_THEORA int num_theora; #endif int stream_start; int ret; unsigned magic; f->read(&magic, sizeof(magic)); if (SDL_SwapLE32(magic) != 0x5367674F) { // "OggS" in ASCII return -1; } f->seek(0, SEEK_SET); ogg_sync_init(&data->sync); vorbis_info_init(&data->vinfo); vorbis_comment_init(&data->vcomment); #ifdef USE_THEORA theora_info_init(&data->tinfo); theora_comment_init(&data->tcomment); #endif #ifdef USE_THEORA num_theora = 0; #endif num_vorbis = 0; stream_start = 0; while (!stream_start) { ogg_stream_state test; if (OggGetNextPage(&data->page, &data->sync, f)) { return -1; } if (!ogg_page_bos(&data->page)) { if (num_vorbis) { ogg_stream_pagein(&data->astream, &data->page); } #ifdef USE_THEORA if (num_theora) { ogg_stream_pagein(&data->vstream, &data->page); } #endif stream_start = 1; break; } ogg_stream_init(&test, ogg_page_serialno(&data->page)); ogg_stream_pagein(&test, &data->page); // initial codec headers while (ogg_stream_packetout(&test, &packet) == 1) { #ifdef USE_THEORA if (theora_decode_header(&data->tinfo, &data->tcomment, &packet) >= 0) { memcpy(&data->vstream, &test, sizeof(test)); ++num_theora; } else #endif if (!vorbis_synthesis_headerin(&data->vinfo, &data->vcomment, &packet)) { memcpy(&data->astream, &test, sizeof(test)); ++num_vorbis; } else { ogg_stream_clear(&test); } } } data->audio = num_vorbis; #ifdef USE_THEORA data->video = num_theora; #endif // remainint codec headers while ((num_vorbis && num_vorbis < 3) #ifdef USE_THEORA || (num_theora && num_theora < 3) ) { // are we in the theora page ? while (num_theora && num_theora < 3 && (ret = ogg_stream_packetout(&data->vstream, &packet))) { if (ret < 0) { return -1; } if (theora_decode_header(&data->tinfo, &data->tcomment, &packet)) { return -1; } ++num_theora; } #else ) { #endif // are we in the vorbis page ? while (num_vorbis && num_vorbis < 3 && (ret = ogg_stream_packetout(&data->astream, &packet))) { if (ret < 0) { return -1; } if (vorbis_synthesis_headerin(&data->vinfo, &data->vcomment, &packet)) { return -1; } ++num_vorbis; } if (OggGetNextPage(&data->page, &data->sync, f)) { break; } if (num_vorbis) { ogg_stream_pagein(&data->astream, &data->page); } #ifdef USE_THEORA if (num_theora) { ogg_stream_pagein(&data->vstream, &data->page); } #endif } if (num_vorbis) { vorbis_synthesis_init(&data->vdsp, &data->vinfo); vorbis_block_init(&data->vdsp, &data->vblock); } else { vorbis_info_clear(&data->vinfo); vorbis_comment_clear(&data->vcomment); } #ifdef USE_THEORA if (num_theora) { theora_decode_init(&data->tstate, &data->tinfo); data->tstate.internal_encode = NULL; // needed for a bug in libtheora (fixed in next release) } else { theora_info_clear(&data->tinfo); theora_comment_clear(&data->tcomment); } return !(num_vorbis || num_theora); #else return !num_vorbis; #endif }
static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure = gst_caps_get_structure (caps, 0); GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad)); const GValue *par; gint fps_n, fps_d; gst_structure_get_int (structure, "width", &enc->width); gst_structure_get_int (structure, "height", &enc->height); gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); par = gst_structure_get_value (structure, "pixel-aspect-ratio"); theora_info_clear (&enc->info); theora_info_init (&enc->info); /* Theora has a divisible-by-sixteen restriction for the encoded video size but * we can define a visible area using the frame_width/frame_height */ enc->info_width = enc->info.width = (enc->width + 15) & ~15; enc->info_height = enc->info.height = (enc->height + 15) & ~15; enc->info.frame_width = enc->width; enc->info.frame_height = enc->height; /* center image if needed */ if (enc->center) { /* make sure offset is even, for easier decoding */ enc->offset_x = GST_ROUND_UP_2 ((enc->info_width - enc->width) / 2); enc->offset_y = GST_ROUND_UP_2 ((enc->info_height - enc->height) / 2); } else { enc->offset_x = 0; enc->offset_y = 0; } enc->info.offset_x = enc->offset_x; enc->info.offset_y = enc->offset_y; enc->info.fps_numerator = enc->fps_n = fps_n; enc->info.fps_denominator = enc->fps_d = fps_d; if (par) { enc->info.aspect_numerator = gst_value_get_fraction_numerator (par); enc->info.aspect_denominator = gst_value_get_fraction_denominator (par); } else { /* setting them to 0 indicates that the decoder can chose a good aspect * ratio, defaulting to 1/1 */ enc->info.aspect_numerator = 0; enc->info.aspect_denominator = 0; } enc->info.colorspace = OC_CS_UNSPECIFIED; enc->info.target_bitrate = enc->video_bitrate; enc->info.quality = enc->video_quality; enc->info.dropframes_p = 0; enc->info.quick_p = (enc->quick ? 1 : 0); enc->info.keyframe_auto_p = (enc->keyframe_auto ? 1 : 0); enc->info.keyframe_frequency = enc->keyframe_freq; enc->info.keyframe_frequency_force = enc->keyframe_force; enc->info.keyframe_data_target_bitrate = enc->video_bitrate * 1.5; enc->info.keyframe_auto_threshold = enc->keyframe_threshold; enc->info.keyframe_mindistance = enc->keyframe_mindistance; enc->info.noise_sensitivity = enc->noise_sensitivity; enc->info.sharpness = enc->sharpness; /* as done in theora */ enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1); GST_DEBUG_OBJECT (enc, "keyframe_frequency_force is %d, granule shift is %d", enc->info.keyframe_frequency_force, enc->granule_shift); theora_enc_reset (enc); enc->initialised = TRUE; gst_object_unref (enc); return TRUE; }
static void enc_uninit(MSFilter *f){ EncState *s=(EncState*)f->data; theora_info_clear(&s->tinfo); ms_free(s); }
void DGVideo::load() { int stateFlag = 0; if (!_hasResource) { log->error(DGModVideo, "%s", DGMsg280005); return; } //log->trace(DGModVideo, "%s %s", DGMsg080001, _resource); _handle = fopen(_resource, "rb"); if (_handle == NULL) { log->error(DGModVideo, "%s: %s", DGMsg280002, _resource); return; } ogg_sync_init(&_theoraInfo->oy); theora_comment_init(&_theoraInfo->tc); theora_info_init(&_theoraInfo->ti); while (!stateFlag) { size_t ret = _bufferData(&_theoraInfo->oy); if (ret == 0) break; while (ogg_sync_pageout(&_theoraInfo->oy, &_theoraInfo->og) > 0) { ogg_stream_state test; if (!ogg_page_bos(&_theoraInfo->og)) { _queuePage(_theoraInfo, &_theoraInfo->og); stateFlag = 1; break; } ogg_stream_init(&test, ogg_page_serialno(&_theoraInfo->og)); ogg_stream_pagein(&test, &_theoraInfo->og); ogg_stream_packetout(&test, &_theoraInfo->op); if (!_theoraInfo->theora_p && theora_decode_header(&_theoraInfo->ti, &_theoraInfo->tc, &_theoraInfo->op) >= 0) { memcpy(&_theoraInfo->to, &test, sizeof(test)); _theoraInfo->theora_p = 1; } else { ogg_stream_clear(&test); } } } while (_theoraInfo->theora_p && _theoraInfo->theora_p < 3) { int ret; while (_theoraInfo->theora_p && (_theoraInfo->theora_p < 3) && (ret = ogg_stream_packetout(&_theoraInfo->to, &_theoraInfo->op))) { if (ret < 0) { log->error(DGModVideo, "%s", DGMsg280003); return; } if (theora_decode_header(&_theoraInfo->ti, &_theoraInfo->tc, &_theoraInfo->op)) { log->error(DGModVideo, "%s", DGMsg280003); return; } _theoraInfo->theora_p++; if (_theoraInfo->theora_p == 3) break; } if (ogg_sync_pageout(& _theoraInfo->oy, & _theoraInfo->og) > 0) _queuePage(_theoraInfo, &_theoraInfo->og); else { size_t ret = _bufferData(&_theoraInfo->oy); if (ret == 0) { log->error(DGModVideo, "%s", DGMsg280004); return; } } } if (_theoraInfo->theora_p) { theora_decode_init(&_theoraInfo->td, &_theoraInfo->ti); } else { theora_info_clear(&_theoraInfo->ti); theora_comment_clear(&_theoraInfo->tc); } _currentFrame.width = _theoraInfo->ti.width; _currentFrame.height = _theoraInfo->ti.height; _currentFrame.depth = 24; // NOTE: We only support flat RGB for now _currentFrame.data = (unsigned char*)malloc((_theoraInfo->ti.width * _theoraInfo->ti.height) * 3); while (ogg_sync_pageout(&_theoraInfo->oy, &_theoraInfo->og) > 0) { _queuePage(_theoraInfo, &_theoraInfo->og); } _frameDuration = (float)(1/((double)_theoraInfo->ti.fps_numerator / _theoraInfo->ti.fps_denominator)); _isLoaded = true; }
static int granulepos_test_encode (int frequency, int auto_p) { theora_info ti; theora_state th; int result; int frame, tframe, keyframe, keydist; int shift; double rate, ttime; yuv_buffer yuv; unsigned char *framedata; ogg_packet op; long long int last_granule = -1; /* INFO ("+ Initializing theora_info struct"); */ theora_info_init (&ti); ti.width = 32; ti.height = 32; ti.frame_width = ti.width; ti.frame_height = ti.frame_height; ti.offset_x = 0; ti.offset_y = 0; ti.fps_numerator = 16; ti.fps_denominator = 1; ti.aspect_numerator = 1; ti.aspect_denominator = 1; ti.colorspace = OC_CS_UNSPECIFIED; ti.pixelformat = OC_PF_420; ti.target_bitrate = 0; ti.quality = 16; ti.dropframes_p = 0; ti.quick_p = 1; /* check variations of automatic or forced keyframe choice */ ti.keyframe_auto_p = auto_p; /* check with variations of the maximum gap */ ti.keyframe_frequency = frequency; ti.keyframe_frequency_force = frequency; ti.keyframe_data_target_bitrate = ti.target_bitrate * 1.5; ti.keyframe_auto_threshold = 80; ti.keyframe_mindistance = MIN(8, frequency); ti.noise_sensitivity = 1; /* INFO ("+ Initializing theora_state for encoding"); */ result = theora_encode_init (&th, &ti); if (result == OC_DISABLED) { INFO ("+ Clearing theora_state"); theora_clear (&th); } else if (result < 0) { FAIL ("negative return code initializing encoder"); } /* INFO ("+ Setting up dummy 4:2:0 frame data"); */ framedata = calloc(ti.height, ti.width); yuv.y_width = ti.width; yuv.y_height = ti.height; yuv.y_stride = ti.width; yuv.y = framedata; yuv.uv_width = ti.width / 2; yuv.uv_height = ti.width / 2; yuv.uv_stride = ti.width; yuv.u = framedata; yuv.v = framedata; INFO ("+ Checking granulepos generation"); shift = theora_granule_shift(&ti); rate = (double)ti.fps_denominator/ti.fps_numerator; for (frame = 0; frame < frequency * 2 + 1; frame++) { result = theora_encode_YUVin (&th, &yuv); if (result < 0) { printf("theora_encode_YUVin() returned %d\n", result); FAIL ("negative error code submitting frame for compression"); } theora_encode_packetout (&th, frame >= frequency * 2, &op); if ((long long int)op.granulepos < last_granule) FAIL ("encoder returned a decreasing granulepos value"); last_granule = op.granulepos; keyframe = op.granulepos >> shift; keydist = op.granulepos - (keyframe << shift); tframe = theora_granule_frame (&th, op.granulepos); ttime = theora_granule_time(&th, op.granulepos); #if DEBUG printf("++ frame %d granulepos %lld %d:%d %d %.3lfs\n", frame, (long long int)op.granulepos, keyframe, keydist, tframe, theora_granule_time (&th, op.granulepos)); #endif if ((keyframe + keydist) != frame + 1) FAIL ("encoder granulepos does not map to the correct frame number"); if (tframe != frame) FAIL ("theora_granule_frame returned incorrect results"); if (fabs(rate*(frame+1) - ttime) > 1.0e-6) FAIL ("theora_granule_time returned incorrect results"); } /* clean up */ /* INFO ("+ Freeing dummy frame data"); */ free (framedata); /* INFO ("+ Clearing theora_info struct"); */ theora_info_clear (&ti); /* INFO ("+ Clearing theora_state"); */ theora_clear (&th); return 0; }
int main(int argc,char *argv[]){ int i,j; ogg_packet op; FILE *infile = stdin; #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ /* Beware the evil ifdef. We avoid these where we can, but this one we cannot. Don't add any more, you'll probably go to hell if you do. */ _setmode( _fileno( stdin ), _O_BINARY ); #endif /* open the input file if any */ if(argc==2){ infile=fopen(argv[1],"rb"); if(infile==NULL){ fprintf(stderr,"Unable to open '%s' for playback.\n", argv[1]); exit(1); } } if(argc>2){ usage(); exit(1); } /* start up Ogg stream synchronization layer */ ogg_sync_init(&oy); /* init supporting Vorbis structures needed in header parsing */ vorbis_info_init(&vi); vorbis_comment_init(&vc); /* init supporting Theora structures needed in header parsing */ theora_comment_init(&tc); theora_info_init(&ti); /* Ogg file open; parse the headers */ /* Only interested in Vorbis/Theora streams */ while(!stateflag){ int ret=buffer_data(infile,&oy); if(ret==0)break; while(ogg_sync_pageout(&oy,&og)>0){ ogg_stream_state test; /* is this a mandated initial header? If not, stop parsing */ if(!ogg_page_bos(&og)){ /* don't leak the page; get it into the appropriate stream */ queue_page(&og); stateflag=1; break; } ogg_stream_init(&test,ogg_page_serialno(&og)); ogg_stream_pagein(&test,&og); ogg_stream_packetout(&test,&op); /* identify the codec: try theora */ if(!theora_p && theora_decode_header(&ti,&tc,&op)>=0){ /* it is theora */ memcpy(&to,&test,sizeof(test)); theora_p=1; }else if(!vorbis_p && vorbis_synthesis_headerin(&vi,&vc,&op)>=0){ /* it is vorbis */ memcpy(&vo,&test,sizeof(test)); vorbis_p=1; }else{ /* whatever it is, we don't care about it */ ogg_stream_clear(&test); } } /* fall through to non-bos page parsing */ } /* we're expecting more header packets. */ while((theora_p && theora_p<3) || (vorbis_p && vorbis_p<3)){ int ret; /* look for further theora headers */ while(theora_p && (theora_p<3) && (ret=ogg_stream_packetout(&to,&op))){ if(ret<0){ fprintf(stderr,"Error parsing Theora stream headers; corrupt stream?\n"); exit(1); } if(theora_decode_header(&ti,&tc,&op)){ printf("Error parsing Theora stream headers; corrupt stream?\n"); exit(1); } theora_p++; if(theora_p==3)break; } /* look for more vorbis header packets */ while(vorbis_p && (vorbis_p<3) && (ret=ogg_stream_packetout(&vo,&op))){ if(ret<0){ fprintf(stderr,"Error parsing Vorbis stream headers; corrupt stream?\n"); exit(1); } if(vorbis_synthesis_headerin(&vi,&vc,&op)){ fprintf(stderr,"Error parsing Vorbis stream headers; corrupt stream?\n"); exit(1); } vorbis_p++; if(vorbis_p==3)break; } /* The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec */ if(ogg_sync_pageout(&oy,&og)>0){ queue_page(&og); /* demux into the appropriate stream */ }else{ int ret=buffer_data(infile,&oy); /* someone needs more data */ if(ret==0){ fprintf(stderr,"End of file while searching for codec headers.\n"); exit(1); } } } /* and now we have it all. initialize decoders */ if(theora_p){ theora_decode_init(&td,&ti); printf("Ogg logical stream %x is Theora %dx%d %.02f fps video\n", (unsigned int)to.serialno,ti.width,ti.height, (double)ti.fps_numerator/ti.fps_denominator); if(ti.width!=ti.frame_width || ti.height!=ti.frame_height) printf(" Frame content is %dx%d with offset (%d,%d).\n", ti.frame_width, ti.frame_height, ti.offset_x, ti.offset_y); report_colorspace(&ti); dump_comments(&tc); }else{ /* tear down the partial theora setup */ theora_info_clear(&ti); theora_comment_clear(&tc); } if(vorbis_p){ vorbis_synthesis_init(&vd,&vi); vorbis_block_init(&vd,&vb); fprintf(stderr,"Ogg logical stream %x is Vorbis %d channel %d Hz audio.\n", (unsigned int)vo.serialno,vi.channels,(int)vi.rate); }else{ /* tear down the partial vorbis setup */ vorbis_info_clear(&vi); vorbis_comment_clear(&vc); } /* open audio */ if(vorbis_p)open_audio(); /* open video */ if(theora_p)open_video(); /* install signal handler as SDL clobbered the default */ signal (SIGINT, sigint_handler); /* on to the main decode loop. We assume in this example that audio and video start roughly together, and don't begin playback until we have a start frame for both. This is not necessarily a valid assumption in Ogg A/V streams! It will always be true of the example_encoder (and most streams) though. */ stateflag=0; /* playback has not begun */ while(!got_sigint){ /* we want a video and audio frame ready to go at all times. If we have to buffer incoming, buffer the compressed data (ie, let ogg do the buffering) */ while(vorbis_p && !audiobuf_ready){ int ret; float **pcm; /* if there's pending, decoded audio, grab it */ if((ret=vorbis_synthesis_pcmout(&vd,&pcm))>0){ int count=audiobuf_fill/2; int maxsamples=(audiofd_fragsize-audiobuf_fill)/2/vi.channels; for(i=0;i<ret && i<maxsamples;i++) for(j=0;j<vi.channels;j++){ int val=rint(pcm[j][i]*32767.f); if(val>32767)val=32767; if(val<-32768)val=-32768; audiobuf[count++]=val; } vorbis_synthesis_read(&vd,i); audiobuf_fill+=i*vi.channels*2; if(audiobuf_fill==audiofd_fragsize)audiobuf_ready=1; if(vd.granulepos>=0) audiobuf_granulepos=vd.granulepos-ret+i; else audiobuf_granulepos+=i; }else{ /* no pending audio; is there a pending packet to decode? */ if(ogg_stream_packetout(&vo,&op)>0){ if(vorbis_synthesis(&vb,&op)==0) /* test for success! */ vorbis_synthesis_blockin(&vd,&vb); }else /* we need more data; break out to suck in another page */ break; } } while(theora_p && !videobuf_ready){ /* theora is one in, one out... */ if(ogg_stream_packetout(&to,&op)>0){ theora_decode_packetin(&td,&op); videobuf_granulepos=td.granulepos; videobuf_time=theora_granule_time(&td,videobuf_granulepos); /* is it already too old to be useful? This is only actually useful cosmetically after a SIGSTOP. Note that we have to decode the frame even if we don't show it (for now) due to keyframing. Soon enough libtheora will be able to deal with non-keyframe seeks. */ if(videobuf_time>=get_time()) videobuf_ready=1; }else break; } if(!videobuf_ready && !audiobuf_ready && feof(infile))break; if(!videobuf_ready || !audiobuf_ready){ /* no data yet for somebody. Grab another page */ int bytes=buffer_data(infile,&oy); while(ogg_sync_pageout(&oy,&og)>0){ queue_page(&og); } } /* If playback has begun, top audio buffer off immediately. */ if(stateflag) audio_write_nonblocking(); /* are we at or past time for this video frame? */ if(stateflag && videobuf_ready && videobuf_time<=get_time()){ video_write(); videobuf_ready=0; } if(stateflag && (audiobuf_ready || !vorbis_p) && (videobuf_ready || !theora_p) && !got_sigint){ /* we have an audio frame ready (which means the audio buffer is full), it's not time to play video, so wait until one of the audio buffer is ready or it's near time to play video */ /* set up select wait on the audiobuffer and a timeout for video */ struct timeval timeout; fd_set writefs; fd_set empty; int n=0; FD_ZERO(&writefs); FD_ZERO(&empty); if(audiofd>=0){ FD_SET(audiofd,&writefs); n=audiofd+1; } if(theora_p){ long milliseconds=(videobuf_time-get_time())*1000-5; if(milliseconds>500)milliseconds=500; if(milliseconds>0){ timeout.tv_sec=milliseconds/1000; timeout.tv_usec=(milliseconds%1000)*1000; n=select(n,&empty,&writefs,&empty,&timeout); if(n)audio_calibrate_timer(0); } }else{ select(n,&empty,&writefs,&empty,NULL); } } /* if our buffers either don't exist or are ready to go, we can begin playback */ if((!theora_p || videobuf_ready) && (!vorbis_p || audiobuf_ready))stateflag=1; /* same if we've run out of input */ if(feof(infile))stateflag=1; } /* tear it all down */ audio_close(); SDL_Quit(); if(vorbis_p){ ogg_stream_clear(&vo); vorbis_block_clear(&vb); vorbis_dsp_clear(&vd); vorbis_comment_clear(&vc); vorbis_info_clear(&vi); } if(theora_p){ ogg_stream_clear(&to); theora_clear(&td); theora_comment_clear(&tc); theora_info_clear(&ti); } ogg_sync_clear(&oy); if(infile && infile!=stdin)fclose(infile); fprintf(stderr, "\r " "\nDone.\n"); return(0); }