Changeset 40322


Ignore:
Timestamp:
04/17/17 22:27:46 (6 years ago)
Author:
obi
Message:

update libeplayer3 new version only buffer

Location:
titan
Files:
36 added
20 edited

Legend:

Unmodified
Added
Removed
  • titan/libeplayer3/Makefile.am.sh4

    r39831 r40322  
    55
    66AM_CPPFLAGS = \
    7         -Iinclude
     7        -Iinclude \
     8        -Iexternal
    89
    910lib_LTLIBRARIES = libeplayer3.la
     
    1112container/container.c \
    1213container/container_ffmpeg.c \
    13 container/container_ass.c \
    14 container/text_srt.c \
    15 container/text_ssa.c \
    1614manager/manager.c \
    1715manager/audio.c \
    1816manager/video.c \
    1917manager/subtitle.c \
    20 manager/dvbsubtitle.c \
    21 manager/teletext.c \
    2218output/linuxdvb_sh4.c \
    2319output/output_subtitle.c \
    2420output/output.c \
    25 output/output_pipe.c \
    2621output/writer/common/pes.c \
    2722output/writer/common/misc.c \
    2823output/writer/sh4/writer.c \
    29 output/writer/sh4/framebuffer.c \
    3024output/writer/sh4/aac.c \
    3125output/writer/sh4/ac3.c \
     
    4034output/writer/sh4/wma.c \
    4135output/writer/sh4/wmv.c \
    42 playback/playback.c
     36playback/playback.c \
     37external/ffmpeg/src/bitstream.c \
     38external/ffmpeg/src/latmenc.c \
     39external/ffmpeg/src/mpeg4audio.c
     40
    4341
    4442#SOURCE_FILES+=" output/writer/sh4/divx.c
  • titan/libeplayer3/container/container_ffmpeg.c

    r39877 r40322  
    4949#include <libavutil/opt.h>
    5050
     51#include <ffmpeg/mpeg4audio.h>
     52
    5153#include "common.h"
    5254#include "misc.h"
     
    5557#include "pcm.h"
    5658#include "ffmpeg_metadata.h"
    57 #include "subtitle.h"
    58 
    5959/* ***************************** */
    6060/* Makros/Constants              */
    6161/* ***************************** */
     62#if (LIBAVFORMAT_VERSION_MAJOR > 57)
     63#define TS_BYTES_SEEKING 0
     64#else
     65#define TS_BYTES_SEEKING 1
     66#endif
     67
    6268/* Some STB with old kernels have problem with default
    6369 * read/write functions in ffmpeg which use open/read
     
    6773#define SAM_CUSTOM_IO
    6874
    69 //SULGE DEBUG ENABLED
    7075#define SAM_WITH_DEBUG
    7176#ifdef SAM_WITH_DEBUG
     
    7479#define FFMPEG_SILENT
    7580#endif
    76 
    77 //#define FFMPEG_DEBUG
    7881
    7982#ifdef FFMPEG_DEBUG
     
    144147static int32_t container_ffmpeg_seek_bytes(off_t pos);
    145148static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute);
    146 //static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec);
     149static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec);
    147150static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length);
    148151static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts);
     
    152155 * we start playback before download was finished
    153156 */
    154 static int32_t progressive_download = 0;
    155 void progressive_download_set(int32_t val)
    156 {
    157     progressive_download = val;
    158 }
    159 
    160 /* This is very bad to include source file
    161  * and must be corrected in the future
    162  */
    163 //#include "buff_ffmpeg.c"
    164 
     157static int32_t progressive_playback = 0;
     158void progressive_playback_set(int32_t val)
     159{
     160    progressive_playback = val;
     161}
     162
     163#include "buff_ffmpeg.c"
     164#include "wrapped_ffmpeg.c"
     165#include "tools_ffmpeg.c"
    165166#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    166167#include "mpeg4p2_ffmpeg.c"
     168#endif
     169
     170#ifdef HAVE_FLV2MPEG4_CONVERTER
     171#include "flv2mpeg4_ffmpeg.c"
    167172#endif
    168173
     
    173178static int32_t wma_software_decode = 0;
    174179static int32_t aac_software_decode = 0;
     180#ifdef __sh__
     181static int32_t aac_latm_software_decode = 1;
     182#else
     183static int32_t aac_latm_software_decode = 0;
     184#endif
     185
    175186static int32_t ac3_software_decode = 0;
    176187static int32_t eac3_software_decode = 0;
     
    182193static int32_t rtmp_proto_impl = 0; // 0 - auto, 1 - native, 2 - librtmp
    183194
    184 //for buffered io
    185 #define FILLBUFSIZE 0
    186 #define FILLBUFDIFF 1048576
    187 #define FILLBUFPAKET 5120
    188 #define FILLBUFSEEKTIME 3 //sec
    189 #define TIMEOUT_MAX_ITERS 10
    190 
    191 static int ffmpeg_buf_size = FILLBUFSIZE + FILLBUFDIFF;
    192 static ffmpeg_buf_seek_time = FILLBUFSEEKTIME;
    193 static int(*ffmpeg_read_org)(void *opaque, uint8_t *buf, int buf_size) = NULL;
    194 static int(*ffmpeg_real_read_org)(void *opaque, uint8_t *buf, int buf_size) = NULL;
    195 
    196 static int64_t(*ffmpeg_seek_org)(void *opaque, int64_t offset, int whence) = NULL;
    197 static unsigned char* ffmpeg_buf_read = NULL;
    198 static unsigned char* ffmpeg_buf_write = NULL;
    199 static unsigned char* ffmpeg_buf = NULL;
    200 static pthread_t fillerThread;
    201 static int hasfillerThreadStarted[10] = {0,0,0,0,0,0,0,0,0,0};
    202 int hasfillerThreadStartedID = 0;
    203 static pthread_mutex_t fillermutex;
    204 static int ffmpeg_buf_valid_size = 0;
    205 static int ffmpeg_do_seek_ret = 0;
    206 static int ffmpeg_do_seek = 0;
    207 static int ffmpeg_buf_stop = 0;
    208 //for buffered io (end)
    209 
    210 
    211 static int64_t playPts = -1;
    212 static int32_t finishTimeout = 0;
    213 static int8_t pauseTimeout = 0;
    214 static int64_t maxInjectedPTS = INVALID_PTS_VALUE;
    215 
    216 void reset_finish_timeout()
    217 {
    218     playPts = -1;
    219     finishTimeout = 0;
    220 }
    221 
    222 static int64_t update_max_injected_pts(int64_t pts)
    223 {
    224     if(pts > 0 && pts != INVALID_PTS_VALUE)
    225     {
    226         if(maxInjectedPTS == INVALID_PTS_VALUE || pts > maxInjectedPTS)
    227         {
    228             maxInjectedPTS = pts;
    229         }
    230     }
    231     return maxInjectedPTS;
    232 }
    233 
    234 int64_t get_play_pts()
    235 {
    236     return playPts;
    237 }
    238 
    239 static int8_t is_finish_timeout()
    240 {
    241     if (finishTimeout > TIMEOUT_MAX_ITERS)
    242     {
    243         return 1;
    244     }
    245     return 0;
    246 }
    247 
    248 static Context_t *context = 0;
    249 
    250 static void update_finish_timeout()
    251 {
    252     if(0 == pauseTimeout)
    253     {   
    254         int64_t maxInjectedPts = update_max_injected_pts(-1);
    255         int64_t currPts = -1;
    256 
    257 // segfault
    258 //        int32_t ret = context->playback->Command(context, PLAYBACK_PTS, &currPts);
    259         int32_t ret = 0;
    260 
    261         finishTimeout += 1;
    262        
    263         if(maxInjectedPts < 0 || maxInjectedPts == INVALID_PTS_VALUE)
    264         {
    265             maxInjectedPts = 0;
    266         }
    267        
    268         //printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts);
    269        
    270         /* On some STBs PTS readed from decoder is invalid after seek or at start
    271          * this is the reason for additional validation when we what to close immediately
    272          */
    273 
    274         if( !progressive_download && 0 == ret && currPts >= maxInjectedPts &&
    275             ((currPts - maxInjectedPts) / 90000) < 2 )
    276         {
    277             /* close immediately
    278              */
    279             finishTimeout = TIMEOUT_MAX_ITERS + 1;
    280         }
    281         else if (0 == ret && (playPts != currPts && maxInjectedPts > currPts))
    282         {
    283             playPts = currPts;
    284             finishTimeout = 0;
    285         }
    286     }
    287 }
    288 
    289 void set_pause_timeout(uint8_t pause)
    290 {
    291     reset_finish_timeout();
    292     pauseTimeout = pause;
    293 }
    294 
    295 
    296 static int32_t container_set_ffmpeg_buf_seek_time(int32_t* time)
    297 {
    298     ffmpeg_buf_seek_time = (*time);
    299     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    300 }
    301 
    302 static int32_t container_set_ffmpeg_buf_size(int32_t* size)
    303 {
    304     if(ffmpeg_buf == NULL)
    305     {
    306         if(*size == 0)
    307         {
    308             ffmpeg_buf_size = 0;
    309         }
    310         else
    311         {
    312             ffmpeg_buf_size = (*size) + FILLBUFDIFF;
    313         }
    314     }
    315    
    316     ffmpeg_printf(10, "size=%d, buffer size=%d\n", (*size), ffmpeg_buf_size);
    317     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    318 }
    319 
    320 static int32_t container_get_ffmpeg_buf_size(int32_t* size)
    321 {
    322     *size = ffmpeg_buf_size - FILLBUFDIFF;
    323     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    324 }
    325 
    326 static int32_t container_get_fillbufstatus(int32_t* size)
    327 {
    328     int32_t rwdiff = 0;
    329 
    330     if(ffmpeg_buf != NULL && ffmpeg_buf_read != NULL && ffmpeg_buf_write != NULL)
    331     {
    332         if(ffmpeg_buf_read < ffmpeg_buf_write)
    333             rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
    334         if(ffmpeg_buf_read > ffmpeg_buf_write)
    335         {
    336             rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
    337             rwdiff += ffmpeg_buf_write - ffmpeg_buf;
    338         }
    339 
    340         *size = rwdiff;
    341     }
    342 
    343     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    344 }
    345 
    346 static int32_t container_stop_buffer()
    347 {
    348     ffmpeg_buf_stop = 1;
    349     return 0;
    350 }
    351 
    352 //flag 0: start direct
    353 //flag 1: from thread
    354 static void ffmpeg_filler(Context_t *context, int32_t id, int32_t* inpause, int32_t flag)
    355 {
    356     int32_t len = 0;
    357     int32_t rwdiff = ffmpeg_buf_size;
    358     uint8_t buf[FILLBUFPAKET];
    359 
    360     if(ffmpeg_read_org == NULL || ffmpeg_seek_org == NULL)
    361     {
    362         ffmpeg_err("ffmpeg_read_org or ffmpeg_seek_org is NULL\n");
    363         return;
    364     }
    365 
    366     while( (flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) ||
    367            (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) )
    368     {
    369   //       if( 0 == PlaybackDieNow(0))
    370   //       {
    371   //          break;
    372   //       }
    373          
    374          if(flag == 0 && ffmpeg_buf_stop == 1)
    375          {
    376              ffmpeg_buf_stop = 0;
    377              break;
    378          }
    379 
    380          getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
    381          //do a seek
    382          if(ffmpeg_do_seek != 0)
    383          {
    384              ffmpeg_do_seek_ret = ffmpeg_seek_org(avContextTab[0]->pb->opaque, avContextTab[0]->pb->pos + ffmpeg_do_seek, SEEK_SET);
    385              if(ffmpeg_do_seek_ret >= 0)
    386              {
    387                  ffmpeg_buf_write = ffmpeg_buf;
    388                  ffmpeg_buf_read = ffmpeg_buf;
    389              }
    390 
    391              ffmpeg_do_seek = 0;
    392          }
    393 
    394          if(ffmpeg_buf_read == ffmpeg_buf_write)
    395          {
    396              ffmpeg_buf_valid_size = 0;
    397              rwdiff = ffmpeg_buf_size;
    398          }
    399          
    400          if(ffmpeg_buf_read < ffmpeg_buf_write)
    401          {
    402              rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
    403              rwdiff += ffmpeg_buf_read - ffmpeg_buf;
    404          }
    405          
    406          if(ffmpeg_buf_read > ffmpeg_buf_write)
    407          {
    408             rwdiff = ffmpeg_buf_read - ffmpeg_buf_write;
    409          }
    410          
    411          int32_t size = FILLBUFPAKET;
    412          if(rwdiff - FILLBUFDIFF < size)
    413          {
    414              size = (rwdiff - FILLBUFDIFF);
    415          }
    416 
    417          if(ffmpeg_buf_write + size > ffmpeg_buf + ffmpeg_buf_size)
    418          {
    419              size = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
    420          }
    421 
    422          if(ffmpeg_buf_write == ffmpeg_buf + ffmpeg_buf_size)
    423          {
    424              ffmpeg_buf_write = ffmpeg_buf;
    425          }
    426 
    427          releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    428 
    429          if(size > 0)
    430          {
    431              if(flag == 1 && hasfillerThreadStarted[id] == 2) break;
    432              len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size);
    433              if(flag == 1 && hasfillerThreadStarted[id] == 2) break;
    434 
    435              ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len);
    436 
    437              getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
    438              if(len > 0)
    439              {
    440                  memcpy(ffmpeg_buf_write, buf, len);
    441                  ffmpeg_buf_write += len;
    442              }
    443              else
    444              {
    445                  releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    446                  ffmpeg_err("read not ok ret=%d\n", len);
    447                  break;
    448              }
    449              releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    450         }
    451         else
    452         {
    453             //on long pause the server close the connection, so we use seek to reconnect
    454             if(context != NULL && context->playback != NULL && inpause != NULL)
    455             {
    456                 if((*inpause) == 0 && context->playback->isPaused)
    457                 {
    458                     (*inpause) = 1;
    459                 }
    460                 else if((*inpause) == 1 && !context->playback->isPaused)
    461                 {
    462                     int32_t buflen = 0;
    463                     (*inpause) = 0;
    464 
    465                     getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
    466                     if(ffmpeg_buf_read < ffmpeg_buf_write)
    467                     {
    468                         buflen = ffmpeg_buf_write - ffmpeg_buf_read;
    469                     }
    470                    
    471                     if(ffmpeg_buf_read > ffmpeg_buf_write)
    472                     {
    473                         buflen = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
    474                         buflen += ffmpeg_buf_write - ffmpeg_buf;
    475                     }
    476                     ffmpeg_seek_org(avContextTab[0]->pb->opaque, avContextTab[0]->pb->pos + buflen, SEEK_SET);
    477                     releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    478                 }
    479             }
    480         }
    481     }
    482 }
    483 
    484 static void ffmpeg_fillerTHREAD(Context_t *context)
    485 {
    486     int32_t inpause = 0;
    487     int32_t id = hasfillerThreadStartedID;
    488 
    489     ffmpeg_printf(10, "Running ID=%d!\n", id);
    490 
    491     while(hasfillerThreadStarted[id] == 1)
    492     {
    493         ffmpeg_filler(context, id, &inpause, 1);
    494         usleep(10000);
    495     }
    496 
    497     hasfillerThreadStarted[id] = 0;
    498 
    499     ffmpeg_printf(10, "terminating ID=%d\n", id);
    500 }
    501 
    502 static int32_t ffmpeg_start_fillerTHREAD(Context_t *context)
    503 {
    504     int32_t error;
    505     int32_t ret = 0, i = 0;
    506     pthread_attr_t attr;
    507 
    508     ffmpeg_printf(10, "\n");
    509 
    510     if (context && context->playback && context->playback->isPlaying)
    511     {
    512         ffmpeg_printf(10, "is Playing\n");
    513     }
    514     else
    515     {
    516         ffmpeg_printf(10, "is NOT Playing\n");
    517     }
    518    
    519     //get filler thread ID
    520     //if the thread hangs for long time, we use a new id
    521     for(i = 0; i < 10; i++)
    522     {
    523         if(hasfillerThreadStarted[i] == 0)
    524         {
    525             hasfillerThreadStartedID = i;
    526             break;
    527         }
    528     }
    529 
    530     if (hasfillerThreadStarted[hasfillerThreadStartedID] == 0)
    531     {
    532         pthread_attr_init(&attr);
    533         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    534 
    535         hasfillerThreadStarted[hasfillerThreadStartedID] = 1;
    536         if((error = pthread_create(&fillerThread, &attr, (void *)&ffmpeg_fillerTHREAD, context)) != 0)
    537         {
    538             hasfillerThreadStarted[hasfillerThreadStartedID] = 0;
    539             ffmpeg_printf(10, "Error creating filler thread, error:%d:%s\n", error,strerror(error));
    540 
    541             ret = cERR_CONTAINER_FFMPEG_ERR;
    542         }
    543         else
    544         {
    545             ffmpeg_printf(10, "Created filler thread\n");
    546         }
    547     }
    548     else
    549     {
    550         ffmpeg_printf(10, "All filler thread ID's in use!\n");
    551 
    552         ret = cERR_CONTAINER_FFMPEG_ERR;
    553     }
    554 
    555     ffmpeg_printf(10, "exiting with value %d\n", ret);
    556     return ret;
    557 }
    558 
    559 static int32_t ffmpeg_read_real(void *opaque, uint8_t *buf, int32_t buf_size)
    560 {
    561     int32_t len = buf_size;
    562     int32_t rwdiff = 0;
    563 
    564     if(buf_size > 0)
    565     {
    566         getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
    567 
    568         if(ffmpeg_buf_read < ffmpeg_buf_write)
    569             rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
    570         if(ffmpeg_buf_read > ffmpeg_buf_write)
    571         {
    572             rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
    573             rwdiff += ffmpeg_buf_write - ffmpeg_buf;
    574         }
    575         rwdiff--;
    576 
    577         if(len > rwdiff)
    578         {
    579             len = rwdiff;
    580         }
    581 
    582         if (ffmpeg_buf_read + len > ffmpeg_buf + ffmpeg_buf_size)
    583         {
    584             len = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
    585         }
    586 
    587         if(len > 0)
    588         {
    589             memcpy(buf, ffmpeg_buf_read, len);
    590             ffmpeg_buf_read += len;
    591 
    592             if(ffmpeg_buf_valid_size < FILLBUFDIFF)
    593             {
    594                 if(ffmpeg_buf_valid_size + len > FILLBUFDIFF)
    595                 {
    596                     ffmpeg_buf_valid_size = FILLBUFDIFF;
    597                 }
    598                 else
    599                 {
    600                     ffmpeg_buf_valid_size += len;
    601                 }
    602             }
    603 
    604             if(ffmpeg_buf_read == ffmpeg_buf + ffmpeg_buf_size)
    605             {
    606                 ffmpeg_buf_read = ffmpeg_buf;
    607             }
    608         }
    609         else
    610         {
    611             len = 0;
    612         }
    613         releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    614     }
    615 
    616     return len;
    617 }
    618 
    619 static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size)
    620 {
    621     int32_t sumlen = 0;
    622     int32_t len = 0;
    623     int32_t count = 2000;
    624 
    625 //    while(sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0))
    626     while(sumlen < buf_size && (--count) > 0)
    627     {
    628         len = ffmpeg_read_real(opaque, buf, buf_size - sumlen);
    629         sumlen += len;
    630         buf += len;
    631         if(len == 0)
    632         {
    633             usleep(10000);
    634         }
    635     }
    636 
    637     if(count == 0)
    638     {
    639         if(sumlen == 0)
    640         {
    641             ffmpeg_err( "Timeout waiting for buffered data (buf_size=%d sumlen=%d)!\n", buf_size, sumlen);
    642         }
    643         else
    644         {
    645             ffmpeg_err( "Timeout, not all buffered data availabel (buf_size=%d sumlen=%d)!\n", buf_size, sumlen);
    646         }
    647     }
    648 
    649     return sumlen;
    650 }
    651 
    652 static int64_t ffmpeg_seek(void *opaque, int64_t offset, int32_t whence)
    653 {
    654     int64_t diff;
    655     int32_t rwdiff = 0;
    656     whence &= ~AVSEEK_FORCE;
    657 
    658     if(whence != SEEK_CUR && whence != SEEK_SET)
    659     {
    660         return AVERROR(EINVAL);
    661     }
    662 
    663     if(whence == SEEK_CUR)
    664     {
    665         diff = offset;
    666     }
    667     else
    668     {
    669         diff = offset - avContextTab[0]->pb->pos;
    670     }
    671 
    672     if(diff == 0)
    673     {
    674         return avContextTab[0]->pb->pos;
    675     }
    676 
    677     getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
    678 
    679     if(ffmpeg_buf_read < ffmpeg_buf_write)
    680     {
    681         rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
    682     }
    683    
    684     if(ffmpeg_buf_read > ffmpeg_buf_write)
    685     {
    686         rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
    687         rwdiff += ffmpeg_buf_write - ffmpeg_buf;
    688     }
    689 
    690     if(diff > 0 && diff < rwdiff)
    691     {
    692         /* can do the seek inside the buffer */
    693         ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
    694         if(diff > (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read)
    695         {
    696             ffmpeg_buf_read = ffmpeg_buf + (diff - ((ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read));
    697         }
    698         else
    699         {
    700             ffmpeg_buf_read = ffmpeg_buf_read + diff;
    701         }
    702     }
    703     else if(diff < 0 && diff * -1 < ffmpeg_buf_valid_size)
    704     {
    705         /* can do the seek inside the buffer */
    706         ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
    707         int32_t tmpdiff = diff * -1;
    708         if(tmpdiff > ffmpeg_buf_read - ffmpeg_buf)
    709         {
    710             ffmpeg_buf_read = (ffmpeg_buf + ffmpeg_buf_size) - (tmpdiff - (ffmpeg_buf_read - ffmpeg_buf));
    711         }
    712         else
    713         {
    714             ffmpeg_buf_read = ffmpeg_buf_read - tmpdiff;
    715         }
    716     }
    717     else
    718     {
    719         releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    720         ffmpeg_printf(20, "real-seek diff=%lld\n", diff);
    721 
    722         ffmpeg_do_seek_ret = 0;
    723         ffmpeg_do_seek = diff;
    724         while(ffmpeg_do_seek != 0)
    725         {
    726             usleep(100000);
    727         }
    728 
    729         ffmpeg_do_seek = 0;
    730         if(ffmpeg_do_seek_ret < 0)
    731         {
    732             ffmpeg_err("seek not ok ret=%d\n", ffmpeg_do_seek_ret);
    733             return ffmpeg_do_seek_ret;
    734         }
    735 
    736         //fill buffer
    737         int32_t count = ffmpeg_buf_seek_time * 10;
    738         int32_t size = 0;
    739 
    740         container_get_fillbufstatus(&size);
    741         while(size < ffmpeg_buf_size - FILLBUFDIFF && (--count) > 0)
    742         {
    743             usleep(100000);
    744             container_get_fillbufstatus(&size);
    745         }
    746 
    747         return avContextTab[0]->pb->pos + diff;
    748     }
    749 
    750     releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    751     return avContextTab[0]->pb->pos + diff;
    752 }
    753 
    754 static void ffmpeg_buf_free()
    755 {
    756     ffmpeg_read_org = NULL;
    757     ffmpeg_seek_org = NULL;
    758     ffmpeg_buf_read = NULL;
    759     ffmpeg_buf_write = NULL;
    760     free(ffmpeg_buf);
    761     ffmpeg_buf = NULL;
    762     ffmpeg_buf_valid_size = 0;
    763     ffmpeg_do_seek_ret = 0;
    764     ffmpeg_do_seek = 0;
    765     ffmpeg_buf_stop = 0;
    766     hasfillerThreadStartedID = 0;
    767 }
     195#ifdef HAVE_FLV2MPEG4_CONVERTER
     196static int32_t flv2mpeg4_converter = 1;
     197#else
     198static int32_t flv2mpeg4_converter = 0;
     199#endif
    768200
    769201/* ***************************** */
     
    771203/* ***************************** */
    772204
    773 ///////////////
    774 #define MINMALLOC 4096
    775 #include <ctype.h>
    776 
    777 int file_exist(char* filename)
    778 {
    779         if(access(filename, F_OK) == 0)
    780                 return 1;
    781         else
    782                 return 0;
    783 }
    784 
    785 char* strstrip(char *text)
    786 {
    787         char* tmpstr = text;
    788 
    789         if(text == NULL) return NULL;
    790         int len = strlen(text);
    791 
    792         while(isspace(tmpstr[len - 1])) tmpstr[--len] = '\0';
    793         while(*tmpstr && isspace(*tmpstr)) ++tmpstr, --len;
    794 
    795         if(text != tmpstr) memmove(text, tmpstr, len + 1);
    796 
    797         return text;
    798 }
    799 
    800 char* string_strip_whitechars(char *text)
    801 {
    802         char *p1 = text, *p2 = text;
    803 
    804         if(text == NULL)
    805                 return NULL;
    806 
    807         while(*p1 != '\0')
    808         {
    809                 if(*p1 == ' ' && *(p1 + 1) == ' ')
    810                         ++p1;
    811                 else
    812                         *p2++ = *p1++;
    813         }
    814         *p2 = '\0';
    815 
    816         return text;
    817 }
    818 
    819 char* readfiletomem(const char* filename, int flag)
    820 {
    821         FILE *fd = NULL;
    822         char *fileline = NULL, *buf = NULL, *tmpbuf = NULL;
    823         int bufsize = 0, bufoldsize = 0;
    824 
    825         fileline = malloc(MINMALLOC);
    826         if(fileline == NULL)
    827         {
    828 //              err("no mem");
    829                 return NULL;
    830         }
    831 
    832         fd = fopen(filename, "r");
    833         if(fd == NULL)
    834         {
    835 //              perr("can't open %s", filename);
    836                 free(fileline);
    837                 return NULL;
    838         }
    839 
    840         while(fgets(fileline, MINMALLOC, fd) != NULL)
    841         {
    842                 if(flag == 1)
    843                         if(fileline[0] == '#' || fileline[0] == '\n')
    844                                 continue;
    845 
    846                 bufoldsize = bufsize;
    847                 bufsize += strlen(fileline);
    848                 tmpbuf = buf;   buf = realloc(buf, bufsize + 1);
    849                 if(buf == NULL)
    850                 {
    851 //                      err("no mem");
    852                         free(fileline);
    853                         free(tmpbuf);
    854                         fclose(fd);
    855                         return NULL;
    856                 }
    857 
    858                 sprintf(buf + bufoldsize, "%s", fileline);
    859         }
    860 
    861         free(fileline);
    862         fclose(fd);
    863         return buf;
    864 }
    865 
    866 struct splitstr
    867 {
    868         char* part;
    869 };
    870 
    871 struct splitstr* strsplit(char *str, char *tok, int* count)
    872 {
    873         char *tmpstr = NULL;
    874         struct splitstr *array = NULL, *tmparray = NULL;
    875         *count = 0;
    876 
    877         if(str == NULL || tok == NULL)
    878                 return NULL;
    879 
    880         tmpstr = strtok(str, tok);
    881         while(tmpstr != NULL)
    882         {
    883                 *count = *count + 1;
    884                 tmparray = array; array = (struct splitstr*)realloc(array, sizeof(struct splitstr*) * (*count));
    885                 if(array == NULL)
    886                 {
    887 //                      err("no mem");
    888                         free(tmparray);
    889                         return NULL;
    890                 }
    891                
    892                 (&array[(*count) - 1])->part = tmpstr;
    893                 tmpstr = strtok(NULL, tok);
    894         }
    895 
    896         return array;
    897 }
    898 
    899 char* ostrcat(char* value1, char* value2, int free1, int free2)
    900 {
    901         int len = 0, len1 = 0, len2 = 0;
    902         char* buf = NULL;
    903 
    904         if(value1 == NULL && value2 == NULL) return NULL;
    905 
    906         if(value1 != NULL) len1 = strlen(value1);
    907         if(value2 != NULL) len2 = strlen(value2);
    908 
    909         len = len1 + len2 + 1;
    910 
    911         if(free1 == 1)
    912                 buf = realloc(value1, len);
    913         else
    914                 buf = malloc(len);
    915         if(buf == NULL)
    916         {
    917                 if(free1 == 1) free(value1);
    918                 if(free2 == 1) free(value2);
    919                 return NULL;
    920         }
    921 
    922         if(free1 == 0 && len1 > 0) memcpy(buf, value1, len1);
    923         if(len2 > 0) memcpy(buf + len1, value2, len2);
    924         buf[len - 1] = '\0';
    925 
    926         if(free2 == 1) free(value2);
    927 
    928         //helpfull for memleak detect
    929         //if(buf != NULL && strlen(buf) == 0x0b - 0x01)
    930         //      printf("******** memleak string (%s) (%p) ********\n", buf, buf);
    931 
    932         return buf;
    933 }
    934 
    935 char* ostrstr(char* str, char* search)
    936 {
    937         char* ret = NULL;
    938 
    939         if(str == NULL || search == NULL) return NULL;
    940         ret = strstr(str, search);
    941 
    942         return ret;
    943 }
    944 
    945 char* string_replace(char *search, char *replace, char *string, int free1)
    946 {
    947         char* searchpos = NULL;
    948         char* tmpstr = NULL;
    949 
    950         if(string == NULL || search == NULL)
    951         {
    952                 tmpstr = ostrcat(tmpstr, string, 1, 0);
    953                 if(free1 == 1) free(string);
    954                 return tmpstr;
    955         }
    956 
    957         searchpos = ostrstr(string, search);
    958 
    959         if(searchpos == NULL)
    960         {
    961                 tmpstr = ostrcat(tmpstr, string, 1, 0);
    962                 if(free1 == 1) free(string);
    963                 return tmpstr;
    964         }
    965 
    966         tmpstr = strndup(string, searchpos - string);
    967         if(replace != NULL)
    968                 tmpstr = ostrcat(tmpstr, replace, 1, 0);
    969         tmpstr = ostrcat(tmpstr, string + (searchpos - string) + strlen(search), 1, 0);
    970 
    971         if(free1 == 1) free(string);
    972 
    973         return tmpstr;
    974 }
    975 
    976 char* stringreplacechar(char *str, char c1, char c2)
    977 {
    978         char *p1 = str;
    979 
    980         if(str == NULL) return NULL;
    981 
    982         while(*p1 != '\0')
    983         {
    984                 if(*p1 == c1) *p1 = c2;
    985                 p1++;
    986         }
    987 
    988         return str;
    989 }
    990 
    991 char* string_replace_all(char *search, char *replace, char *string, int free1)
    992 {
    993         char* tmpstr = NULL;
    994         char* searchpos = NULL;
    995 
    996         if(string == NULL || search == NULL)
    997         {
    998                 tmpstr = ostrcat(tmpstr, string, 1, 0);
    999                 if(free1 == 1) free(string);
    1000                 return tmpstr;
    1001         }
    1002 
    1003         searchpos = strstr(string, search);
    1004         if(searchpos == NULL)
    1005         {
    1006                 tmpstr = ostrcat(tmpstr, string, 1, 0);
    1007                 if(free1 == 1) free(string);
    1008                 return tmpstr;
    1009         }
    1010 
    1011         int count = 0;
    1012         int stringlen = strlen(string);
    1013         int searchlen = strlen(search);
    1014         int replacelen = strlen(replace);
    1015 
    1016         while(searchpos != NULL)
    1017         {
    1018                 count++;
    1019                 searchpos = strstr(searchpos + searchlen, search);
    1020         }
    1021 
    1022         int len = stringlen - (searchlen * count) + (replacelen * count);
    1023         tmpstr = calloc(1, len + 1);
    1024         if(tmpstr == NULL)
    1025         {
    1026 //              err("no mem");
    1027                 tmpstr = ostrcat(tmpstr, string, 1, 0);
    1028                 if(free1 == 1) free(string);
    1029                 return tmpstr;
    1030         }
    1031 
    1032         len = 0;       
    1033         char* str = string;
    1034         char* tmp = tmpstr;
    1035         searchpos = strstr(str, search);
    1036         while(searchpos != NULL)
    1037         {
    1038                 len = searchpos - str;
    1039                 memcpy(tmp, str, len);
    1040                 memcpy(tmp + len, replace, replacelen);
    1041                 tmp += len + replacelen;
    1042                 str += len + searchlen;
    1043                 searchpos = strstr(str, search);
    1044         }
    1045         memcpy(tmp, str, strlen(str));
    1046 
    1047         if(free1 == 1) free(string);
    1048 
    1049         return tmpstr;
    1050 }
    1051 
    1052 int ostrcmp(char* value1, char* value2)
    1053 {
    1054         int ret = 1;
    1055 
    1056         if(value1 != NULL && value2 != NULL)
    1057                 ret = strcmp(value1, value2);
    1058 
    1059         return ret;
    1060 }
    1061 ////////////
    1062 
    1063 static void ffmpeg_silen_callback (void * avcl, int level, const char * fmt, va_list vl)
     205static void ffmpeg_silen_callback(void * avcl, int level, const char * fmt, va_list vl)
    1064206{
    1065207    return;
     
    1078220}
    1079221
     222void aac_latm_software_decoder_set(const int32_t val)
     223{
     224    aac_latm_software_decode = val;
     225}
     226
    1080227void ac3_software_decoder_set(const int32_t val)
    1081228{
     
    1116263{
    1117264    rtmp_proto_impl = val;
     265}
     266
     267void flv2mpeg4_converter_set(const int32_t val)
     268{
     269    flv2mpeg4_converter = val;
    1118270}
    1119271
     
    1150302}
    1151303
    1152 //for buffered io
    1153 void getfillerMutex(const char *filename, const char *function, int line) {
    1154     ffmpeg_printf(100, "::%d requesting mutex\n", line);
    1155 
    1156     pthread_mutex_lock(&fillermutex);
    1157 
    1158     ffmpeg_printf(100, "::%d received mutex\n", line);
    1159 }
    1160 
    1161 void releasefillerMutex(const char *filename, const const char *function, int line) {
    1162     pthread_mutex_unlock(&fillermutex);
    1163 
    1164     ffmpeg_printf(100, "::%d released mutex\n", line);
    1165 }
    1166 //for buffered io (end)encoding
    1167 
    1168 static char* Codec2Encoding(AVCodecContext *codec, int32_t *version)
    1169 {
    1170     ffmpeg_printf(10, "Codec ID: %d (%.8d)\n", (int32_t)codec->codec_id, (int32_t)codec->codec_id);
    1171     switch (codec->codec_id)
     304static char* Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile, int32_t *version)
     305{
     306    ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id);
     307    switch (codec_id)
    1172308    {
    1173309    case AV_CODEC_ID_MPEG1VIDEO:
     
    1180316        return "V_H263";
    1181317    case AV_CODEC_ID_FLV1:
    1182         return "V_FLV";
     318        return flv2mpeg4_converter ? "V_MPEG4" : "V_FLV";
    1183319    case AV_CODEC_ID_VP5:
    1184320    case AV_CODEC_ID_VP6:
    1185321    case AV_CODEC_ID_VP6F:
    1186322        return "V_VP6";
     323    case AV_CODEC_ID_VP8:
     324        return "V_VP8";
     325#if LIBAVCODEC_VERSION_MAJOR > 54
     326    case AV_CODEC_ID_VP9:
     327        return "V_VP9";
     328#endif
    1187329    case AV_CODEC_ID_RV10:
    1188330    case AV_CODEC_ID_RV20:
     
    1213355#endif
    1214356        return "V_MPEG4/ISO/AVC";
     357#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(55, 92, 100)
     358    case AV_CODEC_ID_HEVC:
     359    // case AV_CODEC_ID_H265:
     360        return "V_HEVC";
     361#endif
    1215362    case AV_CODEC_ID_AVS:
    1216363        return "V_AVS";
     
    1220367        return (mp3_software_decode) ? "A_IPCM" : "A_MP3";
    1221368    case AV_CODEC_ID_AAC:
    1222         return (aac_software_decode) ? "A_IPCM" : "A_AAC";
     369        if (extradata_size >= 2)
     370        {
     371            MPEG4AudioConfig m4ac;
     372            int off = avpriv_mpeg4audio_get_config(&m4ac, extradata, extradata_size * 8, 1);
     373            ffmpeg_printf(1,"aac [%d] off[%d]\n", m4ac.object_type, off);
     374            if (off < 0 || 2 != m4ac.object_type)
     375            {
     376                return "A_IPCM";
     377            }
     378        }
     379        return (aac_software_decode) ? "A_IPCM" : "A_AAC"; 
     380    case AV_CODEC_ID_AAC_LATM:
     381        return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM";
    1223382    case AV_CODEC_ID_AC3:
    1224383        return  (ac3_software_decode) ? "A_IPCM" : "A_AC3";
     
    1280439    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
    1281440    case AV_CODEC_ID_DVB_TELETEXT:
    1282 //    case AV_CODEC_ID_BITMAP:
     441//    case CODEC_ID_DVB_TELETEXT:
     442//        return "S_TEXT/SRT"; /* fixme */
    1283443    case AV_CODEC_ID_TEXT: ///< raw UTF-8 text
    1284444        return "S_TEXT/UTF-8";
     
    1288448        return "S_TEXT/SUBRIP";
    1289449    default:
    1290         ffmpeg_err("Codec ID %d (%.8d) not found\n", (int32_t)codec->codec_id, (int32_t)codec->codec_id);
     450        ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
    1291451        // Default to injected-pcm for unhandled audio types.
    1292         if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
     452        if (media_type == AVMEDIA_TYPE_AUDIO)
    1293453        {
    1294454            return "A_IPCM";
    1295455        }
    1296 
    1297         if (codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
    1298         {
    1299             return "S_TEXT/SRT";
    1300         }
    1301 
    1302         ffmpeg_err("Codec ID %d (%.8d) not found\n", (int32_t)codec->codec_id, (int32_t)codec->codec_id);
     456        ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
    1303457    }
    1304458    return NULL;
     
    1328482
    1329483    return pts;
    1330 }
    1331 
    1332 /*Hellmaster1024: get the Duration of the subtitle from the SSA line*/
    1333 int64_t getDurationFromSSALine(unsigned char* line){
    1334 
    1335 ffmpeg_printf(0, "obiiii zzzzzz=%s\n", line);
    1336 
    1337 
    1338     int i,h,m,s,ms;
    1339     char* Text = strdup((char*) line);
    1340     char* ptr1;
    1341     char* ptr[10];
    1342     int64_t msec;
    1343 
    1344     ptr1 = Text;
    1345     ptr[0]=Text;
    1346     for (i=0; i < 3 && *ptr1 != '\0'; ptr1++) {
    1347         if (*ptr1 == ',') {
    1348             ptr[++i]=ptr1+1;
    1349             *ptr1 = '\0';
    1350         }
    1351     }
    1352 
    1353     sscanf(ptr[2],"%d:%d:%d.%d",&h,&m,&s,&ms);
    1354     msec = (ms*10) + (s*1000) + (m*60*1000) + (h*24*60*1000);
    1355     sscanf(ptr[1],"%d:%d:%d.%d",&h,&m,&s,&ms);
    1356     msec -= (ms*10) + (s*1000) + (m*60*1000) + (h*24*60*1000);
    1357 
    1358 //    ffmpeg_printf(10, "%s %s %f\n", ptr[2], ptr[1], (float) msec / 1000.0);
    1359   ffmpeg_printf(10, "%s %s %f\n", ptr[2], ptr[1], msec / 1000);
    1360 
    1361 ffmpeg_printf(0, "obiiii xxxxxxxx\n");
    1362     free(Text);
    1363 ffmpeg_printf(0, "obiiii yyyyyyyy\n");
    1364 
    1365 //    return (float)msec/1000.0;
    1366     return msec/1000;
    1367484}
    1368485
     
    1371488 */
    1372489
    1373 #if LIBAVCODEC_VERSION_MAJOR < 54
    1374 static char* searchMeta(AVMetadata *metadata, char* ourTag)
    1375 #else
    1376 static char* searchMeta(AVDictionary * metadata, char* ourTag)
    1377 #endif
     490static char* searchMeta(void * metadata, char* ourTag)
    1378491{
    1379492#if LIBAVCODEC_VERSION_MAJOR < 54
     
    1416529    threadname[16] = 0;
    1417530    prctl (PR_SET_NAME, (unsigned long)&threadname);
    1418 //    AVPacket   packet;
    1419 //    av_init_packet(&packet);
    1420 
    1421 //    off_t   lastSeek = -1;
    1422 //    int64_t lastPts = -1;
     531    AVPacket   packet;
     532    off_t   lastSeek = -1;
     533    int64_t lastPts = -1;
    1423534    int64_t currentVideoPts = -1;
    1424535    int64_t currentAudioPts = -1;
     
    1430541    int64_t lastAudioDts = -1;
    1431542   
    1432 //    int64_t showtime = 0;
    1433 //    int64_t bofcount = 0;
    1434 //    int32_t       err = 0;
     543    int64_t showtime = 0;
     544    int64_t bofcount = 0;
     545    int32_t       err = 0;
    1435546    AudioVideoOut_t avOut;
    1436547   
    1437 //    g_context = context;
     548    g_context = context;
    1438549
    1439550    SwrContext *swr = NULL;
     
    1449560    AVBitStreamFilterContext *mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
    1450561#endif
    1451    
     562#ifdef HAVE_FLV2MPEG4_CONVERTER
     563    Flv2Mpeg4Context flv2mpeg4_context;
     564    memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context));
     565#endif
    1452566    ffmpeg_printf(10, "\n");
    1453567    while ( context->playback->isCreationPhase )
     
    1461575    while ( context && context->playback && context->playback->isPlaying )
    1462576    {
    1463             AVPacket   packet;
    1464         av_init_packet(&packet);
    1465 
    1466577        //IF MOVIE IS PAUSED, WAIT
    1467578        if (context->playback->isPaused)
     
    1504615                    if(NULL != avContextTab[i])
    1505616                    {
    1506                         av_seek_frame(avContextTab[i], -1, seek_target_seconds, 0);
     617                        if (avContextTab[i]->start_time != AV_NOPTS_VALUE)
     618                        {
     619                            seek_target_seconds += avContextTab[i]->start_time;
     620                            printf("SEEK SECONDS [%lld]\n", seek_target_seconds);
     621                        }
     622                        //av_seek_frame(avContextTab[i], -1, seek_target_seconds, 0);
     623                        avformat_seek_file(avContextTab[i], -1, INT64_MIN, seek_target_seconds, INT64_MAX, 0);
    1507624                    }
    1508625                    else
     
    1532649                if(NULL != avContextTab[i])
    1533650                {
    1534                     uint32_t j;
    1535                     for (j = 0; j < avContextTab[i]->nb_streams; j++)
    1536                     {
    1537                         if (avContextTab[i]->streams[j]->codec && avContextTab[i]->streams[j]->codec->codec)
    1538                         {
    1539                             avcodec_flush_buffers(avContextTab[i]->streams[j]->codec);
    1540                         }
    1541                     }
     651                    wrapped_avcodec_flush_buffers(i);
    1542652                }
    1543653                else
     
    1554664            }
    1555665#endif
     666#ifdef HAVE_FLV2MPEG4_CONVERTER
     667            flv2mpeg4_context_reset(&flv2mpeg4_context);
     668#endif
    1556669        }
    1557670
     
    1568681            }
    1569682        }
    1570 
     683       
    1571684        if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0 )
    1572685        {
     
    1576689            Track_t *audioTrack = NULL;
    1577690            Track_t *subtitleTrack = NULL;
    1578                         Track_t *dvbsubtitleTrack = NULL;
    1579                         Track_t *teletextTrack = NULL;
    1580691
    1581692            int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id;
     
    1587698                ffmpeg_err("error getting video track\n");
    1588699            }
    1589            
     700            
    1590701            if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0)
    1591702            {
     
    1603714            {
    1604715#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    1605                 AVCodecContext *codec_context = ((AVStream*)(videoTrack->stream))->codec;
    1606                 if (codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context)
     716                AVCodecContext *codec_context = videoTrack->avCodecCtx;
     717                if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context)
    1607718                {
    1608719                    // should never happen, if it does print error and exit immediately, so we can easily spot it
     
    1617728                        exit(1);
    1618729                    }
     730                    update_max_injected_pts(latestPts);
     731                }
     732                else
     733#endif
     734#ifdef HAVE_FLV2MPEG4_CONVERTER
     735                if (get_codecpar(avContextTab[cAVIdx]->streams[packet.stream_index])->codec_id == AV_CODEC_ID_FLV1 &&
     736                    0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7) )
     737                {
     738                    flv2mpeg4_write_packet(context, &flv2mpeg4_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet);
    1619739                    update_max_injected_pts(latestPts);
    1620740                }
     
    1656776                   
    1657777                    if (skipPacket)
    1658                     {
    1659 #if LIBAVCODEC_VERSION_MAJOR >= 56
    1660                         av_packet_unref(&packet);
    1661 #else
    1662                         av_free_packet(&packet);
    1663 #endif
     778                    {   
     779                        wrapped_packet_unref(&packet);
    1664780                        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    1665781                        continue;
     
    1679795                    avOut.height     = videoTrack->height;
    1680796                    avOut.type       = "video";
     797                   
     798                    if (avContextTab[cAVIdx]->iformat->flags & AVFMT_TS_DISCONT)
     799                    {
     800                        avOut.infoFlags = 1; // TS container
     801                    }
    1681802
    1682803                    if (context->output->video->Write(context, &avOut) < 0)
     
    1723844                if (skipPacket)
    1724845                {
    1725 #if LIBAVCODEC_VERSION_MAJOR >= 56
    1726                     av_packet_unref(&packet);
    1727 #else
    1728                     av_free_packet(&packet);
    1729 #endif
     846                    wrapped_packet_unref(&packet);
    1730847                    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    1731848                    continue;
     
    1733850               
    1734851                pcmPrivateData_t pcmExtradata;
    1735                 pcmExtradata.channels              = ((AVStream*) audioTrack->stream)->codec->channels;
    1736                 pcmExtradata.bits_per_coded_sample = ((AVStream*) audioTrack->stream)->codec->bits_per_coded_sample;
    1737                 pcmExtradata.sample_rate           = ((AVStream*) audioTrack->stream)->codec->sample_rate;
    1738                 pcmExtradata.bit_rate              = ((AVStream*) audioTrack->stream)->codec->bit_rate;
    1739                 pcmExtradata.ffmpeg_codec_id       = ((AVStream*) audioTrack->stream)->codec->codec_id;
     852                pcmExtradata.channels              = get_codecpar(audioTrack->stream)->channels;
     853                pcmExtradata.bits_per_coded_sample = get_codecpar(audioTrack->stream)->bits_per_coded_sample;
     854                pcmExtradata.sample_rate           = get_codecpar(audioTrack->stream)->sample_rate;
     855                pcmExtradata.bit_rate              = get_codecpar(audioTrack->stream)->bit_rate;
     856                pcmExtradata.ffmpeg_codec_id       = get_codecpar(audioTrack->stream)->codec_id;
    1740857                pcmExtradata.bResampling           = restart_audio_resampling;
    1741858               
    1742                 uint8_t *pAudioExtradata    = ((AVStream*) audioTrack->stream)->codec->extradata;
    1743                 uint32_t audioExtradataSize = ((AVStream*) audioTrack->stream)->codec->extradata_size;
     859                uint8_t *pAudioExtradata    = get_codecpar(audioTrack->stream)->extradata;
     860                uint32_t audioExtradataSize = get_codecpar(audioTrack->stream)->extradata_size;
    1744861                   
    1745862                ffmpeg_printf(200, "AudioTrack index = %d\n",pid);
     
    1765882                    }
    1766883                }
    1767                 else if (audioTrack->inject_as_pcm == 1)
    1768                 {
    1769                     AVCodecContext *c = ((AVStream*)(audioTrack->stream))->codec;
     884                else if (audioTrack->inject_as_pcm == 1 && audioTrack->avCodecCtx)
     885                {
     886                    AVCodecContext *c = audioTrack->avCodecCtx;
    1770887
    1771888                    if (restart_audio_resampling)
     
    1779896                        if (decoded_frame)
    1780897                        {
    1781 
    1782 #if (LIBAVCODEC_VERSION_MAJOR >= 55)
    1783                             av_frame_free(&decoded_frame);
     898                            wrapped_frame_free(&decoded_frame);
     899                            decoded_frame = NULL;
     900                        }
     901                    }
     902#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
     903                    while (packet.size > 0 || (!packet.size && !packet.data))
    1784904#else
    1785                             avcodec_free_frame(&decoded_frame);
    1786 #endif
    1787                             decoded_frame = NULL;
    1788                         }
    1789                         /* It seems that this is not needed and make long black
    1790                          * on BRCM STBs, but maybe this is needed for SH4 STBs
    1791                          * there is need to check
    1792                          */
    1793                         //context->output->Command(context, OUTPUT_CLEAR, NULL);
    1794                         //context->output->Command(context, OUTPUT_PLAY, NULL);
    1795                     }
    1796 
    1797905                    while(packet.size > 0)
     906#endif
    1798907                    {
    1799908                        if(do_seek_target_seconds || do_seek_target_bytes)
     
    1802911                        }
    1803912                       
    1804                         int32_t got_frame = 0;
    1805913                        if (!decoded_frame)
    1806914                        {
    1807 #if (LIBAVCODEC_VERSION_MAJOR >= 55)
    1808                             decoded_frame = av_frame_alloc();
    1809 #else
    1810                             decoded_frame = avcodec_alloc_frame();
    1811 #endif
     915                            decoded_frame = wrapped_frame_alloc();
    1812916                            if (!decoded_frame)
    1813917                            {
     
    1818922                        else
    1819923                        {
    1820 #if (LIBAVCODEC_VERSION_MAJOR >= 55)
    1821                             av_frame_unref(decoded_frame);
     924                            wrapped_frame_unref(decoded_frame);
     925                        }
     926#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
     927                        int ret = avcodec_send_packet(c, &packet);
     928                        if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
     929                        {
     930                            restart_audio_resampling = 1;
     931                            break;
     932                        }
     933                       
     934                        if (ret >= 0)
     935                        {
     936                            packet.size = 0;
     937                        }
     938                       
     939                        ret = avcodec_receive_frame(c, decoded_frame);
     940                        if (ret < 0)
     941                        {
     942                            if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
     943                            {
     944                                restart_audio_resampling = 1;
     945                                break;
     946                            }
     947                            else
     948                            {
     949                                continue;
     950                            }
     951                        }
    1822952#else
    1823                             avcodec_get_frame_defaults(decoded_frame);
    1824 #endif
    1825                         }
    1826 
     953                        int32_t got_frame = 0;
    1827954                        int32_t len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &packet);
    1828955                        if (len < 0)
     
    1839966                            continue;
    1840967                        }
    1841                        
     968#endif
    1842969                        int32_t e = 0;
    1843970                        if (!swr)
     
    19551082                {
    19561083                    ffmpeg_printf(200, "write audio aac\n");
    1957                     ffmpeg_printf(200, ">>>>>>> %x %x %x %x %x %x %x\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]);
     1084                    ffmpeg_printf(200, ">>>>>>> %x %x %x %x %x %x\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]);
    19581085
    19591086                    avOut.data       = packet.data;
     
    19921119                }
    19931120            }
    1994 /*
    19951121            else if (subtitleTrack && (subtitleTrack->Id == pid))
    19961122            {
     
    20041130                    duration = (int64_t)av_rescale(packet.duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
    20051131                }
    2006                 else if(packet.convergence_duration != 0 && packet.convergence_duration != AV_NOPTS_VALUE )
     1132                else if(get_packet_duration(&packet) != 0 && get_packet_duration(&packet) != AV_NOPTS_VALUE )
    20071133                {
    20081134                    // duration in milliseconds
    2009                     duration = (int64_t)av_rescale(packet.convergence_duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
     1135                    duration = (int64_t)av_rescale(get_packet_duration(&packet), (int64_t)stream->time_base.num * 1000, stream->time_base.den);
    20101136                }
    20111137
     
    20231149                    }
    20241150                }
    2025                     }
    2026 */
    2027                     else if (subtitleTrack && (subtitleTrack->Id == pid))
    2028                     {
    2029                                 int64_t duration = -1;
    2030                 int64_t pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts);
    2031                 AVStream *stream = subtitleTrack->stream;
    2032 
    2033                 if (packet.duration != 0)
    2034                 {
    2035 //mkv1
    2036                     // duration in milliseconds
    2037                     duration = (int64_t)av_rescale(packet.duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
    2038                 }
    2039                 else if(packet.convergence_duration != 0 && packet.convergence_duration != AV_NOPTS_VALUE )
    2040                 {
    2041                     // duration in milliseconds
    2042                     duration = (int64_t)av_rescale(packet.convergence_duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
    2043                 }
    2044 
    2045                             if ((pts > latestPts) && (!videoTrack) && (!audioTrack))
    2046                                         latestPts = pts;
    2047        
    2048                             /*Hellmaster1024: in mkv the duration for ID_TEXT is stored in convergence_duration */
    2049 #if (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25)
    2050                     ffmpeg_printf(20, "Packet duration %lld\n", packet.duration);
    2051 #else
    2052                     ffmpeg_printf(20, "Packet duration %d\n", packet.duration);
    2053                     ffmpeg_printf(20, "Packet convergence_duration %lld\n", packet.convergence_duration);
    2054 #endif
    2055                             if(packet.duration != 0) // FIXME: packet.duration is 32 bit, AV_NOPTS_VALUE is 64 bit --martii
    2056                                 {
    2057 //mkv2
    2058                                         duration=(packet.duration)/1000;
    2059                                 }
    2060                             else if(packet.convergence_duration != 0 && packet.convergence_duration != AV_NOPTS_VALUE )
    2061                                 {
    2062                                 ffmpeg_printf(0, "obiiii a4444444444444444\n");
    2063                                         duration=(packet.convergence_duration)/1000;
    2064                                 }
    2065                             else if(((AVStream*)subtitleTrack->stream)->codec->codec_id == AV_CODEC_ID_SSA)
    2066                             {
    2067                                         /*Hellmaster1024 if the duration is not stored in packet.duration or
    2068                                         packet.convergence_duration we need to calculate it any other way, for SSA it is stored in
    2069                                         the Text line*/
    2070                                         duration = getDurationFromSSALine(packet.data);
    2071                             }
    2072                             else
    2073                             {
    2074                                         /* no clue yet */
    2075                             }
    2076                             /* konfetti: I've found cases where the duration from getDurationFromSSALine
    2077                              * is zero (start end and are really the same in text). I think it make's
    2078                              * no sense to pass those.
    2079                              */
    2080 //mkv3
    2081                             if (duration > 0)
    2082                             {
    2083 //mkv4
    2084                                         /* is there a decoder ? */
    2085                                         if (((AVStream*) subtitleTrack->stream)->codec->codec)
    2086                                         {
    2087                                                 AVSubtitle sub;
    2088                                                 int got_sub_ptr;
    2089        
    2090                                                 if (avcodec_decode_subtitle2(((AVStream*) subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0)
    2091                                                 {
    2092                                                         ffmpeg_err("error decoding subtitle\n");
    2093                                                 }
    2094                                                 else
    2095                                                 {
    2096                                                 unsigned int i;
    2097        
    2098                                                         ffmpeg_printf(0, "format %d\n", sub.format);
    2099                                                         ffmpeg_printf(0, "start_display_time %d\n", sub.start_display_time);
    2100                                                         ffmpeg_printf(0, "end_display_time %d\n", sub.end_display_time);
    2101                                                         ffmpeg_printf(0, "num_rects %d\n", sub.num_rects);
    2102                                                         ffmpeg_printf(0, "pts %lld\n", sub.pts);
    2103                                                        
    2104                                                         for (i = 0; i < sub.num_rects; i++)
    2105                                                         {
    2106                                                                 ffmpeg_printf(0, "x %d\n", sub.rects[i]->x);
    2107                                                                 ffmpeg_printf(0, "y %d\n", sub.rects[i]->y);
    2108                                                                 ffmpeg_printf(0, "w %d\n", sub.rects[i]->w);
    2109                                                                 ffmpeg_printf(0, "h %d\n", sub.rects[i]->h);
    2110                                                                 ffmpeg_printf(0, "nb_colors %d\n", sub.rects[i]->nb_colors);
    2111                                                                 ffmpeg_printf(0, "type %d\n", sub.rects[i]->type);
    2112                                                                 ffmpeg_printf(0, "text %s\n", sub.rects[i]->text);
    2113                                                                 ffmpeg_printf(0, "ass %s\n", sub.rects[i]->ass);
    2114                                                                 // pict ->AVPicture                                             
    2115                                                         }
    2116                                                 }
    2117                                         }
    2118                                         else if(((AVStream*)subtitleTrack->stream)->codec->codec_id == AV_CODEC_ID_SSA)
    2119                                         {
    2120                                             SubtitleData_t data;
    2121                
    2122                                             ffmpeg_printf(10, "videoPts %lld\n", currentVideoPts);
    2123                
    2124                                             data.data      = packet.data;
    2125                                             data.len       = packet.size;
    2126                                             data.extradata = subtitleTrack->extraData;
    2127                                             data.extralen  = subtitleTrack->extraSize;
    2128                                             data.pts       = pts;
    2129                                             data.duration  = duration;
    2130                
    2131                                             context->container->assContainer->Command(context, CONTAINER_DATA, &data);
    2132                                         }
    2133                                         else
    2134                                         {
    2135 //mkv5
    2136                                             /* hopefully native text ;) */
    2137                
    2138                                             unsigned char* line = text_to_ass((char *)packet.data,pts/90,duration);
    2139                                             ffmpeg_printf(50,"text line is %s\n",(char *)packet.data);
    2140                                             ffmpeg_printf(50,"Sub line is %s\n",line);
    2141                                             ffmpeg_printf(20, "videoPts %lld %f\n", currentVideoPts,currentVideoPts/90000.0);
    2142                                             SubtitleData_t data;
    2143                                             data.data      = line;
    2144                                             data.len       = strlen((char*)line);
    2145                                             data.extradata = (unsigned char *) DEFAULT_ASS_HEAD;
    2146                                             data.extralen  = strlen(DEFAULT_ASS_HEAD);
    2147                                             data.pts       = pts;
    2148                                             data.duration  = duration;
    2149                
    2150                                             context->container->assContainer->Command(context, CONTAINER_DATA, &data);
    2151                                             free(line);
    2152                                         }
    2153                             } /* duration */
    2154 //mkv6
    2155                     }
    2156                     else if (dvbsubtitleTrack && (dvbsubtitleTrack->Id == pid))
    2157                     {
    2158                             dvbsubtitleTrack->pts = pts = calcPts(cAVIdx, dvbsubtitleTrack->stream, packet.pts);
    2159        
    2160                             ffmpeg_printf(200, "DvbSubTitle index = %d\n",pid);
    2161        
    2162                             avOut.data       = packet.data;
    2163                             avOut.len        = packet.size;
    2164                             avOut.pts        = pts;
    2165                             avOut.extradata  = NULL;
    2166                             avOut.extralen   = 0;
    2167                             avOut.frameRate  = 0;
    2168                             avOut.timeScale  = 0;
    2169                             avOut.width      = 0;
    2170                             avOut.height     = 0;
    2171                             avOut.type       = "dvbsubtitle";
    2172        
    2173                             if (context->output->dvbsubtitle->Write(context, &avOut) < 0)
    2174                             {
    2175                                         //ffmpeg_err("writing data to dvbsubtitle fifo failed\n");
    2176                             }
    2177                     }
    2178                     else if (teletextTrack && (teletextTrack->Id == pid))
    2179                     {
    2180                             teletextTrack->pts = pts = calcPts(cAVIdx, teletextTrack->stream, packet.pts);
    2181        
    2182                             ffmpeg_printf(200, "TeleText index = %d\n",pid);
    2183        
    2184                             avOut.data       = packet.data;
    2185                             avOut.len        = packet.size;
    2186                             avOut.pts        = pts;
    2187                             avOut.extradata  = NULL;
    2188                             avOut.extralen   = 0;
    2189                             avOut.frameRate  = 0;
    2190                             avOut.timeScale  = 0;
    2191                             avOut.width      = 0;
    2192                             avOut.height     = 0;
    2193                             avOut.type       = "teletext";
    2194        
    2195                             if (context->output->teletext->Write(context, &avOut) < 0)
    2196                             {
    2197                                         //ffmpeg_err("writing data to teletext fifo failed\n");
    2198                             }
    2199                     }
     1151            }
    22001152        }
    22011153        else
     
    22071159                if( 0 == av_strerror(ffmpegStatus, errbuf, sizeof(errbuf)) )
    22081160                {
    2209                     // In this way we inform user about error within the core
     1161                    /* In this way we inform user about error within the core
     1162                     */
    22101163                    printf("{\"log\":\"Frame read error: '%s'\"}\n", errbuf);
    22111164                }
    22121165               
    2213 //                if( ffmpegStatus == AVERROR(EAGAIN) )
    2214 //                {
    2215 //                    continue;
    2216 //                }
     1166                /*
     1167                if( ffmpegStatus == AVERROR(EAGAIN) )
     1168                {
     1169                    continue;
     1170                }
     1171                */
    22171172                ffmpegStatus = 0;
    22181173            }
    2219 
     1174           
    22201175            if(!is_finish_timeout() && !context->playback->isTSLiveMode)
    22211176            {
     
    22401195                    if( 0 == container_ffmpeg_get_length(context, &tmpLength) && tmpLength > 0 && get_play_pts() > 0)
    22411196                    {
     1197#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    22421198                        if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    22431199                        {
     
    22461202                        }
    22471203                        else
     1204#endif
    22481205                        {
    22491206                            seek_target_seconds = 0;
     
    22591216                // av_read_frame failed
    22601217                ffmpeg_err("no data ->end of file reached ? \n");
    2261 #if LIBAVCODEC_VERSION_MAJOR >= 56
    2262                 av_packet_unref(&packet);
    2263 #else
    2264                 av_free_packet(&packet);
    2265 #endif
     1218                wrapped_packet_unref(&packet);
    22661219                releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    22671220                if( bEndProcess )
     
    22731226                    continue;
    22741227                }
    2275             }         
    2276         }
    2277        
    2278 #if LIBAVCODEC_VERSION_MAJOR >= 56
    2279         av_packet_unref(&packet);
    2280 #else
    2281         av_free_packet(&packet);
    2282 #endif
     1228            }
     1229        }
     1230        wrapped_packet_unref(&packet);
    22831231        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    22841232    } /* while */
     
    22881236        swr_free(&swr);
    22891237    }
    2290    
     1238    
    22911239    if (decoded_frame)
    22921240    {
    2293 #if (LIBAVCODEC_VERSION_MAJOR >= 55)
    2294         av_frame_free(&decoded_frame);
    2295 #else
    2296         avcodec_free_frame(&decoded_frame);
    2297 #endif
    2298     }
    2299    
     1241        wrapped_frame_free(&decoded_frame);
     1242    }
     1243   
    23001244#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    23011245    mpeg4p2_context_reset(&mpeg4p2_context);
     
    23201264{
    23211265    PlaybackHandler_t *p = (PlaybackHandler_t *)ctx;
    2322 //    return p->abortRequested || PlaybackDieNow(0);
    2323 //      secound http stream not working with PlaybackDieNow(0)
    2324     return p->abortRequested;
     1266    return p->abortRequested;// || PlaybackDieNow(0);
    23251267}
    23261268
     
    23841326    avContextTab[AVIdx]->interrupt_callback.callback = interrupt_cb;
    23851327    avContextTab[AVIdx]->interrupt_callback.opaque = context->playback;
    2386 ffmpeg_printf(10, "filename2 %s\n", filename);
    23871328
    23881329#ifdef SAM_CUSTOM_IO
     
    24051346    AVDictionary **pavio_opts = NULL;
    24061347    eRTMPProtoImplType rtmpProtoImplType = RTMP_NONE;
     1348    uint8_t numOfRTMPImpl = 0;
    24071349    if (0 == strncmp(filename, "ffrtmp", 6))
    24081350    {
     
    24331375        const char *protoName = NULL;
    24341376        uint8_t haveNativeProto = 0;
    2435         uint8_t numOfRTMPImpl = 0;
    24361377       
    2437 //        while (protoName = avio_enum_protocols(&opaque, 1))
    2438         while (protoName == avio_enum_protocols(&opaque, 1))
     1378        while (protoName = avio_enum_protocols(&opaque, 1))
    24391379        {
    24401380            if (0 == strcmp("rtmp", protoName))
     
    24641404                    /* if we have both impl, we will prefer native
    24651405                     * unless uri contain param wich can be understandable
    2466                      * only by by librtmp
     1406                     * only by librtmp
    24671407                     */
    24681408                    if (strstr(filename, " token=") ||
     
    25991539                free(swfUrl);
    26001540                free(swfVfy);
    2601 
    2602                 pavio_opts = &avio_opts;
    26031541            }
    26041542           
     
    27611699
    27621700                }
    2763 ////////
    27641701
    27651702                ffmpeg_printf(10, "check tslivemode\n");
     
    27701707                        context->playback->isTSLiveMode = 1;
    27711708                }
     1709////////
    27721710
    27731711        av_dict_set(&avio_opts, "reconnect", "1", 0);
    27741712        if (context->playback->isTSLiveMode) // special mode for live TS stream with skip packet
    27751713        {
    2776                         ffmpeg_printf(10, "use tslivemode\n");
    27771714            av_dict_set(&avio_opts, "seekable", "0", 0);
    27781715            av_dict_set(&avio_opts, "reconnect_at_eof", "1", 0);
    27791716            av_dict_set(&avio_opts, "reconnect_streamed", "1", 0);
    27801717        }
    2781         pavio_opts = &avio_opts;
    2782     }
    2783 
     1718    }
     1719   
     1720    pavio_opts = &avio_opts;
     1721   
    27841722    if ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0)
    27851723    {
    2786         char error[512];
    2787 
    2788         ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
    2789         av_strerror(err, error, 512);
    2790         fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
    2791 
    2792         if(avio_opts != NULL)
    2793         {
    2794             av_dict_free(&avio_opts);
    2795         }
    2796         //for buffered io
    2797         ffmpeg_buf_free();
    2798         //for buffered io (end)
    2799 
    2800         releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    2801         return cERR_CONTAINER_FFMPEG_OPEN;
     1724        if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN &&
     1725            rtmpProtoImplType == RTMP_NATIVE &&
     1726            numOfRTMPImpl > 1)
     1727        {
     1728            // retry with librtmp
     1729            err = avformat_open_input(&avContextTab[AVIdx], filename+2, fmt, pavio_opts);
     1730            // filename2 - another memory leak, and also only once, so does not matter
     1731        }
     1732       
     1733        if (err != 0)
     1734        {
     1735            char error[512];
     1736
     1737            ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
     1738            av_strerror(err, error, 512);
     1739            fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
     1740
     1741            if(avio_opts != NULL)
     1742            {
     1743                av_dict_free(&avio_opts);
     1744            }
     1745            releaseMutex(__FILE__, __FUNCTION__,__LINE__);
     1746            return cERR_CONTAINER_FFMPEG_OPEN;
     1747        }
    28021748    }
    28031749
     
    28071753    if (context->playback->noprobe)
    28081754    {
    2809 #if (LIBAVFORMAT_VERSION_MAJOR > 55) && (LIBAVFORMAT_VERSION_MAJOR < 57)
    2810         avContextTab[AVIdx]->max_analyze_duration2 = 1;
    2811 #else
    2812         avContextTab[AVIdx]->max_analyze_duration = 1;
    2813 #endif
     1755        wrapped_set_max_analyze_duration(avContextTab[AVIdx], 1);
    28141756    }
    28151757
     
    28191761    {
    28201762        ffmpeg_err("Error avformat_find_stream_info\n");
    2821 #ifdef this_is_ok
    2822         /* crow reports that sometimes this returns an error
    2823          * but the file is played back well. so remove this
    2824          * until other works are done and we can prove this.
    2825          */
    2826         avformat_close_input(&avContextTab[AVIdx]);
    2827         //for buffered io
    2828         ffmpeg_buf_free();
    2829         //for buffered io (end)
    2830         releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    2831         return cERR_CONTAINER_FFMPEG_STREAM;
    2832 #endif
    28331763    }
    28341764
     
    28651795            }
    28661796        }
    2867 //        else if (progressive_download)
    2868 //        {
    2869 //            avContextTab[AVIdx]->pb->read_packet = ffmpeg_read_wrapper;
    2870 //        }
     1797        else if (progressive_playback)
     1798        {
     1799            avContextTab[AVIdx]->pb->read_packet = ffmpeg_read_wrapper;
     1800        }
    28711801    }
    28721802//for buffered io (end)
     
    28771807int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
    28781808{
    2879 //    int32_t err = 0;
     1809    int32_t err = 0;
    28801810
    28811811    ffmpeg_printf(10, ">\n");
    2882 
    2883     //for buffered io
    2884     ffmpeg_buf_free();
    2885     //for buffered io end
    28861812
    28871813    if (playFilesNames == NULL)
     
    29201846    av_register_all();
    29211847    avformat_network_init();
    2922 
    2923         char* tmpstr = NULL;
    2924     tmpstr = readfiletomem("/mnt/config/titan.cfg", 1);
    2925     if(ostrstr(tmpstr, "debuglevel=99") != NULL)
    2926            av_log_set_level( AV_LOG_DEBUG );
    2927         free(tmpstr), tmpstr = NULL;
    2928 
     1848   
    29291849    // SULGE DEBUG ENABLED
    29301850    // make ffmpeg silen
    2931     // av_log_set_level( AV_LOG_DEBUG );
     1851    //av_log_set_level( AV_LOG_DEBUG );
    29321852    av_log_set_callback(ffmpeg_silen_callback);
    29331853 
     
    29581878int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial)
    29591879{
    2960 //      Track_t *videoTrack = NULL;
    29611880    Track_t *audioTrack = NULL;
    29621881    Track_t *subtitleTrack = NULL;
    2963     Track_t *dvbsubtitleTrack = NULL;
    2964     Track_t *teletextTrack = NULL;
    2965 
    29661882   
    29671883    if (terminating)
     
    29731889    {
    29741890        context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack);
    2975     }
    2976 
    2977     if (initial && context->manager->dvbsubtitle)
    2978     {
    2979         context->manager->dvbsubtitle->Command(context, MANAGER_GET_TRACK, &dvbsubtitleTrack);
    2980     }
    2981 
    2982     if (initial && context->manager->teletext)
    2983     {
    2984         context->manager->teletext->Command(context, MANAGER_GET_TRACK, &teletextTrack);
    29851891    }
    29861892
     
    30291935            int32_t version = 0;
    30301936
    3031             char *encoding = Codec2Encoding(stream->codec, &version);
     1937            char *encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \
     1938                                            (uint8_t *)get_codecpar(stream)->extradata, \
     1939                                            (int)get_codecpar(stream)->extradata_size, \
     1940                                            (int)get_codecpar(stream)->profile, &version);
    30321941           
    30331942            if(encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm)
     
    30501959             */
    30511960            memset(&track, 0, sizeof(track));
    3052             track.AVIdx = cAVIdx;
    3053 
    3054             switch (stream->codec->codec_type)
     1961            track.AVIdx = cAVIdx; 
     1962
     1963            switch (get_codecpar(stream)->codec_type)
    30551964            {
    30561965            case AVMEDIA_TYPE_VIDEO:
    3057                 ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n",stream->codec->codec_type);
     1966                ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
    30581967
    30591968                if (encoding != NULL)
     
    30621971                    track.version        = version;
    30631972
    3064                     track.width          = stream->codec->width;
    3065                     track.height         = stream->codec->height;
     1973                    track.width          = get_codecpar(stream)->width;
     1974                    track.height         = get_codecpar(stream)->height;
    30661975                   
    30671976                    /* We will return here PAR (Pixel Aspect Ratio) client need to calculate DAR(Display Aspect Ratio)
     
    30751984                    if (0 == track.aspect_ratio_num  || 0 == track.aspect_ratio_den)
    30761985                    {
    3077                         track.aspect_ratio_num = stream->codec->sample_aspect_ratio.num;
    3078                         track.aspect_ratio_den = stream->codec->sample_aspect_ratio.den;
    3079                     }
    3080 
    3081                     track.extraData      = stream->codec->extradata;
    3082                     track.extraSize      = stream->codec->extradata_size;
     1986                        track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num;
     1987                        track.aspect_ratio_den = get_codecpar(stream)->sample_aspect_ratio.den;
     1988                    }
     1989
     1990                    track.extraData      = get_codecpar(stream)->extradata;
     1991                    track.extraSize      = get_codecpar(stream)->extradata_size;
    30831992
    30841993                    track.aacbuf         = 0;
    30851994                    track.have_aacheader = -1;
    30861995                   
    3087                     track.frame_rate = (uint32_t)(1000 * (int64_t)(stream->r_frame_rate.num) / (int64_t)(stream->r_frame_rate.den));
    3088 
     1996                    AVRational rateRational = get_frame_rate(stream);
     1997                    if (rateRational.den!=0)
     1998                    {
     1999                        track.frame_rate = (uint32_t)(1000 * (int64_t)(rateRational.num) / (int64_t)(rateRational.den));
     2000                    }
     2001                   
    30892002                    /* fixme: revise this */
    30902003                    if (track.frame_rate < 23970)
     
    30972010                    }
    30982011                   
    3099                     ffmpeg_printf(10, "bit_rate       [%d]\n",stream->codec->bit_rate);
    3100                     ffmpeg_printf(10, "flags          [%d]\n",stream->codec->flags);
    3101                     ffmpeg_printf(10, "frame_bits     [%d]\n",stream->codec->frame_bits);
    3102                     ffmpeg_printf(10, "time_base.den  [%d]\n",stream->time_base.den);
    3103                     ffmpeg_printf(10, "time_base.num  [%d]\n",stream->time_base.num);
    3104                     ffmpeg_printf(10, "width          [%d]\n",stream->codec->width);
    3105                     ffmpeg_printf(10, "height         [%d]\n",stream->codec->height);
    3106                     ffmpeg_printf(10, "frame_rate num [%d]\n",stream->r_frame_rate.num);
    3107                     ffmpeg_printf(10, "frame_rate den [%d]\n",stream->r_frame_rate.den);
     2012                    ffmpeg_printf(10, "bit_rate       [%d]\n", get_codecpar(stream)->bit_rate);
     2013                    ffmpeg_printf(10, "time_base.den  [%d]\n", stream->time_base.den);
     2014                    ffmpeg_printf(10, "time_base.num  [%d]\n", stream->time_base.num);
     2015                    ffmpeg_printf(10, "width          [%d]\n", get_codecpar(stream)->width);
     2016                    ffmpeg_printf(10, "height         [%d]\n", get_codecpar(stream)->height);
     2017                    ffmpeg_printf(10, "frame_rate num [%d]\n", rateRational.num);
     2018                    ffmpeg_printf(10, "frame_rate den [%d]\n", rateRational.den);
    31082019
    31092020                    ffmpeg_printf(10, "frame_rate     [%u]\n", track.frame_rate);
     
    31162027
    31172028                    track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
    3118                     if(stream->duration == AV_NOPTS_VALUE)
     2029                    if(stream->duration == AV_NOPTS_VALUE || 0 == strncmp(avContext->iformat->name, "dash", 4))
    31192030                    {
    31202031                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
     
    31242035                    if (context->manager->video)
    31252036                    {
    3126                         ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n", cAVIdx);
     2037                        if (get_codecpar(stream)->codec_id == AV_CODEC_ID_MPEG4)
     2038                        {
     2039                            track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
     2040                        }
     2041                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n");
    31272042                        if( context->manager->video->Command(context, MANAGER_ADD, &track) < 0)
    31282043                        {
     
    31342049                else
    31352050                {
    3136                     ffmpeg_err("codec type video but codec unknown %d\n", stream->codec->codec_id);
     2051                    ffmpeg_err("codec type video but codec unknown %d\n", get_codecpar(stream)->codec_id);
    31372052                }
    31382053                break;
    31392054            case AVMEDIA_TYPE_AUDIO:
    3140                 ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",stream->codec->codec_type);
     2055                ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",get_codecpar(stream)->codec_type);
    31412056
    31422057                if (encoding != NULL)
    31432058                {
    31442059                    AVDictionaryEntry *lang;
    3145                     track.type           = eTypeES;
     2060                    track.type = eTypeES;
    31462061
    31472062                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
     
    31672082                    {
    31682083                        track.inject_as_pcm = 1;
    3169                         ffmpeg_printf(10, " Handle inject_as_pcm = %d\n", track.inject_as_pcm);
    3170 
    3171                         AVCodec *codec = avcodec_find_decoder(stream->codec->codec_id);
    3172 
    3173                         //( (AVStream*) audioTrack->stream)->codec->flags |= CODEC_FLAG_TRUNCATED;
    3174                         int errorCode = avcodec_open2(stream->codec, codec, NULL);
    3175                         if(codec != NULL && !errorCode)
    3176                         {
    3177                            ffmpeg_printf(10, "AVCODEC__INIT__SUCCESS\n");
    3178                         }
    3179                         else
    3180                         {
    3181                            ffmpeg_printf(10, "AVCODEC__INIT__FAILED error[%d]\n", errorCode);
     2084                        track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
     2085                        if (track.avCodecCtx)
     2086                        {
     2087                            ffmpeg_printf(10, " Handle inject_as_pcm = %d\n", track.inject_as_pcm);
     2088
     2089                            AVCodec *codec = avcodec_find_decoder(get_codecpar(stream)->codec_id);
     2090
     2091                            int errorCode = avcodec_open2(track.avCodecCtx, codec, NULL);
     2092                            if(codec != NULL && !errorCode)
     2093                            {
     2094                               ffmpeg_printf(10, "AVCODEC__INIT__SUCCESS\n");
     2095                            }
     2096                            else
     2097                            {
     2098                               ffmpeg_printf(10, "AVCODEC__INIT__FAILED error[%d]\n", errorCode);
     2099                            }
    31822100                        }
    31832101                    }
     
    31862104                        track.inject_raw_pcm = 1;
    31872105                    }
    3188                     else if(stream->codec->codec_id == AV_CODEC_ID_AAC)
     2106                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC_LATM)
     2107                    {
     2108                        const char marker[] = "LATM";
     2109                        track.aacbuflen = sizeof(marker)/sizeof(char);
     2110                        track.aacbuf = malloc(track.aacbuflen);
     2111                        memcpy(track.aacbuf, marker, track.aacbuflen);
     2112                       
     2113                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM no extradata ACC header should be available in each frame\n");
     2114                        track.have_aacheader = 1;
     2115                    }
     2116                    else if(!strncmp(encoding, "A_AAC_LATM", 10))
     2117                    {
     2118                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM extradata will be used in aac writter\n");
     2119                    }
     2120                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC)
    31892121                    {
    31902122                        if( 0 == strncmp(avContext->iformat->name, "mpegts", 6) ||
     
    31942126                            track.aacbuflen = sizeof(marker)/sizeof(char);
    31952127                            track.aacbuf = malloc(track.aacbuflen);
    3196                             //assert(track.aacbuf);
    31972128                            memcpy(track.aacbuf, marker, track.aacbuflen);
    31982129                           
     
    32032134                        {
    32042135                            ffmpeg_printf(10, "Create AAC ExtraData\n");
    3205                             ffmpeg_printf(10, "stream->codec->extradata_size %d\n", stream->codec->extradata_size);
    3206                             //Hexdump(stream->codec->extradata, stream->codec->extradata_size);
     2136                            ffmpeg_printf(10, "get_codecpar(stream)->extradata_size %d\n", get_codecpar(stream)->extradata_size);
     2137                            //Hexdump(get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
    32072138
    32082139                            /*  extradata:
     
    32222153
    32232154                            int32_t object_type = 2; // LC
    3224                             int32_t sample_index = aac_get_sample_rate_index(stream->codec->sample_rate);
    3225                             int32_t chan_config = stream->codec->channels;
    3226                             if(stream->codec->extradata_size >= 2)
     2155                            int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate);
     2156                            int32_t chan_config = get_codecpar(stream)->channels - 1;
     2157                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
     2158                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
     2159                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
     2160                           
     2161                            if (get_codecpar(stream)->extradata_size >= 2)
    32272162                            {
    3228                                 uint8_t *h = stream->codec->extradata;
    3229                                 object_type = h[0] >> 3;
    3230                                 sample_index = ((h[0] & 0x7) << 1) |((h[1] & 0x80) >> 7);
    3231                                 chan_config = (h[1] & 0x78) >> 3;
     2163                                MPEG4AudioConfig m4ac;
     2164                                int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
     2165                                if (off >= 0)
     2166                                {
     2167                                    object_type  = m4ac.object_type;
     2168                                    sample_index = m4ac.sampling_index;
     2169                                    if (sample_index == 0x0f)
     2170                                    {
     2171                                        sample_index = aac_get_sample_rate_index(m4ac.sample_rate);
     2172                                    }
     2173                                    chan_config  = m4ac.chan_config;
     2174                                }
    32322175                            }
    3233 
    3234                             ffmpeg_printf(10,"aac object_type %d\n", object_type);
    3235                             ffmpeg_printf(10,"aac sample_index %d\n", sample_index);
    3236                             ffmpeg_printf(10,"aac chan_config %d\n", chan_config);
    3237                             ffmpeg_printf(10,"aac chan_config %d\n", chan_config);
    3238 
    3239                             object_type -= 1; // Cause of ADTS
    3240 
     2176                           
     2177                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
     2178                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
     2179                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
     2180
     2181                           
     2182                            // https://wiki.multimedia.cx/index.php/ADTS
     2183                            object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1
     2184                           
    32412185                            track.aacbuflen = AAC_HEADER_LENGTH;
    32422186                            track.aacbuf = malloc(8);
     
    32632207
    32642208                    }
    3265                     else if(stream->codec->codec_id == AV_CODEC_ID_WMAV1
    3266                         || stream->codec->codec_id == AV_CODEC_ID_WMAV2
    3267                         || stream->codec->codec_id == AV_CODEC_ID_WMAPRO
    3268                         || stream->codec->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (stream->codec->extradata_size > 0)
     2209                    else if(get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1
     2210                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2
     2211                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO
     2212                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0)
    32692213                    {
    32702214                        ffmpeg_printf(10,"Create WMA ExtraData\n");
    3271                         uint16_t channels = stream->codec->channels;
    3272                         uint32_t rate = stream->codec->sample_rate;
    3273                         uint32_t bitrate = stream->codec->bit_rate;
    3274                         uint16_t block_align = stream->codec->block_align;
    3275                         uint16_t depth = stream->codec->bits_per_coded_sample;
    3276                         uint32_t codec_data_size = stream->codec->extradata_size;
    3277                         uint8_t *codec_data_pointer = stream->codec->extradata;
     2215                        uint16_t channels = get_codecpar(stream)->channels;
     2216                        uint32_t rate = get_codecpar(stream)->sample_rate;
     2217                        uint32_t bitrate = get_codecpar(stream)->bit_rate;
     2218                        uint16_t block_align = get_codecpar(stream)->block_align;
     2219                        uint16_t depth = get_codecpar(stream)->bits_per_coded_sample;
     2220                        uint32_t codec_data_size = get_codecpar(stream)->extradata_size;
     2221                        uint8_t *codec_data_pointer = get_codecpar(stream)->extradata;
    32782222                       
    32792223                        // type_specific_data
     
    32832227                        #define WMA_LOSSLESS            0x163
    32842228                        uint16_t codec_id = 0;
    3285                         switch(stream->codec->codec_id)
     2229                        switch(get_codecpar(stream)->codec_id)
    32862230                        {
    32872231                            //TODO: What code for lossless ?
     
    33012245                        }
    33022246#ifdef __sh__
    3303                         track.aacbuflen = 104 + stream->codec->extradata_size;
     2247                        track.aacbuflen = 104 + get_codecpar(stream)->extradata_size;
    33042248                        track.aacbuf = malloc(track.aacbuflen);
    33052249                        memset (track.aacbuf, 0, track.aacbuflen);
     
    33272271                        memset(track.aacbuf + 60, 0, 4); // time_offset_hi (not used)
    33282272
    3329                         uint8_t type_specific_data_length = 18 + stream->codec->extradata_size;
     2273                        uint8_t type_specific_data_length = 18 + get_codecpar(stream)->extradata_size;
    33302274                        memcpy(track.aacbuf + 64, &type_specific_data_length, 4); //type_specific_data_length
    33312275
     
    33412285                        memcpy(track.aacbuf + 78, &codec_id, 2); //codec_id
    33422286
    3343                         uint16_t number_of_channels = stream->codec->channels;
     2287                        uint16_t number_of_channels = get_codecpar(stream)->channels;
    33442288                        memcpy(track.aacbuf + 80, &number_of_channels, 2); //number_of_channels
    33452289
    3346                         uint32_t samples_per_second = stream->codec->sample_rate;
     2290                        uint32_t samples_per_second = get_codecpar(stream)->sample_rate;
    33472291                        ffmpeg_printf(1, "samples_per_second = %d\n", samples_per_second);
    33482292                        memcpy(track.aacbuf + 82, &samples_per_second, 4); //samples_per_second
    33492293
    3350                         uint32_t average_number_of_bytes_per_second = stream->codec->bit_rate / 8;
     2294                        uint32_t average_number_of_bytes_per_second = get_codecpar(stream)->bit_rate / 8;
    33512295                        ffmpeg_printf(1, "average_number_of_bytes_per_second = %d\n", average_number_of_bytes_per_second);
    33522296                        memcpy(track.aacbuf + 86, &average_number_of_bytes_per_second, 4); //average_number_of_bytes_per_second
    33532297
    3354                         uint16_t block_alignment = stream->codec->block_align;
     2298                        uint16_t block_alignment = get_codecpar(stream)->block_align;
    33552299                        ffmpeg_printf(1, "block_alignment = %d\n", block_alignment);
    33562300                        memcpy(track.aacbuf + 90, &block_alignment, 2); //block_alignment
    33572301
    3358                         uint16_t bits_per_sample =
    3359                         stream->codec->sample_fmt>=0?(stream->codec->sample_fmt+1)*8:8;
    3360                         ffmpeg_printf(1, "bits_per_sample = %d (%d)\n", bits_per_sample, stream->codec->sample_fmt);
     2302#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
     2303                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->format;
     2304#else
     2305                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->sample_fmt;
     2306#endif
     2307                        uint16_t bits_per_sample = sample_fmt>=0 ? (sample_fmt+1)*8 : 8;
     2308                        ffmpeg_printf(1, "bits_per_sample = %d (%d)\n", bits_per_sample, sample_fmt);
    33612309                        memcpy(track.aacbuf + 92, &bits_per_sample, 2); //bits_per_sample
    33622310
    3363                         memcpy(track.aacbuf + 94, &stream->codec->extradata_size, 2); //bits_per_sample
    3364 
    3365                         memcpy(track.aacbuf + 96, stream->codec->extradata, stream->codec->extradata_size);
     2311                        memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample
     2312
     2313                        memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
    33662314#else
    3367                         track.aacbuflen = 18 + stream->codec->extradata_size;
     2315                        track.aacbuflen = 18 + get_codecpar(stream)->extradata_size;
    33682316                        track.aacbuf = malloc(track.aacbuflen);
    33692317                        memset (track.aacbuf, 0, track.aacbuflen);
     
    34022350
    34032351                        //ffmpeg_printf(1, "priv_data:\n");
    3404                         //Hexdump(stream->codec->priv_data, track.aacbuflen);
     2352                        //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen);
    34052353
    34062354                        track.have_aacheader = 1;
     
    34092357                    if (context->manager->audio)
    34102358                    {
    3411                         ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n", cAVIdx);
     2359                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n");
    34122360                        if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0)
    34132361                        {
     
    34192367                else //encoding != NULL
    34202368                {
    3421                     ffmpeg_err("codec type audio but codec unknown %d\n", stream->codec->codec_id);
     2369                    ffmpeg_err("codec type audio but codec unknown %d\n", get_codecpar(stream)->codec_id);
    34222370                }
    34232371                break;
    34242372            case AVMEDIA_TYPE_SUBTITLE:
    34252373            {
    3426                 if (stream->codec->codec_id != AV_CODEC_ID_SSA &&
     2374                if (get_codecpar(stream)->codec_id != AV_CODEC_ID_SSA &&
    34272375#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100)
    3428                     stream->codec->codec_id != AV_CODEC_ID_ASS &&
    3429 #endif
    3430                     stream->codec->codec_id != AV_CODEC_ID_SUBRIP &&
    3431                     stream->codec->codec_id != AV_CODEC_ID_TEXT &&
    3432                     stream->codec->codec_id != AV_CODEC_ID_SRT)
    3433                 {
    3434                     ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)stream->codec->codec_id);
    3435                     printf("SULGE subtitle with not supported codec codec_id[%u]\n", (uint32_t)stream->codec->codec_id);
     2376                    get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS &&
     2377#endif
     2378                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
     2379                    get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
     2380                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT)
     2381                {
     2382                    ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id);
    34362383                }
    34372384                else if (initial && context->manager->subtitle)
     
    34402387                    memset(&track, 0, sizeof(track));
    34412388
    3442                     ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", stream->codec->codec_type);
     2389                    ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type);
    34432390                   
    34442391                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
     
    34572404                    }
    34582405
    3459                     track.extraData      = stream->codec->extradata;
    3460                     track.extraSize      = stream->codec->extradata_size;
    3461 
    3462                     ffmpeg_printf(1, "subtitle codec %d\n", stream->codec->codec_id);
    3463                     ffmpeg_printf(1, "subtitle width %d\n", stream->codec->width);
    3464                     ffmpeg_printf(1, "subtitle height %d\n", stream->codec->height);
     2406                    track.extraData      = get_codecpar(stream)->extradata;
     2407                    track.extraSize      = get_codecpar(stream)->extradata_size;
     2408
     2409                    ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id);
     2410                    ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width);
     2411                    ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height);
    34652412                    ffmpeg_printf(1, "subtitle stream %p\n", stream);
    34662413
    34672414                    ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name);
     2415                   
    34682416                    if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0)
    34692417                    {
    34702418                        ffmpeg_err("failed to add subtitle track %d\n", n);
    34712419                    }
    3472 /*
    3473                                     if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && context->manager->teletext)
    3474                                     {
    3475                                                 ffmpeg_printf(10, "dvb_teletext\n");
    3476                                                 int i = 0;
    3477                                                 AVDictionaryEntry *t = NULL;
    3478                                                 do {
    3479                                                         char tmp[30];
    3480                                                         snprintf(tmp, sizeof(tmp), "teletext_%d", i);
    3481                                                         t = av_dict_get(stream->metadata, tmp, NULL, 0);
    3482                                                         if (t) {
    3483                                                                 track.Name = t->value;
    3484                                                                 if (context->manager->teletext->Command(context, MANAGER_ADD, &track) < 0)
    3485                                                                         ffmpeg_err("failed to add teletext track %d\n", n);
    3486                                                         }
    3487                                                         i++;
    3488                                                 } while (t);
    3489                                     }
    3490                                     else if (stream->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE && context->manager->dvbsubtitle)
    3491                                     {
    3492                                                 ffmpeg_printf(10, "dvb_subtitle\n");
    3493                                                 lang = av_dict_get(stream->metadata, "language", NULL, 0);
    3494                                                 if (context->manager->dvbsubtitle->Command(context, MANAGER_ADD, &track) < 0) {
    3495                                                     ffmpeg_err("failed to add dvbsubtitle track %d\n", n);
    3496                                                 }
    3497                                     }
    3498                                     else if (initial && context->manager->subtitle)
    3499                                     {
    3500                                                 if (!stream->codec->codec)
    3501                                                 {
    3502                                                     stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id);
    3503                                                     if (!stream->codec->codec)
    3504                                                                 ffmpeg_err("avcodec_find_decoder failed for subtitle track %d\n", n);
    3505                                                     else if (avcodec_open2(stream->codec, stream->codec->codec, NULL))
    3506                                                     {
    3507                                                         ffmpeg_err("avcodec_open2 failed for subtitle track %d\n", n);
    3508                                                         stream->codec->codec = NULL;
    3509                                                     }
    3510                                                 }
    3511                                                 if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0)
    3512                                                 {
    3513                                                     // konfetti: fixme: is this a reason to return with error?
    3514                                                     ffmpeg_err("failed to add subtitle track %d\n", n);
    3515                                                 }
    3516                                     }*/
    35172420                }
    35182421                break;
    35192422            }
    3520 /*
    3521         case AVMEDIA_TYPE_SUBTITLE:
    3522         {
    3523             AVDictionaryEntry *lang;
    3524 
    3525             ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n",stream->codec->codec_type);
    3526 
    3527                 lang = av_dict_get(stream->metadata, "language", NULL, 0);
    3528                
    3529                 track.Name = lang ? lang->value : "und";
    3530 
    3531             ffmpeg_printf(10, "Language %s\n", track.Name);
    3532 
    3533             track.Encoding       = encoding;
    3534             track.stream         = stream;
    3535             track.Id             = ((AVStream *) (track.stream))->id;
    3536 //          track.duration       = (double)stream->duration * av_q2d(stream->time_base) * 1000.0;
    3537             track.duration       = (double)stream->duration * av_q2d(stream->time_base) * 1000;
    3538 
    3539             track.aacbuf         = 0;
    3540             track.have_aacheader = -1;
    3541 
    3542             track.width          = -1; // will be filled online from videotrack
    3543             track.height         = -1; // will be filled online from videotrack
    3544 
    3545             track.extraData      = stream->codec->extradata;
    3546             track.extraSize      = stream->codec->extradata_size;
    3547 
    3548             ffmpeg_printf(1, "subtitle codec %d\n", stream->codec->codec_id);
    3549             ffmpeg_printf(1, "subtitle width %d\n", stream->codec->width);
    3550             ffmpeg_printf(1, "subtitle height %d\n", stream->codec->height);
    3551             ffmpeg_printf(1, "subtitle stream %p\n", stream);
    3552 
    3553             if(stream->duration == AV_NOPTS_VALUE) {
    3554                         ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
    3555                         track.duration = (double) avContext->duration / 1000.0;
    3556             }
    3557             else
    3558             {
    3559 //                      track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0;
    3560                         track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000;
    3561             }
    3562 
    3563             ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name);
    3564 
    3565             if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && context->manager->teletext)
    3566             {
    3567                         ffmpeg_printf(10, "dvb_teletext\n");
    3568                         int i = 0;
    3569                         AVDictionaryEntry *t = NULL;
    3570                         do {
    3571                                 char tmp[30];
    3572                                 snprintf(tmp, sizeof(tmp), "teletext_%d", i);
    3573                                 t = av_dict_get(stream->metadata, tmp, NULL, 0);
    3574                                 if (t) {
    3575                                         track.Name = t->value;
    3576                                         if (context->manager->teletext->Command(context, MANAGER_ADD, &track) < 0)
    3577                                                 ffmpeg_err("failed to add teletext track %d\n", n);
    3578                                 }
    3579                                 i++;
    3580                         } while (t);
    3581             }
    3582             else if (stream->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE && context->manager->dvbsubtitle)
    3583             {
    3584                         ffmpeg_printf(10, "dvb_subtitle\n");
    3585                         lang = av_dict_get(stream->metadata, "language", NULL, 0);
    3586                         if (context->manager->dvbsubtitle->Command(context, MANAGER_ADD, &track) < 0) {
    3587                             ffmpeg_err("failed to add dvbsubtitle track %d\n", n);
    3588                         }
    3589             }
    3590             else if (initial && context->manager->subtitle)
    3591             {
    3592                         if (!stream->codec->codec)
    3593                         {
    3594                             stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id);
    3595                             if (!stream->codec->codec)
    3596                                         ffmpeg_err("avcodec_find_decoder failed for subtitle track %d\n", n);
    3597                             else if (avcodec_open2(stream->codec, stream->codec->codec, NULL))
    3598                             {
    3599                                 ffmpeg_err("avcodec_open2 failed for subtitle track %d\n", n);
    3600                                 stream->codec->codec = NULL;
    3601                             }
    3602                         }
    3603                         if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0)
    3604                         {
    3605                             // konfetti: fixme: is this a reason to return with error?
    3606                             ffmpeg_err("failed to add subtitle track %d\n", n);
    3607                         }
    3608             }
    3609 
    3610             break;
    3611         }
    3612 */
    36132423            case AVMEDIA_TYPE_UNKNOWN:
    36142424            case AVMEDIA_TYPE_DATA:
     
    36162426            case AVMEDIA_TYPE_NB:
    36172427            default:
    3618                 ffmpeg_err("not handled or unknown codec_type %d\n", stream->codec->codec_type);
     2428                ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type);
    36192429             break;
    36202430            }
     
    36842494        return cERR_CONTAINER_FFMPEG_ERR;
    36852495    }
    3686 
    3687     ffmpeg_printf(10, "111\n");
    3688 
    3689     //for buffered io
    3690     wait_time = 100;
    3691     if(hasfillerThreadStarted[hasfillerThreadStartedID] == 1)
    3692         hasfillerThreadStarted[hasfillerThreadStartedID] = 2; // should end
    3693     while ( (hasfillerThreadStarted[hasfillerThreadStartedID] != 0) && (--wait_time) > 0 ) {
    3694         ffmpeg_printf(10, "Waiting for ffmpeg filler thread to terminate itself, will try another %d times, ID=%d\n", wait_time, hasfillerThreadStartedID);
    3695         usleep(100000);
    3696     }
    3697     ffmpeg_printf(10, "222\n");
    3698 
    3699 
    3700     if (wait_time == 0) {
    3701         ffmpeg_err( "Timeout waiting for filler thread!\n");
    3702 
    3703         ret = cERR_CONTAINER_FFMPEG_ERR;
    3704     }
    3705     ffmpeg_printf(10, "333\n");
    3706 
    3707 
    3708     //for buffered io (end)
    3709 
     2496   
    37102497    if (context->playback)
    37112498    {
     
    37182505        usleep(100000);
    37192506    }
    3720     ffmpeg_printf(10, "444\n");
    3721 
    37222507
    37232508    if (wait_time == 0)
     
    37342519    hasPlayThreadStarted = 0;
    37352520    terminating = 1;
    3736     ffmpeg_printf(10, "555\n");
    3737 
    37382521
    37392522    getMutex(__FILE__, __FUNCTION__,__LINE__);
    3740 
     2523   
     2524    free_all_stored_avcodec_context();
     2525   
    37412526    uint32_t i = 0;
    37422527    for(i=0; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
     
    37632548        }
    37642549    }
    3765     ffmpeg_printf(10, "666\n");
    3766 
    37672550
    37682551    if(avio_opts != NULL)
     
    37752558    ffmpeg_buf_free();
    37762559
    3777     //for buffered io
    3778     ffmpeg_buf_free();
    3779     //for buffered io (end)
    3780     ffmpeg_printf(10, "777\n");
    3781 
    3782 
    37832560    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    37842561
     
    38112588
    38122589/* seeking relative to a given byteposition N seconds ->for reverse playback needed */
    3813 /*
    38142590static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec)
    38152591{
     
    38192595    seek_target_flag = 0;
    38202596
    3821     ffmpeg_printf(10, "seeking %lld sec relativ to %lld\n", sec, pos);
     2597    ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
    38222598
    38232599    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
     
    38552631
    38562632    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
    3857 
     2633#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    38582634    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    38592635    {
     
    38772653        }
    38782654
    3879         ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos, sec);
     2655        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
    38802656
    38812657        seek_target_bytes = pos;
     
    38852661    }
    38862662    else
     2663#endif
    38872664    {
    38882665        sec += pts / 90000;
     
    38932670        }
    38942671
    3895         ffmpeg_printf(10, "2. seeking to position %lld sec ->time base %f %d\n", sec, av_q2d(((AVStream*) current->stream)->time_base), AV_TIME_BASE);
     2672        ffmpeg_printf(10, "2. seeking to position %f sec ->time base %f %d\n", sec, av_q2d(((AVStream*) current->stream)->time_base), AV_TIME_BASE);
    38962673
    38972674        seek_target_seconds = sec * AV_TIME_BASE;
     
    39022679    return cERR_CONTAINER_FFMPEG_NO_ERROR;
    39032680}
    3904 */
    39052681
    39062682static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
     
    39132689    if (!absolute)
    39142690    {
    3915         ffmpeg_printf(10, "seeking %lld sec\n", sec);
     2691        ffmpeg_printf(10, "seeking %f sec\n", sec);
    39162692        if (sec == 0)
    39172693        {
     
    39322708    }
    39332709   
    3934     ffmpeg_printf(10, "goto %lld sec\n", sec);
     2710    ffmpeg_printf(10, "goto %d sec\n", sec);
    39352711    if (sec < 0)
    39362712    {
     
    39692745
    39702746    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
    3971 
     2747#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    39722748    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    39732749    {
     
    40002776        }
    40012777       
    4002         ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos, sec);
     2778        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %d\n", pos, sec);
    40032779
    40042780        seek_target_bytes = pos;
     
    40072783    }
    40082784    else
     2785#endif
    40092786    {
    40102787        seek_target_seconds = sec * AV_TIME_BASE;
     
    40212798    Track_t * videoTrack = NULL;
    40222799    Track_t * audioTrack = NULL;
    4023     Track_t * subtitleTrack = NULL;
    40242800    Track_t * current = NULL;
    40252801
     
    40322808    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
    40332809    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
    4034     context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack);
    40352810
    40362811    if (videoTrack != NULL)
     
    40412816    {
    40422817        current = audioTrack;
    4043     }
    4044     else if (subtitleTrack != NULL)
    4045     {
    4046         current = subtitleTrack;
    40472818    }
    40482819   
     
    40952866     * but now we will not ignore subtitle frame
    40962867     */
    4097 //    int64_t sec = -5;
    4098 //    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
    4099     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    4100 }
    4101 
    4102 static int32_t container_ffmpeg_switch_dvbsubtitle(Context_t* context __attribute__((unused)), int* arg __attribute__((unused)))
    4103 {
    4104     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    4105 }
    4106 
    4107 static int32_t container_ffmpeg_switch_teletext(Context_t* context __attribute__((unused)), int* arg __attribute__((unused)))
    4108 {
     2868    int64_t sec = -5;
     2869    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
    41092870    return cERR_CONTAINER_FFMPEG_NO_ERROR;
    41102871}
     
    42513012        break;
    42523013    }
    4253     case CONTAINER_SWITCH_DVBSUBTITLE: {
    4254         ret = container_ffmpeg_switch_dvbsubtitle(context, (int*) argument);
    4255         break;
    4256     }
    4257     case CONTAINER_SWITCH_TELETEXT: {
    4258         ret = container_ffmpeg_switch_teletext(context, (int*) argument);
    4259         break;
    4260     }
    4261     case CONTAINER_SET_BUFFER_SEEK_TIME: {
    4262     ret = container_set_ffmpeg_buf_seek_time((int*) argument);
    4263     break;
     3014    case CONTAINER_SET_BUFFER_SEEK_TIME:
     3015    {
     3016        ret = container_set_ffmpeg_buf_seek_time((int*) argument);
     3017            break;
    42643018    }
    42653019    case CONTAINER_SET_BUFFER_SIZE:
     
    42973051}
    42983052
    4299 static char *FFMPEG_Capabilities[] = {"avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv","wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "ra", "ram", "rm", "3gp", "amr", NULL };
     3053static char *FFMPEG_Capabilities[] = {"aac", "avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv","wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "ra", "ram", "rm", "3gp", "amr", "webm", "m3u8", "mpd", NULL };
    43003054
    43013055Container_t FFMPEGContainer = {
  • titan/libeplayer3/include/container.h

    r39831 r40322  
    1616CONTAINER_SWITCH_AUDIO,
    1717CONTAINER_SWITCH_SUBTITLE,
    18 CONTAINER_SWITCH_DVBSUBTITLE,
    19 CONTAINER_SWITCH_TELETEXT,
    20 CONTAINER_INFO,
     18CONTAINER_INFO,
    2119CONTAINER_STATUS,
    2220CONTAINER_LAST_PTS,
     
    4139    char * Name;
    4240    Container_t * selectedContainer;
    43     Container_t * textSrtContainer;
    44     Container_t * textSsaContainer;
    45     Container_t * assContainer;
     41
    4642    int (* Command) (/*Context_t*/void  *, ContainerCmd_t, void *);
    4743} ContainerHandler_t;
  • titan/libeplayer3/include/manager.h

    r39831 r40322  
    5353    /* stream from ffmpeg */
    5454    void               *  stream;
     55    /* AVCodecContext  for steam */
     56    void               *  avCodecCtx;
    5557    /* codec extra data (header or some other stuff) */
    5658    void               *  extraData;
     
    9799    Manager_t *video;
    98100    Manager_t *subtitle;
    99     Manager_t *dvbsubtitle;
    100     Manager_t *teletext;
    101101} ManagerHandler_t;
    102102
  • titan/libeplayer3/include/misc.h

    r39831 r40322  
    66#include <sys/stat.h>
    77#include <unistd.h>
     8#include <stdint.h>
    89
    910/* some useful things needed by many files ... */
     
    1516typedef struct BitPacker_s
    1617{
    17     unsigned char*      Ptr;                                    /* write pointer */
    18     unsigned int        BitBuffer;                              /* bitreader shifter */
    19     int                 Remaining;                              /* number of remaining in the shifter */
     18    uint8_t   *Ptr;                                    /* write pointer */
     19    uint32_t   BitBuffer;                              /* bitreader shifter */
     20    int32_t    Remaining;                              /* number of remaining in the shifter */
    2021} BitPacker_t;
    2122
     
    2627#define INVALID_PTS_VALUE                       0x200000000ull
    2728
    28 /* subtitle hacks ->for file subtitles */
    29 #define TEXTSRTOFFSET 100
    30 #define TEXTSSAOFFSET 200
    31 
    3229/* ***************************** */
    3330/* Prototypes                    */
    3431/* ***************************** */
    3532
    36 void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length);
     33void PutBits(BitPacker_t * ld, uint32_t code, uint32_t length);
    3734void FlushBits(BitPacker_t * ld);
     35int8_t PlaybackDieNow(int8_t val);
    3836
    3937/* ***************************** */
     
    7775{
    7876  static char path[100];
    79   unsigned int i = 0;
    80   int pos = 0;
     77  uint32_t i = 0;
     78  int32_t pos = 0;
    8179
    8280  while((name[i] != 0) && (i < sizeof(path)))
     
    9694}
    9795
    98 static inline int IsDreambox()
     96static inline int32_t IsDreambox()
    9997{
    10098    struct stat buffer;   
     
    102100}
    103101
     102static inline uint32_t ReadUint32(uint8_t *buffer)
     103{
     104    uint32_t num = (uint32_t)buffer[0] << 24 |
     105                   (uint32_t)buffer[1] << 16 |
     106                   (uint32_t)buffer[2] << 8  |
     107                   (uint32_t)buffer[3];
     108    return num;
     109}
     110
     111static inline uint16_t ReadUInt16(uint8_t *buffer)
     112{
     113    uint16_t num = (uint16_t)buffer[0] << 8 |
     114                   (uint16_t)buffer[1];
     115    return num;
     116}
     117
    104118#endif
  • titan/libeplayer3/include/output.h

    r39831 r40322  
    2727    OUTPUT_GET_FRAME_COUNT,
    2828    OUTPUT_GET_PROGRESSIVE,
    29     OUTPUT_SUBTITLE_REGISTER_FUNCTION = 222,
    30     OUTPUT_SUBTITLE_REGISTER_BUFFER = 223,
    31     OUTPUT_GET_SUBTITLE_OUTPUT,
    32     OUTPUT_SET_SUBTITLE_OUTPUT
    3329} OutputCmd_t;
    3430
     
    5046    uint32_t         height;
    5147   
     48    uint32_t         infoFlags;
     49   
    5250    char            *type;
    5351} AudioVideoOut_t;
    54 /*
     52
    5553typedef struct
    5654{
     
    6462    char            *type;
    6563} SubtitleOut_t;
    66 */
     64
    6765
    6866typedef struct Output_s
     
    7775extern Output_t LinuxDvbOutput;
    7876extern Output_t SubtitleOutput;
    79 extern Output_t PipeOutput;
    8077
    8178typedef struct OutputHandler_s
     
    8582    Output_t *video;
    8683    Output_t *subtitle;
    87     Output_t *dvbsubtitle;
    88     Output_t *teletext;
    8984    int32_t (* Command) (/*Context_t*/void  *, OutputCmd_t, void *);
    9085} OutputHandler_t;
  • titan/libeplayer3/include/playback.h

    r39831 r40322  
    44#include <stdint.h>
    55
    6 int8_t PlaybackDieNow(int8_t val);
    7 
    8 typedef enum {PLAYBACK_OPEN, PLAYBACK_CLOSE, PLAYBACK_PLAY, PLAYBACK_STOP, PLAYBACK_PAUSE, PLAYBACK_CONTINUE, PLAYBACK_FLUSH, PLAYBACK_TERM, PLAYBACK_FASTFORWARD, PLAYBACK_SEEK, PLAYBACK_SEEK_ABS, PLAYBACK_PTS, PLAYBACK_LENGTH, PLAYBACK_SWITCH_AUDIO, PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_SLOWMOTION, PLAYBACK_FASTBACKWARD, PLAYBACK_GET_FRAME_COUNT, PLAYBACK_SWITCH_TELETEXT, PLAYBACK_SWITCH_DVBSUBTITLE, PLAYBACK_FRAMEBUFFER_LOCK, PLAYBACK_FRAMEBUFFER_UNLOCK} PlaybackCmd_t;
     6typedef enum {PLAYBACK_OPEN, PLAYBACK_CLOSE, PLAYBACK_PLAY, PLAYBACK_STOP, PLAYBACK_PAUSE, PLAYBACK_CONTINUE, PLAYBACK_FLUSH, PLAYBACK_TERM, PLAYBACK_FASTFORWARD, PLAYBACK_SEEK, PLAYBACK_SEEK_ABS, PLAYBACK_PTS, PLAYBACK_LENGTH, PLAYBACK_SWITCH_AUDIO, PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_SLOWMOTION, PLAYBACK_FASTBACKWARD, PLAYBACK_GET_FRAME_COUNT} PlaybackCmd_t;
    97
    108typedef struct PlaybackHandler_s
     
    3129    uint8_t isAudio;
    3230    uint8_t isSubtitle;
    33     uint8_t isDvbSubtitle;
    34     uint8_t isTeletext;
    35     uint8_t mayWriteToFramebuffer;
    3631    uint8_t abortRequested;
    3732
  • titan/libeplayer3/include/writer.h

    r39831 r40322  
    66#include <stdint.h>
    77
    8 typedef enum { eNone, eAudio, eVideo, eGfx} eWriterType_t;
     8typedef enum { eNone, eAudio, eVideo} eWriterType_t;
    99
    1010typedef struct {
     
    2121    unsigned int           Height;
    2222    unsigned char          Version;
     23    unsigned int           InfoFlags;
    2324} WriterAVCallData_t;
    2425
    25 typedef struct {
    26     unsigned char*         data;
    27     unsigned int           Width;
    28     unsigned int           Height;
    29     unsigned int           Stride;
    30     unsigned int           color;
    3126
    32     unsigned int           x;       /* dst x ->given by ass */
    33     unsigned int           y;       /* dst y ->given by ass */
    34 
    35     /* destination values if we use a shared framebuffer */
    36     int                    fd;
    37     unsigned int           Screen_Width;
    38     unsigned int           Screen_Height;
    39     uint32_t               *destination;
    40     unsigned int           destStride;
    41 } WriterFBCallData_t;
    4227
    4328typedef struct WriterCaps_s {
     
    6651extern Writer_t WriterAudioEAC3;
    6752extern Writer_t WriterAudioAAC;
    68 extern Writer_t WriterAudioAACHE;
     53extern Writer_t WriterAudioAACLATM;
    6954extern Writer_t WriterAudioAACPLUS;
    7055extern Writer_t WriterAudioDTS;
     
    8671extern Writer_t WriterVideoMSCOMP;
    8772extern Writer_t WriterVideoH263;
     73extern Writer_t WriterVideoH265;
    8874extern Writer_t WriterVideoFLV;
    8975extern Writer_t WriterVideoVC1;
     76extern Writer_t WriterVideoVP6;
     77extern Writer_t WriterVideoVP8;
     78extern Writer_t WriterVideoVP9;
     79extern Writer_t WriterVideoSPARK;
    9080extern Writer_t WriterFramebuffer;
    9181extern Writer_t WriterPipe;
    92 extern Writer_t WriterDVBSubtitle;
    9382
    9483Writer_t* getWriter(char* encoding);
     
    9685Writer_t* getDefaultVideoWriter();
    9786Writer_t* getDefaultAudioWriter();
    98 Writer_t* getDefaultFramebufferWriter();
    9987ssize_t write_with_retry(int fd, const void *buf, size_t size);
    10088ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic);
  • titan/libeplayer3/main/exteplayer.c

    r39876 r40322  
    3939
    4040extern int ffmpeg_av_dict_set(const char *key, const char *value, int flags);
    41 extern void  aac_software_decoder_set(const int32_t val);
    42 extern void  dts_software_decoder_set(const int32_t val);
    43 extern void  wma_software_decoder_set(const int32_t val);
    44 extern void  ac3_software_decoder_set(const int32_t val);
    45 extern void eac3_software_decoder_set(const int32_t val);
    46 extern void  mp3_software_decoder_set(const int32_t val);
    47 extern void rtmp_proto_impl_set(const int32_t val);
     41extern void       aac_software_decoder_set(const int32_t val);
     42extern void  aac_latm_software_decoder_set(const int32_t val);
     43extern void       dts_software_decoder_set(const int32_t val);
     44extern void       wma_software_decoder_set(const int32_t val);
     45extern void       ac3_software_decoder_set(const int32_t val);
     46extern void      eac3_software_decoder_set(const int32_t val);
     47extern void       mp3_software_decoder_set(const int32_t val);
     48extern void            rtmp_proto_impl_set(const int32_t val);
     49extern void        flv2mpeg4_converter_set(const int32_t val);
    4850
    4951extern void pcm_resampling_set(int32_t val);
    5052extern void stereo_software_decoder_set(int32_t val);
    5153extern void insert_pcm_as_lpcm_set(int32_t val);
    52 extern void progressive_download_set(int32_t val);
     54extern void progressive_playback_set(int32_t val);
    5355
    5456extern OutputHandler_t         OutputHandler;
     
    275277    int aopt = 0, bopt = 0;
    276278    char *copt = 0, *dopt = 0;
    277     while ( (c = getopt(argc, argv, "wae3dlsrimvn:x:u:c:h:o:p:t:9:")) != -1)
     279    while ( (c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:t:9:0:1:4:f:")) != -1)
    278280    {
    279281        switch (c)
    280282        {
    281283        case 'a':
     284        {
     285            int flag = atoi(optarg);
    282286            printf("Software decoder will be used for AAC codec\n");
    283             aac_software_decoder_set(1);
    284             break;
     287            aac_software_decoder_set(flag & 0x01);
     288            aac_latm_software_decoder_set(flag & 0x02);
     289            break;
     290        }
    285291        case 'e':
    286292            printf("Software decoder will be used for EAC3 codec\n");
     
    317323        case 'o':
    318324            printf("Set progressive download to %d\n", atoi(optarg));
    319             progressive_download_set(atoi(optarg));
     325            progressive_playback_set(atoi(optarg));
    320326            break;
    321327        case 'p':
     
    354360            rtmp_proto_impl_set(atoi(optarg));
    355361            break;
     362        case '0':
     363            ffmpeg_av_dict_set("video_rep_index", optarg, 0);
     364            break;
     365        case '1':
     366            ffmpeg_av_dict_set("audio_rep_index", optarg, 0);
     367            break;
     368        case '4':
     369#ifdef HAVE_FLV2MPEG4_CONVERTER
     370            flv2mpeg4_converter_set(atoi(optarg));
     371#endif
     372            break;
     373        case 'f':
     374        {
     375            char *ffopt = strdup(optarg);
     376            char *ffval = strchr(ffopt, '=');
     377            if (ffval)
     378            {
     379                *ffval = '\0';
     380                ffval += 1;
     381                ffmpeg_av_dict_set(ffopt, ffval, 0);
     382            }
     383            free(ffopt);
     384            break;
     385        }
    356386        default:
    357387            printf ("?? getopt returned character code 0%o ??\n", c);
     
    395425    int commandRetVal = -1;
    396426    /* inform client that we can handle additional commands */
    397     fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 30);
     427    fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 34);
    398428
    399429    if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx))
    400430    {
    401431        printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
    402         printf("[-a] AAC software decoding\n");
     432        printf("[-a 0|1|2|3] AAC software decoding - 1 bit - AAC ADTS, 2 - bit AAC LATM\n");
    403433        printf("[-e] EAC3 software decoding\n");
    404434        printf("[-3] AC3 software decoding\n");
     
    408438        printf("[-l] software decoder use LPCM for injection (otherwise wav PCM will be used)\n");
    409439        printf("[-s] software decoding as stereo [downmix]\n");
     440#ifdef HAVE_FLV2MPEG4_CONVERTER
     441        printf("[-4 0|1] - disable/enable flv2mpeg4 converter\n");
     442#endif
    410443        printf("[-i] play in infinity loop\n");
    411444        printf("[-v] switch to live TS stream mode\n");
     
    419452        printf("[-c cookies] set cookies - not working at now, please use -h instead\n");
    420453        printf("[-x separateAudioUri]\n");
     454        printf("[-0 idx] video MPEG-DASH representation index\n");
     455        printf("[-1 idx] audio MPEG-DASH representation index\n");
     456        printf("[-f ffopt=ffval] any other ffmpeg option\n");
    421457       
    422458        exit(1);
     
    436472
    437473    // make sure to kill myself when parent dies
    438 //    prctl(PR_SET_PDEATHSIG, SIGKILL);
    439 
    440 //    SetBuffering();
     474    prctl(PR_SET_PDEATHSIG, SIGKILL);
     475
     476    SetBuffering();
    441477   
    442478    //Registrating output devices
     
    560596                if( 1 == sscanf(argvBuff+1, "%d", &flags) )
    561597                {
    562                     progressive_download_set(flags);
     598                    progressive_playback_set(flags);
    563599                    fprintf(stderr, "{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags);
    564600                }
  • titan/libeplayer3/manager/manager.c

    r39831 r40322  
    4141extern Manager_t VideoManager;
    4242extern Manager_t SubtitleManager;
    43 extern Manager_t DvbSubtitleManager;
    44 extern Manager_t TeletextManager;
    4543
    4644ManagerHandler_t ManagerHandler = {
     
    4846    &AudioManager,
    4947    &VideoManager,
    50     &SubtitleManager,
    51         &DvbSubtitleManager,
    52         &TeletextManager
     48    &SubtitleManager
    5349};
    5450
  • titan/libeplayer3/manager/subtitle.c

    r39831 r40322  
    3333#define TRACKWRAP 20
    3434
    35 #define SAM_WITH_DEBUG
     35//#define SAM_WITH_DEBUG
    3636#ifdef SAM_WITH_DEBUG
    3737#define SUBTITLE_MGR_DEBUG
     
    4343#ifdef SUBTITLE_MGR_DEBUG
    4444
    45 static short debug_level = 20;
     45static short debug_level = 10;
    4646
    4747#define subtitle_mgr_printf(level, x...) do { \
  • titan/libeplayer3/manager/video.c

    r39831 r40322  
    3232/* ***************************** */
    3333#define TRACKWRAP 4
    34 #define SAM_WITH_DEBUG
     34
    3535#ifdef SAM_WITH_DEBUG
    3636#define VIDEO_MGR_DEBUG
  • titan/libeplayer3/output/linuxdvb_mipsel.c

    r39882 r40322  
    131131
    132132    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    133                                
     133
    134134    if (video && videofd < 0)
    135135    {
    136                 fcntl(videofd, F_SETFL, fcntl(videofd, F_GETFL) | O_NONBLOCK);
    137 
    138136        videofd = open(VIDEODEV, O_RDWR | O_NONBLOCK);
    139 
    140                 fcntl(videofd, F_SETFL, fcntl(videofd, F_GETFL) | O_NONBLOCK);
    141137
    142138        if (videofd < 0)
     
    168164    if (audio && audiofd < 0)
    169165    {
    170                 fcntl(audiofd, F_SETFL, fcntl(audiofd, F_GETFL) | O_NONBLOCK);
    171 
    172166        audiofd = open(AUDIODEV, O_RDWR | O_NONBLOCK);
    173 
    174                 fcntl(audiofd, F_SETFL, fcntl(audiofd, F_GETFL) | O_NONBLOCK);
    175167
    176168        if (audiofd < 0)
     
    230222        audiofd = -1;
    231223    }
    232 
    233         fcntl(videofd, F_SETFL, fcntl(videofd, F_GETFL) | O_NONBLOCK);
    234 
    235         fcntl(audiofd, F_SETFL, fcntl(audiofd, F_GETFL) | O_NONBLOCK);
    236224
    237225    releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     
    10221010            call.Width        = out->width;
    10231011            call.Height       = out->height;
     1012            call.InfoFlags    = out->infoFlags;
    10241013            call.Version      = 0; // is unsingned char
    10251014
     
    10701059            call.FrameRate      = out->frameRate;
    10711060            call.FrameScale     = out->timeScale;
     1061            call.InfoFlags      = out->infoFlags;
    10721062            call.Version        = 0; /* -1; unsigned char cannot be negative */
    10731063
  • titan/libeplayer3/output/linuxdvb_sh4.c

    r39877 r40322  
    10051005            call.Width        = out->width;
    10061006            call.Height       = out->height;
     1007            call.InfoFlags      = out->infoFlags;
    10071008            call.Version      = 0; // is unsingned char
    10081009
     
    10531054            call.FrameRate      = out->frameRate;
    10541055            call.FrameScale     = out->timeScale;
     1056            call.InfoFlags      = out->infoFlags;
    10551057            call.Version        = 0; /* -1; unsigned char cannot be negative */
    10561058
  • titan/libeplayer3/output/output.c

    r39831 r40322  
    3131/* Makros/Constants              */
    3232/* ***************************** */
    33 //#define SAM_WITH_DEBUG
    3433
    3534#ifdef SAM_WITH_DEBUG
     
    4140#ifdef OUTPUT_DEBUG
    4241
    43 static short debug_level = 300;
     42static short debug_level = 0;
    4443
    4544#define output_printf(level, x...) do { \
     
    7271    &LinuxDvbOutput,
    7372    &SubtitleOutput,
    74     &PipeOutput,
    7573    NULL
    7674};
     
    132130                    return;
    133131                }
    134                 else if (!strcmp("dvbsubtitle", port))
    135                 {
    136                     context->output->dvbsubtitle = AvailableOutput[i];
    137                     return;
    138                 }
    139                 else if (!strcmp("teletext", port))
    140                 {
    141                     context->output->teletext = AvailableOutput[i];
    142                     return;
    143                 }
    144132            }
    145133        }
     
    162150    {
    163151        context->output->subtitle = NULL;
    164     }
    165     else if (!strcmp("dvbsubtitle", port))
    166     {
    167         context->output->dvbsubtitle = NULL;
    168     }
    169     else if (!strcmp("teletext", port))
    170     {
    171         context->output->teletext = NULL;
    172152    }
    173153}
     
    198178                ret |= context->output->subtitle->Command(context, OUTPUT_OPEN, "subtitle");
    199179            }
    200             if (context->playback->isDvbSubtitle)
    201                         {
    202                 ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    203                         }
    204             if (context->playback->isTeletext)
    205                         {
    206                 ret |= context->output->teletext->Command(context, command, "teletext");
    207                         }
    208180        }
    209181        else
     
    229201                ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle");
    230202            }
    231             if (context->playback->isDvbSubtitle)
    232                         {
    233                 ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    234                         }
    235             if (context->playback->isTeletext)
    236                         {
    237                 ret |= context->output->teletext->Command(context, command, "teletext");
    238                         }
    239203        }
    240204        else
     
    282246                }
    283247            }
    284                         if (context->playback->isDvbSubtitle)
    285                         {
    286                    ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    287                         }
    288                         if (context->playback->isTeletext)
    289                         {
    290                                    ret |= context->output->teletext->Command(context, command, "teletext");
    291                         }
    292248        }
    293249        else
     
    313269                ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle");
    314270            }
    315                         if (context->playback->isDvbSubtitle)
    316                         {
    317                    ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    318                         }
    319                         if (context->playback->isTeletext)
    320                         {
    321                                    ret |= context->output->teletext->Command(context, command, "teletext");
    322                         }
    323271        }
    324272        else
     
    344292                ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
    345293            }
    346                         if (context->playback->isDvbSubtitle)
    347                         {
    348                    ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    349                         }
    350                         if (context->playback->isTeletext)
    351                         {
    352                                    ret |= context->output->teletext->Command(context, command, "teletext");
    353                         }
    354294        }
    355295        else
     
    436376                ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
    437377            }
    438                         if (context->playback->isDvbSubtitle)
    439                         {
    440                    ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    441                         }
    442                         if (context->playback->isTeletext)
    443                         {
    444                                    ret |= context->output->teletext->Command(context, command, "teletext");
    445                         }
    446378        }
    447379        else
     
    482414                ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
    483415            }
    484                         if (context->playback->isDvbSubtitle)
    485                         {
    486                    ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    487                         }
    488                         if (context->playback->isTeletext)
    489                         {
    490                                    ret |= context->output->teletext->Command(context, command, "teletext");
    491                         }
    492416        }
    493417        else
     
    532456                return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle");
    533457            }
    534                         if (context->playback->isDvbSubtitle)
    535                         {
    536                    return context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
    537                         }
    538                         if (context->playback->isTeletext)
    539                         {
    540                                 return context->output->teletext->Command(context, command, "teletext");
    541                         }
    542458        }
    543459        else
     
    646562    NULL, //video
    647563    NULL, //subtitle
    648     NULL, // dvbsubtitle
    649     NULL, // teletext
    650564    &Command
    651565};
  • titan/libeplayer3/output/output_subtitle.c

    r39831 r40322  
    3232#include <memory.h>
    3333#include <asm/types.h>
    34 #include <pthread.h>
    3534#include <errno.h>
    3635
    3736#include "common.h"
    3837#include "output.h"
    39 #include "subtitle.h"
    4038
    4139/* ***************************** */
     
    4341/* ***************************** */
    4442
     43//SULGE DEBUG ENABLED
     44//#define SAM_WITH_DEBUG
     45#ifdef SAM_WITH_DEBUG
    4546#define SUBTITLE_DEBUG
     47#else
     48#define SUBTITLE_SILENT
     49#endif
    4650
    4751#ifdef SUBTITLE_DEBUG
     
    6569#define cERR_SUBTITLE_ERROR            -1
    6670
    67 static const char FILENAME[] = "subtitle.c";
     71static const char FILENAME[] = __FILE__;
    6872
    6973/*
     
    8185/* ***************************** */
    8286
    83 struct sub_t {
    84     char *                 text;
    85     unsigned long long int pts;
    86     unsigned long int      milliDuration;
    87 };
    88 
    8987
    9088/* ***************************** */
     
    9391
    9492static pthread_mutex_t mutex;
    95 
    96 static pthread_t thread_sub;
    97 
    98 void* clientData = NULL;
    99 void  (*clientFunction) (long int, size_t, char *, void *);
    100 
    101 static struct sub_t subPuffer[PUFFERSIZE];
    102 static int readPointer = 0;
    103 static int writePointer = 0;
    104 static int hasThreadStarted = 0;
    10593static int isSubtitleOpened = 0;
    106 static int      screen_width            = 0;
    107 static int      screen_height           = 0;
    108 static int      destStride              = 0;
    109 static void     (*framebufferBlit)      = NULL;
    110 static uint32_t *destination            = NULL;
    11194
    11295/* ***************************** */
     
    117100/* MISC Functions                */
    118101/* ***************************** */
    119 static void getMutex(int line) {
     102static void getMutex(int line)
     103{
    120104    subtitle_printf(100, "%d requesting mutex\n", line);
    121105
     
    125109}
    126110
    127 static void releaseMutex(int line) {
     111static void releaseMutex(int line)
     112{
    128113    pthread_mutex_unlock(&mutex);
    129114
     
    131116}
    132117
    133 void replace_all(char ** string, char * search, char * replace) {
    134     int len = 0;
    135     char * ptr = NULL;
    136     char tempString[512];
    137     char newString[512];
    138 
    139     newString[0] = '\0';
    140 
    141     if ((string == NULL) || (*string == NULL) || (search == NULL) || (replace == NULL))
    142     {
    143         subtitle_err("null pointer passed\n");
    144         return;
    145     }
     118/* ***************************** */
     119/* Functions                     */
     120/* ***************************** */
     121
     122static char * ass_get_text(char *str)
     123{
     124    // Events are stored in the Block in this order:
     125    // ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text
     126    // 91,0,Default,,0,0,0,,maar hij smaakt vast tof.
     127    int i = 0;
     128    char *p_str = str;
     129    while(i < 8 && *p_str != '\0')
     130    {
     131        if (*p_str == ',')
     132            i++;
     133        p_str++;
     134    }
     135    // standardize hard break: '\N' -> '\n'
     136    // http://docs.aegisub.org/3.2/ASS_Tags/
     137    char *p_newline = NULL;
     138    while((p_newline = strstr(p_str, "\\N")) != NULL)
     139        *(p_newline + 1) = 'n';
     140    return p_str;
     141}
     142
     143static char * json_string_escape(char *str)
     144{
     145    static char tmp[2048];
     146    char *ptr1 = tmp;
     147    char *ptr2 = str;
     148    while (*ptr2 != '\0')
     149    {
     150        switch (*ptr2)
     151        {
     152        case '"':
     153            *ptr1++ = '\\';
     154            *ptr1++ = '\"';
     155        break;
     156        case '\\':
     157            *ptr1++ = '\\';
     158            *ptr1++ = '\\';
     159        break;
     160        case '\b':
     161            *ptr1++ = '\\';
     162            *ptr1++ = 'b';
     163        break;
     164        case '\f':
     165            *ptr1++ = '\\';
     166            *ptr1++ = 'f';
     167        break;
     168        case '\n':
     169            *ptr1++ = '\\';
     170            *ptr1++ = 'n';
     171        break;
     172        case '\r':
     173            *ptr1++ = '\\';
     174            *ptr1++ = 'r';
     175        break;
     176        case '\t':
     177            *ptr1++ = '\\';
     178            *ptr1++ = 't';
     179        break;
     180        default:
     181            *ptr1++ = *ptr2;
     182            break;
     183        }
     184       
     185        ++ptr2;
     186    }
     187    *ptr1 = '\0';
     188    return tmp;
     189}
     190
     191static int Flush()
     192{   
     193    fprintf(stderr, "{\"s_f\":{\"r\":0}}\n");
     194    return cERR_SUBTITLE_NO_ERROR;
     195}
     196
     197static int Write(void *_context, void *data)
     198{
     199    Context_t  *context = (Context_t *)_context;
     200    char *Encoding      = NULL;
     201    SubtitleOut_t *out  = NULL;
     202    int32_t curtrackid  = -1;
    146203   
    147     strncpy(tempString, *string, 511);
    148     tempString[511] = '\0';
    149 
    150     free(*string);
    151 
    152     while ((ptr = strstr(tempString, search)) != NULL) {
    153         len  = ptr - tempString;
    154         strncpy(newString, tempString, len);
    155         newString[len] = '\0';
    156         strcat(newString, replace);
    157 
    158         len += strlen(search);
    159         strcat(newString, tempString+len);
    160 
    161         strcpy(tempString, newString);
    162     }
    163 
    164     subtitle_printf(20, "strdup in line %d\n", __LINE__);
    165 
    166     if(newString[0] != '\0')
    167         *string = strdup(newString);
    168     else
    169         *string = strdup(tempString);
    170 
    171 }
    172 
    173 int subtitle_ParseASS (char **Line) {
    174     char* Text;
    175     int   i;
    176     char* ptr1;
    177 
    178     if ((Line == NULL) || (*Line == NULL))
     204    subtitle_printf(10, "\n");
     205
     206    if (data == NULL)
    179207    {
    180208        subtitle_err("null pointer passed\n");
    181209        return cERR_SUBTITLE_ERROR;
    182210    }
    183    
    184     Text = strdup(*Line);
    185 
    186     subtitle_printf(10, "-> Text = %s\n", *Line);
    187 
    188     ptr1 = Text;
    189    
    190     for (i=0; i < 9 && *ptr1 != '\0'; ptr1++) {
    191 
    192         subtitle_printf(20, "%s",ptr1);
    193 
    194         if (*ptr1 == ',')
    195             i++;
    196     }
    197 
    198     free(*Line);
    199 
    200     *Line = strdup(ptr1);
    201     free(Text);
    202 
    203     replace_all(Line, "\\N", "\n");
    204 
    205     replace_all(Line, "{\\i1}", "<i>");
    206     replace_all(Line, "{\\i0}", "</i>");
    207 
    208     subtitle_printf(10, "<- Text=%s\n", *Line);
    209 
    210     return cERR_SUBTITLE_NO_ERROR;
    211 }
    212 
    213 int subtitle_ParseSRT (char **Line) {
    214 
    215     if ((Line == NULL) || (*Line == NULL))
    216     {
    217         subtitle_err("null pointer passed\n");
    218         return cERR_SUBTITLE_ERROR;
    219     }
    220 
    221     subtitle_printf(20, "-> Text=%s\n", *Line);
    222 
    223     replace_all(Line, "\x0d", "");
    224     replace_all(Line, "\n\n", "\\N");
    225     replace_all(Line, "\n", "");
    226     replace_all(Line, "\\N", "\n");
    227     replace_all(Line, "ö", "oe");
    228     replace_all(Line, "ä", "ae");
    229     replace_all(Line, "ü", "ue");
    230     replace_all(Line, "Ö", "Oe");
    231     replace_all(Line, "Ä", "Ae");
    232     replace_all(Line, "Ü", "Ue");
    233     replace_all(Line, "ß", "ss");
    234 
    235     subtitle_printf(10, "<- Text=%s\n", *Line);
    236 
    237     return cERR_SUBTITLE_NO_ERROR;
    238 }
    239 
    240 int subtitle_ParseSSA (char **Line) {
    241 
    242     if ((Line == NULL) || (*Line == NULL))
    243     {
    244         subtitle_err("null pointer passed\n");
    245         return cERR_SUBTITLE_ERROR;
    246     }
    247 
    248     subtitle_printf(20, "-> Text=%s\n", *Line);
    249 
    250     replace_all(Line, "\x0d", "");
    251     replace_all(Line, "\n\n", "\\N");
    252     replace_all(Line, "\n", "");
    253     replace_all(Line, "\\N", "\n");
    254     replace_all(Line, "ö", "oe");
    255     replace_all(Line, "ä", "ae");
    256     replace_all(Line, "ü", "ue");
    257     replace_all(Line, "Ö", "Oe");
    258     replace_all(Line, "Ä", "Ae");
    259     replace_all(Line, "Ü", "Ue");
    260     replace_all(Line, "ß", "ss");
    261 
    262     subtitle_printf(10, "<- Text=%s\n", *Line);
    263 
    264     return cERR_SUBTITLE_NO_ERROR;
    265 }
    266 
    267 void addSub(Context_t  *context, char * text, unsigned long long int pts, unsigned long int milliDuration) {
    268     int count = 20;
    269    
    270     subtitle_printf(50, "index %d\n", writePointer);
    271 
    272     if(context && context->playback && !context->playback->isPlaying)
    273     {
    274         subtitle_err("1. aborting ->no playback\n");
    275         return;
    276     }
    277    
    278     if (text == NULL)
    279     {
    280         subtitle_err("null pointer passed\n");
    281         return;
    282     }
    283 
    284     if (pts == 0)
    285     {
    286         subtitle_err("pts 0\n");
    287         return;
    288     }
    289 
    290     if (milliDuration == 0)
    291     {
    292         subtitle_err("duration 0\n");
    293         return;
    294     }
    295    
    296     while (subPuffer[writePointer].text != NULL) {
    297         //List is full, wait till we got some free space
    298 
    299         if(context && context->playback && !context->playback->isPlaying)
    300         {
    301             subtitle_err("2. aborting ->no playback\n");
    302             return;
    303         }
    304 
    305 /* konfetti: we dont want to block forever here. if no buffer
    306  * is available we start ring from the beginning and loose some stuff
    307  * which is acceptable!
    308  */
    309         subtitle_printf(10, "waiting on free buffer %d - %d (%d) ...\n", writePointer, readPointer, count);
    310         usleep(10000);
    311         count--;
    312        
    313         if (count == 0)
    314         {
    315             subtitle_err("abort waiting on buffer...\n");
    316             break;
    317         }
    318     }
    319    
    320     subtitle_printf(20, "from mkv: %s pts:%lld milliDuration:%lud\n",text,pts,milliDuration);
    321 
    322     getMutex(__LINE__);
    323 
    324     if (count == 0)
    325     {
    326         int i;
    327         subtitle_err("freeing not delivered data\n");
    328        
    329         //Reset all
    330         readPointer = 0;
    331         writePointer = 0;
    332 
    333         for (i = 0; i < PUFFERSIZE; i++) {
    334             if (subPuffer[i].text != NULL)
    335                free(subPuffer[i].text);
    336             subPuffer[i].text          = NULL;
    337             subPuffer[i].pts           = 0;
    338             subPuffer[i].milliDuration = 0;
    339         }
    340     }
    341 
    342     subPuffer[writePointer].text = strdup(text);
    343     subPuffer[writePointer].pts = pts;
    344     subPuffer[writePointer].milliDuration = milliDuration;
    345 
    346     writePointer++;
    347    
    348     if (writePointer == PUFFERSIZE)
    349         writePointer = 0;
    350 
    351     if (writePointer == readPointer)
    352     {
    353         /* this should not happen, and means that there is nor reader or
    354          * the reader has performance probs ;)
    355          * the recovery is done at startup of this function - but next time
    356          */
    357         subtitle_err("ups something went wrong. no more readers? \n");
    358     }
    359 
    360     releaseMutex(__LINE__);
    361 
    362     subtitle_printf(10, "<\n");
    363 }
    364 
    365 int getNextSub(char ** text, unsigned long long int * pts, long int * milliDuration) {
    366 
    367     subtitle_printf(50, "index %d\n", readPointer);
    368 
    369     if (text == NULL)
    370     {
    371         subtitle_err("null pointer passed\n");
    372         return cERR_SUBTITLE_ERROR;
    373     }
    374 
    375     getMutex(__LINE__);
    376 
    377     if (subPuffer[readPointer].text == NULL)
    378     {
    379         /* this is acutally not an error, because it may happen
    380          * that there is no subtitle for a while
    381          */
    382         subtitle_printf(200, "null in subPuffer\n");
    383         releaseMutex(__LINE__);
    384         return cERR_SUBTITLE_ERROR;
    385     }
    386    
    387     *text = strdup(subPuffer[readPointer].text);
    388     free(subPuffer[readPointer].text);
    389     subPuffer[readPointer].text = NULL;
    390 
    391     *pts = subPuffer[readPointer].pts;
    392     subPuffer[readPointer].pts = 0;
    393 
    394     *milliDuration = subPuffer[readPointer].milliDuration;
    395     subPuffer[readPointer].milliDuration = 0;
    396 
    397     readPointer++;
    398 
    399     if (readPointer == PUFFERSIZE)
    400         readPointer = 0;
    401 
    402     if (writePointer == readPointer)
    403     {
    404         /* this may happen, in normal case the reader is ones ahead the
    405          * writer. So this is the normal case that we eat the data
    406          * and have the reader reached.
    407          */
    408         subtitle_printf(20, "ups something went wrong. no more writers? \n");
    409     }
    410 
    411     releaseMutex(__LINE__);
    412 
    413     subtitle_printf(20, "readPointer %d\n",readPointer);
    414     subtitle_printf(10, "<\n");
    415 
    416     return cERR_SUBTITLE_NO_ERROR;
    417 }
    418 
    419 /* **************************** */
    420 /* Worker Thread                */
    421 /* **************************** */
    422 
    423 static void* SubtitleThread(void* data) {
    424     Context_t *context = (Context_t*) data;
    425     char *                  subText             = NULL;
    426     long int                subMilliDuration    = 0;
    427     unsigned long long int  subPts              = 0;
    428     unsigned long long int  Pts                 = 0;
    429 
    430     subtitle_printf(10, "\n");
    431     hasThreadStarted = 1;
    432 
    433     while ( context->playback->isCreationPhase ) {
    434         subtitle_err("Thread waiting for end of init phase...\n");
    435         usleep(1000);
    436     }
    437 
    438     subtitle_printf(10, "done\n");
    439 
    440     while ( context &&
    441             context->playback &&
    442             context->playback->isPlaying && hasThreadStarted == 1) {
    443 
    444         int curtrackid = -1;
    445        
    446         if (context && context->manager && context->manager->subtitle)
    447             context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
    448 
    449         subtitle_printf(50, "curtrackid %d\n", curtrackid);
    450 
    451         if (curtrackid >= 0) {
    452             if (getNextSub(&subText, &subPts, &subMilliDuration) != 0) {
    453                 usleep(500000);
    454                 continue;
    455             }
    456 
    457             if (context && context->playback)
    458                 context->playback->Command(context, PLAYBACK_PTS, &Pts);
    459             else break;
    460 
    461             if(Pts > subPts) {
    462                 subtitle_printf(10,"subtitle is to late, ignoring\n");
    463                 if(subText != NULL)
    464                     free(subText);
    465                 continue;
    466             }
    467 
    468             subtitle_printf(20, "Pts:%llu < subPts%llu duration %ld\n", Pts, subPts,subMilliDuration);
    469 
    470             while ( context &&
    471                     context->playback &&
    472                     context->playback->isPlaying &&
    473                     Pts < subPts && hasThreadStarted == 1) {
    474 
    475                 unsigned long int diff = subPts - Pts;
    476                 diff = (diff*1000)/90.0;
    477 
    478                 subtitle_printf(50, "DIFF: %lud\n", diff);
    479                 if(diff > 100)
    480                     usleep(diff);
    481 
    482                 if (context && context->playback)
    483                     context->playback->Command(context, PLAYBACK_PTS, &Pts);
    484                 else
    485                 {
    486                    subtitle_err("no playback ? terminated?\n");
    487                    break;
    488                 }
    489                 subtitle_printf(20, "cur: %llu wanted: %llu\n", Pts, subPts);
    490             }
    491 
    492             if (    context &&
    493                     context->playback &&
    494                     context->playback->isPlaying &&
    495                     subText != NULL && hasThreadStarted == 1) {
    496 
    497                 if(clientFunction != NULL)
    498                     clientFunction(subMilliDuration, strlen(subText), subText, clientData);
    499                 else
    500                     subtitle_printf(10, "writing Sub failed (%ld) (%d) \"%s\"\n", subMilliDuration, strlen(subText), subText);
    501 
    502                 free(subText);
    503             }
    504         } /* trackID >= 0 */
    505         else //Wait
    506             usleep(500000);
    507 
    508     } /* outer while */
    509    
    510     subtitle_printf(0, "has ended\n");
    511  
    512     hasThreadStarted = 0;
    513    
    514     return NULL;
    515 }
    516 
    517 /* ***************************** */
    518 /* Functions                     */
    519 /* ***************************** */
    520 
    521 static int Write(void* _context, void *data) {
    522     Context_t  * context = (Context_t  *) _context;
    523     char * Encoding = NULL;
    524     char * Text;
    525     SubtitleOut_t * out;
    526     int DataLength;
    527     unsigned long long int Pts;
    528     float Duration;
    529  
    530     subtitle_printf(10, "\n");
    531 
    532     if (data == NULL)
    533     {
    534         subtitle_err("null pointer passed\n");
    535         return cERR_SUBTITLE_ERROR;
    536     }
    537211
    538212    out = (SubtitleOut_t*) data;
    539213   
    540     if (out->type == eSub_Txt)
    541     {
    542         Text = strdup((const char*) out->u.text.data);
    543     } else
    544     {
    545 /* fixme handle gfx subs from container_ass and send it to
    546  * the callback. this must be implemented also in e2/neutrino
    547  * then.
    548  */   
    549         subtitle_err("subtitle gfx currently not handled\n");
    550         return cERR_SUBTITLE_ERROR;
    551     }
    552 
    553     DataLength = out->u.text.len;
    554     Pts = out->pts;
    555     Duration = out->duration;
     214    context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
     215    if (curtrackid != out->trackId)
     216    {
     217        Flush();
     218    }
     219    context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);
     220
     221    if (Encoding == NULL)
     222    {
     223       subtitle_err("encoding unknown\n");
     224       return cERR_SUBTITLE_ERROR;
     225    }
    556226   
    557     context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);
    558 
    559     if (Encoding == NULL)
    560     {
    561        subtitle_err("encoding unknown\n");
    562        free(Text);
    563        return cERR_SUBTITLE_ERROR;
    564     }
    565    
    566     subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding,Text, DataLength);
    567 
    568     if (    !strncmp("S_TEXT/SSA",  Encoding, 10) ||
    569             !strncmp("S_SSA",       Encoding, 5))
    570         subtitle_ParseSSA(&Text);
    571    
    572     else if(!strncmp("S_TEXT/ASS",  Encoding, 10) ||
    573             !strncmp("S_AAS",       Encoding, 5))
    574         subtitle_ParseASS(&Text);
    575    
    576     else if(!strncmp("S_TEXT/SRT",  Encoding, 10) ||
    577             !strncmp("S_SRT",       Encoding, 5))
    578         subtitle_ParseSRT(&Text);
     227    subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char*) out->data, out->len);
     228
     229    if(!strncmp("S_TEXT/SUBRIP", Encoding, 13))
     230    {
     231        fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data));
     232    }
     233    else if (!strncmp("S_TEXT/ASS", Encoding, 10))
     234    {
     235        fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, ass_get_text((char *)out->data));
     236    }
    579237    else
    580238    {
     
    582240        return  cERR_SUBTITLE_ERROR;
    583241    }
    584    
    585     subtitle_printf(10, "Text:%s Duration:%f\n", Text,Duration);
    586 
    587     addSub(context, Text, Pts, Duration * 1000);
    588    
    589     free(Text);
    590     free(Encoding);
    591242
    592243    subtitle_printf(10, "<\n");
    593 
    594244    return cERR_SUBTITLE_NO_ERROR;
    595245}
    596246
    597 static int subtitle_Open(Context_t* context __attribute__((unused))) {
    598     int i;
     247static int32_t subtitle_Open(Context_t *context __attribute__((unused)))
     248{
     249    uint32_t i = 0 ;
    599250
    600251    subtitle_printf(10, "\n");
     
    608259    getMutex(__LINE__);
    609260
    610     //Reset all
    611     readPointer = 0;
    612     writePointer = 0;
    613 
    614     for (i = 0; i < PUFFERSIZE; i++) {
    615         subPuffer[i].text          = NULL;
    616         subPuffer[i].pts           = 0;
    617         subPuffer[i].milliDuration = 0;
    618     }
    619 
    620261    isSubtitleOpened = 1;
    621262
     
    623264
    624265    subtitle_printf(10, "<\n");
    625 
    626266    return cERR_SUBTITLE_NO_ERROR;
    627267}
    628268
    629 static int subtitle_Close(Context_t* context __attribute__((unused))) {
    630     int i;
     269static int32_t subtitle_Close(Context_t *context __attribute__((unused)))
     270{
     271    uint32_t i = 0 ;
    631272
    632273    subtitle_printf(10, "\n");
     
    634275    getMutex(__LINE__);
    635276
    636     //Reset all
    637     readPointer = 0;
    638     writePointer = 0;
    639 
    640     for (i = 0; i < PUFFERSIZE; i++) {
    641         if (subPuffer[i].text != NULL)
    642            free(subPuffer[i].text);
    643 
    644         subPuffer[i].text          = NULL;
    645         subPuffer[i].pts           = 0;
    646         subPuffer[i].milliDuration = 0;
    647     }
    648 
    649277    isSubtitleOpened = 0;
    650278
     
    656284}
    657285
    658 static int subtitle_Play(Context_t* context) {
    659     subtitle_printf(10, "\n");
    660 
    661     if (hasThreadStarted == 0)
    662     {
    663         pthread_attr_t attr;
    664        
    665         pthread_attr_init(&attr);
    666        
    667         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    668        
    669         if (pthread_create (&thread_sub, &attr, &SubtitleThread, (void*) context) != 0)
    670         {
    671            subtitle_err("Error creating thread\n");
    672            hasThreadStarted = 0;
    673         } else
    674         {
    675            subtitle_printf(10, "Created thread\n");
    676         }
    677     }
    678     else
    679     {
    680         subtitle_err("thread already created.\n");
    681         return cERR_SUBTITLE_ERROR;
    682     }
    683 
    684     subtitle_printf(10, "<\n");
    685 
    686     return cERR_SUBTITLE_NO_ERROR;
    687 }
    688 
    689 static int subtitle_Stop(Context_t* context __attribute__((unused))) {
    690     int wait_time = 100;
    691     int i;
    692    
    693     subtitle_printf(10, "\n");
    694 
    695                 if(hasThreadStarted != 0) {
    696             hasThreadStarted = 2;
    697             while ( (hasThreadStarted != 0) && (--wait_time) > 0 ) {
    698                 subtitle_printf(10, "Waiting for subtitle thread to terminate itself, will try another %d times\n", wait_time);
    699                 usleep(100000);
    700             }
    701     }
    702 
    703     if (wait_time == 0) {
    704         subtitle_err("Timeout waiting for thread!\n");
    705 
    706         return cERR_SUBTITLE_ERROR;
    707     }
    708    
    709     hasThreadStarted = 0;
    710 
    711     /* konfetti: thread has ended, so nobody will eat the date...
    712      * free the data...
    713      */
    714 
    715     getMutex(__LINE__);
    716 
    717     //Reset all
    718     readPointer = 0;
    719     writePointer = 0;
    720 
    721     for (i = 0; i < PUFFERSIZE; i++) {
    722         if (subPuffer[i].text != NULL)
    723            free(subPuffer[i].text);
    724 
    725         subPuffer[i].text          = NULL;
    726         subPuffer[i].pts           = 0;
    727         subPuffer[i].milliDuration = 0;
    728     }
    729 
    730     releaseMutex(__LINE__);
    731 
    732     subtitle_printf(10, "<\n");
    733 
    734     return cERR_SUBTITLE_NO_ERROR;
    735 }
    736 
    737 void subtitle_SignalConnect(void (*fkt) (long int, size_t, char *, void *))
    738 {
    739     subtitle_printf(10, "%p\n", fkt);
    740 
    741     clientFunction = fkt;
    742 }
    743 
    744 void subtitle_SignalConnectBuffer(void* data)
    745 {
    746     subtitle_printf(10, "%p\n", data);
    747 
    748     clientData = data;
    749 }
    750 
    751 static int Command(void  *_context, OutputCmd_t command, void * argument) {
     286static int Command(void  *_context, OutputCmd_t command, void *argument)
     287{
    752288    Context_t  *context = (Context_t*) _context;
    753289    int ret = cERR_SUBTITLE_NO_ERROR;
     
    755291    subtitle_printf(50, "%d\n", command);
    756292
    757     switch(command) {
    758     case OUTPUT_OPEN: {
     293    switch(command)
     294    {
     295    case OUTPUT_OPEN:
     296    {
    759297        ret = subtitle_Open(context);
    760298        break;
    761299    }
    762     case OUTPUT_CLOSE: {
     300    case OUTPUT_CLOSE:
     301    {
    763302        ret = subtitle_Close(context);
    764303        break;
    765304    }
    766     case OUTPUT_PLAY: {
    767         ret = subtitle_Play(context);
    768         break;
    769     }
    770     case OUTPUT_STOP: {
    771         ret = subtitle_Stop(context);
    772         break;
    773     }
    774     case OUTPUT_SWITCH: {
    775         subtitle_err("Subtitle Switch not implemented\n");
    776         ret = cERR_SUBTITLE_ERROR;
    777         break;
    778     }
    779     case OUTPUT_GET_SUBTITLE_OUTPUT: {
    780         SubtitleOutputDef_t* out = (SubtitleOutputDef_t*)argument;
    781         out->screen_width = screen_width;
    782         out->screen_height = screen_height;
    783         out->framebufferBlit = framebufferBlit;
    784         out->destination = destination;
    785         out->destStride = destStride;
    786         break;
    787     }
    788     case OUTPUT_SET_SUBTITLE_OUTPUT: {
    789         SubtitleOutputDef_t* out = (SubtitleOutputDef_t*)argument;
    790         screen_width = out->screen_width;
    791         screen_height = out->screen_height;
    792         framebufferBlit = out->framebufferBlit;
    793         destination = out->destination;
    794         destStride = out->destStride;
    795         break;
    796     }
    797     case OUTPUT_SUBTITLE_REGISTER_FUNCTION: {
    798         subtitle_SignalConnect(argument);
    799         break;
    800     }
    801     case OUTPUT_SUBTITLE_REGISTER_BUFFER: {
    802         subtitle_SignalConnectBuffer(argument);
    803         break;
    804     }
    805     case OUTPUT_FLUSH: {
    806         subtitle_err("Subtitle Flush not implemented\n");
    807         ret = cERR_SUBTITLE_ERROR;
    808         break;
    809     }
    810     case OUTPUT_PAUSE: {
     305    case OUTPUT_PLAY:
     306    {
     307        break;
     308    }
     309    case OUTPUT_STOP:
     310    {
     311        break;
     312    }
     313    case OUTPUT_SWITCH:
     314    {
     315        ret = Flush();
     316        break;
     317    }
     318    case OUTPUT_FLUSH:
     319    {
     320        ret = Flush();
     321        break;
     322    }
     323    case OUTPUT_CLEAR:
     324    {
     325        ret = Flush();
     326        break;
     327    }
     328    case OUTPUT_PAUSE:
     329    {
    811330        subtitle_err("Subtitle Pause not implemented\n");
    812331        ret = cERR_SUBTITLE_ERROR;
    813         break;
    814     }
    815     case OUTPUT_CONTINUE: {
     332        break;
     333    }
     334    case OUTPUT_CONTINUE:
     335    {
    816336        subtitle_err("Subtitle Continue not implemented\n");
    817337        ret = cERR_SUBTITLE_ERROR;
    818         break;
    819     }
    820 
     338        break;
     339    }
    821340    default:
    822341        subtitle_err("OutputCmd %d not supported!\n", command);
     
    826345
    827346    subtitle_printf(50, "exiting with value %d\n", ret);
    828 
    829347    return ret;
    830348}
     
    833351static char *SubtitleCapabilitis[] = { "subtitle", NULL };
    834352
    835 struct Output_s SubtitleOutput = {
     353Output_t SubtitleOutput = {
    836354    "Subtitle",
    837355    &Command,
  • titan/libeplayer3/output/writer/mipsel/writer.c

    r39877 r40322  
    6262static Writer_t * AvailableWriter[] = {
    6363    &WriterAudioAAC,
    64     &WriterAudioAACHE,
     64    &WriterAudioAACLATM,
    6565    &WriterAudioAACPLUS,
    6666    &WriterAudioAC3,
     
    7676   
    7777    &WriterVideoH264,
     78    &WriterVideoH265,
    7879    &WriterVideoH263,
    7980    &WriterVideoMPEG4,
     
    8283    &WriterVideoVC1,
    8384    &WriterVideoDIVX3,
    84     //&WriterVideoWMV,
     85    &WriterVideoVP6,
     86    &WriterVideoVP8,
     87    &WriterVideoVP9,
     88    &WriterVideoSPARK,
     89    &WriterVideoWMV,
    8590    NULL
    8691};
     
    208213}
    209214
    210 Writer_t* getDefaultFramebufferWriter()
    211 {
    212     int i;
    213 
    214     for (i = 0; AvailableWriter[i] != NULL; i++)
    215     {
    216         writer_printf(10, "%s\n", AvailableWriter[i]->caps->textEncoding);
    217         if (strcmp(AvailableWriter[i]->caps->textEncoding, "framebuffer") == 0)
    218         {
    219             writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
    220             return AvailableWriter[i];
    221         }
    222     }
    223 
    224     writer_printf(1, "%s: no writer found\n", __func__);
    225 
    226     return NULL;
    227 }
  • titan/libeplayer3/output/writer/sh4/writer.c

    r39831 r40322  
    8484    &WriterVideoFLV,
    8585    &WriterVideoVC1,
    86     &WriterFramebuffer,
    8786    NULL
    8887};
     
    152151}
    153152
    154 Writer_t* getDefaultFramebufferWriter()
    155 {
    156     int i;
    157 
    158     for (i = 0; AvailableWriter[i] != NULL; i++)
    159     {
    160         writer_printf(10, "%s\n", AvailableWriter[i]->caps->textEncoding);
    161         if (strcmp(AvailableWriter[i]->caps->textEncoding, "framebuffer") == 0)
    162         {
    163             writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
    164             return AvailableWriter[i];
    165         }
    166     }
    167 
    168     writer_printf(1, "%s: no writer found\n", __func__);
    169 
    170     return NULL;
    171 }
  • titan/libeplayer3/playback/playback.c

    r39877 r40322  
    130130            return cERR_PLAYBACK_ERROR;
    131131        }
    132         //CHECK FOR SUBTITLES
    133         if (context->container && context->container->textSrtContainer)
    134             context->container->textSrtContainer->Command(context, CONTAINER_INIT, context->playback->uri+7);
    135 
    136         if (context->container && context->container->textSsaContainer)
    137             context->container->textSsaContainer->Command(context, CONTAINER_INIT, context->playback->uri+7);
    138 
    139         if (context->container && context->container->assContainer)
    140             context->container->assContainer->Command(context, CONTAINER_INIT, NULL);
    141132    }
    142133    else if (strstr(uri, "://"))
     
    185176    }
    186177
    187     if (context->container && context->container->textSrtContainer)
    188         context->container->textSrtContainer->Command(context, CONTAINER_DEL, NULL);
    189 
    190     if (context->container && context->container->textSsaContainer)
    191         context->container->textSsaContainer->Command(context, CONTAINER_DEL, NULL);
    192 
    193178    context->manager->audio->Command(context, MANAGER_DEL, NULL);
    194179    context->manager->video->Command(context, MANAGER_DEL, NULL);
    195         context->manager->subtitle->Command(context, MANAGER_DEL, NULL);
    196     context->manager->dvbsubtitle->Command(context, MANAGER_DEL, NULL);
    197     context->manager->teletext->Command(context, MANAGER_DEL, NULL);
    198180
    199181    context->playback->isPaused     = 0;
     
    282264    {
    283265        set_pause_timeout(1);
    284                 if(context->playback->SlowMotion)
    285                         context->output->Command(context, OUTPUT_CLEAR, NULL);
    286 
     266       
    287267        context->output->Command(context, OUTPUT_PAUSE, NULL);
    288268
     
    316296
    317297        set_pause_timeout(0);
    318         if(context->playback->SlowMotion)
    319             context->output->Command(context, OUTPUT_CLEAR, NULL);
     298
    320299        context->output->Command(context, OUTPUT_CONTINUE, NULL);
    321300
     
    410389}
    411390
    412 static int PlaybackFastForward(Context_t  *context, int* speed) {
    413     int32_t ret = cERR_PLAYBACK_NO_ERROR;
    414 
    415     playback_printf(10, "speed %d\n", *speed);
    416 
    417     /* Audio only forwarding not supported */
    418     if (context->playback->isVideo && !context->playback->isHttp && !context->playback->BackWard && (!context->playback->isPaused || context->playback->isPlaying)) {
    419 
    420         if ((*speed <= 0) || (*speed > cMaxSpeed_ff))
    421         {
    422             playback_err("speed %d out of range (1 - %d) \n", *speed, cMaxSpeed_ff);
    423             return cERR_PLAYBACK_ERROR;
    424         }
    425 
    426         context->playback->isForwarding = 1;
    427         context->playback->Speed = *speed;
    428 
    429         playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed);
    430 
    431         context->output->Command(context, OUTPUT_FASTFORWARD, NULL);
    432     } else
    433     {
    434         playback_err("fast forward not possible\n");
    435         ret = cERR_PLAYBACK_ERROR;
    436     }
    437 
    438     playback_printf(10, "exiting with value %d\n", ret);
    439 
    440     return ret;
    441 }
    442 
    443 static int PlaybackFastBackward(Context_t  *context,int* speed) {
    444     int32_t ret = cERR_PLAYBACK_NO_ERROR;
    445 
    446     playback_printf(10, "speed = %d\n", *speed);
    447 
    448     /* Audio only reverse play not supported */
    449     if (context->playback->isVideo && !context->playback->isForwarding && (!context->playback->isPaused || context->playback->isPlaying)) {
    450 
    451         if ((*speed > 0) || (*speed < cMaxSpeed_fr))
    452         {
    453             playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr);
    454             return cERR_PLAYBACK_ERROR;
    455         }
    456 
    457         if (*speed == 0)
    458         {
    459             context->playback->BackWard = 0;
    460             context->playback->Speed = 0;    /* reverse end */
    461         } else
    462         {
    463             context->playback->isSeeking = 1;
    464             context->playback->Speed = *speed;
    465             context->playback->BackWard = 2^(*speed);
    466          
    467             playback_printf(1, "S %d B %f\n", context->playback->Speed, context->playback->BackWard);
    468         }
    469 
    470         context->output->Command(context, OUTPUT_AUDIOMUTE, "1");
    471         context->output->Command(context, OUTPUT_CLEAR, NULL);
    472         if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0)
    473         {
    474             playback_err("OUTPUT_REVERSE failed\n");
    475             context->playback->BackWard = 0;
    476             context->playback->Speed = 1;
    477             context->playback->isSeeking = 0;
    478             ret = cERR_PLAYBACK_ERROR;
    479         }
    480     } else
    481     {
    482         playback_err("fast backward not possible\n");
    483         ret = cERR_PLAYBACK_ERROR;
    484     }
    485 
    486     context->playback->isSeeking = 0;
    487     playback_printf(10, "exiting with value %d\n", ret);
    488 
    489     return ret;
    490 }
    491 
    492 static int32_t PlaybackSlowMotion(Context_t  *context,int* speed) {
    493     int32_t ret = cERR_PLAYBACK_NO_ERROR;
    494 
    495     playback_printf(10, "\n");
    496 
    497     //Audio only forwarding not supported
    498     if (context->playback->isVideo && !context->playback->isHttp && context->playback->isPlaying) {
    499         if(context->playback->isPaused)
    500             PlaybackContinue(context);
    501 
    502         switch(*speed) {
    503         case 2:
    504             context->playback->SlowMotion = 2;
    505             break;
    506         case 4:
    507             context->playback->SlowMotion = 4;
    508             break;
    509         case 8:
    510             context->playback->SlowMotion = 8;
    511             break;
    512         }
    513 
    514         playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion);
    515 
    516         context->output->Command(context, OUTPUT_SLOWMOTION, NULL);
    517     } else
    518     {
    519         playback_err("slowmotion not possible\n");
    520         ret = cERR_PLAYBACK_ERROR;
    521     }
    522 
    523     playback_printf(10, "exiting with value %d\n", ret);
    524 
    525     return ret;
    526 }
    527 
    528391static int32_t PlaybackSeek(Context_t  *context, int64_t *pos, uint8_t absolute)
    529392{
     
    683546    playback_printf(10, "Track: %d\n", *track);
    684547
    685         if (context && context->playback && context->playback->isPlaying ) {
    686         if (context->manager && context->manager->subtitle) {
    687             int trackid;
    688            
    689             if (context->manager->subtitle->Command(context, MANAGER_SET, track) < 0)
    690             {
    691                 playback_err("manager set track failed\n");
    692                         }
    693 /*
    694548    if (context && context->playback && context->playback->isPlaying )
    695549    {
    696         int trackid;
    697 
    698550        if (context->manager && context->manager->subtitle)
    699551        {
     
    714566                }
    715567            }
    716 
    717 */
    718 #if 0
    719                     if (*track == 0xffff) {
    720                         //CHECK FOR SUBTITLES
    721                         if (context->container && context->container->textSrtContainer)
    722                             context->container->textSrtContainer->Command(context, CONTAINER_INIT, context->playback->uri+7);
    723        
    724                         if (context->container && context->container->textSsaContainer)
    725                             context->container->textSsaContainer->Command(context, CONTAINER_INIT, context->playback->uri+7);
    726        
    727                         if (context->container && context->container->assContainer)
    728                             context->container->assContainer->Command(context, CONTAINER_INIT, NULL);
    729                     }
    730 #endif
    731             context->manager->subtitle->Command(context, MANAGER_GET, &trackid);
    732 
    733 /* konfetti: I make this hack a little bit nicer,
    734  * but its still a hack in my opinion ;)
    735  */
    736             if (context->container && context->container->assContainer)
    737                 context->container->assContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &trackid);
    738 
    739             if (trackid >= TEXTSRTOFFSET)
    740             {
    741                 if (context->container && context->container->textSrtContainer)
    742                      context->container->textSrtContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &trackid);
    743             }
    744             if (trackid >= TEXTSSAOFFSET)
    745             {
    746                  if (context->container && context->container->textSsaContainer)
    747                      context->container->textSsaContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &trackid);
    748             }
    749 
    750568        }
    751569        else
     
    760578        ret = cERR_PLAYBACK_ERROR;
    761579    }
    762 
    763     playback_printf(10, "exiting with value %d\n", ret);
    764 
    765     return ret;
    766 }
    767 
    768 static int32_t PlaybackSwitchDVBSubtitle(Context_t  *context, int* pid) {
    769     int ret = cERR_PLAYBACK_NO_ERROR;
    770 
    771     playback_printf(10, "Track: %d\n", *pid);
    772 
    773     if (context && context->manager && context->manager->dvbsubtitle ) {
    774         if (context->manager->dvbsubtitle->Command(context, *pid == 0xffff ? MANAGER_DEL : MANAGER_SET, pid) < 0) {
    775                 playback_err("dvbsub manager set track failed\n");
    776                 ret = cERR_PLAYBACK_ERROR;
    777         }
    778     } else
    779         playback_err("no dvbsubtitle\n");
    780 
    781     if (*pid == 0xffff)
    782         container_ffmpeg_update_tracks(context, context->playback->uri, 0);
    783 
    784     playback_printf(10, "exiting with value %d\n", ret);
    785 
    786     return ret;
    787 }
    788 
    789 static int32_t PlaybackSwitchTeletext(Context_t  *context, int* pid) {
    790     int ret = cERR_PLAYBACK_NO_ERROR;
    791 
    792     playback_printf(10, "Track: %d\n", *pid);
    793 
    794     if (context && context->manager && context->manager->teletext ) {
    795         if (context->manager->teletext->Command(context, *pid == 0xffff ? MANAGER_DEL : MANAGER_SET, pid)) {
    796                 playback_err("ttxsub manager set track failed\n");
    797                 ret = cERR_PLAYBACK_ERROR;
    798         }
    799     } else
    800         playback_err("no ttxsubtitle\n");
    801 
    802     if (*pid == 0xffff)
    803         container_ffmpeg_update_tracks(context, context->playback->uri, 0);
    804580
    805581    playback_printf(10, "exiting with value %d\n", ret);
     
    904680            break;
    905681        }
    906         case PLAYBACK_SWITCH_DVBSUBTITLE:
    907         {
    908             ret = PlaybackSwitchDVBSubtitle(context, (int*)argument);
    909             break;
    910         }
    911         case PLAYBACK_SWITCH_TELETEXT:
    912         {
    913             ret = PlaybackSwitchTeletext(context, (int*)argument);
    914             break;
    915         }
    916682        case PLAYBACK_INFO:
    917683        {
     
    919685            break;
    920686        }
    921             case PLAYBACK_SLOWMOTION:
    922             {
    923                 ret = PlaybackSlowMotion(context,(int*)argument);
    924                 break;
    925             }
    926             case PLAYBACK_FASTBACKWARD:
    927             {
    928                 ret = PlaybackFastBackward(context,(int*)argument);
    929                 break;
    930             }
    931             case PLAYBACK_FASTFORWARD:
    932             {
    933                 ret = PlaybackFastForward(context,(int*)argument);
    934                 break;
    935             }
    936687        case PLAYBACK_GET_FRAME_COUNT:
    937688        {
     
    939690            break;
    940691        }
    941             case PLAYBACK_FRAMEBUFFER_LOCK:
    942             {
    943                 context->playback->mayWriteToFramebuffer = 0;
    944                 ret = cERR_PLAYBACK_NO_ERROR;
    945                         break;
    946             }
    947             case PLAYBACK_FRAMEBUFFER_UNLOCK:
    948             {
    949                 context->playback->mayWriteToFramebuffer = 1;
    950                 ret = cERR_PLAYBACK_NO_ERROR;
    951                         break;
    952                 }
    953692        default:
    954         {
    955693            playback_err("PlaybackCmd %d not supported!\n", command);
    956694            ret = cERR_PLAYBACK_ERROR;
    957695            break;
    958                 }
    959696    }
    960697
     
    984721    0,          //isAudio
    985722    0,          //isSubtitle
    986     0,          //isDvbSubtitle
    987     0,          //isTeletext
    988     1,                  //mayWriteToFramebuffer
    989723    0,          //abortRequested
    990724    &Command,   //Command
  • titan/titan/player.h

    r39878 r40322  
    2626extern ContainerHandler_t ContainerHandler;
    2727extern ManagerHandler_t ManagerHandler;
     28
    2829#ifdef BETA
    2930#include <stdlib.h>
     
    5859extern void insert_pcm_as_lpcm_set(int32_t val);
    5960extern void progressive_download_set(int32_t val);
     61extern void progressive_playback_set(int32_t val);
    6062
    6163static void SetBuffering()
     
    12041206                        player->container->Command(player, CONTAINER_ADD, "mp3");
    12051207//#endif
     1208
    12061209                if(player && player->container && player->container->selectedContainer)
    12071210                {
     
    12101213                        int32_t seektime = getconfigint("playerbufferseektime", NULL);
    12111214#else
    1212                         int size = getconfigint("playerbuffersize", NULL);
    1213                         int seektime = getconfigint("playerbufferseektime", NULL);
     1215                        int32_t* size = (int32_t*)getconfigint("playerbuffersize", NULL);
     1216                        int32_t* seektime = (int32_t*)getconfigint("playerbufferseektime", NULL);
     1217
     1218                        progressive_playback_set(1);
     1219//                      container_set_ffmpeg_buf_size(size);
    12141220#endif
    12151221
     
    12231229            prctl(PR_SET_PDEATHSIG, SIGKILL);
    12241230
    1225 //          SetBuffering();
     1231            SetBuffering();
    12261232#endif
    12271233                //Registrating output devices
Note: See TracChangeset for help on using the changeset viewer.