summaryrefslogtreecommitdiffstats
path: root/branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c
diff options
context:
space:
mode:
Diffstat (limited to 'branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c')
-rw-r--r--branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c707
1 files changed, 0 insertions, 707 deletions
diff --git a/branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c b/branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c
deleted file mode 100644
index 67fb3e6..0000000
--- a/branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* This file is part of Open Source Doubango Framework.
-*
-* DOUBANGO is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* DOUBANGO is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tdav_codec_theora.c
- * @brief Theora codec plugin
- * RTP payloader/depayloader follows draft-barbato-avt-rtp-theora-01.
- * For more information about Theora, http://www.theora.org/doc/Theora.pdf.
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/theora/tdav_codec_theora.h"
-
-#if HAVE_FFMPEG
-
-#include "tinydav/video/tdav_converter_video.h"
-
-#include "tinyrtp/rtp/trtp_rtp_packet.h"
-
-#include "tsk_time.h"
-#include "tsk_params.h"
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define THEORA_RTP_PAYLOAD_SIZE 900
-#define THEORA_PAYLOAD_HEADER_SIZE 4 /* 2.2. Payload Header */
-#define THEORA_PAYLOAD_LENGTH_SIZE 2 /* 2.2. Payload Header */
-#define THEORA_IDENT_HEADER_SIZE 42 /* 6.2 Identification Header Decode */
-#define THEORA_CONF_SEND_COUNT 10 /* at 250ms, 500ms, 1000ms, .... */
-
-/* 2.2. Payload Header filed 'F'*/
-typedef enum theora_frag_type_e{
- Not_Fragmented = 0,
- Start_Fragment = 1,
- Continuation_Fragment = 2,
- End_Fragment = 3,
-}
-theora_frag_type_t;
-
-/* 2.2. Payload Header field 'TDT'*/
-typedef enum theora_datatype_e{
- Raw_Theora_payload = 0,
- Theora_Packed_Configuration_payload = 1,
- Legacy_Theora_Comment_payload = 2,
- Reserved = 3,
-}
-theora_datatype_t;
-
-static int tdav_codec_theora_send(tdav_codec_theora_t* self, const uint8_t* data, tsk_size_t size, theora_datatype_t tdt);
-static void tdav_codec_theora_rtp_callback(tdav_codec_theora_t *self, const void *data, tsk_size_t size, tsk_bool_t marker);
-
-static void tdav_codec_theora_encap(tdav_codec_theora_t* theora, const uint8_t* pdata, tsk_size_t size);
-
-/* ============ Theora Plugin interface functions ================= */
-
-#define tdav_codec_theora_fmtp_set tsk_null
-
-int tdav_codec_theora_open(tmedia_codec_t* self)
-{
- int ret;
- int size;
- float bitRate = 64000.f;
-
- tdav_codec_theora_t* theora = (tdav_codec_theora_t*)self;
-
- if(!theora){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is not opened */
-
- //
- // Encoder
- //
- if(!(theora->encoder.codec = avcodec_find_encoder(CODEC_ID_THEORA))){
- TSK_DEBUG_ERROR("Failed to find Theora encoder");
- return -2;
- }
- theora->encoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(theora->encoder.context);
-
- theora->encoder.context->pix_fmt = PIX_FMT_YUV420P;
- theora->encoder.context->time_base.num = 1;
- theora->encoder.context->time_base.den = TMEDIA_CODEC_VIDEO(theora)->fps;
- theora->encoder.context->width = TMEDIA_CODEC_VIDEO(theora)->width;
- theora->encoder.context->height = TMEDIA_CODEC_VIDEO(theora)->height;
-
- //theora->encoder.context->mb_qmin = theora->encoder.context->qmin = 4;
- //theora->encoder.context->mb_qmax = theora->encoder.context->qmax = 4;
- theora->encoder.context->mb_decision = FF_MB_DECISION_SIMPLE;
-
- switch(self->bl){
- case tmedia_bl_low:
- default:
- bitRate = 64000.f;
- break;
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- bitRate = 128000.f;
- break;
- }
-
- theora->encoder.context->thread_count = 1;
- theora->encoder.context->rtp_payload_size = THEORA_RTP_PAYLOAD_SIZE;
- theora->encoder.context->opaque = tsk_null;
- theora->encoder.context->bit_rate = (int) (bitRate * 0.80f);
- theora->encoder.context->bit_rate_tolerance = (int) (bitRate * 0.20f);
- theora->encoder.context->gop_size = TMEDIA_CODEC_VIDEO(theora)->fps*2; // each 2 seconds
-
- // Picture (YUV 420)
- if(!(theora->encoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create encoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(theora->encoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, theora->encoder.context->width, theora->encoder.context->height);
- if(!(theora->encoder.buffer = tsk_calloc(size, sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate encoder buffer");
- return -2;
- }
-
- // Open encoder
- if((ret = avcodec_open(theora->encoder.context, theora->encoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open Theora encoder");
- return ret;
- }
-
- //
- // Decoder
- //
- if(!(theora->decoder.codec = avcodec_find_decoder(CODEC_ID_THEORA))){
- TSK_DEBUG_ERROR("Failed to find Theora decoder");
- return -2;
- }
- theora->decoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(theora->decoder.context);
-
- theora->decoder.context->pix_fmt = PIX_FMT_YUV420P;
- theora->decoder.context->width = TMEDIA_CODEC_VIDEO(theora)->width;
- theora->decoder.context->height = TMEDIA_CODEC_VIDEO(theora)->height;
-
- // Picture (YUV 420)
- if(!(theora->decoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create decoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(theora->decoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, theora->decoder.context->width, theora->decoder.context->height);
- if(!(theora->decoder.accumulator = tsk_calloc((size + FF_INPUT_BUFFER_PADDING_SIZE), sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate decoder buffer");
- return -2;
- }
-
- if(!(theora->decoder.accumulator = tsk_calloc((size + FF_INPUT_BUFFER_PADDING_SIZE), sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate decoder buffer");
- return -2;
- }
-
- // Open decoder
- //if((ret = avcodec_open(theora->decoder.context, theora->decoder.codec)) < 0){
- // TSK_DEBUG_ERROR("Failed to open Theora decoder");
- // return ret;
- //}
-
- return 0;
-}
-
-int tdav_codec_theora_close(tmedia_codec_t* self)
-{
- tdav_codec_theora_t* theora = (tdav_codec_theora_t*)self;
-
- if(!theora){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is opened */
-
- //
- // Encoder
- //
- if(theora->encoder.context){
- avcodec_close(theora->encoder.context);
- av_free(theora->encoder.context);
- theora->encoder.context = tsk_null;
- }
- if(theora->encoder.picture){
- av_free(theora->encoder.picture);
- }
- if(theora->encoder.buffer){
- TSK_FREE(theora->encoder.buffer);
- }
-
- //
- // Decoder
- //
- if(theora->decoder.context){
- avcodec_close(theora->decoder.context);
- if(theora->decoder.context->extradata){
- TSK_FREE(theora->decoder.context->extradata);
- theora->decoder.context->extradata_size = 0;
- }
- av_free(theora->decoder.context);
- theora->decoder.context = tsk_null;
- }
- if(theora->decoder.picture){
- av_free(theora->decoder.picture);
- theora->decoder.picture = tsk_null;
- }
- if(theora->decoder.accumulator){
- TSK_FREE(theora->decoder.accumulator);
- }
-
- return 0;
-}
-
-//#include "tsk_time.h"
-tsk_size_t tdav_codec_theora_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- int ret;
- int size;
-
- tdav_codec_theora_t* theora = (tdav_codec_theora_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- // wrap yuv420 buffer
- size = avpicture_fill((AVPicture *)theora->encoder.picture, (uint8_t*)in_data, PIX_FMT_YUV420P, theora->encoder.context->width, theora->encoder.context->height);
- if(size != in_size){
- /* guard */
- TSK_DEBUG_ERROR("Invalid size");
- return 0;
- }
- /* Flip */
-#if FLIP_ENCODED_PICT
- tdav_converter_video_flip(theora->encoder.picture, theora->encoder.context->height);
-#endif
-
- // Encode data
- //theora->encoder.picture->pts = tsk_time_epoch();
- theora->encoder.picture->pts = AV_NOPTS_VALUE;
- //theora->encoder.picture->pict_type = FF_I_TYPE;
- ret = avcodec_encode_video(theora->encoder.context, theora->encoder.buffer, size, theora->encoder.picture);
- if(ret > 0){
- tdav_codec_theora_encap(theora, theora->encoder.buffer, (tsk_size_t)ret);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_theora_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
-{
- const uint8_t* pdata = in_data;
- int pkts;
- const uint8_t* pay_ptr;
- tsk_size_t pay_size;
- //tsk_size_t hdr_size;
- tsk_size_t xsize, retsize = 0;
- int got_picture_ptr;
- int ret;
-
- tdav_codec_theora_t* theora = (tdav_codec_theora_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- if(!self || !in_data || (in_size<(THEORA_PAYLOAD_HEADER_SIZE + THEORA_PAYLOAD_LENGTH_SIZE)) || !out_data || !theora->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* Packet lost? */
- if(theora->decoder.last_seq != (rtp_hdr->seq_num - 1) && theora->decoder.last_seq){
- if(theora->decoder.last_seq == rtp_hdr->seq_num){
- // Could happen on some stupid emulators
- //TSK_DEBUG_INFO("Packet duplicated, seq_num=%d", rtp_hdr->seq_num);
- return 0;
- }
- TSK_DEBUG_INFO("Packet lost, seq_num=%d", rtp_hdr->seq_num);
- }
- theora->decoder.last_seq = rtp_hdr->seq_num;
-
- xsize = avpicture_get_size(theora->decoder.context->pix_fmt, theora->decoder.context->width, theora->decoder.context->height);
-
- /* 2.2. Payload Header
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Configuration Ident | F |TDT|# pkts.|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- /* 2.3. Payload Data
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Payload Length | Theora Data ..
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- pkts = (pdata[3] & 0x0F);
- pay_ptr = (pdata + THEORA_PAYLOAD_HEADER_SIZE);
-
- do{ /* pkts=0 for fragmented packets */
-
- pay_size = pay_ptr[0], pay_size<<=8, pay_size |= pay_ptr[1]; /* Big Endian read */
- pay_ptr += THEORA_PAYLOAD_LENGTH_SIZE;
- /* check size validity */
- if((pay_ptr + pay_size)>(pdata + in_size)){
- TSK_DEBUG_ERROR("Too short");
- break;
- }
-
- switch((pdata[3]>>4) & 0x03){
- case Raw_Theora_payload:
- { /* ====== Theora data (2.2. Payload Header, 2.3. Payload Data) ====== */
- /* append buffer */
- if((int)(theora->decoder.accumulator_pos + pay_size) <= xsize){
- memcpy(&((uint8_t*)theora->decoder.accumulator)[theora->decoder.accumulator_pos], pay_ptr, pay_size);
- theora->decoder.accumulator_pos += pay_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- theora->decoder.accumulator_pos = 0;
- break;
- }
- /* only take care if last packet (What about the RTP marker?) */
- if(((pdata[3]>>6) == Not_Fragmented || (pdata[3]>>6) == End_Fragment /*|| rtp_hdr->marker*/) && theora->decoder.opened){
- AVPacket packet;
- /* Perform decoding */
- av_init_packet(&packet);
- packet.size = theora->decoder.accumulator_pos;
- packet.data = theora->decoder.accumulator;
- ret = avcodec_decode_video2(theora->decoder.context, theora->decoder.picture, &got_picture_ptr, &packet);
-
- if(ret <0 || !got_picture_ptr){
- TSK_DEBUG_WARN("Failed to decode the buffer");
- }
- else{
- retsize = xsize;
-#if FLIP_DECODED_PICT
- tdav_converter_video_flip(theora->decoder.picture, theora->decoder.context->height);
-#endif
- /* allocate buffer */
- if(*out_max_size <xsize){
- if((*out_data = tsk_realloc(*out_data, xsize))){
- *out_max_size = xsize;
- }
- else{
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- }
- /* copy picture into a linear buffer */
- avpicture_layout((AVPicture *)theora->decoder.picture, theora->decoder.context->pix_fmt, theora->decoder.context->width, theora->decoder.context->height,
- *out_data, retsize);
- }
- /* in all cases: reset accumulator */
- theora->decoder.accumulator_pos = 0;
- }
- break;
- }
- case Theora_Packed_Configuration_payload:
- {/* ====== Configuration packet (3.1.1. Packed Configuration) ====== */
- static uint8_t __theora_comment_hdr[] = {0x81, 0x74, 0x68, 0x65, 0x6F, 0x72, 0x61,
- 0x00, 0x00, 0x00, 0x08, /* 4-byte length */
- 'd', 'o', 'u', 'b', 'a', 'n', 'g', 'o', /* UTF-8 encoded string */
- };
-
- /* http://www.theora.org/doc/Theora.pdf - Chapter 6
- A Theora bitstream begins with three header packets. The header packets
- are, in order, the identifcation header, the comment header, and the setup
- header. All are required for decode compliance. An end-of-packet condition
- encountered while decoding the identification or setup header packets renders
- the stream undecodable. An end-of-packet condition encountered while decode
- the comment header is a non-fatal error condition, and MAY be ignored by a
- decoder.
-
- Decode continues according to HEADERTYPE. The identification header
- is type 0x80, the comment header is type 0x81, and the setup header is type
- 0x82.
- */
- /*TSK_DEBUG_INFO("Theora_Packed_Configuration_payload");*/
-
- if(!theora->decoder.opened /*|| (conf_ident changed)*/){
- if(!theora->decoder.conf_pkt){
- theora->decoder.conf_pkt = tsk_buffer_create(pay_ptr, pay_size);
- }
- else{
- tsk_buffer_append(theora->decoder.conf_pkt, pay_ptr, pay_size);
- }
-
- if((pdata[3]>>6) == Not_Fragmented || (pdata[3]>>6) == End_Fragment || rtp_hdr->marker){
- if(theora->decoder.conf_pkt->size > THEORA_IDENT_HEADER_SIZE){
- const uint8_t* conf_ptr = theora->decoder.conf_pkt->data;
- int setup_size = theora->decoder.conf_pkt->size - THEORA_IDENT_HEADER_SIZE;
- int extradata_size = (2 + THEORA_IDENT_HEADER_SIZE) + (2 + setup_size) + (2 + sizeof(__theora_comment_hdr));
- if(conf_ptr[0] == 0x80 && conf_ptr[THEORA_IDENT_HEADER_SIZE] == 0x82){ /* Do not check for 't'h'e'o'r'a' */
- /* save configration identification */
- memcpy(theora->decoder.conf_ident, &pdata[0], sizeof(theora->decoder.conf_ident));
- if(theora->decoder.context->extradata){
- TSK_FREE(theora->decoder.context->extradata);
- }
- if((theora->decoder.context->extradata = tsk_calloc(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE, 1))){
- int index = 0;
- /* Because of endianess pb. do not use uint16_t or uint32_t */
- theora->decoder.context->extradata[index++] = 0x00;
- theora->decoder.context->extradata[index++] = THEORA_IDENT_HEADER_SIZE;
- memcpy(&theora->decoder.context->extradata[index], &conf_ptr[0], THEORA_IDENT_HEADER_SIZE);
- index += THEORA_IDENT_HEADER_SIZE;
-
- theora->decoder.context->extradata[index++] = (setup_size >>8) & 0xFF;
- theora->decoder.context->extradata[index++] = (setup_size & 0xFF);
- memcpy(&theora->decoder.context->extradata[index], &conf_ptr[THEORA_IDENT_HEADER_SIZE], setup_size);
- index+=setup_size;
-
- theora->decoder.context->extradata[index++] = 0x00;
- theora->decoder.context->extradata[index++] = sizeof(__theora_comment_hdr);/* <0xFF */
- memcpy(&theora->decoder.context->extradata[index], __theora_comment_hdr, sizeof(__theora_comment_hdr));
-
- theora->decoder.context->extradata_size = extradata_size;
-
- if((ret = avcodec_open(theora->decoder.context, theora->decoder.codec)) == 0){
- theora->decoder.opened = tsk_true;
- }
- else{
- TSK_DEBUG_ERROR("Failed to open theora decoder %d", ret);
- TSK_FREE(theora->decoder.context->extradata);
- theora->decoder.context->extradata_size = 0;
- }
- }
- }
- else{
- TSK_DEBUG_ERROR("Invalid configuration packet");
- }
- }
- else{
- TSK_DEBUG_ERROR("Too short");
- }
- tsk_buffer_cleanup(theora->decoder.conf_pkt);
- }
- }
- break;
- }
- case Legacy_Theora_Comment_payload:
- /*TSK_DEBUG_INFO("Legacy_Theora_Comment_payload");*/
- break;
- case Reserved:
- /*TSK_DEBUG_INFO("Reserved");*/
- break;
- }
- }
- while(--pkts>0);
-
-
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_theora_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tsk_bool_t ret = tsk_true; // accept decoding any size
- tsk_params_L_t* params = tsk_null;
- tmedia_codec_video_t* theora = (tmedia_codec_video_t*)codec;
-
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
- int width = tsk_params_get_param_value_as_int(params, "width");
- int height = tsk_params_get_param_value_as_int(params, "height");
-
- // Set Encoding size
- switch(codec->bl){
- case tmedia_bl_low:
- default:
- if(width<=176 && height<=144){
- theora->width = width, theora->height = height;
- }
- else{
- theora->width = 176, theora->height = 144;
- }
- break;
-
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- if(width<=352 && height<=288){
- theora->width = width, theora->height = height;
- }
- else{
- theora->width = 352, theora->height = 288;
- }
- break;
- }
- }
- TSK_OBJECT_SAFE_FREE(params);
-
- return ret;
-}
-
-char* tdav_codec_theora_fmtp_get(const tmedia_codec_t* self)
-{
- switch(self->bl){
- case tmedia_bl_low:
- default:
- return tsk_strdup("sampling=YCbCr-4:2:0; width=176; height=144");
- break;
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- return tsk_strdup("sampling=YCbCr-4:2:0; width=352; height=288");
- break;
- }
-}
-
-
-
-/* constructor */
-static tsk_object_t* tdav_codec_theora_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_theora_t *theora = self;
- if(theora){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- //TSK_OBJECT_SAFE_FREE(theora->conf_data);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_theora_dtor(tsk_object_t * self)
-{
- tdav_codec_theora_t *theora = self;
- if(theora){
- /* deinit base */
- tmedia_codec_video_deinit(self);
- /* deinit self */
- TSK_OBJECT_SAFE_FREE(theora->decoder.conf_pkt);
- TSK_FREE(theora->rtp.ptr);
- theora->rtp.size = 0;
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_theora_def_s =
-{
- sizeof(tdav_codec_theora_t),
- tdav_codec_theora_ctor,
- tdav_codec_theora_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_theora_plugin_def_s =
-{
- &tdav_codec_theora_def_s,
-
- tmedia_video,
- "theora",
- "Theora Codec",
- TMEDIA_CODEC_FORMAT_THEORA,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_theora_open,
- tdav_codec_theora_close,
- tdav_codec_theora_encode,
- tdav_codec_theora_decode,
- tdav_codec_theora_fmtp_match,
- tdav_codec_theora_fmtp_get,
- tdav_codec_theora_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_theora_plugin_def_t = &tdav_codec_theora_plugin_def_s;
-
-
-
-static void tdav_codec_theora_encap(tdav_codec_theora_t* theora, const uint8_t* pdata, tsk_size_t size)
-{
- if((theora->encoder.conf_count < THEORA_CONF_SEND_COUNT) && theora->encoder.context && theora->encoder.context->extradata){
- if((theora->encoder.conf_last + (250 *theora->encoder.conf_count)) < tsk_time_epoch()){
- int hdr_size, i, exd_size = theora->encoder.context->extradata_size, conf_pkt_size = 0;
- uint8_t *conf_pkt_ptr = tsk_null, *exd_ptr = theora->encoder.context->extradata;
- for(i=0; i<3 && exd_size; i++){
- hdr_size = exd_ptr[0], hdr_size<<=8, hdr_size |= exd_ptr[1];
- exd_ptr += 2;
- exd_size -= 2;
- if(hdr_size > exd_size){
- TSK_DEBUG_ERROR("Invalid extradata");
- TSK_FREE(conf_pkt_ptr);
- conf_pkt_size = 0;
- }
-
- if(exd_ptr[0] == 0x80 || exd_ptr[0] == 0x82){ /* Ignore 'comment' which is equal to '0x81' */
- if((conf_pkt_ptr = tsk_realloc(conf_pkt_ptr, (conf_pkt_size + hdr_size)))){
- memcpy((conf_pkt_ptr + conf_pkt_size), exd_ptr, hdr_size);
- conf_pkt_size += hdr_size;
- }
- }
- exd_size -= hdr_size;
- exd_ptr += hdr_size;
- }
-
- /* Send the conf pack */
- if(conf_pkt_ptr && conf_pkt_size){
- /*TSK_DEBUG_INFO("Sending Configuration Packet");*/
- tdav_codec_theora_send(theora, conf_pkt_ptr, conf_pkt_size, Theora_Packed_Configuration_payload);
- TSK_FREE(conf_pkt_ptr);
- }
-
- theora->encoder.conf_last = tsk_time_epoch();
- theora->encoder.conf_count++;
- }
- }
-
- /* Send Theora Raw data */
- tdav_codec_theora_send(theora, pdata, size, Raw_Theora_payload);
-}
-
-int tdav_codec_theora_send(tdav_codec_theora_t* self, const uint8_t* data, tsk_size_t size, theora_datatype_t tdt)
-{
- /* 2.2. Payload Header
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Configuration Ident | F |TDT|# pkts.|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- uint8_t pay_hdr[THEORA_PAYLOAD_HEADER_SIZE/*4*/ + THEORA_PAYLOAD_LENGTH_SIZE/*2*/] = {0x01, 0x19, 0x83, 0x00, 0x00, 0x00};
- //uint8_t* pay_ptr = tsk_null;
- tsk_size_t pay_size;
- tsk_bool_t frag, first = tsk_true;
-
- pay_hdr[3] = (tdt & 0xFF) <<4;
-
- /* whether the packet will be fragmented or not */
- frag = (size > THEORA_RTP_PAYLOAD_SIZE);
-
- while(size){
- pay_size = TSK_MIN(THEORA_RTP_PAYLOAD_SIZE, size);
- pay_hdr[4] = pay_size>>8, pay_hdr[5] = pay_size & 0xFF;
-
- if(frag){
- if(first){
- first = tsk_false;
- pay_hdr[3] &= 0x3F, pay_hdr[3] |= (Start_Fragment <<6);
- }
- else{ /* could not be 'first' and 'last' */
- if(size<=THEORA_RTP_PAYLOAD_SIZE){
- /* Last frag */
- pay_hdr[3] &= 0x3F, pay_hdr[3] |= (End_Fragment <<6);
- }
- else{
- /* Continuation frag */
- pay_hdr[3] &= 0x3F, pay_hdr[3] |= (Continuation_Fragment <<6);
- }
- }
- }
- else{
- pay_hdr[3] |= 0x01; /* 'pkts' */
- pay_hdr[3] &= 0x3F, pay_hdr[3] |= (Not_Fragmented <<6);
- }
-
- if(self->rtp.size < (pay_size + sizeof(pay_hdr))){
- if(!(self->rtp.ptr = tsk_realloc(self->rtp.ptr, (pay_size + sizeof(pay_hdr))))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- return -2;
- }
- self->rtp.size = (pay_size + sizeof(pay_hdr));
- }
-
- memcpy(self->rtp.ptr, pay_hdr, sizeof(pay_hdr));
- memcpy((self->rtp.ptr + sizeof(pay_hdr)), data, pay_size);
- data += pay_size;
- size -= pay_size;
-
- // Send data over the network
- if(TMEDIA_CODEC_VIDEO(self)->callback){
- TMEDIA_CODEC_VIDEO(self)->callback(TMEDIA_CODEC_VIDEO(self)->callback_data, self->rtp.ptr, (pay_size + sizeof(pay_hdr)), (3003* (30/TMEDIA_CODEC_VIDEO(self)->fps)), (size == 0));
- }
- }
-
- return 0;
-}
-
-#endif /* HAVE_FFMPEG */ \ No newline at end of file
OpenPOWER on IntegriCloud