summaryrefslogtreecommitdiffstats
path: root/branches/1.0/tinyDAV/src/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'branches/1.0/tinyDAV/src/codecs')
-rw-r--r--branches/1.0/tinyDAV/src/codecs/amr/tdav_codec_amr.c810
-rw-r--r--branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv16.c249
-rw-r--r--branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv32.c0
-rw-r--r--branches/1.0/tinyDAV/src/codecs/dtmf/tdav_codec_dtmf.c123
-rw-r--r--branches/1.0/tinyDAV/src/codecs/g711/g711.c295
-rw-r--r--branches/1.0/tinyDAV/src/codecs/g711/tdav_codec_g711.c304
-rw-r--r--branches/1.0/tinyDAV/src/codecs/g729/tdav_codec_g729.c454
-rw-r--r--branches/1.0/tinyDAV/src/codecs/gsm/tdav_codec_gsm.c208
-rw-r--r--branches/1.0/tinyDAV/src/codecs/h261/tdav_codec_h261.c539
-rw-r--r--branches/1.0/tinyDAV/src/codecs/h263/tdav_codec_h263.c1230
-rw-r--r--branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264.c871
-rw-r--r--branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264_rtp.c356
-rw-r--r--branches/1.0/tinyDAV/src/codecs/ilbc/tdav_codec_ilbc.c256
-rw-r--r--branches/1.0/tinyDAV/src/codecs/mp4ves/tdav_codec_mp4ves.c634
-rw-r--r--branches/1.0/tinyDAV/src/codecs/msrp/tdav_codec_msrp.c110
-rw-r--r--branches/1.0/tinyDAV/src/codecs/speex/tdav_codec_speex.c282
-rw-r--r--branches/1.0/tinyDAV/src/codecs/theora/tdav_codec_theora.c707
17 files changed, 0 insertions, 7428 deletions
diff --git a/branches/1.0/tinyDAV/src/codecs/amr/tdav_codec_amr.c b/branches/1.0/tinyDAV/src/codecs/amr/tdav_codec_amr.c
deleted file mode 100644
index 71de9ee..0000000
--- a/branches/1.0/tinyDAV/src/codecs/amr/tdav_codec_amr.c
+++ /dev/null
@@ -1,810 +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_amr.c
- * @brief AMR-NB and AMR-WB codecs.
- * RTP payloader/depayloader are based on RFC 4867
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/amr/tdav_codec_amr.h"
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#include <stdlib.h> /* atoi() */
-
-#if HAVE_OPENCORE_AMR
-
-#if defined(_MSC_VER)
-# pragma comment(lib, "..\\thirdparties\\win32\\lib\\opencore\\libopencore-amrnb.a")
-#endif
-
-#define NO_DATA 15
-#define DEFAULT_ENC_MODE ((enum Mode)MR122) /* Higher, could be changed by remote party by using CMR */
-
-/* From WmfDecBytesPerFrame in dec_input_format_tab.cpp */
-static const int tdav_codec_amr_nb_sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };
-/* From pvamrwbdecoder_api.h, by dividing by 8 and rounding up */
-static const int tdav_codec_amr_wb_sizes[] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, -1, -1 };
-
-/* ============ Common ================= */
-int tdav_codec_amr_init(tdav_codec_amr_t* self, tdav_codec_amr_type_t type, tdav_codec_amr_mode_t mode);
-int tdav_codec_amr_deinit(tdav_codec_amr_t* self);
-tdav_codec_amr_mode_t tdav_codec_amr_get_mode(const char* fmtp);
-int tdav_codec_amr_parse_fmtp(tdav_codec_amr_t* self, const char* fmtp);
-tsk_size_t tdav_codec_amr_oa_decode(tdav_codec_amr_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);
-tsk_size_t tdav_codec_amr_be_decode(tdav_codec_amr_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);
-tsk_size_t tdav_codec_amr_be_encode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size);
-tsk_size_t tdav_codec_amr_oa_encode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size);
-uint8_t tdav_codec_amr_bitbuffer_read(const void* bits, tsk_size_t size, tsk_size_t start, tsk_size_t count);
-
-/* ============ AMR-NB Plugin interface =================
- The AMR codec was originally developed and standardized by the
- European Telecommunications Standards Institute (ETSI) for GSM
- cellular systems. It is now chosen by the Third Generation
- Partnership Project (3GPP) as the mandatory codec for third
- generation (3G) cellular systems [1].
-
- The AMR codec is a multi-mode codec that supports eight narrow band
- speech encoding modes with bit rates between 4.75 and 12.2 kbps. The
- sampling frequency used in AMR is 8000 Hz and the speech encoding is
- performed on 20 ms speech frames. Therefore, each encoded AMR speech
- frame represents 160 samples of the original speech.
-
- Among the eight AMR encoding modes, three are already separately
- adopted as standards of their own. Particularly, the 6.7 kbps mode
- is adopted as PDC-EFR [18], the 7.4 kbps mode as IS-641 codec in TDMA
- [17], and the 12.2 kbps mode as GSM-EFR [16].
-*/
-
-#define tdav_codec_amrnb_fmtp_set tsk_null
-
-int tdav_codec_amrnb_open(tmedia_codec_t* self)
-{
- tdav_codec_amr_t* amrnb = (tdav_codec_amr_t*)self;
-
- if(!TDAV_CODEC_AMR(amrnb)->encoder){
- if(!(TDAV_CODEC_AMR(amrnb)->encoder = Encoder_Interface_init(0))){
- TSK_DEBUG_ERROR("Failed to initialize AMR-NB encoder");
- return -2;
- }
- }
-
- if(!TDAV_CODEC_AMR(amrnb)->decoder){
- if(!(TDAV_CODEC_AMR(amrnb)->decoder = Decoder_Interface_init())){
- TSK_DEBUG_ERROR("Failed to initialize AMR-NB encoder");
- return -2;
- }
- }
-
- return 0;
-}
-
-int tdav_codec_amrnb_close(tmedia_codec_t* self)
-{
- tdav_codec_amr_t* amrnb = (tdav_codec_amr_t*)self;
-
- if(TDAV_CODEC_AMR(amrnb)->encoder){
- Encoder_Interface_exit(TDAV_CODEC_AMR(amrnb)->encoder);
- TDAV_CODEC_AMR(amrnb)->encoder = tsk_null;
- }
-
- if(TDAV_CODEC_AMR(amrnb)->decoder){
- Decoder_Interface_exit(TDAV_CODEC_AMR(amrnb)->decoder);
- TDAV_CODEC_AMR(amrnb)->decoder = tsk_null;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_amrnb_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tdav_codec_amr_t* amr = (tdav_codec_amr_t*)self;
-
- switch(amr->mode){
- case tdav_codec_amr_mode_be:
- return tdav_codec_amr_be_encode(amr, in_data, in_size, out_data, out_max_size);
- default:
- return tdav_codec_amr_oa_encode(amr, in_data, in_size, out_data, out_max_size);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_amrnb_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)
-{
- tdav_codec_amr_t* amr = (tdav_codec_amr_t*)self;
-
- switch(amr->mode){
- case tdav_codec_amr_mode_be:
- return tdav_codec_amr_be_decode(amr, in_data, in_size, out_data, out_max_size, proto_hdr);
- default:
- return tdav_codec_amr_oa_decode(amr, in_data, in_size, out_data, out_max_size, proto_hdr);
- }
-}
-
-char* tdav_codec_amrnb_fmtp_get(const tmedia_codec_t* codec)
-{
- const tdav_codec_amr_t* amr = (const tdav_codec_amr_t*)codec;
-
- /* We support all modes, all ... */
- if(amr){
- switch(amr->mode){
- case tdav_codec_amr_mode_be:
- return tsk_strdup("octet-align=0");
- default:
- return tsk_strdup("octet-align=1");
- }
- }
- return tsk_null;
-}
-
-tsk_bool_t tdav_codec_amrnb_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tdav_codec_amr_t* amr = (tdav_codec_amr_t*)codec;
-
- if(amr){
- /* Match mode */
- if(tdav_codec_amr_get_mode(fmtp) != amr->mode){
- TSK_DEBUG_INFO("Failed to match [%s]", fmtp);
- return tsk_false;
- }
- /* check parameters validity */
- if(tdav_codec_amr_parse_fmtp(amr, fmtp)){
- TSK_DEBUG_INFO("Failed to match [%s]", fmtp);
- return tsk_false;
- }
-
- return tsk_true;
- }
- return tsk_false;
-}
-
-
-//
-// AMR-NB OA Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_amrnb_oa_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_amr_t *amrnb_oa = self;
- if(amrnb_oa){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_amr_init(TDAV_CODEC_AMR(amrnb_oa), tdav_codec_amr_type_nb, tdav_codec_amr_mode_oa);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_amrnb_oa_dtor(tsk_object_t * self)
-{
- tdav_codec_amr_t *amrnb_oa = self;
- if(amrnb_oa){
- /* deinit base */
- tmedia_codec_audio_deinit(amrnb_oa);
- /* deinit self */
- tdav_codec_amr_deinit(TDAV_CODEC_AMR(amrnb_oa));
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_amrnb_oa_def_s =
-{
- sizeof(tdav_codec_amr_t),
- tdav_codec_amrnb_oa_ctor,
- tdav_codec_amrnb_oa_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_amrnb_oa_plugin_def_s =
-{
- &tdav_codec_amrnb_oa_def_s,
-
- tmedia_audio,
- "AMR",
- "AMR Narrow Band - Octet Aligned",
- TMEDIA_CODEC_FORMAT_AMR_NB_OA,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_amrnb_open,
- tdav_codec_amrnb_close,
- tdav_codec_amrnb_encode,
- tdav_codec_amrnb_decode,
- tdav_codec_amrnb_fmtp_match,
- tdav_codec_amrnb_fmtp_get,
- tdav_codec_amrnb_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_amrnb_oa_plugin_def_t = &tdav_codec_amrnb_oa_plugin_def_s;
-
-//
-// AMR-NB BE Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_amrnb_be_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_amr_t *amrnb_be = self;
- if(amrnb_be){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_amr_init(TDAV_CODEC_AMR(amrnb_be), tdav_codec_amr_type_nb, tdav_codec_amr_mode_be);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_amrnb_be_dtor(tsk_object_t * self)
-{
- tdav_codec_amr_t *amrnb_be = self;
- if(amrnb_be){
- /* deinit base */
- tmedia_codec_audio_deinit(amrnb_be);
- /* deinit self */
- tdav_codec_amr_deinit(TDAV_CODEC_AMR(amrnb_be));
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_amrnb_be_def_s =
-{
- sizeof(tdav_codec_amr_t),
- tdav_codec_amrnb_be_ctor,
- tdav_codec_amrnb_be_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_amrnb_be_plugin_def_s =
-{
- &tdav_codec_amrnb_be_def_s,
-
- tmedia_audio,
- "AMR",
- "AMR Narrow Band - Bandwidth-Efficient",
- TMEDIA_CODEC_FORMAT_AMR_NB_BE,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_amrnb_open,
- tdav_codec_amrnb_close,
- tdav_codec_amrnb_encode,
- tdav_codec_amrnb_decode,
- tdav_codec_amrnb_fmtp_match,
- tdav_codec_amrnb_fmtp_get,
- tdav_codec_amrnb_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_amrnb_be_plugin_def_t = &tdav_codec_amrnb_be_plugin_def_s;
-
-
-
-
-
-
-
-
-
-//
-// Common functions
-//
-
-int tdav_codec_amr_init(tdav_codec_amr_t* self, tdav_codec_amr_type_t type, tdav_codec_amr_mode_t mode)
-{
- if(self){
- self->type = type;
- self->mode = mode;
- self->encoder_mode = DEFAULT_ENC_MODE;
-
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid Parameter");
- return -1;
- }
-}
-
-int tdav_codec_amr_deinit(tdav_codec_amr_t* self)
-{
- if(self){
- switch(self->type){
- case tdav_codec_amr_type_nb:
- { /* AMR-NB */
- if(self->encoder){
- Encoder_Interface_exit(self->encoder);
- self->encoder = tsk_null;
- }
- if(self->decoder){
- Decoder_Interface_exit(self->decoder);
- self->decoder = tsk_null;
- }
- break;
- }
- case tdav_codec_amr_type_wb:
- { /* AMR-WB */
- break;
- }
- }
-
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid Parameter");
- return -1;
- }
-}
-
-tdav_codec_amr_mode_t tdav_codec_amr_get_mode(const char* fmtp)
-{
- /* RFC 4867 - 8.1. AMR Media Type Registration
- octet-align: Permissible values are 0 and 1. If 1, octet-aligned
- operation SHALL be used. If 0 or if not present, bandwidth-efficient operation is employed.
- */
- tdav_codec_amr_mode_t mode = tdav_codec_amr_mode_be;
- tsk_size_t size = tsk_strlen(fmtp);
- int start, end;
-
- if((start = tsk_strindexOf(fmtp, size, "octet-align")) !=-1){
- tsk_param_t* param;
- if((end = tsk_strindexOf((fmtp+start), (size-start), ";")) == -1){
- end = size;
- }
- if((param = tsk_params_parse_param((fmtp+start), (end-start)))){
- if(param->value && tsk_strequals(param->value, "1")){
- mode = tdav_codec_amr_mode_oa;
- }
- TSK_OBJECT_SAFE_FREE(param);
- }
- }
- return mode;
-}
-
-int tdav_codec_amr_parse_fmtp(tdav_codec_amr_t* self, const char* fmtp)
-{
- int ret = 0;
- int val_int;
- const char* val_str;
- //--tdav_codec_amr_mode_t mode = self->mode;
- tsk_params_L_t* params = tsk_null;
-
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
- /* Do not check "octet-align" => already done by the caller of this function */
-
- /* === mode-set ===*/
- if((val_str = tsk_params_get_param_value(params, "mode-set"))){
- char* modes = tsk_strdup(val_str);
- char* pch;
- int mode_int;
- pch = strtok(modes, ", ");
- while(pch){
- mode_int = atoi(pch);
- self->modes |= 0x0001 << mode_int;
- pch = strtok(tsk_null, ", ");
- }
-
- TSK_FREE(modes);
- }
- else{
- self->modes = 0xFFFF;
- }
-
- /* === interleaving ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "interleaving")) != -1){
- TSK_DEBUG_WARN("interleaving not supported");
- ret = -1; goto bail;
- }
- /* === mode-change-period ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "mode-change-period")) != -1){
- if(val_int != 1 && val_int != 2){
- TSK_DEBUG_ERROR("Invalid [mode-change-period]");
- ret = -1; goto bail;
- }
- self->mcp = (unsigned)val_int;
- }
- /* === mode-change-capability ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "mode-change-capability")) != -1){
- if(val_int != 1 && val_int != 2){
- TSK_DEBUG_ERROR("Invalid [mode-change-capability]");
- ret = -1; goto bail;
- }
- self->mcc = (unsigned)val_int;
- }
- /* === mode-change-neighbor ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "mode-change-neighbor")) != -1){
- if(val_int != 0 && val_int != 1){
- TSK_DEBUG_ERROR("Invalid [mode-change-neighbor]");
- ret = -1; goto bail;
- }
- self->mcn = (unsigned)val_int;
- }
- }
-
-bail:
- TSK_OBJECT_SAFE_FREE(params);
- return ret;
-}
-
-
-/* RFC 4867 - 4.2. Payload Structure
- +----------------+-------------------+----------------
- | payload header | table of contents | speech data ...
- +----------------+-------------------+----------------
-*/
-/* RFC 4867 - 4.4.2. The Payload Table of Contents and Frame CRCs
- The table of contents (ToC) consists of a list of ToC entries, each representing a speech frame.
- +---------------------+
- | list of ToC entries |
- +---------------------+
- | list of frame CRCs | (optional)
- - - - - - - - - - - -
- Note, for ToC entries with FT=14 or 15, there will be no
- corresponding speech frame or frame CRC present in the payload.
-*/
-
-
-tsk_size_t tdav_codec_amr_be_encode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t out_size = 0, i;
- int ret_size;
- uint8_t ToC;
- static uint8_t CMR = NO_DATA /* No interleaving */;
-
- uint8_t outbuf[60 + 1]; /* enought for both NB and WB at ptime=20ms */
- if(!amr || !in_data || !in_size || !out_data || (amr->mode != tdav_codec_amr_mode_be)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* Encode */
- if((ret_size = Encoder_Interface_Encode(amr->encoder, amr->encoder_mode, in_data, outbuf, 0)) <= 0){
- TSK_DEBUG_ERROR("Encoder_Interface_Encode() failed");
- goto bail;
- }
-
-
- /* allocate output buffer */
- if((int)*out_max_size <ret_size){
- if(!(*out_data = tsk_realloc(*out_data, ret_size))){
- *out_max_size = 0;
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- goto bail;
- }
- *out_max_size = ret_size;
- }
-
- out_size = ret_size;
-
- /* CMR (4bits) */
- ((uint8_t*)*out_data)[0] = (CMR<<4);
- /* ToC (Always ONE Frame, don't need to test for [F]) (6bits)*/
- ToC = outbuf[0]>>2/*2*[P]*/;
- ((uint8_t*)*out_data)[0] |= (ToC >> 2/*[Q],[1-FT]*/) & 0xF; /* 4bits */
- ((uint8_t*)*out_data)[1] = (ToC & 0x3/*[1-FT],[Q]*/)<<6; /* 2bits */
-
- /* === THERE ARE 2 EXTRA BITS === */
-
- for(i=1; i<out_size-1; i++){
- ((uint8_t*)*out_data)[i] |= outbuf[i]>>2;/* 6bits */
- ((uint8_t*)*out_data)[i+1] = outbuf[i]<<6;/* 2bits */
- }
-
-bail:
- return out_size;
-}
-
-tsk_size_t tdav_codec_amr_be_decode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
-{
- tsk_size_t out_size = 0, pcm_frame_size = 0, index = 0;
- const uint8_t* pdata = (const uint8_t*)in_data;
- //--const uint8_t* pend = (pdata + in_size);
- uint8_t CMR;
- int toc_entries = 0, i, k; // ToC entries count
-
- if(!amr || !in_data || !in_size || !out_data || (amr->mode != tdav_codec_amr_mode_be)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* compute PCM frame size */
- switch(TDAV_CODEC_AMR(amr)->type){
- case tdav_codec_amr_type_nb:
- pcm_frame_size = 160 * sizeof(short);
- break;
- case tdav_codec_amr_type_wb:
- pcm_frame_size = 320 * sizeof(short);
- break;
- default:
- TSK_DEBUG_ERROR("Invalid AMR type");
- return 0;
- }
-
- /* CMR (4bits) */
- CMR = tdav_codec_amr_bitbuffer_read(in_data, (in_size*8), index, 4);
- index += 4;
- if(CMR != NO_DATA){
- amr->encoder_mode = (enum Mode)CMR;
- }
-
- /* F(1bit), FT(4bits), Q(1bit) */
- /* count ToC entries */
- do{ /* At least ONE ToC */
- ++toc_entries;
- ++pdata;
- index += 6;
- }
- while((index < (in_size*8)) && (tdav_codec_amr_bitbuffer_read(in_data, (in_size*8), (index-6), 1)/* F */));
-
- for(i = 0; (i<toc_entries && (in_size < (in_size*8))) ; i++){
- int size = -1;
- uint8_t* speech_data = tsk_null;
- //--int speech_data_size = 0;
- uint8_t ToC = tdav_codec_amr_bitbuffer_read(in_data, (in_size*8), 4/*CMR*/ + (i*6), 6);
-
- switch(TDAV_CODEC_AMR(amr)->type){
- case tdav_codec_amr_type_nb:
- size = tdav_codec_amr_nb_sizes[(ToC>>1)&0x0F/* FT */];
- break;
- case tdav_codec_amr_type_wb:
- size = tdav_codec_amr_wb_sizes[(ToC>>1)&0x0F/* FT */];
- break;
- }
-
- if((speech_data = tsk_calloc((size + 2/* ToC + '\0' */), sizeof(uint8_t)))){
- /* copy ToC */
- speech_data[0] = (ToC & 0x1F)<<2/* 2*[P] */; /* ToC as OA layout */
- /* copy speech data */
- for(k=0; k<size; k++){
- speech_data[1 + k] = tdav_codec_amr_bitbuffer_read(in_data, (in_size*8), index, 8);
- index+=8;
- if((k==size-1) && (index%8)){
- speech_data[1 + k] <<= (8-(index%8)); //clean
- }
- }
-
- /* allocate/reallocate speech data */
- if(*out_max_size <(out_size + pcm_frame_size)){
- if(!(*out_data = tsk_realloc(*out_data, (out_size + pcm_frame_size)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- TSK_FREE(speech_data);
- goto bail;
- }
- *out_max_size = out_size + pcm_frame_size;
- }
-
- /* decode speech data */
- Decoder_Interface_Decode(amr->decoder, speech_data, &((short*)*out_data)[out_size/sizeof(short)], 0);
- out_size += pcm_frame_size, pdata+= size;
-
- TSK_FREE(speech_data);
- }
- }
-
-bail:
- return out_size;
-}
-
-tsk_size_t tdav_codec_amr_oa_encode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t out_size = 0;
- int ret_size;
- static uint8_t CMR = NO_DATA /* No interleaving */;
-
- uint8_t outbuf[60 + 1]; /* enought for both NB and WB at ptime=20ms */
- if(!amr || !in_data || !in_size || !out_data || (amr->mode != tdav_codec_amr_mode_oa)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* Encode */
- if((ret_size = Encoder_Interface_Encode(amr->encoder, amr->encoder_mode, in_data, outbuf, 0)) <= 0){
- TSK_DEBUG_ERROR("Encoder_Interface_Encode() failed");
- goto bail;
- }
-
- out_size = ret_size + 1 /* CMR without interleaving */;
- /* allocate output buffer */
- if(*out_max_size <out_size){
- if(!(*out_data = tsk_realloc(*out_data, out_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = out_size = 0;
- goto bail;
- }
- *out_max_size = out_size;
- }
-
- /* CMR */
- ((uint8_t*)*out_data)[0] = (CMR << 4);
- /* Only ONE ToC --> believe me */
- memcpy(&((uint8_t*)*out_data)[1], outbuf, ret_size);
-
-bail:
- return out_size;
-}
-
-tsk_size_t tdav_codec_amr_oa_decode(tdav_codec_amr_t* amr, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
-{
- tsk_size_t out_size = 0, pcm_frame_size = 0;
- const uint8_t* pdata = (const uint8_t*)in_data;
- const uint8_t* pend = (pdata + in_size);
- uint8_t CMR;
- int toc_entries = 0, i; // ToC entries count
-
- if(!amr || !in_data || !in_size || !out_data || (amr->mode != tdav_codec_amr_mode_oa)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* compute PCM frame size */
- switch(TDAV_CODEC_AMR(amr)->type){
- case tdav_codec_amr_type_nb:
- pcm_frame_size = 160 * sizeof(short);
- break;
- case tdav_codec_amr_type_wb:
- pcm_frame_size = 320 * sizeof(short);
- break;
- default:
- TSK_DEBUG_ERROR("Invalid AMR type");
- return 0;
- }
-
- /* RFC 4867 - 4.4. Octet-Aligned Mode
- In octet-aligned mode, the payload header consists of a 4-bit CMR, 4
- reserved bits, and optionally, an 8-bit interleaving header, as shown
- below:
-
- 0 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +-+-+-+-+-+-+-+-+- - - - - - - -
- | CMR |R|R|R|R| ILL | ILP |
- +-+-+-+-+-+-+-+-+- - - - - - - -
-
- CMR (4 bits): same as defined in Section 4.3.1.
-
- "interleaving" not supported ==> could ignore ILL and ILP (wich are optional)
- */
-
- CMR = (*pdata++ >> 4);
- if(CMR != NO_DATA){
- /* The codec mode request received in the CMR field is valid until the
- next codec mode request is received, i.e., a newly received CMR value
- corresponding to a speech mode, or NO_DATA overrides the previously
- received CMR value corresponding to a speech mode or NO_DATA. */
- amr->encoder_mode = (enum Mode)CMR; // As we support all modes, do not check for validity
- }
-
- /*
- A ToC entry takes the following format in octet-aligned mode:
- 0 1 2 3 4 5 6 7
- +-+-+-+-+-+-+-+-+
- |F| FT |Q|P|P|
- +-+-+-+-+-+-+-+-+
-
- F (1 bit): see definition in Section 4.3.2.
- FT (4 bits, unsigned integer): see definition in Section 4.3.2.
- Q (1 bit): see definition in Section 4.3.2.
- P bits: padding bits, MUST be set to zero, and MUST be ignored on reception.
- */
-
- /* count ToC entries */
- do{ /* At least ONE ToC */
- ++toc_entries;
- ++pdata;
- }
- while(pdata && (pdata < pend) && (pdata[-1] >> 7/* F */));
-
- for(i = 0; (i<toc_entries && (pdata < pend)) ; i++){
- int size = -1;
- uint8_t* speech_data = tsk_null;
- //--int speech_data_size = 0;
- uint8_t ToC = ((const uint8_t*)in_data)[1/*CMR...*/ + i];
- switch(TDAV_CODEC_AMR(amr)->type){
- case tdav_codec_amr_type_nb:
- size = tdav_codec_amr_nb_sizes[(ToC>>3) & 0x0F/* FT */];
- break;
- case tdav_codec_amr_type_wb:
- size = tdav_codec_amr_wb_sizes[(ToC>>3) & 0x0F/* FT */];
- break;
- }
-
- /* check size */
- if(size <0 || ((pdata + size) > pend)){
- TSK_DEBUG_ERROR("Invalid size");
- break;
- }
-
- if((speech_data = tsk_calloc((size + 2/* ToC + '\0' */), sizeof(uint8_t)))){
- /* copy ToC */
- *speech_data = ToC & 0x7F/* with 'F'=0 */;
- /* copy speech data */
- memcpy((speech_data + 1), pdata, size);
- /* allocate/reallocate speech data */
- if(*out_max_size <(out_size + pcm_frame_size)){
- if(!(*out_data = tsk_realloc(*out_data, (out_size + pcm_frame_size)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- TSK_FREE(speech_data);
- goto bail;
- }
- *out_max_size = (out_size + pcm_frame_size);
- }
- /* decode speech data */
- Decoder_Interface_Decode(amr->decoder, speech_data, &((short*)*out_data)[out_size/sizeof(short)], 0);
- out_size += pcm_frame_size, pdata+= size;
-
- TSK_FREE(speech_data);
- }
- }
-
-bail:
- return out_size;
-}
-
-
-uint8_t tdav_codec_amr_bitbuffer_read(const void* bits, tsk_size_t size, tsk_size_t start, tsk_size_t count)
-{
- uint8_t byte, left, right, pad;
-
- if(!bits || !size || count>8){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if((start + count) > size){
- count = (size - start);
- }
-
- pad = start ? (8 - (start % 8)) : count;
- left = ((uint8_t*)bits)[start/8] << (8-pad);
- right = ((uint8_t*)bits)[((start+count)<size ? (start+count) : start)/8] >> pad;
-
- if((start && (start % 8) != ((start+count)%8)) || (!start && count>8)){
- /* overlap */
- byte = (left | right) >> (8-count);
- }
- else{
- byte = (left | right) & (0xFF >> (8-count));
- }
-
- return byte;
-}
-
-#endif /* HAVE_OPENCORE_AMR */
diff --git a/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv16.c b/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv16.c
deleted file mode 100644
index f78f526..0000000
--- a/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv16.c
+++ /dev/null
@@ -1,249 +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_bv16.c
- * @brief BroadVoice16 codec
- * The payloader/depayloader follow RFC 4298
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/bv/tdav_codec_bv16.h"
-
-#if HAVE_BV16
-
-#if defined(_MSC_VER)
-# pragma comment(lib, "..\\thirdparties\\win32\\lib\\BroadVoice16\\libbv16.a")
-#endif
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#include "typedef.h"
-#include "bvcommon.h"
-#include "bv16cnst.h"
-#include "bv16strct.h"
-#include "bv16.h"
-#include "utility.h"
-#if G192BITSTREAM
-#include "g192.h"
-#else
-#include "bitpack.h"
-#endif
-#include "memutil.h"
-
-/* RFC 4298 - 3.1. BroadVoice16 Bit Stream Definition */
-#define TDAV_BV16_FRAME_SIZE 10
-#define FRSZ_IN_U8 (FRSZ*2)
-
-/* ============ BV16 Plugin interface ================= */
-
-#define tdav_codec_bv16_fmtp_get tsk_null
-#define tdav_codec_bv16_fmtp_set tsk_null
-
-static int sizestate = sizeof(struct BV16_Encoder_State);
-static int sizebitstream = sizeof(struct BV16_Bit_Stream);
-
-int tdav_codec_bv16_open(tmedia_codec_t* self)
-{
- tdav_codec_bv16_t* bv16 = (tdav_codec_bv16_t*)self;
-
- if(!bv16->encoder.state){
- bv16->encoder.state = allocWord16(0, sizestate/2-1);
- Reset_BV16_Encoder((struct BV16_Encoder_State*)bv16->encoder.state);
- }
- if(!bv16->encoder.bs){
- bv16->encoder.bs = allocWord16(0, sizebitstream/2-1);
- }
- if(!bv16->encoder.x){
- bv16->encoder.x = allocWord16(0, FRSZ-1);
- }
-
- if(!bv16->decoder.state){
- bv16->decoder.state = allocWord16(0, sizestate/2-1);
- Reset_BV16_Decoder((struct BV16_Decoder_State*)bv16->decoder.state);
- }
- if(!bv16->decoder.bs){
- bv16->decoder.bs = allocWord16(0, sizebitstream/2-1);
- }
- if(!bv16->decoder.x){
- bv16->decoder.x = allocWord16(0, FRSZ-1);
- }
-
- return 0;
-}
-
-int tdav_codec_bv16_close(tmedia_codec_t* self)
-{
- tdav_codec_bv16_t* bv16 = (tdav_codec_bv16_t*)self;
-
- if(bv16->encoder.state){
- deallocWord16(bv16->encoder.state, 0, sizestate/2-1);
- bv16->encoder.state = tsk_null;
- }
- if(bv16->encoder.bs){
- deallocWord16(bv16->encoder.bs, 0, sizebitstream/2-1);
- bv16->encoder.bs = tsk_null;
- }
- if(bv16->encoder.x){
- deallocWord16(bv16->encoder.x, 0, FRSZ-1);
- bv16->encoder.x = tsk_null;
- }
-
- if(bv16->decoder.state){
- deallocWord16(bv16->decoder.state, 0, sizestate/2-1);
- bv16->decoder.state = tsk_null;
- }
- if(bv16->encoder.bs){
- deallocWord16(bv16->decoder.bs, 0, sizebitstream/2-1);
- bv16->decoder.bs = tsk_null;
- }
- if(bv16->decoder.x){
- deallocWord16(bv16->decoder.x, 0, FRSZ-1);
- bv16->decoder.x = tsk_null;
- }
-
-
-
- return 0;
-}
-
-tsk_size_t tdav_codec_bv16_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- //tsk_size_t out_size = 0;
- tdav_codec_bv16_t* bv16 = (tdav_codec_bv16_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_bv16_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)
-{
- tsk_size_t out_size = 0;
- int i;
- tdav_codec_bv16_t* bv16 = (tdav_codec_bv16_t*)self;
- uint8_t mama[600];
-
- if(!self || !in_data || !in_size || !out_data || (in_size % TDAV_BV16_FRAME_SIZE)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- for(i=0; i<(int)in_size; i+=TDAV_BV16_FRAME_SIZE){
- BV16_BitUnPack(mama, (struct BV16_Bit_Stream*)bv16->decoder.bs);
- //BV16_BitUnPack(&((UWord8 *)in_data)[i], (struct BV16_Bit_Stream*)bv16->decoder.bs);
- BV16_Decode((struct BV16_Bit_Stream*)bv16->decoder.bs, (struct BV16_Decoder_State*)bv16->decoder.state, bv16->decoder.x);
-
-
- if(*out_max_size<(out_size + FRSZ_IN_U8)){
- if(!(*out_data = tsk_realloc(*out_data, (out_size + FRSZ_IN_U8)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = (out_size + FRSZ_IN_U8);
- }
- memcpy(&((uint8_t*)* out_data)[out_size], bv16->decoder.x, FRSZ_IN_U8);
- out_size += FRSZ_IN_U8;
- }
-
-
- return out_size;
-}
-
-tsk_bool_t tdav_codec_bv16_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-
-//
-// BV16 Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_bv16_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_bv16_t *bv16 = self;
- if(bv16){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_bv16_dtor(tsk_object_t * self)
-{
- tdav_codec_bv16_t *bv16 = self;
- if(bv16){
- /* deinit base */
- tmedia_codec_audio_deinit(bv16);
- /* deinit self */
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_bv16_def_s =
-{
- sizeof(tdav_codec_bv16_t),
- tdav_codec_bv16_ctor,
- tdav_codec_bv16_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_bv16_plugin_def_s =
-{
- &tdav_codec_bv16_def_s,
-
- tmedia_audio,
- "BV16",
- "BroadVoice16 Rate",
- TMEDIA_CODEC_FORMAT_BV16,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_bv16_open,
- tdav_codec_bv16_close,
- tdav_codec_bv16_encode,
- tdav_codec_bv16_decode,
- tdav_codec_bv16_fmtp_match,
- tdav_codec_bv16_fmtp_get,
- tdav_codec_bv16_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_bv16_plugin_def_t = &tdav_codec_bv16_plugin_def_s;
-
-
-#endif /* HAVE_BV16 */
diff --git a/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv32.c b/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv32.c
deleted file mode 100644
index e69de29..0000000
--- a/branches/1.0/tinyDAV/src/codecs/bv/tdav_codec_bv32.c
+++ /dev/null
diff --git a/branches/1.0/tinyDAV/src/codecs/dtmf/tdav_codec_dtmf.c b/branches/1.0/tinyDAV/src/codecs/dtmf/tdav_codec_dtmf.c
deleted file mode 100644
index cbd9a03..0000000
--- a/branches/1.0/tinyDAV/src/codecs/dtmf/tdav_codec_dtmf.c
+++ /dev/null
@@ -1,123 +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_dtmf.c
- * @brief DTMF (RFC 4733) codec plugins.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/dtmf/tdav_codec_dtmf.h"
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-
-/* ============ DTMF Plugin interface ================= */
-
-#define tdav_codec_dtmf_fmtp_set tsk_null
-
-tsk_size_t tdav_codec_dtmf_fmtp_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- return 0;
-}
-
-tsk_size_t tdav_codec_dtmf_fmtp_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)
-{
- return 0;
-}
-
-char* tdav_codec_dtmf_fmtp_get(const tmedia_codec_t* self)
-{
- return tsk_strdup("0-15");
-}
-
-tsk_bool_t tdav_codec_dtmf_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-
-//
-// DTMF Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_dtmf_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_dtmf_t *dtmf = self;
- if(dtmf){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_dtmf_dtor(tsk_object_t * self)
-{
- tdav_codec_dtmf_t *dtmf = self;
- if(dtmf){
- /* deinit base */
- tmedia_codec_audio_deinit(dtmf);
- /* deinit self */
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_dtmf_def_s =
-{
- sizeof(tdav_codec_dtmf_t),
- tdav_codec_dtmf_ctor,
- tdav_codec_dtmf_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_dtmf_plugin_def_s =
-{
- &tdav_codec_dtmf_def_s,
-
- tmedia_audio,
- "telephone-event",
- "DTMF Codec (RFC 4733)",
- TMEDIA_CODEC_FORMAT_DTMF,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tsk_null, // open
- tsk_null, // close
- tdav_codec_dtmf_fmtp_encode,
- tdav_codec_dtmf_fmtp_decode,
- tdav_codec_dtmf_fmtp_match,
- tdav_codec_dtmf_fmtp_get,
- tdav_codec_dtmf_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_dtmf_plugin_def_t = &tdav_codec_dtmf_plugin_def_s;
diff --git a/branches/1.0/tinyDAV/src/codecs/g711/g711.c b/branches/1.0/tinyDAV/src/codecs/g711/g711.c
deleted file mode 100644
index 744fad1..0000000
--- a/branches/1.0/tinyDAV/src/codecs/g711/g711.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use. Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-
-/*
- * g711.c
- *
- * u-law, A-law and linear PCM conversions.
- */
-
-/*
- * December 30, 1994:
- * Functions linear2alaw, linear2ulaw have been updated to correctly
- * convert unquantized 16 bit values.
- * Tables for direct u- to A-law and A- to u-law conversions have been
- * corrected.
- * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
- * bli@cpk.auc.dk
- *
- */
-
-#include "tinydav/codecs/g711/g711.h"
-
-#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
-#define QUANT_MASK (0xf) /* Quantization field mask. */
-#define NSEGS (8) /* Number of A-law segments. */
-#define SEG_SHIFT (4) /* Left shift for segment number. */
-#define SEG_MASK (0x70) /* Segment field mask. */
-
-static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
- 0x1FF, 0x3FF, 0x7FF, 0xFFF};
-static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
- 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
-
-/* copy from CCITT G.711 specifications */
-unsigned char _u2a[128] = { /* u- to A-law conversions */
- 1, 1, 2, 2, 3, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 8, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 27, 29, 31, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44,
- 46, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62,
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
-/* corrected:
- 81, 82, 83, 84, 85, 86, 87, 88,
- should be: */
- 80, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128};
-
-unsigned char _a2u[128] = { /* A- to u-law conversions */
- 1, 3, 5, 7, 9, 11, 13, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 33, 34, 34, 35, 35,
- 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 48, 49, 49,
- 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 64,
- 65, 66, 67, 68, 69, 70, 71, 72,
-/* corrected:
- 73, 74, 75, 76, 77, 78, 79, 79,
- should be: */
- 73, 74, 75, 76, 77, 78, 79, 80,
-
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127};
-
-static short search(short val, short *table, short size)
-{
- short i;
-
- for (i = 0; i < size; i++) {
- if (val <= *table++)
- return (i);
- }
- return (size);
-}
-
-/*
- * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
- *
- * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
- *
- * Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 0000000wxyza 000wxyz
- * 0000001wxyza 001wxyz
- * 000001wxyzab 010wxyz
- * 00001wxyzabc 011wxyz
- * 0001wxyzabcd 100wxyz
- * 001wxyzabcde 101wxyz
- * 01wxyzabcdef 110wxyz
- * 1wxyzabcdefg 111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char linear2alaw(short pcm_val) /* 2's complement (16-bit range) */
-{
- short mask;
- short seg;
- unsigned char aval;
-
- pcm_val = pcm_val >> 3;
-
- if (pcm_val >= 0) {
- mask = 0xD5; /* sign (7th) bit = 1 */
- } else {
- mask = 0x55; /* sign bit = 0 */
- pcm_val = -pcm_val - 1;
- }
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_aend, 8);
-
- /* Combine the sign, segment, and quantization bits. */
-
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- aval = (unsigned char) seg << SEG_SHIFT;
- if (seg < 2)
- aval |= (pcm_val >> 1) & QUANT_MASK;
- else
- aval |= (pcm_val >> seg) & QUANT_MASK;
- return (aval ^ mask);
- }
-}
-
-/*
- * alaw2linear() - Convert an A-law value to 16-bit linear PCM
- *
- */
-short alaw2linear(unsigned char a_val)
-{
- short t;
- short seg;
-
- a_val ^= 0x55;
-
- t = (a_val & QUANT_MASK) << 4;
- seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
- switch (seg) {
- case 0:
- t += 8;
- break;
- case 1:
- t += 0x108;
- break;
- default:
- t += 0x108;
- t <<= seg - 1;
- }
- return ((a_val & SIGN_BIT) ? t : -t);
-}
-
-#define BIAS (0x84) /* Bias for linear code. */
-#define CLIP 8159
-
-/*
- * linear2ulaw() - Convert a linear PCM value to u-law
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- * Biased Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 00000001wxyza 000wxyz
- * 0000001wxyzab 001wxyz
- * 000001wxyzabc 010wxyz
- * 00001wxyzabcd 011wxyz
- * 0001wxyzabcde 100wxyz
- * 001wxyzabcdef 101wxyz
- * 01wxyzabcdefg 110wxyz
- * 1wxyzabcdefgh 111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz. * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char linear2ulaw(short pcm_val) /* 2's complement (16-bit range) */
-{
- short mask;
- short seg;
- unsigned char uval;
-
- /* Get the sign and the magnitude of the value. */
- pcm_val = pcm_val >> 2;
- if (pcm_val < 0) {
- pcm_val = -pcm_val;
- mask = 0x7F;
- } else {
- mask = 0xFF;
- }
- if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
- pcm_val += (BIAS >> 2);
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_uend, 8);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
- return (uval ^ mask);
- }
-
-}
-
-/*
- * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-short ulaw2linear(unsigned char u_val)
-{
- short t;
-
- /* Complement to obtain normal u-law value. */
- u_val = ~u_val;
-
- /*
- * Extract and bias the quantization bits. Then
- * shift up by the segment number and subtract out the bias.
- */
- t = ((u_val & QUANT_MASK) << 3) + BIAS;
- t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
-
- return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
-}
-
-/* A-law to u-law conversion */
-unsigned char alaw2ulaw(unsigned char aval)
-{
- aval &= 0xff;
- return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
- (0x7F ^ _a2u[aval ^ 0x55]));
-}
-
-/* u-law to A-law conversion */
-unsigned char ulaw2alaw(unsigned char uval)
-{
- uval &= 0xff;
- return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
- (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
-}
diff --git a/branches/1.0/tinyDAV/src/codecs/g711/tdav_codec_g711.c b/branches/1.0/tinyDAV/src/codecs/g711/tdav_codec_g711.c
deleted file mode 100644
index 4f2dbbe..0000000
--- a/branches/1.0/tinyDAV/src/codecs/g711/tdav_codec_g711.c
+++ /dev/null
@@ -1,304 +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_g711.c
- * @brief G.711u and G.711a (a.k.a PCMU and PCMA) codec plugins.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/g711/tdav_codec_g711.h"
-
-#include "tinydav/codecs/g711/g711.h" /* alforithms */
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-/* ============ G.711u Plugin interface ================= */
-
-#define tdav_codec_g711u_fmtp_get tsk_null
-#define tdav_codec_g711u_fmtp_set tsk_null
-
-tsk_size_t tdav_codec_g711u_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t i;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if(*out_max_size <in_size/2){
- if(!(*out_data = tsk_realloc(*out_data, in_size/2))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = in_size/2;
- }
-
- for(i = 0; i<(in_size/2); i++){
- ((uint8_t*)*out_data)[i] = linear2ulaw(((short*)in_data)[i]);
- }
-
- return (in_size/2);
-}
-
-tsk_size_t tdav_codec_g711u_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)
-{
- tsk_size_t i;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* allocate new buffer */
- if(*out_max_size<(in_size*2)){
- if(!(*out_data = tsk_calloc(in_size, sizeof(short)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = in_size*2;
- }
-
- for(i = 0; i<in_size; i++){
- ((short*)*out_data)[i] = ulaw2linear(((uint8_t*)in_data)[i]);
- }
-
- return (in_size*2);
-}
-
-tsk_bool_t tdav_codec_g711u_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-
-//
-// G.711u Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_g711u_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_g711u_t *g711u = self;
- if(g711u){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_g711u_dtor(tsk_object_t * self)
-{
- tdav_codec_g711u_t *g711u = self;
- if(g711u){
- /* deinit base */
- tmedia_codec_audio_deinit(g711u);
- /* deinit self */
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_g711u_def_s =
-{
- sizeof(tdav_codec_g711u_t),
- tdav_codec_g711u_ctor,
- tdav_codec_g711u_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_g711u_plugin_def_s =
-{
- &tdav_codec_g711u_def_s,
-
- tmedia_audio,
- "PCMU",
- "G.711u codec (From tinyDAV)",
- TMEDIA_CODEC_FORMAT_G711u,
- tsk_false,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tsk_null, // open
- tsk_null, // close
- tdav_codec_g711u_encode,
- tdav_codec_g711u_decode,
- tdav_codec_g711u_fmtp_match,
- tdav_codec_g711u_fmtp_get,
- tdav_codec_g711u_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_g711u_plugin_def_t = &tdav_codec_g711u_plugin_def_s;
-
-
-/* ============ G.711a Plugin interface ================= */
-
-#define tdav_codec_g711a_fmtp_get tsk_null
-#define tdav_codec_g711a_fmtp_set tsk_null
-
-tsk_size_t tdav_codec_g711a_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t i;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if(*out_max_size <in_size/2){
- if(!(*out_data = tsk_realloc(*out_data, in_size/2))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = in_size/2;
- }
-
- for(i = 0; i<(in_size/2); i++){
- ((uint8_t*)*out_data)[i] = linear2alaw(((short*)in_data)[i]);
- }
-
- return (in_size/2);
-}
-
-#if 0
-FILE* file = tsk_null;
-int count = 0;
-#endif
-tsk_size_t tdav_codec_g711a_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)
-{
- tsk_size_t i;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-#if 0
- if(!file && count<=1000){
- file = fopen("./g711a.pcm", "wb");
- }
-#endif
- /* allocate new buffer */
- if(*out_max_size<(in_size*2)){
- if(!(*out_data = tsk_realloc(*out_data, in_size*2))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = in_size*2;
- }
-
- for(i = 0; i<in_size; i++){
- ((short*)*out_data)[i] = alaw2linear(((uint8_t*)in_data)[i]);
- }
-#if 0
- if(++count<=1000){
- fwrite(*out_data, sizeof(short), in_size, file);
- }
- else if(file){
- fclose(file);
- file = tsk_null;
- }
-#endif
- return (in_size*2);
-}
-
-tsk_bool_t tdav_codec_g711a_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-
-//
-// G.711a Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_g711a_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_g711a_t *g711a = self;
- if(g711a){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_g711a_dtor(tsk_object_t * self)
-{
- tdav_codec_g711a_t *g711a = self;
- if(g711a){
- /* deinit base */
- tmedia_codec_audio_deinit(g711a);
- /* deinit self */
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_g711a_def_s =
-{
- sizeof(tdav_codec_g711a_t),
- tdav_codec_g711a_ctor,
- tdav_codec_g711a_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_g711a_plugin_def_s =
-{
- &tdav_codec_g711a_def_s,
-
- tmedia_audio,
- "PCMA",
- "G.711a codec (From tinyDAV)",
- TMEDIA_CODEC_FORMAT_G711a,
- tsk_false,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20, // ptime
- },
-
- /* video */
- {0},
-
- tsk_null, // open
- tsk_null, // close
- tdav_codec_g711a_encode,
- tdav_codec_g711a_decode,
- tdav_codec_g711a_fmtp_match,
- tdav_codec_g711a_fmtp_get,
- tdav_codec_g711a_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_g711a_plugin_def_t = &tdav_codec_g711a_plugin_def_s;
diff --git a/branches/1.0/tinyDAV/src/codecs/g729/tdav_codec_g729.c b/branches/1.0/tinyDAV/src/codecs/g729/tdav_codec_g729.c
deleted file mode 100644
index 3ca6fc7..0000000
--- a/branches/1.0/tinyDAV/src/codecs/g729/tdav_codec_g729.c
+++ /dev/null
@@ -1,454 +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_g729.c
- * @brief G729ab codec.
- * Source from: http://www.itu.int/rec/T-REC-G.729-199610-S!AnnB/en
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/g729/tdav_codec_g729.h"
-
-#if HAVE_G729
-
-#include "g729b/dtx.h"
-#include "g729b/octet.h"
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-
-#if defined(_MSC_VER)
-# pragma comment(lib, "../thirdparties/win32/lib/g729b/g729b.a")
-#endif
-
-Word16 bad_lsf; /* bad LSF indicator */
-
-#ifndef G729_ENABLE_VAD
-# define G729_ENABLE_VAD 1
-#endif
-
-static Word16 bin2int(Word16 no_of_bits, const Word16 *bitstream);
-static void int2bin(Word16 value, Word16 no_of_bits, Word16 *bitstream);
-
-static void unpack_G729(const uint8_t bitstream[], Word16 bits[], int len);
-static void unpack_SID(const uint8_t bitstream[], Word16 bits[]);
-
-static void pack_G729(const Word16 ituBits[], uint8_t bitstream[]);
-static void pack_SID(const Word16 ituBits[], uint8_t bitstream[]);
-
-/* ============ G.729ab Plugin interface ================= */
-
-#define tdav_codec_g729ab_fmtp_set tsk_null
-
-int tdav_codec_g729ab_open(tmedia_codec_t* self)
-{
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self;
-
- // Initialize the decoder
- bad_lsf = 0;
- g729a->decoder.synth = (g729a->decoder.synth_buf + M);
-
- Init_Decod_ld8a();
- Init_Post_Filter();
- Init_Post_Process();
- /* for G.729B */
- Init_Dec_cng();
-
- // Initialize the encoder
- Init_Pre_Process();
- Init_Coder_ld8a();
- Set_zero(g729a->encoder.prm, PRM_SIZE + 1);
- /* for G.729B */
- Init_Cod_cng();
-
-
- return 0;
-}
-
-int tdav_codec_g729ab_close(tmedia_codec_t* self)
-{
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self;
-
- return 0;
-}
-
-tsk_size_t tdav_codec_g729ab_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t ex_size, out_size = 0;
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self;
- int i, frame_count = (in_size / 160);
-
-
- if(!self || !in_data || !in_size || !out_data || (in_size % 160)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- ex_size = (frame_count * 10);
-
- // allocate new buffer if needed
- if(*out_max_size <ex_size){
- if(!(*out_data = tsk_realloc(*out_data, ex_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = ex_size;
- }
-
- for(i=0; i<frame_count; i++){
- extern Word16 *new_speech;
-
- if(g729a->encoder.frame == 32767){
- g729a->encoder.frame = 256;
- }
- else{
- g729a->encoder.frame++;
- }
-
- memcpy(new_speech, &((uint8_t*)in_data)[i*L_FRAME*sizeof(Word16)], sizeof(Word16)*L_FRAME);
-
- Pre_Process(new_speech, L_FRAME);
- Coder_ld8a(g729a->encoder.prm, g729a->encoder.frame, g729a->encoder.vad_enable);
- prm2bits_ld8k(g729a->encoder.prm, g729a->encoder.serial);
-
- if(g729a->encoder.serial[1] == RATE_8000){
- pack_G729(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]);
- out_size += 10;
- }
- else if(g729a->encoder.serial[1] == RATE_SID_OCTET){
- pack_SID(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]);
- out_size += 2;
- }
- else{ // RATE_0
- //TSK_DEBUG_INFO("G729_RATE_0 - Not transmitted");
- return 0;
- }
- }
-
- return out_size;
-}
-
-tsk_size_t tdav_codec_g729ab_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)
-{
- tsk_size_t out_size = 0;
- int i, frame_count;
- const uint8_t* data_start = (const uint8_t*)in_data;
- const uint8_t* data_end;
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self;
-
- if(!self || !in_data || !in_size || !out_data || ((in_size % 10) && (in_size % 10 != 2))){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- data_end = (data_start + in_size);
-
- frame_count = (in_size/10) + ((in_size % 10) ? 1 : 0);
-
- out_size = 160*frame_count;
-
- /* allocate new buffer if needed */
- if(*out_max_size <out_size){
- if(!(*out_data = tsk_realloc(*out_data, out_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = out_size;
- }
-
- for(i=0; i<frame_count; i++){
- memset(g729a->decoder.synth_buf, 0, M);
- g729a->decoder.synth = g729a->decoder.synth_buf + M;
-
- if((data_end - data_start) == 2){
- unpack_SID(data_start, g729a->decoder.serial);
- data_start += 2;
- }
- else{
- unpack_G729(data_start, g729a->decoder.serial, 10);
- data_start += 10;
- }
-
- bits2prm_ld8k(&g729a->decoder.serial[1], g729a->decoder.parm);
-
- /* This part was modified for version V1.3 */
- /* for speech and SID frames, the hardware detects frame erasures
- by checking if all bits are set to zero */
- /* for untransmitted frames, the hardware detects frame erasures
- by testing serial[0] */
-
- g729a->decoder.parm[0] = 0; /* No frame erasure */
- if(g729a->decoder.serial[1] != 0) {
- int j;
- for (j=0; j < g729a->decoder.serial[1]; j++){
- if (g729a->decoder.serial[j+2] == 0){
- g729a->decoder.parm[0] = 1; /* frame erased */
- break;
- }
- }
- }
- else if(g729a->decoder.serial[0] != SYNC_WORD){
- g729a->decoder.parm[0] = 1;
- }
- if(g729a->decoder.parm[1] == 1) {
- /* check parity and put 1 in parm[5] if parity error */
- g729a->decoder.parm[5] = Check_Parity_Pitch(g729a->decoder.parm[4], g729a->decoder.parm[5]);
- }
-
- Decod_ld8a(g729a->decoder.parm, g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, &g729a->decoder.Vad);
- Post_Filter(g729a->decoder.synth, g729a->decoder.Az_dec, g729a->decoder.T2, g729a->decoder.Vad); /* Post-filter */
- Post_Process(g729a->decoder.synth, L_FRAME);
-
- memcpy(&((uint8_t*)*out_data)[160*i], g729a->decoder.synth, 160);
- }
-
-
- return out_size;
-}
-
-tsk_bool_t tdav_codec_g729ab_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tsk_params_L_t* params = tsk_null;
- const char* val_str;
-
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec;
-
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
- if((val_str = tsk_params_get_param_value(params, "annexb"))){
- g729a->encoder.vad_enable = tsk_strequals(val_str, "yes");
- }
-
- TSK_OBJECT_SAFE_FREE(params);
- }
-
- return tsk_true;
-}
-
-char* tdav_codec_g729ab_fmtp_get(const tmedia_codec_t* codec)
-{
- tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec;
-
- if(g729a->encoder.vad_enable){
- return tsk_strdup("annexb=yes");
- }
- else{
- return tsk_strdup("annexb=no");
- }
-}
-
-
-
-
-
-
-/* ============ Internal functions ================= */
-
-
-/**
-* Converts from bitstream (ITU bits) to word16 value
-* @param no_of_bits number of bits to read
-* @param bitstream array containing bits
-* @retval decimal value of bit pattern
-*/
-static Word16 bin2int(Word16 no_of_bits, const Word16 *bitstream)
-{
- Word16 value, i;
- Word16 bit;
-
- value = 0;
- for(i = 0; i < no_of_bits; i++){
- value <<= 1;
- bit = *bitstream++;
- if (bit == BIT_1){
- value += 1;
- }
- }
- return(value);
-}
-
-/*----------------------------------------------------------------------------
- * int2bin convert integer to binary and write the bits bitstream array
- *----------------------------------------------------------------------------
- */
-
-/**
-* Writes Word16 value to bitstream
-* @param value decimal value to write
-* @param no_of_bits number of bits from value to write
-* @param bitstream pointer to the destination stream (ITU bits)
-*/
-static void int2bin(Word16 value, Word16 no_of_bits, Word16 *bitstream)
-{
- Word16 *pt_bitstream;
- Word16 i, bit;
-
- pt_bitstream = bitstream + no_of_bits;
-
- for (i = 0; i < no_of_bits; i++){
- bit = value & (Word16)0x0001; /* get lsb */
- if (bit == 0){
- *--pt_bitstream = BIT_0;
- }
- else{
- *--pt_bitstream = BIT_1;
- }
- value >>= 1;
- }
-}
-
-/**
-* UnPack RTP bitstream as unpacked ITU stream
-* @param bitstream RTP bitstream to unpack
-* @param bits ITU bitstream used as destination (0 - BIT_0, 1 - BIT_1)
-* @param len length of the RTP bitstream
-*/
-static void unpack_G729(const uint8_t bitstream[], Word16 bits[], int len)
-{
- Word16 i;
- *bits++ = SYNC_WORD; /* bit[0], at receiver this bits indicates BFI */
- switch(len){
- case 10:
- *bits++ = SIZE_WORD;
- break;
- case 8: // RATE_6400
- case 15: //RATE_11800
- default:
- TSK_DEBUG_ERROR("%d is an invalid lenght value", len);
- return;
- }
-
- for(i=0; i<len; i++){
- int2bin(bitstream[i], 8, &bits[i*8]);
- }
-}
-
-/**
-* UnPack RTP bitstream containing SID frame as unpacked ITU stream
-* @param bitstream RTP bitstream to unpack
-* @param bits ITU bitstream used as destination (0 - BIT_0, 1 - BIT_1)
-*/
-static void unpack_SID(const uint8_t bitstream[], Word16 bits[])
-{
- *bits++ = SYNC_WORD;
- *bits++ = RATE_SID_OCTET;
- int2bin((Word16)bitstream[0], 8, &bits[0]);
- int2bin((Word16)bitstream[1], 8, &bits[8]);
-}
-
-/**
-* Pack ITU bits into RTP stream
-* @param ituBits ITU stream to pack (80 shorts)
-* @param bitstream RTP bitstream (80 bits, 5 shorts, 10 bytes)
-*/
-static void pack_G729(const Word16 ituBits[], uint8_t bitstream[])
-{
- Word16 word16, i;
- for(i=0; i<5; i++){
- word16 = bin2int(16, (Word16*)&ituBits[i*16]);
- bitstream[i*2] = word16>>8, bitstream[(i*2)+1] = (word16 & 0xFF);
- }
-}
-
-/**
-* Pack ITU bits containing SID frame as RTP stream
-* @param ituBits ITU stream to pack
-* @param bitstream RTP bitstream (15 bits, 1 short, 2 bytes)
-*/
-static void pack_SID(const Word16 ituBits[], uint8_t bitstream[])
-{
- Word16 word16 = bin2int(16, ituBits);
- bitstream[0] = word16>>8, bitstream[1] = (word16 & 0xFF);
-}
-
-
-//
-// g729ab Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_g729ab_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_g729ab_t *g729a = self;
- if(g729a){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- g729a->encoder.vad_enable = G729_ENABLE_VAD; // AnnexB
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_g729ab_dtor(tsk_object_t * self)
-{
- tdav_codec_g729ab_t *g729a = self;
- if(g729a){
- /* deinit base */
- tmedia_codec_audio_deinit(g729a);
- /* deinit self */
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_g729ab_def_s =
-{
- sizeof(tdav_codec_g729ab_t),
- tdav_codec_g729ab_ctor,
- tdav_codec_g729ab_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_g729ab_plugin_def_s =
-{
- &tdav_codec_g729ab_def_s,
-
- tmedia_audio,
- "g729",
- "g729ab Codec",
- TMEDIA_CODEC_FORMAT_G729,
- tsk_false,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_g729ab_open,
- tdav_codec_g729ab_close,
- tdav_codec_g729ab_encode,
- tdav_codec_g729ab_decode,
- tdav_codec_g729ab_fmtp_match,
- tdav_codec_g729ab_fmtp_get,
- tdav_codec_g729ab_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_g729ab_plugin_def_t = &tdav_codec_g729ab_plugin_def_s;
-
-#endif /* HAVE_G729 */ \ No newline at end of file
diff --git a/branches/1.0/tinyDAV/src/codecs/gsm/tdav_codec_gsm.c b/branches/1.0/tinyDAV/src/codecs/gsm/tdav_codec_gsm.c
deleted file mode 100644
index 56748da..0000000
--- a/branches/1.0/tinyDAV/src/codecs/gsm/tdav_codec_gsm.c
+++ /dev/null
@@ -1,208 +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_gsm.c
- * @brief GSM Full Rate Codec (Based on libgsm)
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/gsm/tdav_codec_gsm.h"
-
-#if HAVE_LIBGSM
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define TDAV_GSM_FRAME_SIZE 33
-
-/* ============ GSM Plugin interface ================= */
-
-#define tdav_codec_gsm_fmtp_get tsk_null
-#define tdav_codec_gsm_fmtp_set tsk_null
-
-int tdav_codec_gsm_open(tmedia_codec_t* self)
-{
- tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;
-
- if(!gsm->encoder && !(gsm->encoder = gsm_create())){
- TSK_DEBUG_ERROR("Failed to create GSM encoder");
- return -2;
- }
- if(!gsm->decoder && !(gsm->decoder = gsm_create())){
- TSK_DEBUG_ERROR("Failed to create GSM decoder");
- return -3;
- }
-
- return 0;
-}
-
-int tdav_codec_gsm_close(tmedia_codec_t* self)
-{
- tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;
-
- if(gsm->encoder){
- gsm_destroy(gsm->encoder);
- gsm->encoder = tsk_null;
- }
- if(gsm->decoder){
- gsm_destroy(gsm->decoder);
- gsm->decoder = tsk_null;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_gsm_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tsk_size_t out_size;
- tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- out_size = ((in_size / (TMEDIA_CODEC_PCM_FRAME_SIZE(self) * sizeof(short))) * TDAV_GSM_FRAME_SIZE);
-
- /* allocate new buffer if needed */
- if(*out_max_size <out_size){
- if(!(*out_data = tsk_realloc(*out_data, out_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = out_size;
- }
-
- gsm_encode(gsm->encoder, (gsm_signal*)in_data, (gsm_byte*)*out_data);
-
- return out_size;
-}
-
-tsk_size_t tdav_codec_gsm_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)
-{
- tsk_size_t out_size;
- int ret;
- tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;
-
- if(!self || !in_data || !in_size || !out_data || (in_size % TDAV_GSM_FRAME_SIZE)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- out_size = (in_size / TDAV_GSM_FRAME_SIZE) * (TMEDIA_CODEC_PCM_FRAME_SIZE(self) * sizeof(short));
-
- /* allocate new buffer if needed */
- if(*out_max_size <out_size){
- if(!(*out_data = tsk_realloc(*out_data, out_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = out_size;
- }
-
- ret = gsm_decode(gsm->decoder, (gsm_byte*)in_data, (gsm_signal*)*out_data);
-
- return out_size;
-}
-
-tsk_bool_t tdav_codec_gsm_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-
-//
-// GSM Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_gsm_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_gsm_t *gsm = self;
- if(gsm){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_gsm_dtor(tsk_object_t * self)
-{
- tdav_codec_gsm_t *gsm = self;
- if(gsm){
- /* deinit base */
- tmedia_codec_audio_deinit(gsm);
- /* deinit self */
- if(gsm->encoder){
- gsm_destroy(gsm->encoder);
- }
- if(gsm->decoder){
- gsm_destroy(gsm->decoder);
- }
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_gsm_def_s =
-{
- sizeof(tdav_codec_gsm_t),
- tdav_codec_gsm_ctor,
- tdav_codec_gsm_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_gsm_plugin_def_s =
-{
- &tdav_codec_gsm_def_s,
-
- tmedia_audio,
- "GSM",
- "GSM Full Rate",
- TMEDIA_CODEC_FORMAT_GSM,
- tsk_false,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_gsm_open,
- tdav_codec_gsm_close,
- tdav_codec_gsm_encode,
- tdav_codec_gsm_decode,
- tdav_codec_gsm_fmtp_match,
- tdav_codec_gsm_fmtp_get,
- tdav_codec_gsm_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_gsm_plugin_def_t = &tdav_codec_gsm_plugin_def_s;
-
-
-#endif /* HAVE_LIBGSM */
diff --git a/branches/1.0/tinyDAV/src/codecs/h261/tdav_codec_h261.c b/branches/1.0/tinyDAV/src/codecs/h261/tdav_codec_h261.c
deleted file mode 100644
index 780f2be..0000000
--- a/branches/1.0/tinyDAV/src/codecs/h261/tdav_codec_h261.c
+++ /dev/null
@@ -1,539 +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_h261.c
- * @brief H.261 codec plugin.
- * RTP payloader follows RFC 4587
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/h261/tdav_codec_h261.h"
-
-#if HAVE_FFMPEG
-
-#include "tinydav/video/tdav_converter_video.h"
-
-#include "tinyrtp/rtp/trtp_rtp_packet.h"
-
-#include "tnet_endianness.h"
-
-#include "tsk_time.h"
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define RTP_PAYLOAD_SIZE 700
-#define H261_HEADER_SIZE 4
-
-static void *run(void* self);
-static void tdav_codec_h261_rtp_callback(tdav_codec_h261_t *self, const void *data, tsk_size_t size, tsk_bool_t marker);
-static void tdav_codec_h261_encap(const tdav_codec_h261_t* h261, const uint8_t* pdata, tsk_size_t size);
-
-/* ============ H.261 Plugin interface ================= */
-
-//
-// H.261 object definition
-//
-int tdav_codec_h261_open(tmedia_codec_t* self)
-{
- int ret;
- int size;
-
- tdav_codec_h261_t* h261 = (tdav_codec_h261_t*)self;
-
- if(!h261){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is not opened */
-
- //
- // Encoder
- //
- if(!(h261->encoder.codec = avcodec_find_encoder(CODEC_ID_H261))){
- TSK_DEBUG_ERROR("Failed to find H.261 encoder");
- return -2;
- }
- h261->encoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h261->encoder.context);
-
- h261->encoder.context->pix_fmt = PIX_FMT_YUV420P;
- h261->encoder.context->time_base.num = 1;
- h261->encoder.context->time_base.den = TMEDIA_CODEC_VIDEO(h261)->fps;
- h261->encoder.context->width = TMEDIA_CODEC_VIDEO(h261)->width;
- h261->encoder.context->height = TMEDIA_CODEC_VIDEO(h261)->height;
-
- h261->encoder.context->mb_qmin = h261->encoder.context->qmin = 4;
- h261->encoder.context->mb_qmax = h261->encoder.context->qmax = 31;
- h261->encoder.context->mb_decision = FF_MB_DECISION_SIMPLE;
-
- h261->encoder.context->thread_count = 1;
- h261->encoder.context->rtp_payload_size = RTP_PAYLOAD_SIZE;
- h261->encoder.context->opaque = tsk_null;
- h261->encoder.context->bit_rate = (float) (500000) * 0.80f;
- h261->encoder.context->bit_rate_tolerance = (int) (500000 * 0.20f);
- h261->encoder.context->gop_size = TMEDIA_CODEC_VIDEO(h261)->fps*4; /* each 4 seconds */
-
- // Picture (YUV 420)
- if(!(h261->encoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create encoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h261->encoder.picture);
- //if((ret = avpicture_alloc((AVPicture*)h261->encoder.picture, PIX_FMT_YUV420P, h261->encoder.context->width, h261->encoder.context->height))){
- // TSK_DEBUG_ERROR("Failed to allocate encoder picture");
- // return ret;
- //}
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h261->encoder.context->width, h261->encoder.context->height);
- if(!(h261->encoder.buffer = tsk_calloc(size, sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate encoder buffer");
- return -2;
- }
-
- // Open encoder
- if((ret = avcodec_open(h261->encoder.context, h261->encoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open H.261 encoder");
- return ret;
- }
-
- //
- // Decoder
- //
- if(!(h261->decoder.codec = avcodec_find_decoder(CODEC_ID_H261))){
- TSK_DEBUG_ERROR("Failed to find H.261 decoder");
- }
- h261->decoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h261->decoder.context);
-
- h261->decoder.context->pix_fmt = PIX_FMT_YUV420P;
- h261->decoder.context->width = TMEDIA_CODEC_VIDEO(h261)->width;
- h261->decoder.context->height = TMEDIA_CODEC_VIDEO(h261)->height;
-
- // Picture (YUV 420)
- if(!(h261->decoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create decoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h261->decoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h261->decoder.context->width, h261->decoder.context->height);
- if(!(h261->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(h261->decoder.context, h261->decoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open H.261 decoder");
- return ret;
- }
-
- return 0;
-}
-
-int tdav_codec_h261_close(tmedia_codec_t* self)
-{
- tdav_codec_h261_t* h261 = (tdav_codec_h261_t*)self;
-
- if(!h261){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is opened */
-
- //
- // Encoder
- //
- if(h261->encoder.context){
- avcodec_close(h261->encoder.context);
- av_free(h261->encoder.context);
- h261->encoder.context = tsk_null;
- }
- if(h261->encoder.picture){
- av_free(h261->encoder.picture);
- }
- if(h261->encoder.buffer){
- TSK_FREE(h261->encoder.buffer);
- }
-
- //
- // Decoder
- //
- if(h261->decoder.context){
- avcodec_close(h261->decoder.context);
- av_free(h261->decoder.context);
- h261->decoder.context = tsk_null;
- }
- if(h261->decoder.picture){
- av_free(h261->decoder.picture);
- h261->decoder.picture = tsk_null;
- }
- if(h261->decoder.accumulator){
- TSK_FREE(h261->decoder.accumulator);
- h261->decoder.accumulator_pos = 0;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h261_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_h261_t* h261 = (tdav_codec_h261_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- // delete old buffer
- if(*out_data){
- TSK_FREE(*out_data);
- }
-
- // wrap yuv420 buffer
- size = avpicture_fill((AVPicture *)h261->encoder.picture, (uint8_t*)in_data, PIX_FMT_YUV420P, h261->encoder.context->width, h261->encoder.context->height);
- if(size != in_size){
- /* guard */
- TSK_DEBUG_ERROR("Invalid size");
- return 0;
- }
- /* Flip */
-#if FLIP_ENCODED_PICT
- tdav_converter_video_flip(h261->encoder.picture, h261->encoder.context->height);
-#endif
-
- // Encode data
- h261->encoder.picture->pts = AV_NOPTS_VALUE;
- //h261->encoder.picture->pict_type = FF_I_TYPE;
- ret = avcodec_encode_video(h261->encoder.context, h261->encoder.buffer, size, h261->encoder.picture);
- if(ret > 0){
- tdav_codec_h261_encap(h261, h261->encoder.buffer, (tsk_size_t)ret);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h261_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)
-{
- uint8_t sbit, ebit;
- const uint8_t* pdata = in_data;
- const uint8_t* pay_ptr;
- tsk_size_t pay_size;
- tsk_size_t xsize, retsize = 0;
- int got_picture_ptr;
- int ret;
-
- tdav_codec_h261_t* h261 = (tdav_codec_h261_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- if(!self || !in_data || !in_size || !out_data || !h261->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* RFC 4587
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- sbit = *pdata >> 5;
- ebit = (*pdata >> 2) & 0x07;
-
- /* Check size */
- if(in_size < H261_HEADER_SIZE){
- TSK_DEBUG_ERROR("Too short");
- return 0;
- }
-
- pay_ptr = (pdata + H261_HEADER_SIZE);
- pay_size = (in_size - H261_HEADER_SIZE);
- xsize = avpicture_get_size(h261->decoder.context->pix_fmt, h261->decoder.context->width, h261->decoder.context->height);
-
- /* Packet lost? */
- if(h261->decoder.last_seq != (rtp_hdr->seq_num - 1) && h261->decoder.last_seq){
- TSK_DEBUG_INFO("Packet lost");
- }
- h261->decoder.last_seq = rtp_hdr->seq_num;
-
- if((int)(h261->decoder.accumulator_pos + pay_size) <= xsize){
-
- if((h261->decoder.ebit + sbit) == 8){ /* Perfect one Byte to clean up */
- if(h261->decoder.accumulator_pos){
- ((uint8_t*)h261->decoder.accumulator)[h261->decoder.accumulator_pos-1] =
- (((uint8_t*)h261->decoder.accumulator)[h261->decoder.accumulator_pos-1] & (0xFF << h261->decoder.ebit)) |
- (*pay_ptr << sbit);
- }
- pay_ptr++, pay_size--;
- }
- h261->decoder.ebit = ebit;
-
- memcpy(&((uint8_t*)h261->decoder.accumulator)[h261->decoder.accumulator_pos], pay_ptr, pay_size);
- h261->decoder.accumulator_pos += pay_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- h261->decoder.accumulator_pos = 0;
- return 0;
- }
-
- if(rtp_hdr->marker){
- AVPacket packet;
- /* allocate destination buffer */
- if(*out_max_size <xsize){
- if(!(*out_data = tsk_realloc(*out_data, xsize))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- h261->decoder.accumulator_pos = 0;
- return 0;
- }
- *out_max_size = xsize;
- }
-
- /* decode the picture */
- av_init_packet(&packet);
- packet.size = h261->decoder.accumulator_pos;
- packet.data = h261->decoder.accumulator;
- ret = avcodec_decode_video2(h261->decoder.context, h261->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(h261->decoder.picture, h261->decoder.context->height);
-#endif
- /* copy picture into a linear buffer */
- avpicture_layout((AVPicture *)h261->decoder.picture, h261->decoder.context->pix_fmt, h261->decoder.context->width, h261->decoder.context->height,
- *out_data, retsize);
- }
- /* in all cases: reset accumulator */
- h261->decoder.accumulator_pos = 0;
- }
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_h261_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- int ret;
- unsigned maxbr, fps, width, height;
- tmedia_codec_video_t* h261 = (tmedia_codec_video_t*)codec;
-
- if(!(ret = tmedia_codec_parse_fmtp(fmtp, &maxbr, &fps, &width, &height))){
- h261->max_br = maxbr * 1000;
- h261->fps = fps;
- h261->width = width;
- h261->height = height;
- return tsk_true;
- }
- else{
- TSK_DEBUG_WARN("Failed to match fmtp [%s]", fmtp);
- return tsk_false;
- }
-}
-
-char* tdav_codec_h261_fmtp_get(const tmedia_codec_t* self)
-{
-#if 0
- return tsk_strdup("CIF=2/MaxBR=3840;QCIF=2/MaxBR=1920");
-#else
- return tsk_strdup("QCIF=2");
-#endif
-}
-
-int tdav_codec_h261_fmtp_set(tmedia_codec_t* self, const char* fmtp)
-{
- TSK_DEBUG_INFO("remote fmtp=%s", fmtp);
- return 0;
-}
-
-/* constructor */
-static tsk_object_t* tdav_codec_h261_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h261_t *h261 = self;
- if(h261){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h261_dtor(tsk_object_t * self)
-{
- tdav_codec_h261_t *h261 = self;
- if(h261){
- /* deinit base */
- tmedia_codec_video_deinit(h261); // will call close()
- /* deinit self */
- TSK_FREE(h261->rtp.ptr);
- h261->rtp.size = 0;
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h261_def_s =
-{
- sizeof(tdav_codec_h261_t),
- tdav_codec_h261_ctor,
- tdav_codec_h261_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h261_plugin_def_s =
-{
- &tdav_codec_h261_def_s,
-
- tmedia_video,
- "H261",
- "H261 codec",
- TMEDIA_CODEC_FORMAT_H261,
- tsk_false,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_h261_open,
- tdav_codec_h261_close,
- tdav_codec_h261_encode,
- tdav_codec_h261_decode,
- tdav_codec_h261_fmtp_match,
- tdav_codec_h261_fmtp_get,
- tdav_codec_h261_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h261_plugin_def_t = &tdav_codec_h261_plugin_def_s;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* ============ Callbacks ================= */
-
-static void tdav_codec_h261_encap(const tdav_codec_h261_t* h261, const uint8_t* pdata, tsk_size_t size)
-{
- uint32_t i, last_index = 0;
-
- if(size < RTP_PAYLOAD_SIZE){
- goto last;
- }
-
- for(i = 4; i<(size - 4); i++){
- if(pdata[i] == 0x00 && pdata[i+1] == 0x00 && pdata[i+2]>=0x80){ /* PSC or (GBSC) found */
- if((i - last_index) >= RTP_PAYLOAD_SIZE){
- tdav_codec_h261_rtp_callback((tdav_codec_h261_t*)h261, pdata+last_index,
- (i - last_index), (last_index == size));
- }
- last_index = i;
- }
- }
-last:
- if(last_index < size - 3/*PSC/GBSC size*/){
- tdav_codec_h261_rtp_callback((tdav_codec_h261_t*)h261, pdata + last_index,
- (size - last_index), tsk_true);
- }
-}
-
-//static void *run(void* self)
-//{
-// uint32_t i, last_index;
-// tsk_list_item_t *curr;
-//
-// const uint8_t* pdata;
-// tsk_size_t size;
-//
-// const tdav_codec_h261_t* h261 = ((tdav_runnable_video_t*)self)->userdata;
-//
-// TSK_DEBUG_INFO("H261 thread === START");
-//
-// TSK_RUNNABLE_RUN_BEGIN(self);
-//
-// if((curr = TSK_RUNNABLE_POP_FIRST(self))){
-// /* 4 is sizeof(uint32_t) */
-// pdata = ((const tsk_buffer_t*)curr->data)->data;
-// size = ((const tsk_buffer_t*)curr->data)->size;
-// last_index = 0;
-//
-// if(size < RTP_PAYLOAD_SIZE){
-// goto last;
-// }
-//
-// for(i = 4; i<(size - 4); i++){
-// if(pdata[i] == 0x00 && pdata[i+1] == 0x00 && pdata[i+2]>=0x80){ /* PSC or (GBSC) found */
-// if((i - last_index) >= RTP_PAYLOAD_SIZE){
-// tdav_codec_h261_rtp_callback((tdav_codec_h261_t*)h261, pdata+last_index,
-// (i - last_index), (last_index == size));
-// }
-// last_index = i;
-// }
-// }
-//last:
-// if(last_index < size - 3/*PSC/GBSC size*/){
-// tdav_codec_h261_rtp_callback((tdav_codec_h261_t*)h261, pdata + last_index,
-// (size - last_index), tsk_true);
-// }
-//
-// tsk_object_unref(curr);
-// }
-//
-// TSK_RUNNABLE_RUN_END(self);
-//
-// TSK_DEBUG_INFO("H261 thread === STOP");
-//
-// return tsk_null;
-//}
-
-static void tdav_codec_h261_rtp_callback(tdav_codec_h261_t *self, const void *data, tsk_size_t size, tsk_bool_t marker)
-{
-
-}
-
-
-
-#endif /* HAVE_FFMPEG */ \ No newline at end of file
diff --git a/branches/1.0/tinyDAV/src/codecs/h263/tdav_codec_h263.c b/branches/1.0/tinyDAV/src/codecs/h263/tdav_codec_h263.c
deleted file mode 100644
index 9b247d1..0000000
--- a/branches/1.0/tinyDAV/src/codecs/h263/tdav_codec_h263.c
+++ /dev/null
@@ -1,1230 +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_h263.c
- * @brief H.263-1996 and H.263-1998 codec plugins.
- * RTP payloader follows RFC 4629 for H263+ and RFC 2190 for H263.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/h263/tdav_codec_h263.h"
-
-#if HAVE_FFMPEG
-
-#include "tinydav/video/tdav_converter_video.h"
-
-#include "tinyrtp/rtp/trtp_rtp_packet.h"
-
-#include "tnet_endianness.h"
-
-#include "tsk_time.h"
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define RTP_PAYLOAD_SIZE 750
-
-#define H263P_HEADER_SIZE 2
-#define H263_HEADER_MODE_A_SIZE 4
-#define H263_HEADER_MODE_B_SIZE 8
-#define H263_HEADER_MODE_C_SIZE 12
-
-static void tdav_codec_h263_rtp_callback(tdav_codec_h263_t *self, const void *data, tsk_size_t size, tsk_bool_t marker);
-static void tdav_codec_h263p_rtp_callback(tdav_codec_h263_t *self, const void *data, tsk_size_t size, tsk_bool_t frag, tsk_bool_t marker);
-
-static void tdav_codec_h263_encap(const tdav_codec_h263_t* h263, const uint8_t* pdata, tsk_size_t size);
-
-/* ============ Common To all H263 codecs ================= */
-
-int tdav_codec_h263_init(tdav_codec_h263_t* self, tdav_codec_h263_type_t type, enum CodecID encoder, enum CodecID decoder)
-{
- int ret = 0;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- self->type = type;
-
- if(!(self->encoder.codec = avcodec_find_encoder(encoder))){
- TSK_DEBUG_ERROR("Failed to find [%d]encoder", encoder);
- ret = -2;
- }
-
- if(!(self->decoder.codec = avcodec_find_decoder(decoder))){
- TSK_DEBUG_ERROR("Failed to find [%d] decoder", decoder);
- ret = -3;
- }
-
- /* allocations MUST be done by open() */
- return ret;
-}
-
-int tdav_codec_h263_deinit(tdav_codec_h263_t* self)
-{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- self->encoder.codec = tsk_null;
- self->decoder.codec = tsk_null;
-
- // FFMpeg resources are destroyed by close()
-
-
-
- TSK_FREE(self->rtp.ptr);
- self->rtp.size = 0;
-
- return 0;
-}
-
-
-
-/* ============ H.263-1996 Plugin interface ================= */
-
-//
-// H.263-1996 object definition
-//
-int tdav_codec_h263_open(tmedia_codec_t* self)
-{
- int ret;
- int size;
- float bitRate = 64000.f;
-
- tdav_codec_h263_t* h263 = (tdav_codec_h263_t*)self;
-
- if(!h263){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is not opened */
-
- //
- // Encoder
- //
- h263->encoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h263->encoder.context);
-
- h263->encoder.context->pix_fmt = PIX_FMT_YUV420P;
- h263->encoder.context->time_base.num = 1;
- h263->encoder.context->time_base.den = TMEDIA_CODEC_VIDEO(h263)->fps;
- h263->encoder.context->width = TMEDIA_CODEC_VIDEO(h263)->width;
- h263->encoder.context->height = TMEDIA_CODEC_VIDEO(h263)->height;
-
- /*h263->encoder.context->mb_qmin =*/ h263->encoder.context->qmin = 4;
- /*h263->encoder.context->mb_qmax =*/ h263->encoder.context->qmax = 31;
- h263->encoder.context->mb_decision = FF_MB_DECISION_SIMPLE;
- //h263->encoder.context->me_method = ME_EPZS;
- //h263->encoder.context->flags |= CODEC_FLAG_INPUT_PRESERVED | CODEC_FLAG_PASS1;
-
- switch(self->bl){
- case tmedia_bl_low:
- default:
- bitRate = 64000.f;
- break;
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- bitRate = 128000.f;
- break;
- }
-
- h263->encoder.context->thread_count = 1;
- h263->encoder.context->rtp_payload_size = RTP_PAYLOAD_SIZE;
- h263->encoder.context->opaque = tsk_null;
- h263->encoder.context->bit_rate = (int)(bitRate * 0.80f);
- h263->encoder.context->bit_rate_tolerance = (int) (bitRate * 0.20f);
- h263->encoder.context->rc_min_rate = 0;
- h263->encoder.context->gop_size = TMEDIA_CODEC_VIDEO(h263)->fps*3; /* each 3 seconds */
-
-
- // Picture (YUV 420)
- if(!(h263->encoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create encoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h263->encoder.picture);
- //if((ret = avpicture_alloc((AVPicture*)h263->encoder.picture, PIX_FMT_YUV420P, h263->encoder.context->width, h263->encoder.context->height))){
- // TSK_DEBUG_ERROR("Failed to allocate encoder picture");
- // return ret;
- //}
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h263->encoder.context->width, h263->encoder.context->height);
- if(!(h263->encoder.buffer = tsk_calloc(size, sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate encoder buffer");
- return -2;
- }
-
-
- // RTP Callback
- switch(h263->type){
- case tdav_codec_h263_1996:
- { /* H263 - 1996 */
- break;
- }
- case tdav_codec_h263_1998:
- { /* H263 - 1998 */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_UMV; /* Annex D+ */
- h263->encoder.context->flags |= CODEC_FLAG_AC_PRED; /* Annex I and T */
- h263->encoder.context->flags |= CODEC_FLAG_LOOP_FILTER; /* Annex J */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; /* Annex K */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_AIV; /* Annex S */
- break;
- }
- case tdav_codec_h263_2000:
- { /* H263 - 2000 */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_UMV; /* Annex D+ */
- h263->encoder.context->flags |= CODEC_FLAG_AC_PRED; /* Annex I and T */
- h263->encoder.context->flags |= CODEC_FLAG_LOOP_FILTER; /* Annex J */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; /* Annex K */
- h263->encoder.context->flags |= CODEC_FLAG_H263P_AIV; /* Annex S */
- break;
- }
- }
- // Open encoder
- if((ret = avcodec_open(h263->encoder.context, h263->encoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open [%s] codec", TMEDIA_CODEC(h263)->plugin->desc);
- return ret;
- }
-
- //
- // Decoder
- //
- h263->decoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h263->decoder.context);
-
- h263->decoder.context->pix_fmt = PIX_FMT_YUV420P;
- h263->decoder.context->width = TMEDIA_CODEC_VIDEO(h263)->width;
- h263->decoder.context->height = TMEDIA_CODEC_VIDEO(h263)->height;
-
- // Picture (YUV 420)
- if(!(h263->decoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create decoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h263->decoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h263->decoder.context->width, h263->decoder.context->height);
- if(!(h263->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(h263->decoder.context, h263->decoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open [%s] codec", TMEDIA_CODEC(h263)->plugin->desc);
- return ret;
- }
-
- return 0;
-}
-
-int tdav_codec_h263_close(tmedia_codec_t* self)
-{
- tdav_codec_h263_t* h263 = (tdav_codec_h263_t*)self;
-
- if(!h263){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is opened */
-
- //
- // Encoder
- //
- if(h263->encoder.context){
- avcodec_close(h263->encoder.context);
- av_free(h263->encoder.context);
- }
- if(h263->encoder.picture){
- av_free(h263->encoder.picture);
- }
- if(h263->encoder.buffer){
- TSK_FREE(h263->encoder.buffer);
- }
-
- //
- // Decoder
- //
- if(h263->decoder.context){
- avcodec_close(h263->decoder.context);
- av_free(h263->decoder.context);
- }
- if(h263->decoder.picture){
- av_free(h263->decoder.picture);
- }
- if(h263->decoder.accumulator){
- TSK_FREE(h263->decoder.accumulator);
- h263->decoder.accumulator_pos = 0;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h263_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_h263_t* h263 = (tdav_codec_h263_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- // wrap yuv420 buffer
- size = avpicture_fill((AVPicture *)h263->encoder.picture, (uint8_t*)in_data, PIX_FMT_YUV420P, h263->encoder.context->width, h263->encoder.context->height);
- if(size != in_size){
- /* guard */
- TSK_DEBUG_ERROR("Invalid size");
- return 0;
- }
- /* Flip */
-#if FLIP_ENCODED_PICT
- tdav_converter_video_flip(h263->encoder.picture, h263->encoder.context->height);
-#endif
-
- h263->encoder.picture->pts = AV_NOPTS_VALUE;
- ret = avcodec_encode_video(h263->encoder.context, h263->encoder.buffer, size, h263->encoder.picture);
- if(ret > 0){
- tdav_codec_h263_encap(h263, h263->encoder.buffer, (tsk_size_t)ret);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h263_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)
-{
- uint8_t F, P, sbit, ebit;
- const uint8_t* pdata = in_data;
- 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_h263_t* h263 = (tdav_codec_h263_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- if(!self || !in_data || !in_size || !out_data || !h263->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* RFC 2190
- get F and P bits, used to determine the header Mode (A, B or C)
- F: 1 bit
- The flag bit indicates the mode of the payload header. F=0, mode A;
- F=1, mode B or mode C depending on P bit defined below.
- P: 1 bit
- Optional PB-frames mode as defined by the H.263 [4]. "0" implies
- normal I or P frame, "1" PB-frames. When F=1, P also indicates modes:
- mode B if P=0, mode C if P=1.
- */
- F = *pdata >> 7;
- P = (*pdata >> 6) & 0x01;
-
- /* SBIT and EBIT */
- sbit = (*pdata >> 3) & 0x0F;
- ebit = (*pdata & 0x07);
-
- if(F == 0){
- /* MODE A
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |F|P|SBIT |EBIT | SRC |I|U|S|A|R |DBQ| TRB | TR |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- hdr_size = H263_HEADER_MODE_A_SIZE;
- }
- else if(P == 0){ // F=1 and P=0
- /* MODE B
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |F|P|SBIT |EBIT | SRC | QUANT | GOBN | MBA |R |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |I|U|S|A| HMV1 | VMV1 | HMV2 | VMV2 |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- hdr_size = H263_HEADER_MODE_B_SIZE;
- }
- else{ // F=1 and P=1
- /* MODE C
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |F|P|SBIT |EBIT | SRC | QUANT | GOBN | MBA |R |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |I|U|S|A| HMV1 | VMV1 | HMV2 | VMV2 |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | RR |DBQ| TRB | TR |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- hdr_size = H263_HEADER_MODE_C_SIZE;
- }
-
- /* Check size */
- if(in_size < hdr_size){
- TSK_DEBUG_ERROR("Too short");
- return 0;
- }
-
- pay_ptr = (pdata + hdr_size);
- pay_size = (in_size - hdr_size);
- xsize = avpicture_get_size(h263->decoder.context->pix_fmt, h263->decoder.context->width, h263->decoder.context->height);
-
- /* Packet lost? */
- if(h263->decoder.last_seq != (rtp_hdr->seq_num - 1) && h263->decoder.last_seq){
- if(h263->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);
- }
- h263->decoder.last_seq = rtp_hdr->seq_num;
-
- if((int)(h263->decoder.accumulator_pos + pay_size) <= xsize){
- if((h263->decoder.ebit + sbit) == 8){ /* Perfect one Byte to clean up */
- if(h263->decoder.accumulator_pos){
- ((uint8_t*)h263->decoder.accumulator)[h263->decoder.accumulator_pos-1] = (((uint8_t*)h263->decoder.accumulator)[h263->decoder.accumulator_pos-1] & (0xFF << h263->decoder.ebit)) |
- (*pay_ptr & (0xFF >> sbit));
- }
- pay_ptr++, pay_size--;
- }
- h263->decoder.ebit = ebit;
-
- memcpy(&((uint8_t*)h263->decoder.accumulator)[h263->decoder.accumulator_pos], pay_ptr, pay_size);
- h263->decoder.accumulator_pos += pay_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- h263->decoder.accumulator_pos = 0;
- return 0;
- }
-
- if(rtp_hdr->marker){
- AVPacket packet;
- /* allocate destination buffer */
- if(*out_max_size <xsize){
- if(!(*out_data = tsk_realloc(*out_data, xsize))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- h263->decoder.accumulator_pos = 0;
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = xsize;
- }
-
- av_init_packet(&packet);
- packet.size = h263->decoder.accumulator_pos;
- packet.data = h263->decoder.accumulator;
- ret = avcodec_decode_video2(h263->decoder.context, h263->decoder.picture, &got_picture_ptr, &packet);
-
- if(ret <0 || !got_picture_ptr){
- TSK_DEBUG_WARN("Failed to decode the buffer");
- }
- else{
- retsize = xsize;
- /* flip */
-#if FLIP_DECODED_PICT
- tdav_converter_video_flip(h263->decoder.picture, h263->decoder.context->height);
-#endif
- /* copy picture into a linear buffer */
- avpicture_layout((AVPicture *)h263->decoder.picture, h263->decoder.context->pix_fmt, h263->decoder.context->width, h263->decoder.context->height,
- *out_data, retsize);
- }
- /* in all cases: reset accumulator */
- h263->decoder.accumulator_pos = 0;
- }
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_h263_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tsk_bool_t ret = tsk_false;
- tmedia_codec_video_t* h263 = (tmedia_codec_video_t*)codec;
- tsk_params_L_t* params = tsk_null;
-
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
- switch(codec->bl){
- case tmedia_bl_low:
- default:
- if(tsk_params_have_param(params, "QCIF")){
- h263->width = 176, h263->height = 144;
- ret = tsk_true;
- }
- else if(tsk_params_have_param(params, "SQCIF")){
- h263->width = 128, h263->height = 96;
- ret = tsk_true;
- }
- break;
-
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- if(tsk_params_have_param(params, "CIF")){
- h263->width = 352, h263->height = 288;
- ret = tsk_true;
- }
- else if(tsk_params_have_param(params, "QCIF")){
- h263->width = 176, h263->height = 144;
- ret = tsk_true;
- }
- else if(tsk_params_have_param(params, "SQCIF")){
- h263->width = 128, h263->height = 96;
- ret = tsk_true;
- }
- break;
- }
- }
- TSK_OBJECT_SAFE_FREE(params);
-
- return ret;
-}
-
-char* tdav_codec_h263_fmtp_get(const tmedia_codec_t* self)
-{
- switch(self->bl){
- case tmedia_bl_low:
- default:
- return tsk_strdup("QCIF=2;SQCIF=2");
- break;
- case tmedia_bl_medium:
- case tmedia_bl_hight:
- return tsk_strdup("CIF=2;QCIF=2;SQCIF=2");
- break;
- }
-}
-
-int tdav_codec_h263_fmtp_set(tmedia_codec_t* self, const char* fmtp)
-{
- TSK_DEBUG_INFO("remote fmtp=%s", fmtp);
- return 0;
-}
-
-/* constructor */
-static tsk_object_t* tdav_codec_h263_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h263_t *h263 = self;
- if(h263){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h263_init(TDAV_CODEC_H263(self), tdav_codec_h263_1996, CODEC_ID_H263, CODEC_ID_H263);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h263_dtor(tsk_object_t * self)
-{
- tdav_codec_h263_t *h263 = self;
- if(h263){
- /* deinit base */
- tmedia_codec_video_deinit(h263);
- /* deinit self */
- tdav_codec_h263_deinit(TDAV_CODEC_H263(self));
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h263_def_s =
-{
- sizeof(tdav_codec_h263_t),
- tdav_codec_h263_ctor,
- tdav_codec_h263_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h263_plugin_def_s =
-{
- &tdav_codec_h263_def_s,
-
- tmedia_video,
- "H263",
- "H263-1996 codec",
- TMEDIA_CODEC_FORMAT_H263,
- tsk_false,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_h263_open,
- tdav_codec_h263_close,
- tdav_codec_h263_encode,
- tdav_codec_h263_decode,
- tdav_codec_h263_fmtp_match,
- tdav_codec_h263_fmtp_get,
- tdav_codec_h263_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h263_plugin_def_t = &tdav_codec_h263_plugin_def_s;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* ============ H.263-1998 Plugin interface ================= */
-
-//
-// H.263-1998 object definition
-//
-
-int tdav_codec_h263p_open(tmedia_codec_t* self)
-{
- return tdav_codec_h263_open(self);
-}
-
-int tdav_codec_h263p_close(tmedia_codec_t* self)
-{
- return tdav_codec_h263_close(self);
-}
-
-tsk_size_t tdav_codec_h263p_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- return tdav_codec_h263_encode(self, in_data, in_size, out_data, out_max_size);
-}
-
-tsk_size_t tdav_codec_h263p_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)
-{
- uint8_t P, V, PLEN, PEBIT;
- uint8_t* pdata = (uint8_t*)in_data;
- const uint8_t* pay_ptr;
- tsk_size_t pay_size;
- int hdr_size = H263P_HEADER_SIZE;
- tsk_size_t xsize, retsize = 0;
- int got_picture_ptr;
- int ret;
-
- tdav_codec_h263_t* h263 = (tdav_codec_h263_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- if(!self || !in_data || !in_size || ((int)in_size <= hdr_size) || !out_data || !h263->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
-/*
- 5.1. General H.263+ Payload Header
-
- 0 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | RR |P|V| PLEN |PEBIT|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
- P = (pdata[0] & 0x04)>>2;
- V = (pdata[0] & 0x02)>>1;
- PLEN = (((pdata[0] & 0x01)<<5) | pdata[1]>>3);
- PEBIT = pdata[1] & 0x07;
-
- if(V){
- /*
- Indicates the presence of an 8-bit field containing information
- for Video Redundancy Coding (VRC), which follows immediately after
- the initial 16 bits of the payload header, if present. For syntax
- and semantics of that 8-bit VRC field, see Section 5.2.
- */
- }
- if(PLEN){
- /*
- Length, in bytes, of the extra picture header. If no extra
- picture header is attached, PLEN is 0. If PLEN>0, the extra
- picture header is attached immediately following the rest of the
- payload header. Note that the length reflects the omission of the
- first two bytes of the picture start code (PSC). See Section 6.1.
- */
- hdr_size += PLEN;
- if(PEBIT){
- /*
- Indicates the number of bits that shall be ignored in the last
- byte of the picture header. If PLEN is not zero, the ignored bits
- shall be the least significant bits of the byte. If PLEN is zero,
- then PEBIT shall also be zero.
- */
- TSK_DEBUG_WARN("PEBIT ignored");
- }
- }
- if(P){ /* MUST be done after PLEN and PEBIT */
- /*
- Indicates the picture start or a picture segment (GOB/Slice) start
- or a video sequence end (EOS or EOSBS). Two bytes of zero bits
- then have to be prefixed to the payload of such a packet to
- compose a complete picture/GOB/slice/EOS/EOSBS start code. This
- bit allows the omission of the two first bytes of the start codes,
- thus improving the compression ratio.
- */
- hdr_size -= 2;
- pdata[hdr_size] = 0x00, pdata[hdr_size + 1] = 0x00;
- }
-
- pay_ptr = (pdata + hdr_size);
- pay_size = (in_size - hdr_size);
- xsize = avpicture_get_size(h263->decoder.context->pix_fmt, h263->decoder.context->width, h263->decoder.context->height);
-
- /* Packet lost? */
- if(h263->decoder.last_seq != (rtp_hdr->seq_num - 1) && h263->decoder.last_seq){
- if(h263->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);
- }
- h263->decoder.last_seq = rtp_hdr->seq_num;
-
- if((int)(h263->decoder.accumulator_pos + pay_size) <= xsize){
- /* PEBIT is ignored */
- memcpy(&((uint8_t*)h263->decoder.accumulator)[h263->decoder.accumulator_pos], pay_ptr, pay_size);
- h263->decoder.accumulator_pos += pay_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- h263->decoder.accumulator_pos = 0;
- return 0;
- }
-
- if(rtp_hdr->marker){
- AVPacket packet;
- /* allocate destination buffer */
- if(*out_max_size < xsize){
- if(!(*out_data = tsk_realloc(*out_data, xsize))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- h263->decoder.accumulator_pos = 0;
- return 0;
- }
- *out_max_size = xsize;
- }
-
- /* decode the picture */
- av_init_packet(&packet);
- packet.size = h263->decoder.accumulator_pos;
- packet.data = h263->decoder.accumulator;
- ret = avcodec_decode_video2(h263->decoder.context, h263->decoder.picture, &got_picture_ptr, &packet);
-
- if(ret <0 || !got_picture_ptr){
- TSK_DEBUG_WARN("Failed to decode the buffer");
- }
- else{
- retsize = xsize;
- /* flip */
-#if FLIP_DECODED_PICT
- tdav_converter_video_flip(h263->decoder.picture, h263->decoder.context->height);
-#endif
- /* copy picture into a linear buffer */
- avpicture_layout((AVPicture *)h263->decoder.picture, h263->decoder.context->pix_fmt, h263->decoder.context->width, h263->decoder.context->height,
- *out_data, retsize);
- }
- /* in all cases: reset accumulator */
- h263->decoder.accumulator_pos = 0;
- }
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_h263p_fmtp_match(const tmedia_codec_t* self, const char* fmtp)
-{
- return tdav_codec_h263_fmtp_match(self, fmtp);
-}
-
-char* tdav_codec_h263p_fmtp_get(const tmedia_codec_t* self)
-{
- return tdav_codec_h263_fmtp_get(self);
-}
-
-int tdav_codec_h263p_fmtp_set(tmedia_codec_t* self, const char* fmtp)
-{
- TSK_DEBUG_INFO("remote fmtp=%s", fmtp);
- return 0;
-}
-
-/* constructor */
-static tsk_object_t* tdav_codec_h263p_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h263p_t *h263p = self;
- if(h263p){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h263_init(TDAV_CODEC_H263(self), tdav_codec_h263_1998, CODEC_ID_H263P, CODEC_ID_H263);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h263p_dtor(tsk_object_t * self)
-{
- tdav_codec_h263p_t *h263p = self;
- if(h263p){
- /* deinit base */
- tmedia_codec_video_deinit(h263p);
- /* deinit self */
- tdav_codec_h263_deinit(TDAV_CODEC_H263(self));
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h263p_def_s =
-{
- sizeof(tdav_codec_h263p_t),
- tdav_codec_h263p_ctor,
- tdav_codec_h263p_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h263p_plugin_def_s =
-{
- &tdav_codec_h263p_def_s,
-
- tmedia_video,
- "H263-1998",
- "H263-1998 codec",
- TMEDIA_CODEC_FORMAT_H263_1998,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_h263p_open,
- tdav_codec_h263p_close,
- tdav_codec_h263p_encode,
- tdav_codec_h263p_decode,
- tdav_codec_h263p_fmtp_match,
- tdav_codec_h263p_fmtp_get,
- tdav_codec_h263p_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h263p_plugin_def_t = &tdav_codec_h263p_plugin_def_s;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* ============ H.263-2000 Plugin interface ================= */
-
-//
-// H.263-2000 object definition
-//
-
-int tdav_codec_h263pp_open(tmedia_codec_t* self)
-{
- return tdav_codec_h263_open(self);
-}
-
-int tdav_codec_h263pp_close(tmedia_codec_t* self)
-{
- return tdav_codec_h263_close(self);
-}
-
-tsk_size_t tdav_codec_h263pp_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- return tdav_codec_h263_encode(self, in_data, in_size, out_data, out_max_size);
-}
-
-tsk_size_t tdav_codec_h263pp_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)
-{
- return tdav_codec_h263p_decode(self, in_data, in_size, out_data, out_max_size, proto_hdr);
-}
-
-tsk_bool_t tdav_codec_h263pp_fmtp_match(const tmedia_codec_t* self, const char* fmtp)
-{
- return tdav_codec_h263_fmtp_match(self, fmtp);
-}
-
-char* tdav_codec_h263pp_fmtp_get(const tmedia_codec_t* self)
-{
- return tdav_codec_h263_fmtp_get(self);
-}
-
-int tdav_codec_h263pp_fmtp_set(tmedia_codec_t* self, const char* fmtp)
-{
- TSK_DEBUG_INFO("remote fmtp=%s", fmtp);
- return 0;
-}
-
-/* constructor */
-static tsk_object_t* tdav_codec_h263pp_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h263pp_t *h263pp = self;
- if(h263pp){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h263_init(TDAV_CODEC_H263(self), tdav_codec_h263_2000, CODEC_ID_H263P, CODEC_ID_H263);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h263pp_dtor(tsk_object_t * self)
-{
- tdav_codec_h263pp_t *h263pp = self;
- if(h263pp){
- /* deinit base */
- tmedia_codec_video_deinit(h263pp);
- /* deinit self */
- tdav_codec_h263_deinit(TDAV_CODEC_H263(self));
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h263pp_def_s =
-{
- sizeof(tdav_codec_h263pp_t),
- tdav_codec_h263pp_ctor,
- tdav_codec_h263pp_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h263pp_plugin_def_s =
-{
- &tdav_codec_h263pp_def_s,
-
- tmedia_video,
- "H263-2000",
- "H263-2000 codec",
- TMEDIA_CODEC_FORMAT_H263_2000,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_h263pp_open,
- tdav_codec_h263pp_close,
- tdav_codec_h263pp_encode,
- tdav_codec_h263pp_decode,
- tdav_codec_h263pp_fmtp_match,
- tdav_codec_h263pp_fmtp_get,
- tdav_codec_h263pp_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h263pp_plugin_def_t = &tdav_codec_h263pp_plugin_def_s;
-
-
-
-/* ============ Callbacks ================= */
-
-static void tdav_codec_h263_encap(const tdav_codec_h263_t* h263, const uint8_t* pdata, tsk_size_t size)
-{
- tsk_bool_t frag = tsk_false;
- register uint32_t i, last_index = 0;
-
- if(size < RTP_PAYLOAD_SIZE){
- goto last;
- }
-
- for(i = 4; i<(size - 4); i++){
- if(pdata[i] == 0x00 && pdata[i+1] == 0x00 && pdata[i+2]>=0x80){ /* PSC or (GBSC) found */
- if((i - last_index) >= RTP_PAYLOAD_SIZE || tsk_true/* FIXME */){
- switch(h263->type){
- case tdav_codec_h263_1996:
- tdav_codec_h263_rtp_callback((tdav_codec_h263_t*) h263, pdata+last_index,
- (i - last_index), (last_index == size));
- break;
- default:
- tdav_codec_h263p_rtp_callback((tdav_codec_h263_t*) h263, pdata + last_index,
- (i - last_index), frag, (last_index == size));
- frag = tsk_true;
- break;
- }
- last_index = i;
- }
- }
- }
-last:
- if(last_index < size){
- switch(h263->type){
- case tdav_codec_h263_1996:
- tdav_codec_h263_rtp_callback((tdav_codec_h263_t*) h263, pdata + last_index,
- (size - last_index), tsk_true);
- break;
- default:
- tdav_codec_h263p_rtp_callback((tdav_codec_h263_t*) h263, pdata + last_index,
- (size - last_index), frag, tsk_true);
- break;
- }
- }
-}
-
-
-static void tdav_codec_h263_rtp_callback(tdav_codec_h263_t *self, const void *data, tsk_size_t size, tsk_bool_t marker)
-{
- uint8_t* pdata = (uint8_t*)data;
-
- if(self->rtp.size < (size + H263_HEADER_MODE_A_SIZE)){
- if(!(self->rtp.ptr = tsk_realloc(self->rtp.ptr, (size + H263_HEADER_MODE_A_SIZE)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- return;
- }
- self->rtp.size = (size + H263_HEADER_MODE_A_SIZE);
- }
- memcpy((self->rtp.ptr + H263_HEADER_MODE_A_SIZE), data, size);
-
- /* http://eu.sabotage.org/www/ITU/H/H0263e.pdf section 5.1
- * 5.1.1 Picture Start Code (PSC) (22 bits) - PSC is a word of 22 bits. Its value is 0000 0000 0000 0000 1 00000.
-
- *
- * 5.1.1 Picture Start Code (PSC) (22 bits)
- * 5.1.2 Temporal Reference (TR) (8 bits)
- * 5.1.3 Type Information (PTYPE) (Variable Length)
- * – Bit 1: Always "1", in order to avoid start code emulation.
- * – Bit 2: Always "0", for distinction with Recommendation H.261.
-
- * – Bit 3: Split screen indicator, "0" off, "1" on.
- * – Bit 4: Document camera indicator, "0" off, "1" on.
- * – Bit 5: Full Picture Freeze Release, "0" off, "1" on.
- * – Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF,
- "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE.
- If bits 6-8 are not equal to "111", which indicates an extended PTYPE (PLUSPTYPE), the following
- five bits are also present in PTYPE:
- – Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture).
- – Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on.
- – Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.
- – Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.
- – Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.
- */
- if(pdata[0] == 0x00 && pdata[1] == 0x00 && (pdata[2] & 0xfc)==0x80){ /* PSC */
- /* RFC 2190 -5.1 Mode A
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |F|P|SBIT |EBIT | SRC |I|U|S|A|R |DBQ| TRB | TR |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- SRC : 3 bits
- Source format, bit 6,7 and 8 in PTYPE defined by H.263 [4], specifies
- the resolution of the current picture.
-
- I: 1 bit.
- Picture coding type, bit 9 in PTYPE defined by H.263[4], "0" is
- intra-coded, "1" is inter-coded.
- */
-
- // PDATA[4] ======> Bits 3-10 of PTYPE
- uint32_t rtp_hdr = 0;
- uint8_t format, pict_type;
-
- // Source Format = 4,5,6
- format = (pdata[4] & 0x3C)>>2;
- // Picture Coding Type = 7
- pict_type = (pdata[4] & 0x02)>>1;
- // RTP mode A header
- ((uint8_t*)&rtp_hdr)[1] = (format <<5) | (pict_type << 4);
- //rtp_hdr = tnet_htonl(rtp_hdr);
- memcpy(self->rtp.ptr, &rtp_hdr, sizeof(rtp_hdr));
- }
-
- // 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, (size + H263_HEADER_MODE_A_SIZE), (3003* (30/TMEDIA_CODEC_VIDEO(self)->fps)), marker);
- }
-}
-
-static void tdav_codec_h263p_rtp_callback(tdav_codec_h263_t *self, const void *data, tsk_size_t size, tsk_bool_t frag, tsk_bool_t marker)
-{
- uint8_t* pdata = (uint8_t*)data;
- //uint8_t rtp_hdr[2] = {0x00, 0x00};
- //tsk_bool_t eos = tsk_false;
-
- const void* _ptr = tsk_null;
- tsk_size_t _size = 0;
- //static tsk_bool_t frag = tsk_false;
- //tsk_bool_t found_gob = tsk_false;
-
- /* RFC 4629 - 5.1. General H.263+ Payload Header
- The H.263+ payload header is structured as follows:
- 0 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | RR |P|V| PLEN |PEBIT|
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- /* http://eu.sabotage.org/www/ITU/H/H0263e.pdf
- *
- * 5.1.1 Picture Start Code (PSC) (22 bits)
- * ->PSC is a word of 22 bits. Its value is 0000 0000 0000 0000 1 00000.
- * 5.1.27 End Of Sequence (EOS) (22 bits)
- * ->A codeword of 22 bits. Its value is 0000 0000 0000 0000 1 11111
- * 5.2.2 Group of Block Start Code (GBSC) (17 bits)
- * ->A word of 17 bits. Its value is 0000 0000 0000 0000 1
- * C.4.1 End Of Sub-Bitstream code (EOSBS) (23 bits)
- * ->The EOSBS code is a codeword of 23 bits. Its value is 0000 0000 0000 0000 1 11110 0
- *
- *
- * 5.2.3 Group Number (GN) (5 bits)
- * -> last 5 bits
- */
- //if(pdata[0] == 0x00 && pdata[1] == 0x00 && pdata[2] >= 0x80){ /* PSC or EOS or GBSC */
- // uint8_t GN = ((pdata[2]>>2) & 0x1F);
- // found_gob = tsk_true;
- // //TSK_DEBUG_INFO("GN=%u", pdata[2]);
- //
- // /* RFC 4629 - 6.1.1. Packets that begin with a Picture Start Code
- // A packet that begins at the location of a Picture, GOB, slice, EOS,
- // or EOSBS start code shall omit the first two (all zero) bytes from
- // the H.263+ bitstream and signify their presence by setting P=1 in the
- // payload header.
- // */
-
- // if(GN == 0x00){ /* PSC 00000 */
- // /* Use the two first bytes as RTP header */
- // //pdata[0] |= 0x04; // P=1
-
- // /*
- // 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
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | RR |1|V|0|0|0|0|0|0|0|0|0| bitstream data without the :
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // : first two 0 bytes of the PSC
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // */
-
- // //TSK_DEBUG_INFO("H263 - PSC");
- // }
- // else if(GN == 0x1F){ /* EOS 11111 */
- // /* Use the two first bytes as RTP header */
- // //pdata[0] |= 0x04; // P=1
- // eos = tsk_true;
- // /* RFC 4629 - 6.1.3. Packets that begin with an EOS or EOSBS Code
- // 0 1 2
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | RR |1|V|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|0|0|
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // */
- // //TSK_DEBUG_INFO("H263 - EOS");
- // }
- // else /*if((GN >> 4) == 0x01)*/{ /* GBSC 10000 */
- // /* Use the two first bytes as RTP header */
- // //pdata[0] |= 0x04; // P=1
- //
- // /* RFC 4629 - 6.1.2. Packets that begin with GBSC or SSC
- // 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
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | RR |1|V|0 0 1 0 0 1|PEBIT|1 0 0 0 0 0| picture header :
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // : starting with TR, PTYPE ... |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ... | bitstream :
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // : data starting with GBSC/SSC without its first two 0 bytes
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // */
- // //TSK_DEBUG_INFO("H263 - GBSC");
- // found_gob = tsk_false;
- // }
- // //else if(EOSBS) -> Not Supported
- //}
- //else{
- // /* 6.2. Encapsulating Follow-on Packet (P=0) */
- // int i = 0;
- // i++;
- //}
-
- //if(/*eos*/!found_gob && frag){
- // if(self->rtp.size < (size + 2/* H263+ Header size */)){
- // if(!(self->rtp.ptr = tsk_realloc(self->rtp.ptr, (size + 2)))){
- // TSK_DEBUG_ERROR("Failed to allocate new buffer");
- // return;
- // }
- // self->rtp.size = (size + 2);
- // }
- // /* RFC 4629 - 6. Packetization Schemes */
- // //rtp_hdr[0] |= 0x00;
- // //memcpy(self->rtp.ptr, rtp_hdr/* zeros-> is it corretc? */, 2);
- // //memcpy((self->rtp.ptr + 2), pdata, size);
- // //_ptr = self->rtp.ptr;
- // //_size = (size + 2);
-
- // pdata[0] |= pdata[2] > 0x80 ? 0x04 : 0x04;
- // _ptr = pdata;
- // _size = size;
- //}
- //else{
- // pdata[0] |= pdata[2] > 0x80 ? 0x04 : 0x04;
- // _ptr = pdata;
- // _size = size;
- //}
-
-// FIXME
- pdata[0] |= pdata[2] > 0x80 ? 0x04 : 0x04;
- _ptr = pdata;
- _size = size;
-
-
- // Send data over the network
- if(TMEDIA_CODEC_VIDEO(self)->callback){
- TMEDIA_CODEC_VIDEO(self)->callback(TMEDIA_CODEC_VIDEO(self)->callback_data, _ptr, _size, (3003* (30/TMEDIA_CODEC_VIDEO(self)->fps)), marker);
- }
-}
-
-
-
-#endif /* HAVE_FFMPEG */ \ No newline at end of file
diff --git a/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264.c b/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264.c
deleted file mode 100644
index 1f4be60..0000000
--- a/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264.c
+++ /dev/null
@@ -1,871 +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_h264.c
- * @brief H.264 codec plugin
- * RTP payloader/depayloader follows RFC 3984
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/h264/tdav_codec_h264.h"
-
-#if HAVE_FFMPEG && (!defined(HAVE_H264) || HAVE_H264)
-
-#include "tinydav/codecs/h264/tdav_codec_h264_rtp.h"
-#include "tinydav/video/tdav_converter_video.h"
-
-#include "tinyrtp/rtp/trtp_rtp_packet.h"
-
-#include "tsk_params.h"
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define H264_PACKETIZATION_MODE Non_Interleaved_Mode
-#define H264_MAX_BR 452
-#define H264_MAX_MBPS 11880
-
-int tdav_codec_h264_init(tdav_codec_h264_t* self, tdav_codec_h264_profile_t profile);
-int tdav_codec_h264_deinit(tdav_codec_h264_t* self);
-tdav_codec_h264_profile_t tdav_codec_h264_get_profile(const char* fmtp);
-
-static void tdav_codec_h264_encap(const tdav_codec_h264_t* h264, const uint8_t* pdata, tsk_size_t size);
-
-/* ============ H.264 Base Profile X.X Plugin interface functions ================= */
-
-#define tdav_codec_h264_fmtp_set tsk_null /* FIXME: should be removed from all plugins (useless) */
-
-int tdav_codec_h264_open(tmedia_codec_t* self)
-{
- int ret;
- int size;
- float bitRate;
-
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
-
- if(!h264){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is not opened */
-
-
- //
- // Encoder
- //
- h264->encoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h264->encoder.context);
-
-#if TDAV_UNDER_WINDOWS
- h264->encoder.context->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);
-#endif
-
- h264->encoder.context->pix_fmt = PIX_FMT_YUV420P;
- h264->encoder.context->time_base.num = 1;
- h264->encoder.context->time_base.den = TMEDIA_CODEC_VIDEO(h264)->fps;
- h264->encoder.context->width = TMEDIA_CODEC_VIDEO(h264)->width;
- h264->encoder.context->height = TMEDIA_CODEC_VIDEO(h264)->height;
-
- h264->encoder.context->rc_lookahead = 0;
-
- //h264->encoder.context->refs = 1;
- h264->encoder.context->scenechange_threshold = 0;
- h264->encoder.context->me_subpel_quality = 0;
- h264->encoder.context->partitions = X264_PART_I4X4 | X264_PART_I8X8 | X264_PART_P8X8 | X264_PART_B8X8;
- h264->encoder.context->me_method = ME_EPZS;
- h264->encoder.context->trellis = 0;
-
- h264->encoder.context->me_range = 16;
- h264->encoder.context->max_qdiff = 4;
- h264->encoder.context->mb_qmin = h264->encoder.context->qmin = 10;
- h264->encoder.context->mb_qmax = h264->encoder.context->qmax = 51;
- h264->encoder.context->qcompress = 0.6f;
- h264->encoder.context->mb_decision = FF_MB_DECISION_SIMPLE;
- h264->encoder.context->flags2 |= CODEC_FLAG2_FASTPSKIP;
- h264->encoder.context->flags |= CODEC_FLAG_LOOP_FILTER;
- h264->encoder.context->flags |= CODEC_FLAG_GLOBAL_HEADER;
- h264->encoder.context->max_b_frames = 0;
- h264->encoder.context->b_frame_strategy = 1;
- h264->encoder.context->chromaoffset = 0;
-
- switch(h264->profile){
- case tdav_codec_h264_bp10:
- default:
- h264->encoder.context->profile = FF_PROFILE_H264_BASELINE;
- h264->encoder.context->level = 10;
- bitRate = 128000.f;
- break;
- case tdav_codec_h264_bp20:
- h264->encoder.context->profile = FF_PROFILE_H264_BASELINE;
- h264->encoder.context->level = 20;
- bitRate = 491400.f;
- break;
- case tdav_codec_h264_bp30:
- h264->encoder.context->profile = FF_PROFILE_H264_BASELINE;
- h264->encoder.context->level = 30;
- bitRate = 2725300.f;
- break;
- }
-
- h264->encoder.context->crf = 22;
- h264->encoder.context->thread_count = 0;
- h264->encoder.context->rtp_payload_size = H264_RTP_PAYLOAD_SIZE;
- h264->encoder.context->opaque = tsk_null;
- //h264->encoder.context->bit_rate = (int) (bitRate * 0.80f);
- //h264->encoder.context->bit_rate_tolerance = (int) (bitRate * 0.20f);
- h264->encoder.context->gop_size = TMEDIA_CODEC_VIDEO(h264)->fps*4; // Each 4 second(s)
-
-
- // Picture (YUV 420)
- if(!(h264->encoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create encoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h264->encoder.picture);
-
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h264->encoder.context->width, h264->encoder.context->height);
- if(!(h264->encoder.buffer = tsk_calloc(size, sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate encoder buffer");
- return -2;
- }
-
- // Open encoder
- if((ret = avcodec_open(h264->encoder.context, h264->encoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open [%s] codec", TMEDIA_CODEC(h264)->plugin->desc);
- return ret;
- }
-
- //
- // Decoder
- //
- h264->decoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(h264->decoder.context);
-
- h264->decoder.context->pix_fmt = PIX_FMT_YUV420P;
- h264->decoder.context->flags2 |= CODEC_FLAG2_FAST;
- h264->decoder.context->width = TMEDIA_CODEC_VIDEO(h264)->width;
- h264->decoder.context->height = TMEDIA_CODEC_VIDEO(h264)->height;
-
-#if TDAV_UNDER_WINDOWS
- h264->decoder.context->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);
-#endif
-
- // Picture (YUV 420)
- if(!(h264->decoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create decoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(h264->decoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, h264->decoder.context->width, h264->decoder.context->height);
- if(!(h264->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(h264->decoder.context, h264->decoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open [%s] codec", TMEDIA_CODEC(h264)->plugin->desc);
- return ret;
- }
-
- return 0;
-}
-
-int tdav_codec_h264_close(tmedia_codec_t* self)
-{
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
-
- if(!h264){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is opened */
-
- //
- // Encoder
- //
- if(h264->encoder.context){
- avcodec_close(h264->encoder.context);
- av_free(h264->encoder.context);
- }
- if(h264->encoder.picture){
- av_free(h264->encoder.picture);
- }
- if(h264->encoder.buffer){
- TSK_FREE(h264->encoder.buffer);
- }
-
- //
- // Decoder
- //
- if(h264->decoder.context){
- avcodec_close(h264->decoder.context);
- av_free(h264->decoder.context);
- }
- if(h264->decoder.picture){
- av_free(h264->decoder.picture);
- }
- if(h264->decoder.accumulator){
- TSK_FREE(h264->decoder.accumulator);
- h264->decoder.accumulator_pos = 0;
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h264_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 = 0;
- int size;
-
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if(!self->opened){
- TSK_DEBUG_ERROR("Codec not opened");
- return 0;
- }
-
- // wrap yuv420 buffer
- size = avpicture_fill((AVPicture *)h264->encoder.picture, (uint8_t*)in_data, PIX_FMT_YUV420P, h264->encoder.context->width, h264->encoder.context->height);
- if(size != in_size){
- /* guard */
- TSK_DEBUG_ERROR("Invalid size");
- return 0;
- }
- /* Flip */
-#if FLIP_ENCODED_PICT
- tdav_converter_video_flip(h264->encoder.picture, h264->encoder.context->height);
-#endif
-
- if((h264->encoder.frame_count < (int)TMEDIA_CODEC_VIDEO(h264)->fps*3)
- && ((h264->encoder.frame_count++%TMEDIA_CODEC_VIDEO(h264)->fps)==0)){
-
- // You must patch FFmpeg to switch from X264_TYPE_AUTO to X264_TYPE_IDR
- h264->encoder.picture->pict_type = FF_I_TYPE;
- tdav_codec_h264_encap(h264, h264->encoder.context->extradata, (tsk_size_t)h264->encoder.context->extradata_size);
- }
- else{
- // Encode data
- h264->encoder.picture->pts = AV_NOPTS_VALUE;
- ret = avcodec_encode_video(h264->encoder.context, h264->encoder.buffer, size, h264->encoder.picture);
- if(ret >0){
- tdav_codec_h264_encap(h264, h264->encoder.buffer, (tsk_size_t)ret);
- }
- h264->encoder.picture->pict_type = 0;//reset
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_h264_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)
-{
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- const uint8_t* pay_ptr = tsk_null;
- tsk_size_t pay_size = 0;
- int ret;
- tsk_bool_t append_scp;
- tsk_size_t xsize, retsize = 0;
- int got_picture_ptr;
-
- if(!h264 || !in_data || !in_size || !out_data || !h264->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- //TSK_DEBUG_INFO("SeqNo=%hu", rtp_hdr->seq_num);
-
- /* Packet lost? */
- if(h264->decoder.last_seq != (rtp_hdr->seq_num - 1) && h264->decoder.last_seq){
- if(h264->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);
- }
- h264->decoder.last_seq = rtp_hdr->seq_num;
-
-
- /* 5.3. NAL Unit Octet Usage
- +---------------+
- |0|1|2|3|4|5|6|7|
- +-+-+-+-+-+-+-+-+
- |F|NRI| Type |
- +---------------+
- */
- if(*((uint8_t*)in_data) >> 7){
- TSK_DEBUG_WARN("F=1");
- /* reset accumulator */
- h264->decoder.accumulator = 0;
- return 0;
- }
-
- /* get payload */
- if((ret = tdav_codec_h264_get_pay(in_data, in_size, (const void**)&pay_ptr, &pay_size, &append_scp)) || !pay_ptr || !pay_size){
- TSK_DEBUG_ERROR("Depayloader failed to get H.264 content");
- return 0;
- }
- xsize = avpicture_get_size(h264->decoder.context->pix_fmt, h264->decoder.context->width, h264->decoder.context->height);
-
- if((int)(h264->decoder.accumulator_pos + pay_size) <= xsize){
- if(append_scp){
- memcpy(&((uint8_t*)h264->decoder.accumulator)[h264->decoder.accumulator_pos], H264_START_CODE_PREFIX, sizeof(H264_START_CODE_PREFIX));
- h264->decoder.accumulator_pos += sizeof(H264_START_CODE_PREFIX);
- }
-
- memcpy(&((uint8_t*)h264->decoder.accumulator)[h264->decoder.accumulator_pos], pay_ptr, pay_size);
- h264->decoder.accumulator_pos += pay_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- h264->decoder.accumulator_pos = 0;
- return 0;
- }
-
- if(rtp_hdr->marker){
- AVPacket packet;
-
-
- /* decode the picture */
- av_init_packet(&packet);
- packet.size = h264->decoder.accumulator_pos;
- packet.data = h264->decoder.accumulator;
- ret = avcodec_decode_video2(h264->decoder.context, h264->decoder.picture, &got_picture_ptr, &packet);
-
- if(ret <0){
- TSK_DEBUG_ERROR("=============Failed to decode the buffer");
- }
- else if(got_picture_ptr){
-#if FLIP_DECODED_PICT
- tdav_converter_video_flip(h264->decoder.picture, h264->decoder.context->height);
-#endif
- /* fill out */
- if(*out_max_size<xsize){
- if((*out_data = tsk_realloc(*out_data, xsize))){
- *out_max_size = xsize;
- }
- else{
- *out_max_size = 0;
- return 0;
- }
- }
- retsize = xsize;
- avpicture_layout((AVPicture *)h264->decoder.picture, h264->decoder.context->pix_fmt, h264->decoder.context->width, h264->decoder.context->height,
- *out_data, retsize);
- }
- h264->decoder.accumulator_pos = 0;
- }
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_h264_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)codec;
- tsk_params_L_t* params = tsk_null;
- int val_int;
- const char* val_str;
- tsk_bool_t ret = tsk_true;
- tdav_codec_h264_profile_t profile;
-
- if(!h264){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_false;
- }
-
- TSK_DEBUG_INFO("Trying to match [%s]", fmtp);
-
- /* Check whether the profile match (If the profile is missing, then we consider that it's ok) */
- if(((profile = tdav_codec_h264_get_profile(fmtp)) != tdav_codec_h264_bp99) && (profile != h264->profile)){
- TSK_DEBUG_INFO("Profile not matching");
- return tsk_false;
- }
-
- /* e.g. profile-level-id=42e00a; packetization-mode=1; max-br=452; max-mbps=11880 */
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
-
- /* === max-br ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "max-br")) != -1){
- // should compare "max-br"?
- TMEDIA_CODEC_VIDEO(h264)->max_br = val_int*1000;
- }
-
- /* === max-mbps ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "max-mbps")) != -1){
- // should compare "max-mbps"?
- TMEDIA_CODEC_VIDEO(h264)->max_mbps = val_int*1000;
- }
-
- /* === packetization-mode ===*/
- if((val_int = tsk_params_get_param_value_as_int(params, "packetization-mode")) != -1){
- if((packetization_mode_t)val_int == Single_NAL_Unit_Mode || (packetization_mode_t)val_int == Non_Interleaved_Mode){
- h264->pack_mode = (packetization_mode_t)val_int;
- }
- else{
- TSK_DEBUG_INFO("packetization-mode not matching");
- ret = tsk_false;
- goto bail;
- }
- }
-
- /* === profile-level-id ===*/
- if((val_str = tsk_params_get_param_value(params, "profile-level-id"))){
- level_idc_t l_idc;
- /* profile-idc and level-idc already tested by tdav_codec_h264_get_profile() */
- tdav_codec_h264_parse_profile(val_str, tsk_null, tsk_null, &l_idc);
- switch(l_idc){
- case level_idc_1_0:
- case level_idc_1_b:
- case level_idc_1_1:
- TMEDIA_CODEC_VIDEO(h264)->width = 176, TMEDIA_CODEC_VIDEO(h264)->height = 144;
- break;
- default:
- TMEDIA_CODEC_VIDEO(h264)->width = 352, TMEDIA_CODEC_VIDEO(h264)->height = 288;
- //TMEDIA_CODEC_VIDEO(h264)->width = 704, TMEDIA_CODEC_VIDEO(h264)->height = 480;
- break;
- }
- }
- }
-
-bail:
- TSK_OBJECT_SAFE_FREE(params);
- return ret;
-}
-
-char* tdav_codec_h264_fmtp_get(const tmedia_codec_t* self)
-{
- tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
- char* fmtp = tsk_null;
-
- if(!h264){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- switch(h264->profile){
- case tdav_codec_h264_bp10:
- fmtp = tsk_strdup("profile-level-id=42e00a");
- break;
- case tdav_codec_h264_bp20:
- fmtp = tsk_strdup("profile-level-id=42e014");
- break;
- case tdav_codec_h264_bp30:
- fmtp = tsk_strdup("profile-level-id=42e01e");
- break;
- }
-
- if(fmtp){
- tsk_strcat_2(&fmtp, "; packetization-mode=%d; max-br=%d; max-mbps=%d",
- h264->pack_mode, TMEDIA_CODEC_VIDEO(h264)->max_br/1000, TMEDIA_CODEC_VIDEO(h264)->max_mbps/1000);
- }
-
- return fmtp;
-}
-
-
-
-
-/* ============ H.264 Base Profile 1.0 Plugin interface ================= */
-
-/* constructor */
-static tsk_object_t* tdav_codec_h264_bp10_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h264_init(h264, tdav_codec_h264_bp10);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h264_bp10_dtor(tsk_object_t * self)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* deinit base */
- tmedia_codec_video_deinit(self);
- /* deinit self */
- tdav_codec_h264_deinit(h264);
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h264_bp10_def_s =
-{
- sizeof(tdav_codec_h264_t),
- tdav_codec_h264_bp10_ctor,
- tdav_codec_h264_bp10_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h264_bp10_plugin_def_s =
-{
- &tdav_codec_h264_bp10_def_s,
-
- tmedia_video,
- "H264",
- "H264 Base Profile 1.0",
- TMEDIA_CODEC_FORMAT_H264_BP10,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_h264_open,
- tdav_codec_h264_close,
- tdav_codec_h264_encode,
- tdav_codec_h264_decode,
- tdav_codec_h264_fmtp_match,
- tdav_codec_h264_fmtp_get,
- tdav_codec_h264_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h264_bp10_plugin_def_t = &tdav_codec_h264_bp10_plugin_def_s;
-
-
-/* ============ H.264 Base Profile 2.0 Plugin interface ================= */
-
-/* constructor */
-static tsk_object_t* tdav_codec_h264_bp20_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h264_init(h264, tdav_codec_h264_bp20);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h264_bp20_dtor(tsk_object_t * self)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* deinit base */
- tmedia_codec_video_deinit(self);
- /* deinit self */
- tdav_codec_h264_deinit(h264);
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h264_bp20_def_s =
-{
- sizeof(tdav_codec_h264_t),
- tdav_codec_h264_bp20_ctor,
- tdav_codec_h264_bp20_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h264_bp20_plugin_def_s =
-{
- &tdav_codec_h264_bp20_def_s,
-
- tmedia_video,
- "H264",
- "H264 Base Profile 2.0",
- TMEDIA_CODEC_FORMAT_H264_BP20,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {352, 288, 15},
-
- tdav_codec_h264_open,
- tdav_codec_h264_close,
- tdav_codec_h264_encode,
- tdav_codec_h264_decode,
- tdav_codec_h264_fmtp_match,
- tdav_codec_h264_fmtp_get,
- tdav_codec_h264_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h264_bp20_plugin_def_t = &tdav_codec_h264_bp20_plugin_def_s;
-
-
-/* ============ H.264 Base Profile 3.0 Plugin interface ================= */
-
-/* constructor */
-static tsk_object_t* tdav_codec_h264_bp30_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_h264_init(h264, tdav_codec_h264_bp30);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_h264_bp30_dtor(tsk_object_t * self)
-{
- tdav_codec_h264_t *h264 = self;
- if(h264){
- /* deinit base */
- tmedia_codec_video_deinit(self);
- /* deinit self */
- tdav_codec_h264_deinit(h264);
-
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_h264_bp30_def_s =
-{
- sizeof(tdav_codec_h264_t),
- tdav_codec_h264_bp30_ctor,
- tdav_codec_h264_bp30_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h264_bp30_plugin_def_s =
-{
- &tdav_codec_h264_bp30_def_s,
-
- tmedia_video,
- "H264",
- "H264 Base Profile 3.0",
- TMEDIA_CODEC_FORMAT_H264_BP30,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {352, 288, 15},
-
- tdav_codec_h264_open,
- tdav_codec_h264_close,
- tdav_codec_h264_encode,
- tdav_codec_h264_decode,
- tdav_codec_h264_fmtp_match,
- tdav_codec_h264_fmtp_get,
- tdav_codec_h264_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_h264_bp30_plugin_def_t = &tdav_codec_h264_bp30_plugin_def_s;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* ============ Common To all H264 codecs ================= */
-
-int tdav_codec_h264_init(tdav_codec_h264_t* self, tdav_codec_h264_profile_t profile)
-{
- int ret = 0;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- self->pack_mode = H264_PACKETIZATION_MODE;
- self->profile = profile;
- TMEDIA_CODEC_VIDEO(self)->max_mbps = H264_MAX_MBPS*1000;
- TMEDIA_CODEC_VIDEO(self)->max_br = H264_MAX_BR*1000;
-
- // At this time self->plugin is Null
- TMEDIA_CODEC_VIDEO(self)->width = 176;
- TMEDIA_CODEC_VIDEO(self)->height = 144;
- TMEDIA_CODEC_VIDEO(self)->fps = 15;
-
- if(!(self->encoder.codec = avcodec_find_encoder(CODEC_ID_H264))){
- TSK_DEBUG_ERROR("Failed to find H.264 encoder");
- ret = -2;
- }
-
- if(!(self->decoder.codec = avcodec_find_decoder(CODEC_ID_H264))){
- TSK_DEBUG_ERROR("Failed to find H.264 decoder");
- ret = -3;
- }
-
- /* allocations MUST be done by open() */
- return ret;
-}
-
-int tdav_codec_h264_deinit(tdav_codec_h264_t* self)
-{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- self->encoder.codec = tsk_null;
- self->decoder.codec = tsk_null;
-
- // FFMpeg resources are destroyed by close()
-
-
- TSK_FREE(self->rtp.ptr);
- self->rtp.size = 0;
-
- return 0;
-}
-
-tdav_codec_h264_profile_t tdav_codec_h264_get_profile(const char* fmtp)
-{
- tdav_codec_h264_profile_t profile = tdav_codec_h264_bp99;
- tsk_size_t size = tsk_strlen(fmtp);
- int start, end;
-
- if((start = tsk_strindexOf(fmtp, size, "profile-level-id")) !=-1){
- tsk_param_t* param;
- if((end = tsk_strindexOf((fmtp+start), (size-start), ";")) == -1){
- end = size;
- }
-
- if((param = tsk_params_parse_param((fmtp+start), (end-start)))){
- profile_idc_t p_idc;
- level_idc_t l_idc;
- if(param->value){
- tsk_strtrim_both(&param->value);
- }
-
- tdav_codec_h264_parse_profile(param->value, &p_idc, tsk_null, &l_idc);
-
- switch(p_idc){
- case profile_idc_baseline:
- switch(l_idc){
- case level_idc_1_0:
- case level_idc_1_b:
- case level_idc_1_1:
- case level_idc_1_2:
- case level_idc_1_3:
- profile = tdav_codec_h264_bp10;
- break;
- case level_idc_2_0:
- case level_idc_2_1:
- case level_idc_2_2:
- profile = tdav_codec_h264_bp20;
- break;
- case level_idc_3_0:
- profile = tdav_codec_h264_bp30;
- break;
- }
- break;
- case profile_idc_extended:
- case profile_idc_main:
- case profile_idc_high:
- default:
- /* Not supported */
- break;
- }
-
- TSK_OBJECT_SAFE_FREE(param);
- }
- }
- return profile;
-}
-
-static void tdav_codec_h264_encap(const tdav_codec_h264_t* h264, const uint8_t* pdata, tsk_size_t size)
-{
- register uint32_t i;
- uint32_t last_scp, prev_scp;
- static uint32_t size_of_scp = sizeof(H264_START_CODE_PREFIX); /* we know it's equal to 4 ..but */
-
- if(!pdata || !size){
- return;
- }
-
- last_scp = 0, prev_scp = 0;
-/*
-#if 1
- if(size < H264_RTP_PAYLOAD_SIZE){
- goto last;
- }
-#else
- goto last;
-#endif
-*/
- for(i = size_of_scp; i<(size - size_of_scp); i++){
- if(pdata[i] == H264_START_CODE_PREFIX[0] && pdata[i+1] == H264_START_CODE_PREFIX[1] && pdata[i+2] == H264_START_CODE_PREFIX[2] && pdata[i+3] == H264_START_CODE_PREFIX[3]){ /* Found Start Code Prefix */
- prev_scp = last_scp;
- if((i - last_scp) >= H264_RTP_PAYLOAD_SIZE || 1){
- tdav_codec_h264_rtp_callback((tdav_codec_h264_t*) h264, pdata + prev_scp,
- (i - prev_scp), (prev_scp == size));
- }
- last_scp = i;
- }
- }
-//last:
- if(last_scp < size){
- tdav_codec_h264_rtp_callback((tdav_codec_h264_t*) h264, pdata + last_scp,
- (size - last_scp), tsk_true);
- }
-}
-
-#endif /* HAVE_FFMPEG */
diff --git a/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264_rtp.c b/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264_rtp.c
deleted file mode 100644
index a750ccf..0000000
--- a/branches/1.0/tinyDAV/src/codecs/h264/tdav_codec_h264_rtp.c
+++ /dev/null
@@ -1,356 +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_h264_rtp.c
- * @brief H.264 payloader/depayloder as per RFC 3984
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/h264/tdav_codec_h264_rtp.h"
-
-#include "tinydav/codecs/h264/tdav_codec_h264.h"
-
-#if HAVE_FFMPEG && (!defined(HAVE_H264) || HAVE_H264)
-
-#include "tinymedia/tmedia_codec.h"
-
-#include "tsk_string.h"
-#include "tsk_debug.h"
-
-#include "tsk_memory.h"
-#include <string.h> /* strlen() */
-#include <stdlib.h> /* strtol() */
-
-/*
-* ITU H.264 - http://www.itu.int/rec/T-REC-H.264-200903-S/en
-*/
-
-uint8_t H264_START_CODE_PREFIX[4] = { 0x00, 0x00, 0x00, 0x01 };
-
-#define H264_NAL_UNIT_TYPE_HEADER_SIZE 1
-#define H264_F_UNIT_TYPE_HEADER_SIZE 1
-#define H264_FUA_HEADER_SIZE 2
-#define H264_FUB_HEADER_SIZE 4
-#define H264_NAL_AGG_MAX_SIZE 65535
-
-int tdav_codec_h264_get_fua_pay(const uint8_t* in_data, tsk_size_t in_size, const void** out_data, tsk_size_t *out_size, tsk_bool_t* append_scp);
-int tdav_codec_h264_get_nalunit_pay(const uint8_t* in_data, tsk_size_t in_size, const void** out_data, tsk_size_t *out_size);
-
-// profile_level_id MUST be a "null-terminated" string
-int tdav_codec_h264_parse_profile(const char* profile_level_id, profile_idc_t *p_idc, profile_iop_t *p_iop, level_idc_t *l_idc)
-{
- uint32_t value;
-
- if(tsk_strlen(profile_level_id) != 6){
- TSK_DEBUG_ERROR("I say [%s] is an invalid profile-level-id", profile_level_id);
- return -1;
- }
-
- value = strtol(profile_level_id, tsk_null, 16);
-
- /* profile-idc */
- if(p_idc){
- switch((value >> 16)){
- case profile_idc_baseline:
- *p_idc = profile_idc_baseline;
- break;
- case profile_idc_extended:
- *p_idc = profile_idc_extended;
- break;
- case profile_idc_main:
- *p_idc = profile_idc_main;
- break;
- case profile_idc_high:
- *p_idc = profile_idc_high;
- break;
- default:
- *p_idc = profile_idc_none;
- break;
- }
- }
-
- /* profile-iop */
- if(p_iop){
- p_iop->constraint_set0_flag = ((value >> 8) & 0x80)>>7;
- p_iop->constraint_set1_flag = ((value >> 8) & 0x40)>>6;
- p_iop->constraint_set2_flag = ((value >> 8) & 0x20)>>5;
- p_iop->reserved_zero_5bits = ((value >> 8) & 0x1F);
- }
-
- /* level-idc */
- if(l_idc){
- switch((value & 0xFF)){
- case level_idc_1_0:
- *l_idc = level_idc_1_0;
- break;
- case level_idc_1_b:
- *l_idc = level_idc_1_b;
- break;
- case level_idc_1_1:
- *l_idc = level_idc_1_1;
- break;
- case level_idc_1_2:
- *l_idc = level_idc_1_2;
- break;
- case level_idc_1_3:
- *l_idc = level_idc_1_3;
- break;
- case level_idc_2_0:
- *l_idc = level_idc_2_0;
- break;
- case level_idc_2_1:
- *l_idc = level_idc_2_1;
- break;
- case level_idc_2_2:
- *l_idc = level_idc_2_2;
- break;
- case level_idc_3_0:
- *l_idc = level_idc_3_0;
- break;
- default:
- *l_idc = level_idc_none;
- break;
- }
- }
-
- return 0;
-}
-
-int tdav_codec_h264_get_pay(const void* in_data, tsk_size_t in_size, const void** out_data, tsk_size_t *out_size, tsk_bool_t* append_scp)
-{
- const uint8_t* pdata = in_data;
- if(!in_data || !in_size || !out_data || !out_size){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- *out_data = tsk_null;
- *out_size = 0;
- *append_scp = tsk_true;
-
- /* 5.3. NAL Unit Octet Usage
- +---------------+
- |0|1|2|3|4|5|6|7|
- +-+-+-+-+-+-+-+-+
- |F|NRI| Type |
- +---------------+
- */
- switch((pdata[0] & 0x1F)){
- case undefined_0:
- case undefined_30:
- case undefined_31:
- case stap_a:
- case stap_b:
- case mtap16:
- case mtap24:
- break;
- case fu_a:
- return tdav_codec_h264_get_fua_pay(pdata, in_size, out_data, out_size, append_scp);
- case fu_b:
- return -1;
- default: /* NAL unit (1-23) */
- return tdav_codec_h264_get_nalunit_pay(pdata, in_size, out_data, out_size);
- }
-
- TSK_DEBUG_WARN("%d not supported as valid NAL Unit type", (*pdata & 0x1F));
- return -1;
-}
-
-
-int tdav_codec_h264_get_fua_pay(const uint8_t* in_data, tsk_size_t in_size, const void** out_data, tsk_size_t *out_size, tsk_bool_t* append_scp)
-{
- if(in_size <=2){
- TSK_DEBUG_ERROR("Too short");
- return -1;
- }
- /* RFC 3984 - 5.8. Fragmentation Units (FUs)
-
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | FU indicator | FU header | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
- | FU payload |
- | |
- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | :...OPTIONAL RTP padding |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
- The FU indicator octet has the following format:
-
- +---------------+
- |0|1|2|3|4|5|6|7|
- +-+-+-+-+-+-+-+-+
- |F|NRI| Type |
- +---------------+
-
- The FU header has the following format:
-
- +---------------+
- |0|1|2|3|4|5|6|7|
- +-+-+-+-+-+-+-+-+
- |S|E|R| Type |
- +---------------+
- */
-
- if((in_data[1] & 0x80) == 0x80 /*S*/){
- /* discard "FU indicator"
- S: 1 bit
- When set to one, the Start bit indicates the start of a fragmented
- NAL unit. When the following FU payload is not the start of a
- fragmented NAL unit payload, the Start bit is set to zero.
- */
- if(in_size> H264_NAL_UNIT_TYPE_HEADER_SIZE){
- uint8_t hdr;
- *out_data = (in_data + H264_NAL_UNIT_TYPE_HEADER_SIZE);
- *out_size = (in_size - H264_NAL_UNIT_TYPE_HEADER_SIZE);
-
- // F, NRI and Type
- hdr = (in_data[0] & 0xe0) /* F,NRI from "FU indicator"*/ | (in_data[1] & 0x1f) /* type from "FU header" */;
- *((uint8_t*)*out_data) = hdr;
- // Need to append Start Code Prefix
- *append_scp = tsk_true;
- }
- else{
- TSK_DEBUG_ERROR("Too short");
- return -1;
- }
- }
- else{
- /* "FU indicator" and "FU header" */
- if(in_size> H264_FUA_HEADER_SIZE){
- *out_data = (in_data + H264_FUA_HEADER_SIZE);
- *out_size = (in_size - H264_FUA_HEADER_SIZE);
- *append_scp = tsk_false;
- }
- else{
- TSK_DEBUG_ERROR("Too short");
- return -1;
- }
- }
-
- return 0;
-}
-
-int tdav_codec_h264_get_nalunit_pay(const uint8_t* in_data, tsk_size_t in_size, const void** out_data, tsk_size_t *out_size)
-{
-
-/* 5.6. Single NAL Unit Packet
-
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |F|NRI| type | |
- +-+-+-+-+-+-+-+-+ |
- | |
- | Bytes 2..n of a Single NAL unit |
- | |
- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | :...OPTIONAL RTP padding |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-
- *out_data = in_data;
- *out_size = in_size;
-
- return 0;
-}
-
-#if TDAV_UNDER_WINDOWS
-# include "tsk_thread.h"
-#endif
-void tdav_codec_h264_rtp_callback(struct tdav_codec_h264_s *self, const void *data, tsk_size_t size, tsk_bool_t marker)
-{
- uint8_t* pdata = (uint8_t*)data;
-
- if(size>4 && pdata[0] == H264_START_CODE_PREFIX[0] && pdata[1] == H264_START_CODE_PREFIX[1]){
- if(pdata[2] == H264_START_CODE_PREFIX[3]){
- pdata += 3, size -= 3;
- }
- else if(pdata[2] == H264_START_CODE_PREFIX[2] && pdata[3] == H264_START_CODE_PREFIX[3]){
- pdata += 4, size -= 4;
- }
- }
-
- //TSK_DEBUG_INFO("==> SCP %2x %2x %2x %2x", pdata[0], pdata[1], pdata[2], pdata[3]);
-
- if(size < H264_RTP_PAYLOAD_SIZE){
- /* Can be packet in a Single Nal Unit */
- // Send data over the network
- if(TMEDIA_CODEC_VIDEO(self)->callback){
- TMEDIA_CODEC_VIDEO(self)->callback(TMEDIA_CODEC_VIDEO(self)->callback_data, pdata, size, (3003* (30/TMEDIA_CODEC_VIDEO(self)->fps)), marker);
- }
- }
- else if(size > H264_NAL_UNIT_TYPE_HEADER_SIZE){
-#if TDAV_UNDER_WINDOWS
- tsk_bool_t burst = ((size/H264_RTP_PAYLOAD_SIZE) > 5);
- int count = 0;
-#endif
- /* Should be Fragmented as FUA */
- uint8_t fua_hdr[H264_FUA_HEADER_SIZE]; /* "FU indicator" and "FU header" - 2bytes */
- fua_hdr[0] = pdata[0] & 0x60/* F=0 */, fua_hdr[0] |= fu_a;
- fua_hdr[1] = 0x80/* S=1,E=0,R=0 */, fua_hdr[1] |= pdata[0] & 0x1f; /* type */
- // discard header
- pdata += H264_NAL_UNIT_TYPE_HEADER_SIZE;
- size -= H264_NAL_UNIT_TYPE_HEADER_SIZE;
-
- while(size){
- tsk_size_t packet_size = TSK_MIN(H264_RTP_PAYLOAD_SIZE, size);
-
- if(self->rtp.size < (packet_size + H264_FUA_HEADER_SIZE)){
- if(!(self->rtp.ptr = tsk_realloc(self->rtp.ptr, (packet_size + H264_FUA_HEADER_SIZE)))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- return;
- }
- self->rtp.size = (packet_size + H264_FUA_HEADER_SIZE);
- }
- // set E bit
- if((size - packet_size) == 0){
- // Last packet
- fua_hdr[1] |= 0x40;
- }
- // copy FUA header
- memcpy(self->rtp.ptr, fua_hdr, H264_FUA_HEADER_SIZE);
- // reset "S" bit
- fua_hdr[1] &= 0x7F;
- // copy data
- memcpy((self->rtp.ptr + H264_FUA_HEADER_SIZE), pdata, packet_size);
- pdata += packet_size;
- size -= packet_size;
-
- // send data
- if(TMEDIA_CODEC_VIDEO(self)->callback){
- TMEDIA_CODEC_VIDEO(self)->callback(TMEDIA_CODEC_VIDEO(self)->callback_data, self->rtp.ptr, (packet_size + H264_FUA_HEADER_SIZE), (3003* (30/TMEDIA_CODEC_VIDEO(self)->fps)), (size == 0));
-#if TDAV_UNDER_WINDOWS// FIXME: WinSock problem: Why do we get packet lost (burst case only)?
- if(burst && (++count % 2 == 0)){
- tsk_thread_sleep(1); // 1 millisecond
- }
-#endif
- }
- }
- }
-}
-
-#endif /* HAVE_FFMPEG */ \ No newline at end of file
diff --git a/branches/1.0/tinyDAV/src/codecs/ilbc/tdav_codec_ilbc.c b/branches/1.0/tinyDAV/src/codecs/ilbc/tdav_codec_ilbc.c
deleted file mode 100644
index 23271b4..0000000
--- a/branches/1.0/tinyDAV/src/codecs/ilbc/tdav_codec_ilbc.c
+++ /dev/null
@@ -1,256 +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_ilbc.c
- * @brief iLBC codec
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/ilbc/tdav_codec_ilbc.h"
-
-#if HAVE_ILBC
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define TDAV_ILBC_MODE 20
-
-/* ============ iLBC Plugin interface ================= */
-
-#define tdav_codec_ilbc_fmtp_set tsk_null
-
-int tdav_codec_ilbc_open(tmedia_codec_t* self)
-{
- tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self;
-
- initEncode(&ilbc->encoder, TDAV_ILBC_MODE);
- initDecode(&ilbc->decoder, TDAV_ILBC_MODE, tsk_true/* Enhancer */);
-
- return 0;
-}
-
-int tdav_codec_ilbc_close(tmedia_codec_t* self)
-{
- tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self;
-
- //ilbc->encoder = {0};
- //ilbc->decoder = {0};
-
- return 0;
-}
-
-tsk_size_t tdav_codec_ilbc_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self;
- int k;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* convert signal to float */
- for(k=0; k<ilbc->encoder.blockl; k++){
- ilbc->encblock[k] = (float)((short*)in_data)[k];
- }
-
- /* allocate new buffer if needed */
- if((int)*out_max_size <ilbc->encoder.no_of_bytes){
- if(!(*out_data = tsk_realloc(*out_data, ilbc->encoder.no_of_bytes))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = ilbc->encoder.no_of_bytes;
- }
-
- /* do the actual encoding */
- iLBC_encode(*out_data, ilbc->encblock, &ilbc->encoder);
-
- return ilbc->encoder.no_of_bytes;
-}
-
-tsk_size_t tdav_codec_ilbc_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)
-{
- int blocks, i, k, block_size;
- float dtmp;
- tsk_size_t out_size;
- tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if((in_size % NO_OF_BYTES_20MS) == 0){
- /* Using 20ms mode */
- blocks = (in_size/NO_OF_BYTES_20MS);
- out_size = (BLOCKL_20MS * blocks) * sizeof(short);
- block_size = out_size/blocks;
- if(ilbc->decoder.mode != 20){
- initDecode(&ilbc->decoder, 20, tsk_true/* Enhancer */);
- }
- }
- else if((in_size % NO_OF_BYTES_30MS) == 0){
- /* Using 30ms mode */
- blocks = (in_size/NO_OF_BYTES_30MS);
- out_size = (BLOCKL_30MS * blocks) * sizeof(short);
- block_size = out_size/blocks;
- if(ilbc->decoder.mode != 30){
- initDecode(&ilbc->decoder, 30, tsk_true/* Enhancer */);
- }
- }
- else{
- TSK_DEBUG_ERROR("Invalid iLBC mode");
- return 0;
- }
-
- /* allocate new buffer if needed */
- if(*out_max_size<out_size){
- if(!(*out_data = tsk_realloc(*out_data, out_size))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = out_size;
- }
-
- for(i = 0; i<blocks; i++){
- iLBC_decode(ilbc->decblock, &((uint8_t*)in_data)[i*block_size], &ilbc->decoder, 1/* Normal */);
-
- /* convert to short */
- for(k=0; k<ilbc->decoder.blockl; k++){
- dtmp=ilbc->decblock[k];
-
- if(dtmp<MIN_SAMPLE){
- dtmp = MIN_SAMPLE;
- }
- else if(dtmp>MAX_SAMPLE){
- dtmp = MAX_SAMPLE;
- }
-
- ((short*)*out_data)[(i*block_size) + k] = ((short) dtmp);
- }
- }
-
- return out_size;
-}
-
-char* tdav_codec_ilbc_fmtp_get(const tmedia_codec_t* codec)
-{
- char* fmtp = tsk_null;
- tsk_sprintf(&fmtp, "mode=%d", TDAV_ILBC_MODE);
- return fmtp;
-}
-
-tsk_bool_t tdav_codec_ilbc_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* RFC 3952 - 5. Mapping To SDP Parameters
-
- The offer contains the preferred mode of the offerer. The answerer
- may agree to that mode by including the same mode in the answer, or
- may include a different mode. The resulting mode used by both
- parties SHALL be the lower of the bandwidth modes in the offer and
- answer.
-
- That is, an offer of "mode=20" receiving an answer of "mode=30" will
- result in "mode=30" being used by both participants. Similarly, an
- offer of "mode=30" and an answer of "mode=20" will result in
- "mode=30" being used by both participants.
-
- This is important when one end point utilizes a bandwidth constrained
- link (e.g., 28.8k modem link or slower), where only the lower frame
- size will work.
- */
- return tsk_true; // FIXME
-}
-
-
-//
-// iLBC Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_ilbc_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_ilbc_t *ilbc = self;
- if(ilbc){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_ilbc_dtor(tsk_object_t * self)
-{
- tdav_codec_ilbc_t *ilbc = self;
- if(ilbc){
- /* deinit base */
- tmedia_codec_audio_deinit(ilbc);
- /* deinit self */
- //ilbc->encoder = {0};
- //ilbc->decoder = {0};
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_ilbc_def_s =
-{
- sizeof(tdav_codec_ilbc_t),
- tdav_codec_ilbc_ctor,
- tdav_codec_ilbc_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_ilbc_plugin_def_s =
-{
- &tdav_codec_ilbc_def_s,
-
- tmedia_audio,
- "iLBC",
- "iLBC codec",
- TMEDIA_CODEC_FORMAT_ILBC,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_ilbc_open,
- tdav_codec_ilbc_close,
- tdav_codec_ilbc_encode,
- tdav_codec_ilbc_decode,
- tdav_codec_ilbc_fmtp_match,
- tdav_codec_ilbc_fmtp_get,
- tdav_codec_ilbc_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_ilbc_plugin_def_t = &tdav_codec_ilbc_plugin_def_s;
-
-
-#endif /* HAVE_ILBC */
diff --git a/branches/1.0/tinyDAV/src/codecs/mp4ves/tdav_codec_mp4ves.c b/branches/1.0/tinyDAV/src/codecs/mp4ves/tdav_codec_mp4ves.c
deleted file mode 100644
index 731fe2e..0000000
--- a/branches/1.0/tinyDAV/src/codecs/mp4ves/tdav_codec_mp4ves.c
+++ /dev/null
@@ -1,634 +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_mp4ves.c
- * @brief MP4V-ES codec plugin
- * RTP payloader/depayloader follows RFC 3016.
- * ISO-IEC-14496-2: http://www.csus.edu/indiv/p/pangj/aresearch/video_compression/presentation/ISO-IEC-14496-2_2001_MPEG4_Visual.pdf
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Th Dec 2 16:54:58 2010 mdiop
- */
-#include "tinydav/codecs/mp4ves/tdav_codec_mp4ves.h"
-
-#if HAVE_FFMPEG
-
-#include "tinydav/video/tdav_converter_video.h"
-
-#include "tinyrtp/rtp/trtp_rtp_packet.h"
-
-#include "tnet_endianness.h"
-
-#include "tsk_params.h"
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-#define DEFAULT_PROFILE_LEVEL_ID Simple_Profile_Level_1
-
-#define MP4V_RTP_PAYLOAD_SIZE 900
-
-
-// From ISO-IEC-14496-2
-typedef enum mp4v_codes_e
-{
- // To initiate a visual session (6.3.2)
- visual_object_sequence_start_code = 0x000001B0,
- // To terminate a visual session (6.3.2)
- visual_object_sequence_end_code = 0x000001B1,
- // To initiate a visual object (6.3.2)
- visual_object_start_code = 0x000001B5,
- // To identify the beginning of user data. The user data continues until receipt of another start code. (6.3.2.1)
- user_data_start_code = 0x000001B2,
- // The video_object_layer_start_code is a string of 32 bits. The first 28 bits are
- // ‘0000 0000 0000 0000 0000 0001 0010‘ in binary and the last 4-bits represent one of the values in the range of
- // ‘0000’ to ‘1111’ in binary. The video_object_layer_start_code marks a new video object layer. (6.3.3)
- video_object_layer_start_code = 0x0000012,
- // To identify the beginning of a GOV header (6.3.4)
- group_of_vop_start_code = 0x000001B3,
- // To mark the start of a video object plane (6.3.5 )
- vop_start_code = 0x000001B6,
-}
-mp4v_start_code_t;
-
-// From ISO-IEC-14496-2 Annex G
-typedef enum mp4v_profiles_e
-{
- /* Reserved = 0x00000000 */
- Simple_Profile_Level_1 = 1,
- Simple_Profile_Level_2 = 2,
- Simple_Profile_Level_3 = 3,
- /* Reserved 00000100 ? 00010000 */
- Simple_Scalable_Profile_Level_1 = 17,
- Simple_Scalable_Profile_Level_2 = 18,
- /* Reserved 00010011 ? = 0x00100000 */
- Core_Profile_Level_1 = 33,
- Core_Profile_Level_2 = 34,
- /* Reserved 00100011 ? = 0x00110001 */
- Main_Profile_Level_2 = 50,
- Main_Profile_Level_3 = 51,
- Main_Profile_Level_4 = 52,
- /* Reserved 00110101 ? = 0x01000001 */
- N_bit_Profile_Level_2 = 66,
- /* Reserved 01000011 ? = 0x01010000 */
- Scalable_Texture_Profile_Level_1 = 81,
- /* Reserved 01010010 ? 01100000 */
- Simple_Face_Animation_Profile_Level_1 = 97,
- Simple_Face_Animation_Profile_Level_2 = 98,
- Simple_FBA_Profile_Level_1 = 99,
- Simple_FBA_Profile_Level_2 = 100,
- /* Reserved 01100101 ? 01110000 */
- Basic_Animated_Texture_Profile_Level_1 = 113,
- Basic_Animated_Texture_Profile_Level_2 = 114,
- /* Reserved 01110011 ? 10000000 */
- Hybrid_Profile_Level_1 = 129,
- Hybrid_Profile_Level_2 = 130,
- /* Reserved 10000011 ? 10010000 */
- Advanced_Real_Time_Simple_Profile_Level_1 = 145,
- Advanced_Real_Time_Simple_Profile_Level_2 = 146,
- Advanced_Real_Time_Simple_Profile_Level_3 = 147,
- Advanced_Real_Time_Simple_Profile_Level_4 = 148,
- /* Reserved 10010101 ? 10100000 */
-}
-mp4v_profiles_t;
-
-static void tdav_codec_mp4ves_encap(tdav_codec_mp4ves_t* mp4v, const uint8_t* pdata, tsk_size_t size);
-static void tdav_codec_mp4ves_rtp_callback(tdav_codec_mp4ves_t *mp4v, const void *data, tsk_size_t size, tsk_bool_t marker);
-
-/* ============ MP4V-ES Plugin interface functions ================= */
-#define tdav_codec_mp4ves_fmtp_set tsk_null /* MUST be removed from all codecs */
-
-int tdav_codec_mp4ves_open(tmedia_codec_t* self)
-{
- int ret;
- int size;
- float bitRate = 64000.f;
-
- tdav_codec_mp4ves_t* mp4v = (tdav_codec_mp4ves_t*)self;
-
- if(!mp4v){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is not opened */
-
- //
- // Encoder
- //
- if(!(mp4v->encoder.codec = avcodec_find_encoder(CODEC_ID_MPEG4))){
- TSK_DEBUG_ERROR("Failed to find mp4v encoder");
- return -2;
- }
- mp4v->encoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(mp4v->encoder.context);
-
- mp4v->encoder.context->pix_fmt = PIX_FMT_YUV420P;
- mp4v->encoder.context->time_base.num = 1;
- mp4v->encoder.context->time_base.den = TMEDIA_CODEC_VIDEO(mp4v)->fps;
- mp4v->encoder.context->width = TMEDIA_CODEC_VIDEO(mp4v)->width;
- mp4v->encoder.context->height = TMEDIA_CODEC_VIDEO(mp4v)->height;
- mp4v->encoder.context->mb_decision = FF_MB_DECISION_SIMPLE;
-
- switch(self->bl){
- case tmedia_bl_low:
- default:
- bitRate = 64000.f;
- break;
- case tmedia_bl_medium:
- bitRate = 128000.f;
- break;
- case tmedia_bl_hight:
- bitRate = 250000.f;
- break;
- }
-
- mp4v->encoder.context->thread_count = 1;
- mp4v->encoder.context->rtp_payload_size = MP4V_RTP_PAYLOAD_SIZE;
- mp4v->encoder.context->opaque = tsk_null;
- mp4v->encoder.context->bit_rate = (int) (bitRate * 0.80f);
- mp4v->encoder.context->bit_rate_tolerance = (int) (bitRate * 0.20f);
- mp4v->encoder.context->profile = mp4v->profile>>4;
- mp4v->encoder.context->level = mp4v->profile & 0x0F;
- mp4v->encoder.context->gop_size = TMEDIA_CODEC_VIDEO(mp4v)->fps*2; // each 2 seconds
- mp4v->encoder.context->max_b_frames = 0;
- mp4v->encoder.context->b_frame_strategy = 1;
- mp4v->encoder.context->flags |= CODEC_FLAG_AC_PRED;
-
- // Picture (YUV 420)
- if(!(mp4v->encoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create MP4V-ES encoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(mp4v->encoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, mp4v->encoder.context->width, mp4v->encoder.context->height);
- if(!(mp4v->encoder.buffer = tsk_calloc(size, sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate MP4V-ES encoder buffer");
- return -2;
- }
-
- // Open encoder
- if((ret = avcodec_open(mp4v->encoder.context, mp4v->encoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open MP4V-ES encoder");
- return ret;
- }
-
- //
- // Decoder
- //
- if(!(mp4v->decoder.codec = avcodec_find_decoder(CODEC_ID_MPEG4))){
- TSK_DEBUG_ERROR("Failed to find MP4V-ES decoder");
- }
- mp4v->decoder.context = avcodec_alloc_context();
- avcodec_get_context_defaults(mp4v->decoder.context);
-
- mp4v->decoder.context->pix_fmt = PIX_FMT_YUV420P;
- mp4v->decoder.context->width = TMEDIA_CODEC_VIDEO(mp4v)->width;
- mp4v->decoder.context->height = TMEDIA_CODEC_VIDEO(mp4v)->height;
-
- // Picture (YUV 420)
- if(!(mp4v->decoder.picture = avcodec_alloc_frame())){
- TSK_DEBUG_ERROR("Failed to create decoder picture");
- return -2;
- }
- avcodec_get_frame_defaults(mp4v->decoder.picture);
-
- size = avpicture_get_size(PIX_FMT_YUV420P, mp4v->decoder.context->width, mp4v->decoder.context->height);
- if(!(mp4v->decoder.accumulator = tsk_calloc((size + FF_INPUT_BUFFER_PADDING_SIZE), sizeof(uint8_t)))){
- TSK_DEBUG_ERROR("Failed to allocate decoder buffer");
- return -2;
- }
-
- if(!(mp4v->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(mp4v->decoder.context, mp4v->decoder.codec)) < 0){
- TSK_DEBUG_ERROR("Failed to open MP4V-ES decoder");
- return ret;
- }
-
- return 0;
-}
-
-int tdav_codec_mp4ves_close(tmedia_codec_t* self)
-{
- tdav_codec_mp4ves_t* mp4v = (tdav_codec_mp4ves_t*)self;
-
- if(!mp4v){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* the caller (base class) already checked that the codec is opened */
-
- //
- // Encoder
- //
- if(mp4v->encoder.context){
- avcodec_close(mp4v->encoder.context);
- av_free(mp4v->encoder.context);
- mp4v->encoder.context = tsk_null;
- }
- if(mp4v->encoder.picture){
- av_free(mp4v->encoder.picture);
- }
- if(mp4v->encoder.buffer){
- TSK_FREE(mp4v->encoder.buffer);
- }
-
- //
- // Decoder
- //
- if(mp4v->decoder.context){
- avcodec_close(mp4v->decoder.context);
- if(mp4v->decoder.context->extradata){
- TSK_FREE(mp4v->decoder.context->extradata);
- mp4v->decoder.context->extradata_size = 0;
- }
- av_free(mp4v->decoder.context);
- mp4v->decoder.context = tsk_null;
- }
- if(mp4v->decoder.picture){
- av_free(mp4v->decoder.picture);
- mp4v->decoder.picture = tsk_null;
- }
- if(mp4v->decoder.accumulator){
- TSK_FREE(mp4v->decoder.accumulator);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_mp4ves_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_mp4ves_t* mp4v = (tdav_codec_mp4ves_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- // wrap yuv420 buffer
- size = avpicture_fill((AVPicture *)mp4v->encoder.picture, (uint8_t*)in_data, PIX_FMT_YUV420P, mp4v->encoder.context->width, mp4v->encoder.context->height);
- if(size != in_size){
- /* guard */
- TSK_DEBUG_ERROR("Invalid size");
- return 0;
- }
- /* Flip */
-#if FLIP_ENCODED_PICT
- tdav_converter_video_flip(mp4v->encoder.picture, mp4v->encoder.context->height);
-#endif
-
- mp4v->encoder.picture->pts = AV_NOPTS_VALUE;
- ret = avcodec_encode_video(mp4v->encoder.context, mp4v->encoder.buffer, size, mp4v->encoder.picture);
- if(ret > 0){
- tdav_codec_mp4ves_encap(mp4v, mp4v->encoder.buffer, (tsk_size_t)ret);
- }
-
- return 0;
-}
-
-tsk_size_t tdav_codec_mp4ves_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)
-{
- tdav_codec_mp4ves_t* mp4v = (tdav_codec_mp4ves_t*)self;
- const trtp_rtp_header_t* rtp_hdr = proto_hdr;
-
- tsk_size_t xsize, retsize = 0;
- int got_picture_ptr;
- int ret;
-
- if(!self || !in_data || !in_size || !out_data || !mp4v->decoder.context){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- // get expected size
- xsize = avpicture_get_size(mp4v->decoder.context->pix_fmt, mp4v->decoder.context->width, mp4v->decoder.context->height);
-
- /* Packet lost? */
- if(mp4v->decoder.last_seq != (rtp_hdr->seq_num - 1) && mp4v->decoder.last_seq){
- if(mp4v->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);
- }
- mp4v->decoder.last_seq = rtp_hdr->seq_num;
-
- if((mp4v->decoder.accumulator_pos + in_size) <= xsize){
- memcpy(&((uint8_t*)mp4v->decoder.accumulator)[mp4v->decoder.accumulator_pos], in_data, in_size);
- mp4v->decoder.accumulator_pos += in_size;
- }
- else{
- TSK_DEBUG_WARN("Buffer overflow");
- mp4v->decoder.accumulator_pos = 0;
- return 0;
- }
-
- if(rtp_hdr->marker){
- AVPacket packet;
- /* allocate destination buffer */
- if(*out_max_size <xsize){
- if(!(*out_data = tsk_realloc(*out_data, xsize))){
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- mp4v->decoder.accumulator_pos = 0;
- *out_max_size = 0;
- return 0;
- }
- *out_max_size = xsize;
- }
-
- av_init_packet(&packet);
- packet.size = mp4v->decoder.accumulator_pos;
- packet.data = mp4v->decoder.accumulator;
- ret = avcodec_decode_video2(mp4v->decoder.context, mp4v->decoder.picture, &got_picture_ptr, &packet);
-
- if(ret <0 || !got_picture_ptr){
- TSK_DEBUG_WARN("Failed to decode the buffer");
- }
- else{
- retsize = xsize;
- /* flip */
-#if FLIP_DECODED_PICT
- tdav_converter_video_flip(mp4v->decoder.picture, mp4v->decoder.context->height);
-#endif
- /* copy picture into a linear buffer */
- avpicture_layout((AVPicture *)mp4v->decoder.picture, mp4v->decoder.context->pix_fmt, mp4v->decoder.context->width, mp4v->decoder.context->height,
- *out_data, retsize);
- }
- /* in all cases: reset accumulator */
- mp4v->decoder.accumulator_pos = 0;
- }
-
- return retsize;
-}
-
-tsk_bool_t tdav_codec_mp4ves_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- tsk_params_L_t* params = tsk_null;
- tdav_codec_mp4ves_t *mp4v = (tdav_codec_mp4ves_t *)codec;
-
- if(!mp4v){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_false;
- }
-
- /* e.g. profile-level-id=1; xx=yy */
- if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){
- int val_int;
- if((val_int = tsk_params_get_param_value_as_int(params, "profile-level-id")) != -1){
- TSK_DEBUG_INFO("Proposed profile-level-id=%d", val_int);
- mp4v->profile = val_int; // FIXME: Take the remote profile-level-id even if the bandwidth level doesn't match
- }
- }
-
- TSK_OBJECT_SAFE_FREE(params);
-
- return tsk_true;
-}
-
-char* tdav_codec_mp4ves_fmtp_get(const tmedia_codec_t* self)
-{
- tdav_codec_mp4ves_t *mp4v = (tdav_codec_mp4ves_t *)self;
- char* fmtp = tsk_null;
-
- switch(self->bl){
- case tmedia_bl_low:
- default:
- mp4v->profile = Simple_Profile_Level_1;
- break;
- case tmedia_bl_medium:
- mp4v->profile = Simple_Profile_Level_2;
- break;
- case tmedia_bl_hight:
- mp4v->profile = Simple_Profile_Level_3;
- break;
- }
-
- tsk_sprintf(&fmtp, "profile-level-id=%d", mp4v->profile);
- return fmtp;
-}
-
-
-/* ============ Internal functions ================= */
-static void tdav_codec_mp4ves_encap(tdav_codec_mp4ves_t* mp4v, const uint8_t* pdata, tsk_size_t size)
-{
- uint32_t scode; // start code
-
- if(size <= 4/*32bits: start code size*/){
- TSK_DEBUG_ERROR("Too short");
- return;
- }
- // first 32bits
- scode = tnet_htonl_2(pdata);
-
-/* RFC 3016 - 3.3 Examples of packetized MPEG-4 Visual bitstream
-
- VS= Visual Object Sequence
- VO= Visual Object
- VOL= Visual Object Layer
- VOP= Visual Object Plane
- GOV= Group of Visual Object Plane
- VP= Video Plane
-
- +------+------+------+------+
-(a) | RTP | VS | VO | VOL |
- |header|header|header|header|
- +------+------+------+------+
-
- +------+------+------+------+------------+
-(b) | RTP | VS | VO | VOL |Video Packet|
- |header|header|header|header| |
- +------+------+------+------+------------+
-
- +------+-----+------------------+
-(c) | RTP | GOV |Video Object Plane|
- |header| | |
- +------+-----+------------------+
-
- +------+------+------------+ +------+------+------------+
-(d) | RTP | VOP |Video Packet| | RTP | VP |Video Packet|
- |header|header| (1) | |header|header| (2) |
- +------+------+------------+ +------+------+------------+
-
- +------+------+------------+------+------------+------+------------+
-(e) | RTP | VP |Video Packet| VP |Video Packet| VP |Video Packet|
- |header|header| (1) |header| (2) |header| (3) |
- +------+------+------------+------+------------+------+------------+
-
- +------+------+------------+ +------+------------+
-(f) | RTP | VOP |VOP fragment| | RTP |VOP fragment|
- |header|header| (1) | |header| (2) | ___
- +------+------+------------+ +------+------------+
-
- Figure 2 - Examples of RTP packetized MPEG-4 Visual bitstream
-*/
-
-/* RFC 3016 - 3.2 Fragmentation of MPEG-4 Visual bitstream
-
- A fragmented MPEG-4 Visual bitstream is mapped directly onto the RTP
- payload without any addition of extra header fields or any removal of
- Visual syntax elements. The Combined Configuration/Elementary
- streams mode is used.
-
- In the following, header means one of the following:
-
- - Configuration information (Visual Object Sequence Header, Visual
- Object Header and Video Object Layer Header)
- - visual_object_sequence_end_code
- - The header of the entry point function for an elementary stream
- (Group_of_VideoObjectPlane() or the header of VideoObjectPlane(),
- video_plane_with_short_header(), MeshObject() or FaceObject())
- - The video packet header (video_packet_header() excluding
- next_resync_marker())
- - The header of gob_layer()
- See 6.2.1 "Start codes" of ISO/IEC 14496-2 [2][9][4] for the
- definition of the configuration information and the entry point
- functions.
-*/
-
- switch(scode){
- case visual_object_sequence_start_code:
- case visual_object_start_code:
- case user_data_start_code:
- case video_object_layer_start_code:
- case group_of_vop_start_code:
- case vop_start_code:
- {
- register uint32_t i, last_index = 0;
- int startcode = 0xffffffff;
-
- if(scode == visual_object_sequence_start_code && size >=5){
- uint8_t profile_and_level_indication = pdata[4]; /* IEC 14496-2: 6.3.2 Visual Object Sequence and Visual Object */
- TSK_DEBUG_INFO("profile_and_level_indication=%d", profile_and_level_indication);
- }
-
- if(size < MP4V_RTP_PAYLOAD_SIZE){
- goto last;
- }
-
- for(i = 4; i<(size - 4); i++){
- startcode = (startcode <<8) | pdata[i];
- switch(startcode){
- case visual_object_sequence_start_code:
- case group_of_vop_start_code:
- case vop_start_code:
- tdav_codec_mp4ves_rtp_callback(mp4v, pdata + last_index, (i - last_index), (last_index == size));
- last_index = i;
- }
- }
-last:
- if(last_index < size){
- tdav_codec_mp4ves_rtp_callback(mp4v, pdata + last_index, (size - last_index), tsk_true);
- }
- break;
- }
- default:
- TSK_DEBUG_ERROR("%x is an invalide start code", scode);
- break;
- }
-}
-
-static void tdav_codec_mp4ves_rtp_callback(tdav_codec_mp4ves_t *mp4v, const void *data, tsk_size_t size, tsk_bool_t marker)
-{
- // Send data over the network
- if(TMEDIA_CODEC_VIDEO(mp4v)->callback){
- TMEDIA_CODEC_VIDEO(mp4v)->callback(TMEDIA_CODEC_VIDEO(mp4v)->callback_data, data, size, (3003* (30/TMEDIA_CODEC_VIDEO(mp4v)->fps)), marker);
- }
-}
-
-
-/* ============ MP4V-ES Plugin interface ================= */
-
-/* constructor */
-static tsk_object_t* tdav_codec_mp4ves_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_mp4ves_t *mp4v = self;
- if(mp4v){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- mp4v->profile = DEFAULT_PROFILE_LEVEL_ID;
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_mp4ves_dtor(tsk_object_t * self)
-{
- tdav_codec_mp4ves_t *mp4v = self;
- if(mp4v){
- /* deinit base */
- tmedia_codec_video_deinit(self); // will close the codec if opened
- /* deinit self */
- TSK_FREE(mp4v->rtp.ptr);
- mp4v->rtp.size = 0;
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_mp4ves_def_s =
-{
- sizeof(tdav_codec_mp4ves_t),
- tdav_codec_mp4ves_ctor,
- tdav_codec_mp4ves_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_mp4ves_plugin_def_s =
-{
- &tdav_codec_mp4ves_def_s,
-
- tmedia_video,
- "MP4V-ES",
- "MP4V-ES Codec",
- TMEDIA_CODEC_FORMAT_MP4V_ES,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video */
- {176, 144, 15},
-
- tdav_codec_mp4ves_open,
- tdav_codec_mp4ves_close,
- tdav_codec_mp4ves_encode,
- tdav_codec_mp4ves_decode,
- tdav_codec_mp4ves_fmtp_match,
- tdav_codec_mp4ves_fmtp_get,
- tdav_codec_mp4ves_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_mp4ves_plugin_def_t = &tdav_codec_mp4ves_plugin_def_s;
-
-
-#endif /* HAVE_FFMPEG */
-
diff --git a/branches/1.0/tinyDAV/src/codecs/msrp/tdav_codec_msrp.c b/branches/1.0/tinyDAV/src/codecs/msrp/tdav_codec_msrp.c
deleted file mode 100644
index c845ec3..0000000
--- a/branches/1.0/tinyDAV/src/codecs/msrp/tdav_codec_msrp.c
+++ /dev/null
@@ -1,110 +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_msrp.c
- * @brief The Message Session Relay Protocol (MSRP) fake codec.
- * Used for both Message (RFC 4975) and file transfer (RFC 5547).
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/msrp/tdav_codec_msrp.h"
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-/* ============ MSRP Plugin interface ================= */
-#define tdav_codec_msrp_open tsk_null
-#define tdav_codec_msrp_close tsk_null
-#define tdav_codec_msrp_fmtp_get tsk_null
-#define tdav_codec_msrp_fmtp_get tsk_null
-#define tdav_codec_msrp_fmtp_set tsk_null
-#define tdav_codec_msrp_encode tsk_null
-#define tdav_codec_msrp_decode tsk_null
-
-tsk_bool_t tdav_codec_msrp_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{ /* always match */
- return tsk_true;
-}
-
-//
-// MSRP Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_msrp_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_msrp_t *msrp = self;
- if(msrp){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_msrp_dtor(tsk_object_t * self)
-{
- tdav_codec_msrp_t *msrp = self;
- if(msrp){
- /* deinit base */
- tmedia_codec_msrp_deinit(msrp);
- /* deinit self */
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_msrp_def_s =
-{
- sizeof(tdav_codec_msrp_t),
- tdav_codec_msrp_ctor,
- tdav_codec_msrp_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_msrp_plugin_def_s =
-{
- &tdav_codec_msrp_def_s,
-
- tmedia_msrp,
- "message",
- "MSRP fake codec",
- TMEDIA_CODEC_FORMAT_MSRP,
- tsk_false,
- 0, // rate
-
- /* audio */
- {0},
-
- /* video */
- {0},
-
- tdav_codec_msrp_open,
- tdav_codec_msrp_close,
- tdav_codec_msrp_encode,
- tdav_codec_msrp_decode,
- tdav_codec_msrp_fmtp_match,
- tdav_codec_msrp_fmtp_get,
- tdav_codec_msrp_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_msrp_plugin_def_t = &tdav_codec_msrp_plugin_def_s;
diff --git a/branches/1.0/tinyDAV/src/codecs/speex/tdav_codec_speex.c b/branches/1.0/tinyDAV/src/codecs/speex/tdav_codec_speex.c
deleted file mode 100644
index 93565aa..0000000
--- a/branches/1.0/tinyDAV/src/codecs/speex/tdav_codec_speex.c
+++ /dev/null
@@ -1,282 +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_speex.c
- * @brief Speex codecs
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tinydav/codecs/speex/tdav_codec_speex.h"
-
-#if HAVE_LIB_SPEEX
-
-#include "tsk_memory.h"
-#include "tsk_debug.h"
-
-/* ============ Common ================= */
-int tdav_codec_speex_init(tdav_codec_speex_t* self, tdav_codec_speex_type_t type);
-int tdav_codec_speex_deinit(tdav_codec_speex_t* self);
-
-/* ============ iLBC Plugin interface ================= */
-
-#define tdav_codec_speex_fmtp_set tsk_null
-
-int tdav_codec_speex_open(tmedia_codec_t* self)
-{
- static int quality = 6;
- tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;
- tsk_size_t size = 0;
-
- switch(speex->type){
- case tdav_codec_speex_type_nb:
- speex->encoder.state = speex_encoder_init(&speex_nb_mode);
- speex->decoder.state = speex_decoder_init(&speex_nb_mode);
-
- speex_decoder_ctl(speex->decoder.state, SPEEX_GET_FRAME_SIZE, &speex->decoder.size);
- speex->decoder.size = (speex->decoder.size ? speex->decoder.size : 160) * sizeof(spx_int16_t);
- if(!(speex->decoder.buffer = tsk_calloc(speex->decoder.size, 1))){
- speex->decoder.size = 0;
- TSK_DEBUG_ERROR("Failed to allocate new buffer");
- return -3;
- }
-
- speex_encoder_ctl(speex->encoder.state, SPEEX_SET_QUALITY, &quality);
- speex_encoder_ctl(speex->encoder.state, SPEEX_GET_FRAME_SIZE, &speex->encoder.size);
- if(!speex->encoder.size){
- speex->encoder.size = 20;
- }
- break;
- default:
- TSK_DEBUG_ERROR("Not implemented");
- return -2;
- }
-
- speex_bits_init(&speex->encoder.bits);
- speex_bits_init(&speex->decoder.bits);
- speex_bits_reset(&speex->encoder.bits);
- speex_bits_reset(&speex->decoder.bits);
-
- return 0;
-}
-
-int tdav_codec_speex_close(tmedia_codec_t* self)
-{
- tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;
-
-
-
- return 0;
-}
-
-tsk_size_t tdav_codec_speex_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
-{
- tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;
- tsk_size_t outsize = 0;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- speex_bits_reset(&speex->encoder.bits);
- speex_encode_int(speex->encoder.state, (spx_int16_t*)in_data, &speex->encoder.bits);
-
- if(*out_max_size <speex->encoder.size){
- if((*out_data = tsk_realloc(*out_data, speex->encoder.size))){
- *out_max_size = speex->encoder.size;
- }
- else{
- *out_max_size = 0;
- return 0;
- }
- }
-
- outsize = speex_bits_write(&speex->encoder.bits, *out_data, speex->encoder.size);
-
- return outsize;
-}
-
-tsk_size_t tdav_codec_speex_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)
-{
- int ret;
- tsk_size_t out_size = 0;
- tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;
-
- if(!self || !in_data || !in_size || !out_data){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- /* initializes the bit-stream */
- speex_bits_read_from(&speex->decoder.bits, (char*)in_data, in_size);
-
- do{
- /* performs decode() */
- if((ret = speex_decode_int(speex->decoder.state, &speex->decoder.bits, speex->decoder.buffer))){
- TSK_DEBUG_ERROR("Failed to decode the buffer. retcode=%d", ret);
- break;
- }
-
- if(*out_max_size <(out_size + speex->decoder.size)){
- if((*out_data = tsk_realloc(*out_data, (out_size + speex->decoder.size)))){
- *out_max_size = (out_size + speex->decoder.size);
- }
- else{
- *out_max_size = 0;
- return 0;
- }
- }
-
- /* copy output buffer */
- memcpy(&((uint8_t*)*out_data)[out_size], speex->decoder.buffer, speex->decoder.size);
- out_size += speex->decoder.size;
- }
- while(speex_bits_remaining(&speex->decoder.bits) >= 5);
-
-
- return out_size;
-}
-
-char* tdav_codec_speex_fmtp_get(const tmedia_codec_t* codec)
-{
- return tsk_null;
-}
-
-tsk_bool_t tdav_codec_speex_fmtp_match(const tmedia_codec_t* codec, const char* fmtp)
-{
- return tsk_true;
-}
-
-
-//
-// Speex Narrow Band Plugin definition
-//
-
-/* constructor */
-static tsk_object_t* tdav_codec_speex_nb_ctor(tsk_object_t * self, va_list * app)
-{
- tdav_codec_speex_t *speex = self;
- if(speex){
- /* init base: called by tmedia_codec_create() */
- /* init self */
- tdav_codec_speex_init(speex, tdav_codec_speex_type_nb);
- }
- return self;
-}
-/* destructor */
-static tsk_object_t* tdav_codec_speex_nb_dtor(tsk_object_t * self)
-{
- tdav_codec_speex_t *speex = self;
- if(speex){
- /* deinit base */
- tmedia_codec_audio_deinit(speex);
- /* deinit self */
- tdav_codec_speex_deinit(speex);
- }
-
- return self;
-}
-/* object definition */
-static const tsk_object_def_t tdav_codec_speex_nb_def_s =
-{
- sizeof(tdav_codec_speex_t),
- tdav_codec_speex_nb_ctor,
- tdav_codec_speex_nb_dtor,
- tmedia_codec_cmp,
-};
-/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_speex_nb_plugin_def_s =
-{
- &tdav_codec_speex_nb_def_s,
-
- tmedia_audio,
- "SPEEX",
- "Speex Narrow Band Codec",
- TMEDIA_CODEC_FORMAT_SPEEX_NB,
- tsk_true,
- 8000, // rate
-
- { /* audio */
- 1, // channels
- 20 // ptime
- },
-
- /* video */
- {0},
-
- tdav_codec_speex_open,
- tdav_codec_speex_close,
- tdav_codec_speex_encode,
- tdav_codec_speex_decode,
- tdav_codec_speex_fmtp_match,
- tdav_codec_speex_fmtp_get,
- tdav_codec_speex_fmtp_set
-};
-const tmedia_codec_plugin_def_t *tdav_codec_speex_nb_plugin_def_t = &tdav_codec_speex_nb_plugin_def_s;
-
-
-//
-// Common functions
-//
-int tdav_codec_speex_init(tdav_codec_speex_t* self, tdav_codec_speex_type_t type)
-{
- if(self){
- self->type = type;
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-}
-
-int tdav_codec_speex_deinit(tdav_codec_speex_t* self)
-{
- if(self){
- if(self->decoder.state){
- speex_decoder_destroy(self->decoder.state);
- self->decoder.state = tsk_null;
- }
- speex_bits_destroy(&self->decoder.bits);
- if(self->decoder.buffer){
- TSK_FREE(self->decoder.buffer);
- self->decoder.size = 0;
- }
-
- if(self->encoder.state){
- speex_encoder_destroy(self->encoder.state);
- self->encoder.state = tsk_null;
- }
- speex_bits_destroy(&self->encoder.bits);
- self->encoder.size = 0;
-
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-}
-
-#endif /* HAVE_LIB_SPEEX */
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