Changeset 44958


Ignore:
Timestamp:
12/08/20 01:35:11 (3 years ago)
Author:
obi
Message:

[libeplayer3] update to v68

Location:
titan/libeplayer3
Files:
7 added
48 edited

Legend:

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

    r40363 r44958  
    11AUTOMAKE_OPTIONS = subdir-objects
    2 AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
     2AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DHAVE_FLV2MPEG4_CONVERTER
     3#AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
    34
    45CXXFLAGS = -Wall
     
    67AM_CPPFLAGS = \
    78        -Iinclude \
    8         -Iexternal
     9        -Iexternal \
     10        -Iexternal/flv2mpeg4   
    911
    1012lib_LTLIBRARIES = libeplayer3.la
     
    2022output/writer/common/pes.c \
    2123output/writer/common/misc.c \
     24output/writer/common/writer.c \
     25output/linuxdvb_buffering.c \
     26output/graphic_subtitle.c \
    2227output/linuxdvb_mipsel.c \
    2328output/writer/mipsel/writer.c \
    2429output/writer/mipsel/aac.c \
    2530output/writer/mipsel/ac3.c \
     31output/writer/mipsel/bcma.c \
    2632output/writer/mipsel/mp3.c \
    2733output/writer/mipsel/pcm.c \
     
    2935output/writer/mipsel/dts.c \
    3036output/writer/mipsel/amr.c \
    31 output/writer/mipsel/wma.c \
    3237output/writer/mipsel/h265.c \
    3338output/writer/mipsel/h264.c \
    34 output/writer/mipsel/h263.c \
     39output/writer/mipsel/mjpeg.c \
    3540output/writer/mipsel/mpeg2.c \
    3641output/writer/mipsel/mpeg4.c \
     
    4247external/ffmpeg/src/bitstream.c \
    4348external/ffmpeg/src/latmenc.c \
    44 external/ffmpeg/src/mpeg4audio.c
    45 
     49external/ffmpeg/src/mpeg4audio.c \
     50external/ffmpeg/src/xiph.c \
     51external/flv2mpeg4/src/m4vencode.c \
     52external/flv2mpeg4/src/flvdecoder.c \
     53external/flv2mpeg4/src/dcprediction.c \
     54external/flv2mpeg4/src/flv2mpeg4.c \
     55external/plugins/src/png.c
    4656
    4757#libeplayer3_la_LIBADD = -lpthread -lavformat -lavcodec -lavutil -lswresample -lz -lass -lm -lpng
    48 libeplayer3_la_LIBADD = -lpthread -lavformat -lavcodec -lavutil -lswresample
    49 
     58libeplayer3_la_LIBADD = -lswscale -ldl -lpthread -lavformat -lavcodec -lavutil -lswresample
    5059
    5160bin_PROGRAMS = eplayer3
    5261eplayer3_SOURCES = main/exteplayer.c
    5362#eplayer3_LDADD = -leplayer3 -lpthread
    54 eplayer3_LDADD = -leplayer3 -lpthread -lass -lm -lpng
     63#eplayer3_LDADD = -leplayer3 -lpthread -lass -lm -lpng
     64eplayer3_LDADD = -leplayer3 -lswscale -ldl -lpthread -lavformat -lavcodec -lavutil -lswresample
    5565eplayer3_DEPENDENCIES = libeplayer3.la
    5666
  • titan/libeplayer3/container/buff_ffmpeg.c

    r43796 r44958  
    102102        }
    103103       
    104         //printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts);
     104        //printf("ret[%d] playPts[%"PRId64"] currPts[%"PRId64"] maxInjectedPts[%"PRId64"]\n", ret, playPts, currPts, maxInjectedPts);
    105105       
    106106        /* On some STBs PTS readed from decoder is invalid after seek or at start
     
    126126    int32_t len = 0;
    127127//obi
    128 //    if(0 == PlaybackDieNow(0))
    129 //    {
     128  if(0 == PlaybackDieNow(0))
     129  {
    130130//obi (end)
    131131        len = ffmpeg_real_read_org(opaque, buf, buf_size);
    132132//obi
    133 //        while(len < buf_size && g_context && 0 == PlaybackDieNow(0))
    134         while(len < buf_size && g_context)
     133      while(len < buf_size && g_context && 0 == PlaybackDieNow(0))
     134//        while(len < buf_size && g_context)
    135135//obi (end)
    136136        {
     
    159159        }
    160160//obi
    161 //    }
     161  }
    162162//obi (end)
    163163    //printf("len [%d] finishTimeout[%d]\n", len, finishTimeout);
     
    194194}
    195195
    196 void releasefillerMutex(const char *filename, const char *function, int line)
     196void releasefillerMutex(const char *filename, const const char *function, int line)
    197197{
    198198    pthread_mutex_unlock(&fillermutex);
     
    278278         {
    279279//obi
    280 //            break;
     280           break;
    281281//obi (end)
    282282         }
     
    532532    int32_t len = 0;
    533533    int32_t count = 2000;
     534
    534535//obi
    535 //    while(sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0))
    536     while(sumlen < buf_size && (--count) > 0)
     536    while(sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0))
     537//    while(sumlen < buf_size && (--count) > 0)
    537538//obi (end)
    538539    {
     
    602603    {
    603604        /* can do the seek inside the buffer */
    604         ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
     605        ffmpeg_printf(20, "buffer-seek diff=%"PRId64"\n", diff);
    605606        if(diff > (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read)
    606607        {
     
    615616    {
    616617        /* can do the seek inside the buffer */
    617         ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
     618        ffmpeg_printf(20, "buffer-seek diff=%"PRId64"\n", diff);
    618619        int32_t tmpdiff = diff * -1;
    619620        if(tmpdiff > ffmpeg_buf_read - ffmpeg_buf)
     
    629630    {
    630631        releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
    631         ffmpeg_printf(20, "real-seek diff=%lld\n", diff);
     632        ffmpeg_printf(20, "real-seek diff=%"PRId64"\n", diff);
    632633
    633634        ffmpeg_do_seek_ret = 0;
  • titan/libeplayer3/container/container.c

    r40322 r44958  
    2424
    2525#include "common.h"
    26 
    27 #ifdef SAM_WITH_DEBUG
    28 #define CONTAINER_DEBUG
    29 #else
    30 #define CONTAINER_SILENT
    31 #endif
    32 
    33 #ifdef CONTAINER_DEBUG
    34 
    35 static short debug_level = 0;
    36 
    37 #define container_printf(level, x...) do { \
    38 if (debug_level >= level) printf(x); } while (0)
    39 #else
    40 #define container_printf(level, x...)
    41 #endif
    42 
    43 #ifndef CONTAINER_SILENT
    44 #define container_err(x...) do { printf(x); } while (0)
    45 #else
    46 #define container_err(x...)
    47 #endif
     26#include "debug.h"
    4827
    4928static Container_t * AvailableContainer[] = {
  • titan/libeplayer3/container/container_ffmpeg.c

    r43807 r44958  
    2626/* Includes                      */
    2727/* ***************************** */
     28#include "debug.h"
    2829
    2930#include <stdio.h>
     
    5758#include "pcm.h"
    5859#include "ffmpeg_metadata.h"
     60
    5961/* ***************************** */
    6062/* Makros/Constants              */
    6163/* ***************************** */
    62 #if (LIBAVFORMAT_VERSION_MAJOR > 57)
    63 #define TS_BYTES_SEEKING 0
    64 #else
    65 #define TS_BYTES_SEEKING 1
    66 #endif
     64
    6765
    6866/* Some STB with old kernels have problem with default
     
    7169 * std library.
    7270 */
    73 #define SAM_CUSTOM_IO
    74 //obi
    75 #define SAM_WITH_DEBUG
    76 //obi (end)
    77 #ifdef SAM_WITH_DEBUG
    78 #define FFMPEG_DEBUG
    79 #else
    80 #define FFMPEG_SILENT
    81 #endif
    82 
    83 #ifdef FFMPEG_DEBUG
    84 
    85 //obi
    86 static short debug_level = 10;
    87 //obi (end)
    88 
    89 #define ffmpeg_printf(level, fmt, x...) do { \
    90 if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    91 #else
    92 #define ffmpeg_printf(level, fmt, x...)
    93 #endif
    94 
    95 #ifndef FFMPEG_SILENT
    96 #define ffmpeg_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    97 #else
    98 #define ffmpeg_err(fmt, x...)
    99 #endif
     71#define USE_CUSTOM_IO
    10072
    10173/* Error Constants */
     
    12395
    12496static pthread_mutex_t mutex;
     97static pthread_mutex_t seek_mutex;
    12598
    12699static pthread_t PlayThread;
     
    129102static AVFormatContext *avContextTab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL};
    130103static int32_t use_custom_io[IPTV_AV_CONTEXT_MAX_NUM] = {0, 0};
    131 static AVDictionary *avio_opts = NULL;
     104static AVDictionary *g_avio_opts = NULL;
    132105
    133106static uint8_t isContainerRunning = 0;
     
    137110static int32_t restart_audio_resampling = 0;
    138111
    139 static off_t seek_target_bytes = 0;
    140 static int32_t do_seek_target_bytes = 0;
    141 
    142 static int64_t seek_target_seconds = 0;
    143 static int8_t do_seek_target_seconds = 0;
    144 static int64_t prev_seek_time_sec = -1;
    145 
    146 static int32_t seek_target_flag = 0;
     112static int64_t g_seek_target_seconds = 0;
     113static bool g_do_seek_target_seconds = false;
     114static void *g_stamp;
    147115
    148116/* ***************************** */
     
    151119static int32_t container_ffmpeg_seek_bytes(off_t pos);
    152120static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute);
    153 static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec);
    154121static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length);
    155122static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts);
     123static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts);
     124void LinuxDvbBuffSetStamp(void *stamp);
    156125
    157126/* Progressive playback means that we play local file
     
    164133    progressive_playback = val;
    165134}
     135
     136static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line)
     137{
     138    ffmpeg_printf(100, "::%d requesting mutex\n", line);
     139    static bool mutexInitialized = false;
     140
     141    if (!mutexInitialized)
     142    {
     143        pthread_mutex_init(&mutex, NULL);
     144        mutexInitialized = true;
     145    }
     146
     147    pthread_mutex_lock(&mutex);
     148
     149    ffmpeg_printf(100, "::%d received mutex\n", line);
     150}
     151
     152static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line)
     153{
     154    pthread_mutex_unlock(&mutex);
     155
     156    ffmpeg_printf(100, "::%d released mutex\n", line);
     157}
     158
     159static void getSeekMutex()
     160{
     161    static bool mutexInitialized = false;
     162    /* This is not perfect solution because
     163     * there could be race conditions and theoretically pthread_mutex_init
     164     * could be called twice, but anyway
     165     */
     166    if (!mutexInitialized)
     167    {
     168        pthread_mutex_init(&seek_mutex, NULL);
     169        mutexInitialized = true;
     170    }
     171
     172    pthread_mutex_lock(&seek_mutex);
     173}
     174
     175static void releaseSeekMutex()
     176{
     177    pthread_mutex_unlock(&seek_mutex);
     178}
     179
     180typedef int32_t (* Write_FN) (void  *, void *);
     181
     182static int32_t Write(Write_FN WriteFun, void *context, void *privateData, int64_t pts)
     183{
     184    /* Because Write is blocking we will release mutex which protect
     185     * avformat structures, during write time
     186     */
     187    int32_t ret = 0;
     188    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
     189    ret = WriteFun(context, privateData);
     190    getMutex(__FILE__, __FUNCTION__,__LINE__);
     191    return ret;
     192}
     193
    166194
    167195#include "buff_ffmpeg.c"
     
    193221static int32_t eac3_software_decode = 0;
    194222static int32_t dts_software_decode = 0;
     223static int32_t amr_software_decode = 1;
     224static int32_t vorbis_software_decode = 1;
     225static int32_t opus_software_decode = 1;
     226
    195227static int32_t pcm_resampling = 1;
    196228static int32_t stereo_software_decoder = 0;
     
    421453//obi (end)
    422454
    423 static void ffmpeg_silen_callback(void * avcl, int level, const char * fmt, va_list vl)
     455static void ffmpeg_silen_callback(void *avcl, int level, const char *fmt, va_list vl)
    424456{
    425457    return;
    426458}
    427459
    428 static int32_t mutexInitialized = 0;
    429 
    430460void sel_program_id_set(const int32_t val)
    431461{
     
    463493}
    464494
     495void amr_software_decoder_set(const int32_t val)
     496{
     497    amr_software_decode = val;
     498}
     499
     500void vorbis_software_decoder_set(const int32_t val)
     501{
     502    vorbis_software_decode = val;
     503}
     504
     505void opus_software_decoder_set(const int32_t val)
     506{
     507    opus_software_decode = val;
     508}
     509
    465510void stereo_software_decoder_set(const int32_t val)
    466511{
     
    495540int32_t ffmpeg_av_dict_set(const char *key, const char *value, int32_t flags)
    496541{
    497     return av_dict_set(&avio_opts, key, value, flags);
    498 }
    499 
    500 static void initMutex(void)
    501 {
    502     pthread_mutex_init(&mutex, NULL);
    503     mutexInitialized = 1;
    504 }
    505 
    506 static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line)
    507 {
    508     ffmpeg_printf(100, "::%d requesting mutex\n", line);
    509 
    510     if (!mutexInitialized)
    511     {
    512         initMutex();
    513     }
    514 
    515     pthread_mutex_lock(&mutex);
    516 
    517     ffmpeg_printf(100, "::%d received mutex\n", line);
    518 }
    519 
    520 static void releaseMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line)
    521 {
    522     pthread_mutex_unlock(&mutex);
    523 
    524     ffmpeg_printf(100, "::%d released mutex\n", line);
     542    return av_dict_set(&g_avio_opts, key, value, flags);
    525543}
    526544
    527545static char* Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile, int32_t *version)
    528546{
    529     ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id);
     547    ffmpeg_printf(10, "Codec ID: %d (%.8x)\n", codec_id, codec_id);
    530548    switch (codec_id)
    531549    {
     
    533551        return "V_MPEG1";
    534552    case AV_CODEC_ID_MPEG2VIDEO:
    535         return "V_MPEG1";
     553        return "V_MPEG2";
     554    case AV_CODEC_ID_MJPEG:
     555        return "V_MJPEG";
    536556    case AV_CODEC_ID_H263:
    537557    case AV_CODEC_ID_H263P:
     
    552572    case AV_CODEC_ID_RV10:
    553573    case AV_CODEC_ID_RV20:
    554         return "V_RMV";
     574        return "V_RV20";
     575    case AV_CODEC_ID_RV30:
     576        return "V_RV30";
     577    case AV_CODEC_ID_RV40:
     578        return "V_RV40";
     579#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 21, 100)
     580    case AV_CODEC_ID_AVS2:
     581        return "V_AVS2";
     582#endif
    555583    case AV_CODEC_ID_MPEG4:
    556584        return "V_MPEG4";
     
    561589    case AV_CODEC_ID_MSMPEG4V2:
    562590    case AV_CODEC_ID_MSMPEG4V3:
    563         return "V_DIVX3";
     591        return "V_MPEG4"; //"V_DIVX3";
    564592    case AV_CODEC_ID_WMV1:
    565593        *version = 1;
     
    590618        return (mp3_software_decode) ? "A_IPCM" : "A_MP3";
    591619    case AV_CODEC_ID_AAC:
    592         if (extradata_size >= 2)
    593         {
     620        if (extradata_size >= 2) {
    594621            MPEG4AudioConfig m4ac;
    595622            int off = avpriv_mpeg4audio_get_config(&m4ac, extradata, extradata_size * 8, 1);
    596623            ffmpeg_printf(1,"aac [%d] off[%d]\n", m4ac.object_type, off);
    597             if (off < 0 || 2 != m4ac.object_type)
    598             {
     624            if (off < 0) {
    599625                return "A_IPCM";
    600626            }
    601         }
    602         return (aac_software_decode) ? "A_IPCM" : "A_AAC"; 
     627            else if (0 == m4ac.chan_config && STB_HISILICON != GetSTBType()) {
     628                // according to https://wiki.multimedia.cx/index.php/ADTS
     629                // "MPEG-4 Channel Configuration  - in the case of 0, the channel configuration is sent via an inband PCE"     
     630                // we already have AAC_LATM formatter which will include PCE
     631                return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM";
     632            }
     633        }
     634        return (aac_software_decode) ? "A_IPCM" : "A_AAC";
    603635    case AV_CODEC_ID_AAC_LATM:
    604636        return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM";
     
    610642        return (dts_software_decode) ? "A_IPCM" : "A_DTS";
    611643    case AV_CODEC_ID_WMAV1:
     644        return "A_IPCM";
    612645    case AV_CODEC_ID_WMAV2:
    613646            return (wma_software_decode) ? "A_IPCM" : "A_WMA";
     
    621654        return "A_IPCM";
    622655    case AV_CODEC_ID_RA_288:
    623         return "A_IPCM";
    624     case AV_CODEC_ID_VORBIS:
    625656        return "A_IPCM";
    626657    case AV_CODEC_ID_FLAC:
     
    642673        return pcm_resampling ? "A_IPCM" : "A_PCM";
    643674    case AV_CODEC_ID_AMR_NB:
    644         return "A_IPCM";//return "A_AMR";
     675    case AV_CODEC_ID_AMR_WB:
     676        return amr_software_decode ? "A_IPCM" : "A_AMR";
     677    case AV_CODEC_ID_VORBIS:
     678        return vorbis_software_decode ? "A_IPCM" : "A_VORBIS";
     679    case AV_CODEC_ID_OPUS :
     680        return opus_software_decode ? "A_IPCM" : "A_OPUS";
    645681
    646682/* In exteplayer3 embedded text subtitle simple printed
     
    656692        return "S_TEXT/ASS"; /* Hellmaster1024: seems to be ASS instead of SSA */
    657693    case AV_CODEC_ID_DVD_SUBTITLE:
    658     case AV_CODEC_ID_DVB_SUBTITLE:
    659     case AV_CODEC_ID_XSUB:
    660694    case AV_CODEC_ID_MOV_TEXT:
    661     case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
    662695    case AV_CODEC_ID_DVB_TELETEXT:
    663696//    case CODEC_ID_DVB_TELETEXT:
     
    669702    case AV_CODEC_ID_SUBRIP:
    670703        return "S_TEXT/SUBRIP";
     704    case AV_CODEC_ID_WEBVTT:
     705        return "S_TEXT/WEBVTT";
     706    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
     707        return "S_GRAPHIC/PGS";
     708    case AV_CODEC_ID_DVB_SUBTITLE:
     709        return "S_GRAPHIC/DVB";
     710    case AV_CODEC_ID_XSUB:
     711        return "S_GRAPHIC/XSUB";
    671712    default:
    672         ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
     713        ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id);
    673714        // Default to injected-pcm for unhandled audio types.
    674715        if (media_type == AVMEDIA_TYPE_AUDIO)
     
    676717            return "A_IPCM";
    677718        }
    678         ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
     719        ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id);
    679720    }
    680721    return NULL;
     722}
     723
     724static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts)
     725{
     726    if (time_base.den > 0)
     727    {
     728        pts = av_rescale(pts, (int64_t)time_base.num * 90000, time_base.den);
     729    }
     730   
     731    if (start_time != AV_NOPTS_VALUE)
     732    {
     733        pts -= 90000 * start_time / AV_TIME_BASE;
     734    }
     735
     736    if (pts & 0x8000000000000000ull)
     737    {
     738        pts = INVALID_PTS_VALUE;
     739    }
     740    else
     741    {
     742        pts &= 0x01FFFFFFFFull; // PES header can handle only 33 bit PTS
     743    }
     744
     745    return pts;
    681746}
    682747
     
    688753        return INVALID_PTS_VALUE;
    689754    }
    690     else if (stream->time_base.den > 0)
    691     {
    692         pts = av_rescale(pts, (int64_t)stream->time_base.num * 90000, stream->time_base.den);
    693     }
    694    
    695     if (avContextTab[avContextIdx]->start_time != AV_NOPTS_VALUE)
    696     {
    697         pts -= 90000 * avContextTab[avContextIdx]->start_time / AV_TIME_BASE;
    698     }
    699 
    700     if (pts & 0x8000000000000000ull)
    701     {
    702         pts = INVALID_PTS_VALUE;
    703     }
    704 
    705     return pts;
     755   
     756    return doCalcPts(avContextTab[avContextIdx]->start_time, stream->time_base, pts);
    706757}
    707758
     
    763814    int64_t lastAudioDts = -1;
    764815   
     816    int64_t multiContextLastPts[IPTV_AV_CONTEXT_MAX_NUM] = {INVALID_PTS_VALUE, INVALID_PTS_VALUE};
     817   
    765818    int64_t showtime = 0;
    766819    int64_t bofcount = 0;
     
    777830    uint32_t cAVIdx = 0;
    778831
     832    // for seek
     833    int64_t seek_target_seconds = 0;
     834    bool do_seek_target_seconds = false;
     835
     836    int64_t seek_target_bytes = 0;
     837    bool do_seek_target_bytes = false;
     838    int64_t prev_seek_time_sec = -1;
     839    void *stamp;
     840
    779841#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    780     Mpeg4P2Context mpeg4p2_context;
    781     memset(&mpeg4p2_context, 0, sizeof(Mpeg4P2Context));
    782     AVBitStreamFilterContext *mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
     842#ifdef __sh__
     843    Mpeg4P2Context *mpeg4p2_context = NULL;
     844#else
     845    Mpeg4P2Context *mpeg4p2_context = mpeg4p2_context_open();
     846#endif
    783847#endif
    784848#ifdef HAVE_FLV2MPEG4_CONVERTER
     
    789853    while ( context->playback->isCreationPhase )
    790854    {
    791         ffmpeg_err("Thread waiting for end of init phase...\n");
     855        ffmpeg_printf(10, "Thread waiting for end of init phase...\n");
    792856        usleep(1000);
    793857    }
    794858    ffmpeg_printf(10, "Running!\n");
     859
     860    uint32_t bufferSize = 0;
     861    context->output->Command(context, OUTPUT_GET_BUFFER_SIZE, &bufferSize);
     862    ffmpeg_printf(10, "bufferSize [%u]\n", bufferSize);
    795863
    796864    int8_t isWaitingForFinish = 0;
    797865    while ( context && context->playback && context->playback->isPlaying )
    798866    {
    799         //IF MOVIE IS PAUSED, WAIT
    800         if (context->playback->isPaused)
     867        /* When user press PAUSE we call pause on AUDIO and VIDEO decoders,
     868         * we will not wait here because we can still fill
     869         * DVB drivers buffers at PAUSE time
     870         *
     871         */
     872#ifdef __sh__
     873        /* ST DVB drivers skip data if they are written during pause
     874         * so, we must wait here if there is not buffering queue
     875         */
     876        if (0 == bufferSize && context->playback->isPaused)
    801877        {
    802878            ffmpeg_printf(20, "paused\n");
     
    805881            continue;
    806882        }
     883#endif
    807884
    808885        if (context->playback->isSeeking)
     
    826903        }
    827904
     905        getSeekMutex();
     906        if (g_do_seek_target_seconds)
     907        {
     908            do_seek_target_seconds = g_do_seek_target_seconds;
     909            seek_target_seconds = g_seek_target_seconds;
     910            stamp = g_stamp;
     911            g_do_seek_target_seconds = false;
     912        }
     913        releaseSeekMutex();
     914
    828915        if (do_seek_target_seconds || do_seek_target_bytes)
    829916        {
     
    831918            if (do_seek_target_seconds)
    832919            {
    833                 ffmpeg_printf(10, "seek_target_seconds[%lld]\n", seek_target_seconds);
     920                ffmpeg_printf(10, "seek_target_seconds[%"PRId64"]\n", seek_target_seconds);
    834921                uint32_t i = 0;
    835922                for(; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
    836923                {
     924                    multiContextLastPts[i] = INVALID_PTS_VALUE;
    837925                    if(NULL != avContextTab[i])
    838926                    {
     
    844932                        {
    845933                            seek_target_seconds += avContextTab[i]->start_time;
    846                             printf("SEEK SECONDS [%lld]\n", seek_target_seconds);
    847934                        }
    848935                        //av_seek_frame(avContextTab[i], -1, seek_target_seconds, 0);
     
    855942                }
    856943                reset_finish_timeout();
     944                /*
     945                if (bufferSize > 0)
     946                {
     947                    context->output->Command(context, OUTPUT_CLEAR, NULL);
     948                }
     949                */
    857950            }
    858951            else
     
    860953                container_ffmpeg_seek_bytes(seek_target_bytes);
    861954            }
    862             do_seek_target_seconds = 0;
    863             do_seek_target_bytes = 0;
     955            do_seek_target_seconds = false;
     956            do_seek_target_bytes = false;
    864957           
    865958            restart_audio_resampling = 1;
     
    867960            currentAudioPts = -1;
    868961            latestPts = 0;
    869             seek_target_flag = 0;
    870962
    871963            // flush streams
     
    886978            }
    887979#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    888             mpeg4p2_context_reset(&mpeg4p2_context);
    889             if (NULL != mpeg4p2_bsf_context)
    890             {
    891                 av_bitstream_filter_close(mpeg4p2_bsf_context);
    892                 mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
    893             }
     980            mpeg4p2_context_reset(mpeg4p2_context);
    894981#endif
    895982#ifdef HAVE_FLV2MPEG4_CONVERTER
     
    903990            if(NULL != avContextTab[1])
    904991            {
    905                 cAVIdx = currentVideoPts <= currentAudioPts ? 0 : 1;
    906                 if (1 == cAVIdx && prev_seek_time_sec >= 0 )
    907                 {
    908                     avformat_seek_file(avContextTab[1], -1, (currentVideoPts / 90000) * AV_TIME_BASE - AV_TIME_BASE, (currentVideoPts / 90000) * AV_TIME_BASE, (currentVideoPts / 90000) * AV_TIME_BASE + AV_TIME_BASE, 0);
    909                     prev_seek_time_sec = -1;
    910                     wrapped_avcodec_flush_buffers(1);
     992                if (prev_seek_time_sec >= 0)
     993                {
     994                    if (multiContextLastPts[0] != INVALID_PTS_VALUE) {
     995                        int64_t target = av_rescale(multiContextLastPts[0], AV_TIME_BASE, 90000);
     996                        avformat_seek_file(avContextTab[1], -1, INT64_MIN, target, INT64_MAX, 0);
     997                        prev_seek_time_sec = -1;
     998                        wrapped_avcodec_flush_buffers(1);
     999                        cAVIdx = 1;
     1000                    } else {
     1001                        cAVIdx = 0;
     1002                    }
     1003                } else {
     1004                    if (multiContextLastPts[0] != INVALID_PTS_VALUE && multiContextLastPts[1] != INVALID_PTS_VALUE) {
     1005                        cAVIdx = multiContextLastPts[0] < multiContextLastPts[1] ? 0 : 1;
     1006                    } else {
     1007                        cAVIdx = !cAVIdx;
     1008                    }
    9111009                }
    9121010            }
     
    9161014            }
    9171015        }
    918        
     1016
     1017        if (bufferSize > 0)
     1018        {
     1019            LinuxDvbBuffSetStamp(stamp);
     1020        }
    9191021        if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0 )
    9201022        {
     
    9271029            int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id;
    9281030           
     1031            multiContextLastPts[cAVIdx] = calcPts(cAVIdx, avContextTab[cAVIdx]->streams[packet.stream_index], packet.pts);
     1032            ffmpeg_printf(200, "Ctx %d PTS: %"PRId64" PTS[1] %"PRId64"\n", cAVIdx, multiContextLastPts[cAVIdx], multiContextLastPts[1]);
     1033           
    9291034            reset_finish_timeout();
    930 
    931             if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0)
    932             {
    933                 ffmpeg_err("error getting video track\n");
     1035            if(avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL)
     1036            {
     1037                if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0)
     1038                {
     1039                    ffmpeg_err("error getting video track\n");
     1040                }
     1041               
     1042                if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0)
     1043                {
     1044                    ffmpeg_err("error getting audio track\n");
     1045                }
     1046               
     1047                if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0)
     1048                {
     1049                    ffmpeg_err("error getting subtitle track\n");
     1050                }
     1051            }
     1052            else
     1053            {
     1054                ffmpeg_printf(1, "SKIP DISCARDED PACKET packed_size[%d] stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid);
    9341055            }
    9351056           
    936             if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0)
    937             {
    938                 ffmpeg_err("error getting audio track\n");
    939             }
    940            
    941             if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0)
    942             {
    943                 ffmpeg_err("error getting subtitle track\n");
    944             }
    945 
    9461057            ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid);
    9471058
     
    9501061#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    9511062                AVCodecContext *codec_context = videoTrack->avCodecCtx;
    952                 if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context)
    953                 {
    954                     // should never happen, if it does print error and exit immediately, so we can easily spot it
    955                     if (filter_packet(mpeg4p2_bsf_context, codec_context, &packet) < 0)
    956                     {
    957                         ffmpeg_err("cannot filter mpegp2 packet\n");
    958                         exit(1);
    959                     }
    960                     if (mpeg4p2_write_packet(context, &mpeg4p2_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet) < 0)
    961                     {
    962                         ffmpeg_err("cannot write mpeg4p2 packet\n");
    963                         exit(1);
    964                     }
     1063                if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_context)
     1064                {
     1065                    mpeg4p2_write_packet(context, mpeg4p2_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet);
    9651066                    update_max_injected_pts(latestPts);
    9661067                }
     
    9771078#endif
    9781079                {
    979                     uint8_t skipPacket = 0;
     1080                    bool skipPacket = false;
    9801081                    currentVideoPts = videoTrack->pts = pts = calcPts(cAVIdx, videoTrack->stream, packet.pts);
    9811082                    videoTrack->dts = dts = calcPts(cAVIdx, videoTrack->stream, packet.dts);
     
    9991100                                // skip already injected VIDEO packet
    10001101                                ffmpeg_printf(200, "skip already injected VIDEO packet\n");
    1001                                 skipPacket = 1;
     1102                                skipPacket = true;
    10021103                            }
    10031104                        }
     
    10061107                            // skip VIDEO packet with unknown DTS
    10071108                            ffmpeg_printf(200, "skip VIDEO packet with unknown DTS\n");
    1008                             skipPacket = 1;
     1109                            skipPacket = true;
    10091110                        }
    10101111                    }
     
    10171118                    }
    10181119                   
    1019                     ffmpeg_printf(200, "VideoTrack index = %d %lld\n",pid, currentVideoPts);
     1120                    ffmpeg_printf(200, "VideoTrack index = %d %"PRId64"\n",pid, currentVideoPts);
    10201121
    10211122                    avOut.data       = packet.data;
     
    10361137                    }
    10371138
    1038                     if (context->output->video->Write(context, &avOut) < 0)
     1139                    if (Write(context->output->video->Write, context, &avOut, pts) < 0)
    10391140                    {
    10401141                        ffmpeg_err("writing data to video device failed\n");
     
    10891190                pcmExtradata.sample_rate           = get_codecpar(audioTrack->stream)->sample_rate;
    10901191                pcmExtradata.bit_rate              = get_codecpar(audioTrack->stream)->bit_rate;
    1091                 pcmExtradata.ffmpeg_codec_id       = get_codecpar(audioTrack->stream)->codec_id;
     1192                pcmExtradata.block_align           = get_codecpar(audioTrack->stream)->block_align;
     1193                pcmExtradata.frame_size            = get_codecpar(audioTrack->stream)->frame_size;
     1194
     1195                pcmExtradata.codec_id              = get_codecpar(audioTrack->stream)->codec_id;
    10921196                pcmExtradata.bResampling           = restart_audio_resampling;
    10931197               
     
    11121216                    avOut.type       = "audio";
    11131217
    1114                     if (context->output->audio->Write(context, &avOut) < 0)
     1218                    if (Write(context->output->audio->Write, context, &avOut, pts) < 0)
    11151219                    {
    11161220                        ffmpeg_err("(raw pcm) writing data to audio device failed\n");
     
    12201324                                out_sample_rate = *rate ? *rate : 44100;
    12211325                            }
    1222                            
     1326
    12231327                            swr = swr_alloc();
    12241328                            out_channels = c->channels;
    1225                            
     1329
    12261330                            if (c->channel_layout == 0)
    12271331                            {
     
    12711375                            continue;
    12721376                        }
    1273                         int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame),
     1377                        int64_t next_in_pts = av_rescale(wrapped_frame_get_best_effort_timestamp(decoded_frame),
    12741378                                         ((AVStream*) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate,
    12751379                                         ((AVStream*) audioTrack->stream)->time_base.den);
     
    12881392                        // The data described by the sample format is always in native-endian order
    12891393#ifdef WORDS_BIGENDIAN
    1290                         pcmExtradata.ffmpeg_codec_id       = AV_CODEC_ID_PCM_S16BE;
     1394                        pcmExtradata.codec_id       = AV_CODEC_ID_PCM_S16BE;
    12911395#else
    1292                         pcmExtradata.ffmpeg_codec_id       = AV_CODEC_ID_PCM_S16LE;
     1396                        pcmExtradata.codec_id       = AV_CODEC_ID_PCM_S16LE;
    12931397#endif
    12941398
     
    13071411                        avOut.type       = "audio";
    13081412
    1309                         if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
     1413                        if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0)
    13101414                        {
    13111415                            ffmpeg_err("writing data to audio device failed\n");
     
    13171421                {
    13181422                    ffmpeg_printf(200, "write audio aac\n");
    1319                     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]);
     1423                    ffmpeg_printf(200, "> %hhx %hhx %hhx %hhx %x %hhx %hhx\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]);
    13201424
    13211425                    avOut.data       = packet.data;
     
    13301434                    avOut.type       = "audio";
    13311435
    1332                     if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
     1436                    if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0)
    13331437                    {
    13341438                        ffmpeg_err("(aac) writing data to audio device failed\n");
     1439                    }
     1440                }
     1441                else if (pcmExtradata.codec_id == AV_CODEC_ID_VORBIS || pcmExtradata.codec_id == AV_CODEC_ID_OPUS ||
     1442                         pcmExtradata.codec_id == AV_CODEC_ID_WMAV1 || pcmExtradata.codec_id == AV_CODEC_ID_WMAV2 ||
     1443                         pcmExtradata.codec_id == AV_CODEC_ID_WMAPRO || pcmExtradata.codec_id == AV_CODEC_ID_WMALOSSLESS) {
     1444                    avOut.data       = packet.data;
     1445                    avOut.len        = packet.size;
     1446                    avOut.pts        = pts;
     1447                    avOut.extradata  = (uint8_t *) &pcmExtradata;
     1448                    avOut.extralen   = sizeof(pcmExtradata);
     1449                    avOut.frameRate  = 0;
     1450                    avOut.timeScale  = 0;
     1451                    avOut.width      = 0;
     1452                    avOut.height     = 0;
     1453                    avOut.type       = "audio";
     1454
     1455                    pcmExtradata.private_data = pAudioExtradata;
     1456                    pcmExtradata.private_size = audioExtradataSize;
     1457
     1458                    if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) {
     1459                        ffmpeg_err("writing data to audio device failed\n");
    13351460                    }
    13361461                }
     
    13481473                    avOut.type       = "audio";
    13491474
    1350                     if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
     1475                    if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0)
    13511476                    {
    13521477                        ffmpeg_err("writing data to audio device failed\n");
     
    13711496                }
    13721497
    1373                 if (duration > 0)
    1374                 {
    1375 //                  printf("[LIBEPLAYER3/FFMPEGThread] start\n");
    1376 
     1498                if (duration > 0 || duration == -1)
     1499                {
    13771500                    SubtitleOut_t subOut;
    13781501                    memset(&subOut, 0, sizeof(subOut));
    13791502                    subOut.trackId = pid;
    13801503                    subOut.data = (uint8_t *)packet.data;
     1504                    subOut.len = packet.size;
    13811505                    subOut.pts = pts;
    13821506                    subOut.durationMS = duration;
    1383                     //obi
    1384                     tmptrackId = pid;
    1385                     tmpdata = (uint8_t *)packet.data;
    1386 //                  tmpdata = (uint8_t *)&packet.data;
    1387                     //tmplen;
    1388                     tmppts = pts;
    1389                     tmpduration = duration;
    1390                     tmpdata = ostrcat(subOut.data, NULL, 0, 0);
    1391 
    1392                     //*tmptype;
    1393 //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpdata=%s\n", tmpdata);
    1394 //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmppts=%lld\n", tmppts);
    1395 //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpduration=%lld\n", tmpduration);
    1396                     //obi (end)
    1397 
    1398                     if (context->output->subtitle->Write(context, &subOut) < 0)
     1507                    subOut.extradata = get_codecpar(stream)->extradata;
     1508                    subOut.extralen  = get_codecpar(stream)->extradata_size;
     1509                    subOut.width     = get_codecpar(stream)->width;;
     1510                    subOut.height    = get_codecpar(stream)->height;;
     1511                   
     1512                                        //obi
     1513//                                  printf("[LIBEPLAYER3/FFMPEGThread] start\n");
     1514                                        tmptrackId = pid;
     1515                                        tmpdata = (uint8_t *)packet.data;
     1516                                        //                  tmpdata = (uint8_t *)&packet.data;
     1517                                        //tmplen;
     1518                                        tmppts = pts;
     1519                                        tmpduration = duration;
     1520                                        tmpdata = ostrcat(subOut.data, NULL, 0, 0);
     1521
     1522                                        //*tmptype;
     1523                                        //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpdata=%s\n", tmpdata);
     1524                                        //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmppts=%lld\n", tmppts);
     1525                                        //                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpduration=%lld\n", tmpduration);
     1526                                        //obi (end)
     1527                   
     1528                    if (Write(context->output->subtitle->Write, context, &subOut, pts) < 0)
    13991529                    {
    14001530                        ffmpeg_err("writing data to teletext fifo failed\n");
    14011531                    }
    1402                     //obi
    1403                     char* tmpstr = NULL;
    1404                     tmpstr = ostrcat(tmpstr, "duration=", 1, 0);
    1405                     tmpstr = ostrcat(tmpstr, ollutoa(tmpduration), 1, 1);
    1406                     tmpstr = ostrcat(tmpstr, ";pts=", 1, 0);;
    1407                     tmpstr = ostrcat(tmpstr, ollutoa(tmppts), 1, 0);;
    1408                     tmpstr = ostrcat(tmpstr, ";trackid=", 1, 0);;
    1409                     tmpstr = ostrcat(tmpstr, oitoa(tmptrackId), 1, 0);
    1410                     tmpstr = ostrcat(tmpstr, ";subtext=", 1, 0);;
    1411                     tmpstr = ostrcat(tmpstr, tmpdata, 1, 0);;
    1412 
    1413                     free(subtext), subtext = NULL;
    1414                     subtext = ostrcat(subtext, tmpstr, 1, 0);
    1415                     free(tmpstr), tmpstr = NULL;
    1416 
    1417 //                  tmpduration = 0;
    1418                     tmppts = 0;
    1419                     tmptrackId = 0;
    1420 
    1421 //                    printf("[LIBEPLAYER3/FFMPEGThread] set subtext: %s\n", subtext);
    1422                     //obi (end)
     1532                                        //obi
     1533                                        char* tmpstr = NULL;
     1534                                        tmpstr = ostrcat(tmpstr, "duration=", 1, 0);
     1535                                        tmpstr = ostrcat(tmpstr, ollutoa(tmpduration), 1, 1);
     1536                                        tmpstr = ostrcat(tmpstr, ";pts=", 1, 0);;
     1537                                        tmpstr = ostrcat(tmpstr, ollutoa(tmppts), 1, 0);;
     1538                                        tmpstr = ostrcat(tmpstr, ";trackid=", 1, 0);;
     1539                                        tmpstr = ostrcat(tmpstr, oitoa(tmptrackId), 1, 0);
     1540                                        tmpstr = ostrcat(tmpstr, ";subtext=", 1, 0);;
     1541                                        tmpstr = ostrcat(tmpstr, tmpdata, 1, 0);;
     1542
     1543                                        free(subtext), subtext = NULL;
     1544                                        subtext = ostrcat(subtext, tmpstr, 1, 0);
     1545                                        free(tmpstr), tmpstr = NULL;
     1546
     1547                                        //                  tmpduration = 0;
     1548                                        tmppts = 0;
     1549                                        tmptrackId = 0;
     1550
     1551                                        //                    printf("[LIBEPLAYER3/FFMPEGThread] set subtext: %s\n", subtext);
     1552                                                        //obi (end)
     1553
    14231554                }
    14241555            }
     
    14601591                {
    14611592                    seek_target_bytes = 0;
    1462                     do_seek_target_bytes = 1;
     1593                    do_seek_target_bytes = true;
    14631594                    bEndProcess = 0;
    14641595                }
     
    14681599                    if( 0 == container_ffmpeg_get_length(context, &tmpLength) && tmpLength > 0 && get_play_pts() > 0)
    14691600                    {
    1470 #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    1471                         if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    1472                         {
    1473                             seek_target_bytes = 0;
    1474                             do_seek_target_bytes = 1;
    1475                         }
    1476                         else
    1477 #endif
    1478                         {
    1479                             seek_target_seconds = 0;
    1480                             do_seek_target_seconds = 1;
    1481                         }
     1601                        seek_target_seconds = 0;
     1602                        do_seek_target_seconds = 1;
     1603
    14821604                        bEndProcess = 0;
    14831605                        context->output->Command(context, OUTPUT_CLEAR, NULL);
     
    15161638   
    15171639#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
    1518     mpeg4p2_context_reset(&mpeg4p2_context);
    1519     if (NULL != mpeg4p2_bsf_context)
    1520     {
    1521         av_bitstream_filter_close(mpeg4p2_bsf_context);
    1522     }
     1640    mpeg4p2_context_close(mpeg4p2_context);
    15231641#endif
    15241642
     
    15381656    PlaybackHandler_t *p = (PlaybackHandler_t *)ctx;
    15391657//obi
    1540 //    return p->abortRequested || PlaybackDieNow(0);
    1541     return p->abortRequested;
     1658    return p->abortRequested || PlaybackDieNow(0);
     1659//    return p->abortRequested;
    15421660//obi (end)
    15431661}
    15441662
    1545 #ifdef SAM_CUSTOM_IO
     1663#ifdef USE_CUSTOM_IO
     1664typedef struct CustomIOCtx_t
     1665{
     1666    FILE *pFile;
     1667    FILE *pMoovFile;
     1668    int64_t iOffset;
     1669   
     1670    char *szFile;
     1671    uint64_t iFileSize;
     1672    char *szMoovAtomFile;
     1673    uint64_t iMoovAtomOffset;
     1674} CustomIOCtx_t;
     1675
     1676CustomIOCtx_t* custom_io_tab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL};
     1677
    15461678int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize)
    15471679{
    1548     size_t ret = fread ( (void *) buffer, (size_t) 1, (size_t) lSize, (FILE *)ptr );
    1549     return (int)ret;
     1680    CustomIOCtx_t *io = (CustomIOCtx_t *)ptr;
     1681    int ret = 0;
     1682   
     1683    if (!io->pMoovFile)
     1684    {
     1685        ret = (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pFile );
     1686    }
     1687    else
     1688    {
     1689        if (io->iOffset < io->iMoovAtomOffset)
     1690        {
     1691            ret = (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pFile );
     1692            buffer += ret;
     1693            lSize -= ret;
     1694        }
     1695       
     1696        if (io->iOffset + ret >= io->iMoovAtomOffset)
     1697        {
     1698            if (ret)
     1699            {
     1700                if (fseeko(io->pMoovFile, io->iOffset + ret - io->iMoovAtomOffset, SEEK_SET))
     1701                {
     1702                    // something goes wrong
     1703                    ffmpeg_err("fseeko on moov atom file fail \n");
     1704                    lSize = 0;
     1705                }
     1706            }
     1707           
     1708            ret += (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pMoovFile );
     1709        }
     1710       
     1711        io->iOffset += ret;
     1712    }
     1713    return ret;
    15501714}
    15511715
    15521716// whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE
    1553 int64_t SAM_SeekFunc(void* ptr, int64_t pos, int whence)
     1717int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence)
    15541718{   
    1555     if( AVSEEK_SIZE == whence )
    1556     {
    1557         return -1;
    1558     }
    1559     int ret = fseeko((FILE *)ptr, (off_t)pos, whence);
    1560     if(0 == ret)
    1561     {
    1562         return (off_t)ftello((FILE *)ptr);
     1719    CustomIOCtx_t *io = (CustomIOCtx_t *)ptr;
     1720    int64_t ret = -1;
     1721    if (!io->pMoovFile)
     1722    {
     1723        if( AVSEEK_SIZE != whence )
     1724        {
     1725            ret = (int64_t)fseeko(io->pFile, (off_t)pos, whence);
     1726            if(0 == ret)
     1727            {
     1728                ret = (int64_t)ftello(io->pFile);
     1729            }
     1730        }
     1731    }
     1732    else
     1733    {
     1734        switch(whence)
     1735        {
     1736            case SEEK_SET:
     1737                ret = pos;
     1738                break;
     1739            case SEEK_CUR:
     1740                ret += pos;
     1741                break;
     1742            case SEEK_END:
     1743                ret = io->iFileSize + pos;
     1744                break;
     1745            case AVSEEK_SIZE:
     1746                return io->iFileSize;
     1747            default:
     1748                return -1;
     1749        }
     1750       
     1751        if (ret >= 0 && ret <= io->iFileSize)
     1752        {
     1753            if (ret < io->iMoovAtomOffset)
     1754            {
     1755                if(!fseeko(io->pFile, (off_t)ret, SEEK_SET))
     1756                    io->iOffset = ret;
     1757                else
     1758                    ret = -1;
     1759            }
     1760            else
     1761            {
     1762                if(!fseeko(io->pMoovFile, (off_t)(ret - io->iMoovAtomOffset), SEEK_SET))
     1763                    io->iOffset = ret;
     1764                else
     1765                    ret = -1;
     1766            }
     1767        }
     1768        else
     1769        {
     1770            ret = -1;
     1771        }
    15631772    }
    15641773    return ret;
    15651774}
    15661775
    1567 AVIOContext* container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_buffer_size)
    1568 {
    1569         if(strstr(filename, "file://") == filename)
    1570         {
    1571             filename += 7;
    1572         }
     1776AVIOContext* container_ffmpeg_get_avio_context(CustomIOCtx_t *custom_io, size_t avio_ctx_buffer_size)
     1777{
     1778    if(strstr(custom_io->szFile, "file://") == custom_io->szFile)
     1779        custom_io->szFile += 7;
     1780   
     1781    custom_io->pFile = fopen(custom_io->szFile, "rb");
     1782    if(NULL == custom_io->pFile)
     1783    {
     1784        return NULL;
     1785    }
     1786   
     1787    if (custom_io->szMoovAtomFile && custom_io->szMoovAtomFile[0] != '\0')
     1788    {
     1789        if(strstr(custom_io->szMoovAtomFile, "file://") == custom_io->szMoovAtomFile)
     1790            custom_io->szMoovAtomFile += 7;
    15731791       
    1574         FILE *pFile = fopen(filename, "rb");
    1575         if(NULL == pFile)
    1576         {
     1792        custom_io->pMoovFile = fopen(custom_io->szMoovAtomFile, "rb");
     1793        if(NULL == custom_io->pMoovFile)
     1794        {
     1795            fclose(custom_io->pFile);
    15771796            return NULL;
    15781797        }
    1579        
    1580         AVIOContext *avio_ctx = NULL;
    1581         uint8_t *avio_ctx_buffer = NULL;
    1582        
    1583         avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
    1584         if (!avio_ctx_buffer)
    1585         {
    1586             return NULL;
    1587         }
    1588         avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, pFile, &SAM_ReadFunc, NULL, &SAM_SeekFunc);
    1589         if (!avio_ctx)
    1590         {
    1591             return NULL;
    1592         }
    1593         return avio_ctx;
     1798    }
     1799   
     1800    AVIOContext *avio_ctx = NULL;
     1801    uint8_t *avio_ctx_buffer = NULL;
     1802   
     1803    avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
     1804    if (!avio_ctx_buffer)
     1805    {
     1806        return NULL;
     1807    }
     1808    avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, custom_io, &SAM_ReadFunc, NULL, &SAM_SeekFunc);
     1809    if (!avio_ctx)
     1810    {
     1811        return NULL;
     1812    }
     1813    return avio_ctx;
    15941814}
    15951815#endif
    15961816
    1597 int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int32_t AVIdx)
     1817int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uint64_t fileSize, char *moovAtomFile, uint64_t moovAtomOffset, int32_t AVIdx)
    15981818{
    15991819    int32_t err = 0;
     
    16031823    avContextTab[AVIdx]->interrupt_callback.opaque = context->playback;
    16041824
    1605 #ifdef SAM_CUSTOM_IO
     1825#ifdef USE_CUSTOM_IO
    16061826    if(0 == strstr(filename, "://") ||
    16071827       0 == strncmp(filename, "file://", 7))
    16081828    {
    1609         AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096);
     1829        AVIOContext *avio_ctx = NULL;
     1830        custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t));
     1831        sizeof(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t));
     1832       
     1833        custom_io_tab[AVIdx]->szFile = filename;
     1834        custom_io_tab[AVIdx]->iFileSize = fileSize;
     1835        custom_io_tab[AVIdx]->szMoovAtomFile = moovAtomFile;
     1836        custom_io_tab[AVIdx]->iMoovAtomOffset = moovAtomOffset;
     1837       
     1838        avio_ctx = container_ffmpeg_get_avio_context(custom_io_tab[AVIdx], 4096);
    16101839        if(avio_ctx)
    16111840        {
     
    16151844        else
    16161845        {
     1846            free(custom_io_tab[AVIdx]);
     1847            custom_io_tab[AVIdx] = NULL;
    16171848            return cERR_CONTAINER_FFMPEG_OPEN;
    16181849        }
     
    16201851#endif
    16211852
     1853    AVDictionary *avio_opts = NULL;
    16221854    AVDictionary **pavio_opts = NULL;
     1855    av_dict_copy(&avio_opts, g_avio_opts, 0);
     1856
    16231857    eRTMPProtoImplType rtmpProtoImplType = RTMP_NONE;
    16241858    uint8_t numOfRTMPImpl = 0;
     
    18372071        av_dict_set(&avio_opts, "timeout", "20000000", 0); //20sec
    18382072//obi
     2073/*
    18392074                char* cookie = NULL, *tmpstr1 = NULL, *tmpstr2 = NULL, *tmpstr3 = NULL, *tmpstr4 = NULL, *headers = NULL, *useragent = NULL;
    18402075                int count = 0, count1 = 0, count2 = 0, count3 = 0, i = 0, i1 = 0, i2 = 0, i3 = 0, usetslivemode = 0;
     
    19892224                        context->playback->isTSLiveMode = 1;
    19902225                }
     2226                */
    19912227//obi (end)
    19922228
     
    19992235        }
    20002236    }
    2001 
     2237   
    20022238    pavio_opts = &avio_opts;
    20032239   
     
    20192255            ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
    20202256            av_strerror(err, error, 512);
    2021             fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
     2257            E2iSendMsg("{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
    20222258
    20232259            if(avio_opts != NULL)
     
    21342370
    21352371    /* initialize ffmpeg */
    2136     avcodec_register_all();
    2137     av_register_all();
     2372    wrapped_register_all();
    21382373    avformat_network_init();
    21392374
     2375#if FFMPEG_DEBUG_LEVEL >= 10
     2376    av_log_set_level( AV_LOG_DEBUG );
     2377#else
     2378    av_log_set_callback( ffmpeg_silen_callback );
     2379#endif
     2380
    21402381//obi
     2382/*
    21412383    char* tmpstr = NULL;
    21422384    tmpstr = readfiletomem("/mnt/config/titan.cfg", 1);
     
    21462388        av_log_set_callback(ffmpeg_silen_callback);
    21472389    free(tmpstr), tmpstr = NULL;
    2148 //obi (end)
    2149     // SULGE DEBUG ENABLED
    2150     // make ffmpeg silen
    2151     //av_log_set_level( AV_LOG_DEBUG );
    2152     //av_log_set_callback(ffmpeg_silen_callback);
    2153  
     2390*/
     2391//obi (end)
     2392
    21542393    context->playback->abortRequested = 0;
    2155     int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0);
     2394    int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \
     2395                                                   playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
    21562396    if(0 != res)
    21572397    {
     
    21592399    }
    21602400
    2161     if(playFilesNames->szSecondFile)
    2162     {
    2163         res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1);
     2401    if(playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0')
     2402    {
     2403        res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \
     2404                                               playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
    21642405    }
    21652406   
     
    21732414    isContainerRunning = 1;
    21742415    res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1);
    2175 
    21762416    //obi
    2177     //ReadSubtitles(context, playFilesNames->szFirstFile);
     2417//    ReadSubtitles(context, playFilesNames->szFirstFile);
    21782418    //obi (end)
    21792419    return res;
     
    21822422int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial)
    21832423{
    2184     Track_t *audioTrack = NULL;
    2185     Track_t *subtitleTrack = NULL;
     2424    Track_t *currAudioTrack = NULL;
     2425    Track_t *currSubtitleTrack = NULL;
     2426    uint32_t addedVideoTracksCount = 0;
    21862427   
    21872428    if (terminating)
     
    21902431    }
    21912432   
     2433    getMutex(__FILE__, __FUNCTION__,__LINE__);
     2434   
    21922435    if (initial && context->manager->subtitle)
    21932436    {
    2194         context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack);
     2437        context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &currSubtitleTrack);
    21952438    }
    21962439
    21972440    if (context->manager->audio)
    21982441    {
    2199         context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
     2442        context->manager->audio->Command(context, MANAGER_GET_TRACK, &currAudioTrack);
    22002443    }
    22012444
     
    22162459    }
    22172460#endif
    2218 
    22192461
    22202462    ffmpeg_printf(20, "dump format\n");
     
    22942536                }
    22952537               
    2296                 if (!isStreamFromSelProg)
     2538                if (!isStreamFromSelProg) {
     2539                    stream->discard = AVDISCARD_ALL;
     2540                    ffmpeg_printf(1, "cAVIdx[%d]: add DISCARD flag to  stream index[%d]\n", cAVIdx, stream->index);
    22972541                    continue; // skip this stream
     2542                }
    22982543            }
    22992544
     
    23282573            case AVMEDIA_TYPE_VIDEO:
    23292574                ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
    2330 
     2575                // do not discard any stream from second context
     2576                stream->discard = 0 == cAVIdx ? AVDISCARD_ALL : AVDISCARD_DEFAULT; /* by default we discard all video streams */
    23312577                if (encoding != NULL)
    23322578                {
     
    23732619                    }
    23742620                   
    2375                     ffmpeg_printf(10, "bit_rate       [%d]\n", get_codecpar(stream)->bit_rate);
     2621                    ffmpeg_printf(10, "bit_rate       [%"PRId64"]\n", get_codecpar(stream)->bit_rate);
    23762622                    ffmpeg_printf(10, "time_base.den  [%d]\n", stream->time_base.den);
    23772623                    ffmpeg_printf(10, "time_base.num  [%d]\n", stream->time_base.num);
     
    24022648                            track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
    24032649                        }
    2404                         ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n");
     2650                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n", cAVIdx);
    24052651                        if( context->manager->video->Command(context, MANAGER_ADD, &track) < 0)
    24062652                        {
    24072653                            /* konfetti: fixme: is this a reason to return with error? */
    24082654                            ffmpeg_err("failed to add track %d\n", n);
     2655                        }
     2656                        else
     2657                        {
     2658                            if (addedVideoTracksCount == 0) /* at now we can handle only first video track */
     2659                            {
     2660                                stream->discard = AVDISCARD_DEFAULT;
     2661                            }
     2662                            addedVideoTracksCount += 1;
    24092663                        }
    24102664                    }
     
    24172671            case AVMEDIA_TYPE_AUDIO:
    24182672                ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",get_codecpar(stream)->codec_type);
    2419 
     2673                // do not discard any stream from second context
     2674                stream->discard = 0 == cAVIdx ? AVDISCARD_ALL : AVDISCARD_DEFAULT;
    24202675                if (encoding != NULL)
    24212676                {
     
    25172772                            int32_t object_type = 2; // LC
    25182773                            int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate);
    2519                             int32_t chan_config = get_codecpar(stream)->channels - 1;
     2774                            int32_t chan_config = get_chan_config(get_codecpar(stream)->channels);
    25202775                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
    25212776                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
    25222777                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
    25232778                           
     2779                            int off = -1;
    25242780                            if (get_codecpar(stream)->extradata_size >= 2)
    25252781                            {
    25262782                                MPEG4AudioConfig m4ac;
    2527                                 int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
     2783                                off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
    25282784                                if (off >= 0)
    25292785                                {
     
    25422798                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
    25432799
    2544                            
     2800                            if (off >= 0 && chan_config == 0) { // channel config must be send in the inband PCE
     2801                                track.aacbuf = malloc(AAC_HEADER_LENGTH + MAX_PCE_SIZE);
     2802
     2803                                GetBitContext gb;
     2804                                PutBitContext pb;
     2805                                init_put_bits(&pb, track.aacbuf + AAC_HEADER_LENGTH, MAX_PCE_SIZE);
     2806                                init_get_bits8(&gb, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
     2807                                skip_bits_long(&gb, off + 3);
     2808
     2809                                put_bits(&pb, 3, 5); //ID_PCE
     2810                                track.aacbuflen = AAC_HEADER_LENGTH + (avpriv_copy_pce_data(&pb, &gb) + 3) / 8;
     2811                                flush_put_bits(&pb);
     2812                            }
     2813                            else {
     2814                                track.aacbuflen = AAC_HEADER_LENGTH;
     2815                                track.aacbuf = malloc(AAC_HEADER_LENGTH+1);
     2816                            }
     2817
    25452818                            // https://wiki.multimedia.cx/index.php/ADTS
    25462819                            object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1
    2547                            
    2548                             track.aacbuflen = AAC_HEADER_LENGTH;
    2549                             track.aacbuf = malloc(8);
     2820
    25502821                            track.aacbuf[0] = 0xFF;
    25512822                            track.aacbuf[1] = 0xF1;
     
    25702841
    25712842                    }
     2843#ifdef __sh__
    25722844                    else if(get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1
    25732845                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2
     
    25762848                    {
    25772849                        ffmpeg_printf(10,"Create WMA ExtraData\n");
    2578                         uint16_t channels = get_codecpar(stream)->channels;
    2579                         uint32_t rate = get_codecpar(stream)->sample_rate;
    2580                         uint32_t bitrate = get_codecpar(stream)->bit_rate;
    2581                         uint16_t block_align = get_codecpar(stream)->block_align;
    2582                         uint16_t depth = get_codecpar(stream)->bits_per_coded_sample;
    2583                         uint32_t codec_data_size = get_codecpar(stream)->extradata_size;
    2584                         uint8_t *codec_data_pointer = get_codecpar(stream)->extradata;
    2585                        
     2850
    25862851                        // type_specific_data
    2587                         #define WMA_VERSION_1           0x160
    2588                         #define WMA_VERSION_2_9         0x161
    2589                         #define WMA_VERSION_9_PRO       0x162
    2590                         #define WMA_LOSSLESS            0x163
    25912852                        uint16_t codec_id = 0;
    25922853                        switch(get_codecpar(stream)->codec_id)
     
    25942855                            //TODO: What code for lossless ?
    25952856                            case AV_CODEC_ID_WMALOSSLESS:
    2596                                 codec_id = WMA_LOSSLESS;
     2857                                codec_id = 0x163; // WMA_LOSSLESS
    25972858                                break;
    25982859                            case AV_CODEC_ID_WMAPRO:
    2599                                 codec_id = WMA_VERSION_9_PRO;
     2860                                codec_id = 0x162; // WMA_VERSION_9_PRO
    26002861                                break;
    26012862                            case AV_CODEC_ID_WMAV2:
    2602                                 codec_id = WMA_VERSION_2_9 ;
     2863                                codec_id = 0x161; // WMA_VERSION_2_9
    26032864                                break;
    26042865                            case AV_CODEC_ID_WMAV1:
    26052866                            default:
    2606                                 codec_id = WMA_VERSION_1;
     2867                                codec_id = 0x160; // WMA_VERSION_1
    26072868                                break;
    26082869                        }
    2609 #ifdef __sh__
     2870                       
    26102871                        track.aacbuflen = 104 + get_codecpar(stream)->extradata_size;
    26112872                        track.aacbuf = malloc(track.aacbuflen);
     
    26752936
    26762937                        memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
    2677 #else
    2678                         track.aacbuflen = 18 + get_codecpar(stream)->extradata_size;
    2679                         track.aacbuf = malloc(track.aacbuflen);
    2680                         memset (track.aacbuf, 0, track.aacbuflen);
    2681                        
    2682                         uint8_t *data = track.aacbuf;
    2683                         /* codec tag */
    2684                         *(data++) = codec_id & 0xff;
    2685                         *(data++) = (codec_id >> 8) & 0xff;
    2686                         /* channels */
    2687                         *(data++) = channels & 0xff;
    2688                         *(data++) = (channels >> 8) & 0xff;
    2689                         /* sample rate */
    2690                         *(data++) = rate & 0xff;
    2691                         *(data++) = (rate >> 8) & 0xff;
    2692                         *(data++) = (rate >> 16) & 0xff;
    2693                         *(data++) = (rate >> 24) & 0xff;
    2694                         /* byte rate */
    2695                         bitrate /= 8;
    2696                         *(data++) = bitrate & 0xff;
    2697                         *(data++) = (bitrate >> 8) & 0xff;
    2698                         *(data++) = (bitrate >> 16) & 0xff;
    2699                         *(data++) = (bitrate >> 24) & 0xff;
    2700                         /* block align */
    2701                         *(data++) = block_align & 0xff;
    2702                         *(data++) = (block_align >> 8) & 0xff;
    2703                         /* word size */
    2704                         *(data++) = depth & 0xff;
    2705                         *(data++) = (depth >> 8) & 0xff;
    2706                         /* codec data size */
    2707                         *(data++) = codec_data_size & 0xff;
    2708                         *(data++) = (codec_data_size >> 8) & 0xff;
    2709                         memcpy(data, codec_data_pointer, codec_data_size);
     2938
     2939                        ffmpeg_printf(1, "aacbuf:\n");
     2940                        track.have_aacheader = 1;
     2941                    }
    27102942#endif
    2711                         ffmpeg_printf(1, "aacbuf:\n");
    2712                         //Hexdump(track.aacbuf, track.aacbuflen);
    2713 
    2714                         //ffmpeg_printf(1, "priv_data:\n");
    2715                         //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen);
    2716 
    2717                         track.have_aacheader = 1;
    2718                     }
    2719                    
    27202943                    if (context->manager->audio)
    27212944                    {
    2722                         ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n");
     2945                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n", cAVIdx);
    27232946                        if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0)
    27242947                        {
     
    27412964                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
    27422965                    get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
    2743                     get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT)
     2966                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT &&
     2967                    get_codecpar(stream)->codec_id != AV_CODEC_ID_WEBVTT &&
     2968                    ((get_codecpar(stream)->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE &&
     2969                      get_codecpar(stream)->codec_id != AV_CODEC_ID_DVB_SUBTITLE &&
     2970                      get_codecpar(stream)->codec_id != AV_CODEC_ID_XSUB) ||
     2971                     !GetGraphicSubPath() || !GetGraphicSubPath()[0]))
    27442972                {
    27452973                    ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id);
     
    27672995                    }
    27682996
    2769                     track.extraData      = get_codecpar(stream)->extradata;
    2770                     track.extraSize      = get_codecpar(stream)->extradata_size;
    2771 
    27722997                    ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id);
    27732998                    ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width);
     
    27893014            case AVMEDIA_TYPE_NB:
    27903015            default:
     3016                stream->discard = AVDISCARD_ALL;
    27913017                ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type);
    27923018             break;
     
    27953021   
    27963022    }
    2797 
     3023   
     3024    if (context->manager->audio)
     3025    {
     3026        Track_t *Tracks = NULL;
     3027        int32_t TrackCount = 0;
     3028        int32_t selTrackIdx = -1;
     3029       
     3030        context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks);
     3031        context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount);
     3032        if (Tracks && TrackCount)
     3033        {
     3034            int32_t i;
     3035            for (i=0; i < TrackCount; ++i)
     3036            {
     3037                if (Tracks[i].pending || Tracks[i].Id < 0)
     3038                    continue;
     3039               
     3040                if (selTrackIdx == -1)
     3041                    selTrackIdx = i;
     3042                   
     3043                if (currAudioTrack && currAudioTrack->Id == Tracks[i].Id)
     3044                {
     3045                    selTrackIdx = i;
     3046                    break;
     3047                }
     3048            }
     3049           
     3050            if (selTrackIdx > -1)
     3051            {
     3052                ((AVStream*)Tracks[selTrackIdx].stream)->discard = AVDISCARD_DEFAULT;
     3053                if (!currAudioTrack || currAudioTrack->Id != Tracks[selTrackIdx].Id )
     3054                {
     3055                    context->manager->audio->Command(context, MANAGER_SET, &Tracks[selTrackIdx].Id);
     3056                }
     3057            }
     3058        }
     3059    }
     3060   
     3061    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    27983062    return cERR_CONTAINER_FFMPEG_NO_ERROR;
    27993063}
     
    29313195    }
    29323196
    2933     if(avio_opts != NULL)
    2934     {
    2935         av_dict_free(&avio_opts);
     3197    if(g_avio_opts != NULL)
     3198    {
     3199        av_dict_free(&g_avio_opts);
    29363200    }
    29373201
     
    29513215    off_t current_pos = avio_tell(avContextTab[0]->pb);
    29523216
    2953     ffmpeg_printf(20, "seeking to position %lld (bytes)\n", pos);
     3217    ffmpeg_printf(20, "seeking to position %"PRId64" (bytes)\n", pos);
    29543218
    29553219    if (current_pos > pos)
     
    29643228    }
    29653229
    2966     ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb));
     3230    ffmpeg_printf(30, "current_pos after seek %"PRId64"\n", avio_tell(avContextTab[0]->pb));
    29673231
    29683232    return cERR_CONTAINER_FFMPEG_NO_ERROR;
    29693233}
    29703234
    2971 /* seeking relative to a given byteposition N seconds ->for reverse playback needed */
    2972 static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec)
     3235static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
    29733236{
    29743237    Track_t *videoTrack = NULL;
    29753238    Track_t *audioTrack = NULL;
    29763239    Track_t *current = NULL;
    2977     seek_target_flag = 0;
    2978 
    2979     ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
    2980 
    2981     context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
    2982     context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
    2983 
    2984     if (videoTrack != NULL)
    2985     {
    2986         current = videoTrack;
    2987     }
    2988     else if (audioTrack != NULL)
    2989     {
    2990         current = audioTrack;
    2991     }
    2992    
    2993     if (current == NULL)
    2994     {
    2995         ffmpeg_err( "no track avaibale to seek\n");
    2996         return cERR_CONTAINER_FFMPEG_ERR;
    2997     }
    2998 
    2999     if (pos == -1)
    3000     {
    3001         pos = avio_tell(avContextTab[0]->pb);
    3002     }
    3003 
    3004     if (pts == -1)
    3005     {
    3006         pts = current->pts;
    3007     }
    3008    
    3009     if (sec < 0)
    3010     {
    3011         seek_target_flag |= AVSEEK_FLAG_BACKWARD;
    3012     }
    3013 
    3014     ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
    3015 #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    3016     if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    3017     {
    3018         if (avContextTab[0]->bit_rate)
    3019         {
    3020             sec *= avContextTab[0]->bit_rate / 8;
    3021             ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
    3022         }
    3023         else
    3024         {
    3025             sec *= 180000;
    3026         }
    3027 
    3028         pos += sec;
    3029 
    3030         if (pos < 0)
    3031         {
    3032            ffmpeg_err("end of file reached\n");
    3033            releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    3034            return cERR_CONTAINER_FFMPEG_END_OF_FILE;
    3035         }
    3036 
    3037         ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
    3038 
    3039         seek_target_bytes = pos;
    3040         do_seek_target_bytes = 1;
    3041 
    3042         return pos;
    3043     }
    3044     else
    3045 #endif
    3046     {
    3047         sec += pts / 90000;
    3048 
    3049         if (sec < 0)
    3050         {
    3051             sec = 0;
    3052         }
    3053 
    3054         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);
    3055 
    3056         seek_target_seconds = sec * AV_TIME_BASE;
    3057         do_seek_target_seconds = 1;
    3058     }
    3059 
    3060     releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    3061     return cERR_CONTAINER_FFMPEG_NO_ERROR;
    3062 }
    3063 
    3064 static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
    3065 {
    3066     Track_t *videoTrack = NULL;
    3067     Track_t *audioTrack = NULL;
    3068     Track_t *current = NULL;
    3069     seek_target_flag = 0;
    30703240
    30713241    if (!absolute)
    30723242    {
    3073         ffmpeg_printf(10, "seeking %f sec\n", sec);
     3243        ffmpeg_printf(10, "seeking %"PRId64" sec\n", sec);
    30743244        if (sec == 0)
    30753245        {
     
    30903260    }
    30913261   
    3092     ffmpeg_printf(10, "goto %d sec\n", sec);
     3262    ffmpeg_printf(10, "goto %"PRId64" sec\n", sec);
    30933263    if (sec < 0)
    30943264    {
     
    31133283    }
    31143284
    3115     if (sec < 0)
    3116     {
    3117         seek_target_flag |= AVSEEK_FLAG_BACKWARD;
    3118     }
    3119 
    3120     getMutex(__FILE__, __FUNCTION__,__LINE__);
    3121 
    31223285    if (!context->playback || !context->playback->isPlaying)
    31233286    {
    3124         releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    31253287        return cERR_CONTAINER_FFMPEG_NO_ERROR;
    31263288    }
    31273289
    3128     ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
    3129 #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
    3130     if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
    3131     {
    3132         /* konfetti: for ts streams seeking frame per seconds does not work (why?).
    3133         * I take this algo partly from ffplay.c.
    3134         *
    3135         * seeking per HTTP does still not work very good. forward seeks everytime
    3136         * about 10 seconds, backward does not work.
    3137         */
    3138 
    3139         off_t pos = avio_tell(avContextTab[0]->pb);
    3140 
    3141         ffmpeg_printf(10, "pos %lld %d\n", pos, avContextTab[0]->bit_rate);
    3142 
    3143         if (avContextTab[0]->bit_rate)
    3144         {
    3145             sec *= avContextTab[0]->bit_rate / 8;
    3146             ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
    3147         }
    3148         else
    3149         {
    3150             sec *= 180000;
    3151         }
    3152        
    3153         pos = sec;
    3154        
    3155         if (pos < 0)
    3156         {
    3157            pos = 0;
    3158         }
    3159        
    3160         ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %d\n", pos, sec);
    3161 
    3162         seek_target_bytes = pos;
    3163         do_seek_target_bytes = 1;
    3164 
    3165     }
    3166     else
    3167 #endif
    3168     {
    3169         seek_target_seconds = sec * AV_TIME_BASE;
    3170         do_seek_target_seconds = 1;
    3171     }
    3172 
    3173     releaseMutex(__FILE__, __FUNCTION__,__LINE__);
     3290    getSeekMutex();
     3291    g_seek_target_seconds = sec * AV_TIME_BASE;
     3292    g_do_seek_target_seconds = true;
     3293    g_stamp = context->playback->stamp;
     3294    releaseSeekMutex();
     3295
    31743296    return cERR_CONTAINER_FFMPEG_NO_ERROR;
    31753297}
     
    32323354{
    32333355    ffmpeg_printf(10, "track %d\n", *arg);
     3356    getMutex(__FILE__, __FUNCTION__,__LINE__);
     3357    if (context->manager->audio)
     3358    {
     3359        Track_t *Tracks = NULL;
     3360        int32_t TrackCount = 0;
     3361       
     3362        context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks);
     3363        context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount);
     3364        if (Tracks && TrackCount)
     3365        {
     3366            int32_t i;
     3367            for (i=0; i < TrackCount; ++i)
     3368            {
     3369                // do not discard any stream from second context
     3370                if (Tracks[i].AVIdx == 0) {
     3371                    ((AVStream*)Tracks[i].stream)->discard = Tracks[i].Id == *arg ? AVDISCARD_DEFAULT : AVDISCARD_ALL;
     3372                }
     3373            }
     3374        }
     3375    }
     3376    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
    32343377   
    32353378    /* Hellmaster1024: nothing to do here!*/
    3236     int64_t sec = -5;
     3379    int64_t sec = -1;
    32373380    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
    32383381    return cERR_CONTAINER_FFMPEG_NO_ERROR;
     
    32483391     * but now we will not ignore subtitle frame
    32493392     */
    3250     int64_t sec = -5;
     3393    int64_t sec = -1;
    32513394    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
    32523395    //obi
     
    34663609        break;
    34673610    }
    3468     //obi (end)
     3611    //obi (end) 
    34693612    default:
    34703613        ffmpeg_err("ContainerCmd %d not supported!\n", command);
     
    34773620}
    34783621
    3479 static 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 };
     3622static 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", "jpeg", "ra", "ram", "rm", "3gp", "amr", "rmvb", "rm", "webm", "opus", "m3u8", "mpd", NULL };
    34803623
    34813624Container_t FFMPEGContainer = {
  • titan/libeplayer3/container/flv2mpeg4_ffmpeg.c

    r42431 r44958  
    3939    avOut.type       = "video";
    4040
    41     if (ctx->out_ctx->output->video->Write(ctx->out_ctx, &avOut) < 0)
     41    if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut, avOut.pts) < 0)
    4242    {
    4343        ffmpeg_err("writing data to video device failed\n");
  • titan/libeplayer3/container/mpeg4p2_ffmpeg.c

    r42431 r44958  
    44//
    55
    6 #define MPEG4P2_MAX_B_FRAMES_COUNT 5
    7 
     6// mpeg4_unpack_bframes
    87typedef struct
    98{
    10     int b_frames_count;
    11     int first_ip_frame_written;
    12     int64_t packet_duration;
    13     AVPacket *b_frames[MPEG4P2_MAX_B_FRAMES_COUNT];
    14     AVPacket *second_ip_frame;
     9    const AVBitStreamFilter *bsf;
     10    AVBSFContext *ctx;
    1511} Mpeg4P2Context;
    1612
    17 
    18 static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src)
     13static Mpeg4P2Context * mpeg4p2_context_open()
    1914{
    20     if (pkt_dest == NULL)
    21         return;
    22     if (*pkt_dest != NULL)
    23     {
    24         wrapped_packet_unref(*pkt_dest);
    25         av_free(*pkt_dest);
     15    Mpeg4P2Context *context = NULL;
     16    const AVBitStreamFilter *bsf = av_bsf_get_by_name("mpeg4_unpack_bframes");
     17    if (bsf) {
     18        context = malloc(sizeof(Mpeg4P2Context));
     19        if (context) {
     20            memset(context, 0x00, sizeof(Mpeg4P2Context));
     21            context->bsf = bsf;
     22        }
    2623    }
    27     *pkt_dest = av_malloc(sizeof(AVPacket));
    28     av_copy_packet(*pkt_dest, pkt_src);
     24    return context;
    2925}
    3026
    31 static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ctx, AVPacket *pkt)
     27static void mpeg4p2_write(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int64_t start_time, int64_t *currentVideoPts, int64_t *latestPts, AVPacket *pkt)
    3228{
    33     int ret;
    34     AVPacket new_pkt = *pkt;
    35     ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
    36             &new_pkt.data, &new_pkt.size,
    37             pkt->data, pkt->size,
    38             pkt->flags & AV_PKT_FLAG_KEY);
    39     if (ret == 0 && new_pkt.data != pkt->data)
    40     {
    41         if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
    42             return -1;
    43         ret = 1;
    44     }
    45     if (ret > 0)
    46     {
    47         pkt->side_data = NULL;
    48         pkt->side_data_elems = 0;
    49         wrapped_packet_unref(pkt);
    50         new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
    51                 av_buffer_default_free, NULL, 0);
    52         if (!new_pkt.buf)
    53             return -1;
    54     }
    55     if (ret < 0)
    56     {
    57         ffmpeg_err("Failed to filter bitstream with filter %s for stream %d with codec %s\n",
    58                 bsf_ctx->filter->name, pkt->stream_index,
    59                 avcodec_get_name(enc_ctx->codec_id));
    60         return -1;
    61     }
    62     *pkt = new_pkt;
    63     return 0;
    64 }
    65 
    66 static void mpeg4p2_context_reset(Mpeg4P2Context *context)
    67 {
    68     if (context == NULL)
    69         return;
    70     int i;
    71     for (i=0; i < MPEG4P2_MAX_B_FRAMES_COUNT; i++)
    72     {
    73         if (context->b_frames[i] != NULL)
    74         {
    75             wrapped_packet_unref(context->b_frames[i]);
    76             av_free(context->b_frames[i]);
    77         }
    78         context->b_frames[i] = NULL;
    79     }
    80     if (context->second_ip_frame != NULL)
    81     {
    82         wrapped_packet_unref(context->second_ip_frame);
    83         av_free(context->second_ip_frame);
    84     }
    85     context->second_ip_frame = NULL;
    86 
    87     context->b_frames_count = 0;
    88     context->first_ip_frame_written = 0;
    89     context->packet_duration = 0;
    90 }
    91 
    92 static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *currentVideoPts, int64_t *latestPts, AVPacket *pkt)
    93 {
    94     *currentVideoPts = track->pts = calcPts(avContextIdx, track->stream, pkt->pts);
    95     if ((*currentVideoPts > *latestPts) && (*currentVideoPts != INVALID_PTS_VALUE))
    96     {
     29    *currentVideoPts = track->pts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->pts);
     30    if ((*currentVideoPts > *latestPts) && (*currentVideoPts != INVALID_PTS_VALUE)) {
    9731        *latestPts = *currentVideoPts;
    9832    }
    99     track->dts = calcPts(avContextIdx, track->stream, pkt->dts);
     33
     34    track->dts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->dts);
    10035
    10136    AudioVideoOut_t avOut;
     
    10439    avOut.pts        = track->pts;
    10540    avOut.dts        = track->dts;
    106     avOut.extradata  = track->extraData;
    107     avOut.extralen   = track->extraSize;
     41    avOut.extradata  = mpeg4p2_ctx->ctx->par_out->extradata;
     42    avOut.extralen   = mpeg4p2_ctx->ctx->par_out->extradata_size;
    10843    avOut.frameRate  = track->frame_rate;
    10944    avOut.timeScale  = track->TimeScale;
     
    11247    avOut.type       = "video";
    11348
    114     if (ctx->output->video->Write(ctx, &avOut) < 0)
    115     {
     49    if (Write(ctx->output->video->Write, ctx, &avOut, avOut.pts) < 0) {
    11650        ffmpeg_err("writing data to video device failed\n");
    11751    }
    11852}
    11953
     54static int mpeg4p2_context_reset(Mpeg4P2Context *context)
     55{
     56    int ret = 0;
     57    if (context && context->ctx) {
     58        // Flush
     59        ret = av_bsf_send_packet(context->ctx, NULL);
     60        if (ret == 0) {
     61            AVPacket *pkt = NULL;
     62            while ((ret = av_bsf_receive_packet(context->ctx, pkt)) == 0) {
     63                wrapped_frame_unref(pkt);
     64            }
     65        }
     66        av_bsf_free(&context->ctx);
     67    }
     68
     69    return ret;
     70}
     71
    12072static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int cAVIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt)
    12173{
    122     uint8_t *data = pkt->data;
    123     int data_len = pkt->size;
    124     int pos = 0;
    125     if (mpeg4p2_ctx->packet_duration == 0)
    126     {
    127         mpeg4p2_ctx->packet_duration = pkt->duration;
    128     }
    129     while (pos < data_len)
    130     {
    131         if (memcmp(&data[pos], "\x00\x00\x01\xb6", 4))
    132         {
    133             pos++;
    134             continue;
     74    int ret = 0;
     75    if (mpeg4p2_ctx) {
     76        // Setup is needed
     77        if (!mpeg4p2_ctx->ctx) {
     78            ret = av_bsf_alloc(mpeg4p2_ctx->bsf, &mpeg4p2_ctx->ctx);
     79            if (ret == 0) {
     80                AVStream *in = track->stream;
     81                ret = avcodec_parameters_copy(mpeg4p2_ctx->ctx->par_in, in->codecpar);
     82                if (ret == 0) {
     83                    mpeg4p2_ctx->ctx->time_base_in = in->time_base;
     84                    ret = av_bsf_init(mpeg4p2_ctx->ctx);
     85                }
     86            }
    13587        }
    136         pos += 4;
    137         switch ((data[pos] & 0xC0) >> 6)
    138         {
    139             case 0: // I-Frame
    140             case 1: // P-Frame
    141                 if (!mpeg4p2_ctx->first_ip_frame_written)
    142                 {
    143                     mpeg4p2_ctx->first_ip_frame_written = 1;
    144                     pkt->pts = pkt->dts + mpeg4p2_ctx->packet_duration;
    145                     ffmpeg_printf(100, "Writing first I/P packet\n");
    146                     mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, pkt);
     88
     89        if (ret == 0) {
     90            ret = av_bsf_send_packet(mpeg4p2_ctx->ctx, pkt);
     91            if (ret == 0) {
     92                while ((ret = av_bsf_receive_packet(mpeg4p2_ctx->ctx, pkt)) == 0) {
     93                    mpeg4p2_write(ctx, mpeg4p2_ctx, track, avContextTab[cAVIdx]->start_time, pts_current, pts_latest, pkt);
     94                }
     95
     96                if (ret == AVERROR(EAGAIN)) {
    14797                    return 0;
    14898                }
    149                 else if (!mpeg4p2_ctx->second_ip_frame)
    150                 {
    151                     set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
    152                     return 0;
     99
     100                if (ret < 0) {
     101                    ffmpeg_err("av_bsf_receive_packet failed error 0x%x\n", ret);
     102                    mpeg4p2_context_reset(mpeg4p2_ctx);
    153103                }
    154                 else
    155                 {
    156                     if (!mpeg4p2_ctx->b_frames_count)
    157                     {
    158                         mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration;
    159                         ffmpeg_printf(100,"Writing second I/P packet(1)\n");
    160                         mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame);
    161                         set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
    162                         return 0;
    163                     }
    164                     else
    165                     {
    166                         mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count -1]->dts + mpeg4p2_ctx->packet_duration;
    167                         mpeg4p2_ctx->b_frames[0]->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration;
    168                         int i;
    169                         for (i =1; i < mpeg4p2_ctx->b_frames_count; i++)
    170                         {
    171                             mpeg4p2_ctx->b_frames[i]->pts = mpeg4p2_ctx->b_frames[i-1]->dts + mpeg4p2_ctx->packet_duration;
    172                         }
    173                         ffmpeg_printf(100, "Writing second I/P packet(2)\n");
    174                         mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame);
    175                         set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
    176                         for (i =0; i< mpeg4p2_ctx->b_frames_count; i++)
    177                         {
    178                             ffmpeg_printf(100, "Writing B-frame[%d]\n", i);
    179                             mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->b_frames[i]);
    180                         }
    181                         mpeg4p2_ctx->b_frames_count = 0;
    182                         return 0;
    183                     }
    184                 }
    185                 break;
    186             case 3: // S-Frame
    187                 break;
    188             case 2: // B-Frame
    189                 if (!mpeg4p2_ctx->second_ip_frame)
    190                 {
    191                     ffmpeg_err("Cannot predict B-Frame without surrounding I/P-Frames, dropping...");
    192                     return 0;
    193                 }
    194                 if (mpeg4p2_ctx->b_frames_count == MPEG4P2_MAX_B_FRAMES_COUNT)
    195                 {
    196                     ffmpeg_err("Oops max B-Frames count = %d, reached", MPEG4P2_MAX_B_FRAMES_COUNT);
    197                     // not recoverable, to fix just increase MPEG4P2_MAX_B_FRAMES_COUNT
    198                     return -1;
    199                 }
    200                 else
    201                 {
    202                     ffmpeg_printf(100, "Storing B-Frame\n");
    203                     set_packet(&mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count++], pkt);
    204                     return 0;
    205                 }
    206             case 4:
    207             default:
    208                 break;
     104            }
     105        } else {
     106            ffmpeg_err("bsf setup failed error 0x%x\n", ret);
    209107        }
     108       
     109    } else {
     110        ret = -1;
    210111    }
    211     return 0;
     112    return ret;
    212113}
    213114
     115static void mpeg4p2_context_close(Mpeg4P2Context *context)
     116{
     117    if (context) {
     118        mpeg4p2_context_reset(context);
     119        free(context);
     120        return;
     121    }
     122}
     123
  • titan/libeplayer3/container/wrapped_ffmpeg.c

    r43806 r44958  
    143143        if (!avCodecCtx)
    144144        {
    145             fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id);
     145            ffmpeg_err("context3 alloc for stream %d failed\n", (int)stream->id);
    146146            return NULL;
    147147        }
     
    149149        if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0)
    150150        {
    151             fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id);
     151            ffmpeg_err("parameters to context for stream %d failed\n", (int)stream->id);
    152152            avcodec_free_context(&avCodecCtx);
    153153            return NULL;
     
    159159#endif
    160160        store_avcodec_context(avCodecCtx, cAVIdx, stream->id);
    161        
     161
    162162        return avCodecCtx;
    163163    }
     
    188188        }
    189189    }
    190 #endif   
    191 }
     190#endif
     191}
     192
     193static void wrapped_register_all(void)
     194{
     195#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
     196    avcodec_register_all();
     197    av_register_all();
     198#endif
     199}
     200
     201static int64_t wrapped_frame_get_best_effort_timestamp(const AVFrame *frame)
     202{
     203#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
     204    return av_frame_get_best_effort_timestamp(frame);
     205#else
     206    return frame->best_effort_timestamp;
     207#endif
     208}
     209
     210
  • titan/libeplayer3/external/ffmpeg/mpeg4audio.h

    r40322 r44958  
    107107
    108108int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb);
     109uint8_t get_chan_config(int channels);
    109110
    110111#endif /* AVCODEC_MPEG4AUDIO_H */
  • titan/libeplayer3/external/ffmpeg/src/latmenc.c

    r40322 r44958  
    2727#include <ffmpeg/mpeg4audio.h>
    2828#include <ffmpeg/latmenc.h>
     29#include "debug.h"
    2930
    3031/* ***************************** */
    3132/* Makros/Constants              */
    3233/* ***************************** */
    33 //#define LATMENC_SILENT
    34 
    35 #ifndef LATMENC_SILENT
    36 #define latmenc_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    37 #else
    38 #define latmenc_err(fmt, x...)
    39 #endif
    40 
    4134
    4235int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
  • titan/libeplayer3/external/ffmpeg/src/mpeg4audio.c

    r40322 r44958  
    7777    return *index == 0x0f ? get_bits(gb, 24) :
    7878        avpriv_mpeg4audio_sample_rates[*index];
     79}
     80
     81uint8_t get_chan_config(int channels)
     82{
     83    uint8_t chan_config = 0;
     84    int i;
     85    for (i=0; i<FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) {
     86        if (channels == ff_mpeg4audio_channels[i]) {
     87            chan_config = i;
     88            break;
     89        }
     90    }
     91    return chan_config;
    7992}
    8093
  • titan/libeplayer3/external/flv2mpeg4/src/bitwriter.h

    r40322 r44958  
    121121                break;
    122122        default:
    123 //              fprintf(stderr, "flash_bw error!(%d)\n", p->bitoffset);
    124123                break;
    125124        }
  • titan/libeplayer3/external/flv2mpeg4/src/flvdecoder.c

    r40322 r44958  
    465465        if (get_bits(p, 17) != 1)
    466466        {
    467                 fprintf(stderr, "start code error\n");
    468467                return -1;
    469468        }
     
    472471        if (tmp !=0 && tmp != 1)
    473472        {
    474                 fprintf(stderr, "picture format error\n");
    475473                return -1;
    476474        }
     
    479477        picture->frame_number = get_bits(p, 8);
    480478       
    481 //      printf("picture_format: %d\n", tmp);
    482 //      printf("picture_number: %d\n", get_bits(p, 8));
    483                
    484479        tmp = get_bits(p, 3);
    485480        switch (tmp)
     
    499494        case 6: width = 160, height = 120; break;
    500495        default:
    501                 fprintf(stderr, "size error\n");
    502496                return -1;
    503497        }
  • titan/libeplayer3/include/bcm_ioctls.h

    r40322 r44958  
    5252        STREAMTYPE_DIVX4 = 14,
    5353        STREAMTYPE_DIVX5 = 15,
    54         STREAMTYPE_VB6 = 18,
     54        STREAMTYPE_VB6 = 18, /* 17 is also valid for ZGEMMA STBs*/
    5555        STREAMTYPE_SPARK = 21,
     56        STREAMTYPE_MJPEG = 30,
     57        STREAMTYPE_RV30 = 31,  /* rv30: RealVideo 8, suspected to based largely on an early draft of H.264 (included with RealPlayer 8)*/
     58        STREAMTYPE_RV40 = 32, /* RealVideo 9, RealVideo 10*/
     59        STREAMTYPE_AVS2 = 40,
    5660} video_stream_type_t;
    57 
    58 
    5961
    6062typedef enum {
     
    7375        AUDIOTYPE_AC3_PLUS = 0x22,
    7476        AUDIOTYPE_AMR = 0x23,
    75         AUDIOTYPE_RAW = 0xf
     77        AUDIOTYPE_OPUS = 0x24,
     78        AUDIOTYPE_VORBIS = 0x25,
     79        AUDIOTYPE_RAW = 0x30
    7680} audio_stream_type_t;
    7781
  • titan/libeplayer3/include/common.h

    r42431 r44958  
    1010#include <pthread.h>
    1111
    12 typedef char PlayFilesTab_t[2];
    13 
    1412typedef struct PlayFiles_t
    1513{
    1614    char *szFirstFile;
    1715    char *szSecondFile;
     16    char *szFirstMoovAtomFile;
     17    char *szSecondMoovAtomFile;
     18    uint64_t iFirstFileSize;
     19    uint64_t iSecondFileSize;
     20    uint64_t iFirstMoovAtomOffset;
     21    uint64_t iSecondMoovAtomOffset;
    1822} PlayFiles_t;
    1923
     
    2529    ManagerHandler_t    *manager;
    2630} Context_t;
     31// obi
     32char* subtext;
     33// obi
     34int container_ffmpeg_update_tracks(Context_t *context, char *filename, int initial);
    2735
    28 char* subtext;
     36const char* GetGraphicSubPath();
     37int32_t GetGraphicWindowWidth();
     38int32_t GetGraphicWindowHeight();
    2939
    30 int container_ffmpeg_update_tracks(Context_t *context, char *filename, int initial);
     40void E2iSendMsg(const char * format, ...);
     41void E2iStartMsg(void);
     42void E2iEndMsg(void);
     43
    3144#endif
  • titan/libeplayer3/include/container.h

    r41347 r44958  
    2525CONTAINER_GET_BUFFER_STATUS,
    2626CONTAINER_STOP_BUFFER,
     27//obi
    2728CONTAINER_GET_SUBTEXT
     29//obi
    2830} ContainerCmd_t;
    2931
  • titan/libeplayer3/include/manager.h

    r42431 r44958  
    1818    MANAGER_UPDATED_TRACK_INFO,
    1919    MANAGER_REGISTER_UPDATED_TRACK_INFO,
     20    MANAGER_REF_LIST,
     21    MANAGER_REF_LIST_SIZE,
    2022} ManagerCmd_t;
    2123
     
    2830    char *                Name;
    2931    char *                Encoding;
     32// obi
    3033    char *                File;
     34// obi
    3135    int32_t               Id;
    3236    int32_t               AVIdx;
  • titan/libeplayer3/include/misc.h

    r40322 r44958  
    1 #ifndef misc_123
    2 #define misc_123
     1#ifndef _exteplayer3_misc_
     2#define _exteplayer3_misc_
    33
    44#include <dirent.h>
     
    2121} BitPacker_t;
    2222
     23typedef enum {
     24    STB_UNKNOWN,
     25    STB_DREAMBOX,
     26    STB_VUPLUS,
     27    STB_HISILICON,
     28    STB_OTHER=999,
     29} stb_type_t;
     30
    2331/* ***************************** */
    2432/* Makros/Constants              */
    2533/* ***************************** */
    26 
    2734#define INVALID_PTS_VALUE                       0x200000000ull
    2835
     
    3037/* Prototypes                    */
    3138/* ***************************** */
    32 
    3339void PutBits(BitPacker_t * ld, uint32_t code, uint32_t length);
    3440void FlushBits(BitPacker_t * ld);
    3541int8_t PlaybackDieNow(int8_t val);
     42stb_type_t GetSTBType();
    3643
    3744/* ***************************** */
     
    5259}
    5360
    54 /* the function returns the base name */
    55 static inline char * basename(char * name)
    56 {
    57   int i = 0;
    58   int pos = 0;
    59 
    60   while(name[i] != 0)
    61   {
    62     if(name[i] == '/')
    63       pos = i;
    64     i++;
    65   }
    66 
    67   if(name[pos] == '/')
    68     pos++;
    69 
    70   return name + pos;
    71 }
    72 
    73 /* the function returns the directry name */
    74 static inline char * dirname(char * name)
    75 {
    76   static char path[100];
    77   uint32_t i = 0;
    78   int32_t pos = 0;
    79 
    80   while((name[i] != 0) && (i < sizeof(path)))
    81   {
    82     if(name[i] == '/')
    83     {
    84         pos = i;
    85     }
    86     path[i] = name[i];
    87     i++;
    88   }
    89 
    90   path[i] = 0;
    91   path[pos] = 0;
    92 
    93   return path;
    94 }
    95 
    96 static inline int32_t IsDreambox()
    97 {
    98     struct stat buffer;   
    99     return (stat("/proc/stb/tpm/0/serial", &buffer) == 0);
    100 }
    101 
    10261static inline uint32_t ReadUint32(uint8_t *buffer)
    10362{
     
    11675}
    11776
    118 #endif
     77#endif // _exteplayer3_misc_
  • titan/libeplayer3/include/output.h

    r42431 r44958  
    2727    OUTPUT_GET_FRAME_COUNT,
    2828    OUTPUT_GET_PROGRESSIVE,
     29    OUTPUT_SET_BUFFER_SIZE,
     30    OUTPUT_GET_BUFFER_SIZE,
    2931} OutputCmd_t;
    3032
     
    5355typedef struct
    5456{
    55     uint32_t         trackId;
    56     uint8_t         *data;
    57     uint32_t         len;
    58    
    59     int64_t          pts;
    60     int64_t          durationMS; // duration in miliseconds
    61    
    62     char            *type;
     57    uint32_t          trackId;
     58    uint8_t          *data;
     59    uint32_t          len;
     60
     61    uint8_t          *extradata;
     62    uint32_t          extralen;
     63
     64    int64_t           pts;
     65    int64_t           dts;
     66    int64_t           durationMS; // duration in miliseconds
     67
     68    uint32_t         width;
     69    uint32_t         height;
     70
     71    char             *type;
    6372} SubtitleOut_t;
    6473
     
    6877    char * Name;
    6978    int32_t (* Command) (/*Context_t*/void  *, OutputCmd_t, void *);
    70     int32_t (* Write) (/*Context_t*/void  *, void* privateData);
     79    int32_t (* Write) (/*Context_t*/void  *, void *);
    7180    char ** Capabilities;
    7281
  • titan/libeplayer3/include/playback.h

    r42431 r44958  
    33#include <sys/types.h>
    44#include <stdint.h>
     5#include <stdbool.h>
     6
     7typedef void( * PlaybackDieNowCallback )();
     8bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback);
    59
    610typedef 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;
     
    3741    uint8_t isLoopMode;
    3842    uint8_t isTSLiveMode;
     43
     44    void *stamp;
    3945} PlaybackHandler_t;
    4046
  • titan/libeplayer3/include/writer.h

    r42431 r44958  
    55#include <stdio.h>
    66#include <stdint.h>
     7#include "common.h"
    78
    89typedef enum { eNone, eAudio, eVideo} eWriterType_t;
     10typedef ssize_t (* WriteV_t) (int, const struct iovec *, int);
    911
    1012typedef struct {
     
    2224    unsigned char          Version;
    2325    unsigned int           InfoFlags;
     26    WriteV_t               WriteV;
    2427} WriterAVCallData_t;
    25 
    26 
    2728
    2829typedef struct WriterCaps_s {
     
    5758extern Writer_t WriterAudioWMAPRO;
    5859extern Writer_t WriterAudioFLAC;
     60extern Writer_t WriterAudioAMR;
    5961extern Writer_t WriterAudioVORBIS;
    60 extern Writer_t WriterAudioAMR;
     62extern Writer_t WriterAudioOPUS;
    6163
    6264extern Writer_t WriterVideoMPEG1;
     
    7779extern Writer_t WriterVideoVP8;
    7880extern Writer_t WriterVideoVP9;
    79 extern Writer_t WriterVideoSPARK;
     81extern Writer_t WriterVideoMJPEG;
    8082extern Writer_t WriterFramebuffer;
    8183extern Writer_t WriterPipe;
     84extern Writer_t WriterVideoRV30;
     85extern Writer_t WriterVideoRV40;
     86extern Writer_t WriterVideoAVS2;
    8287
    8388Writer_t* getWriter(char* encoding);
     
    8590Writer_t* getDefaultVideoWriter();
    8691Writer_t* getDefaultAudioWriter();
    87 ssize_t write_with_retry(int fd, const void *buf, size_t size);
    88 ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic);
     92ssize_t write_with_retry(int fd, const void *buf, int size);
     93ssize_t writev_with_retry(int fd, const struct iovec *iov, int ic);
     94
     95ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size);
     96void FlushPipe(int pipefd);
     97
     98ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size);
     99
     100// Subtitles
     101
     102typedef enum {
     103    SUBTITLE_CODEC_ID_UNKNOWN,
     104    SUBTITLE_CODEC_ID_SUBRIP,
     105    SUBTITLE_CODEC_ID_ASS,
     106    SUBTITLE_CODEC_ID_WEBVTT,
     107    SUBTITLE_CODEC_ID_PGS,
     108    SUBTITLE_CODEC_ID_DVB,
     109    SUBTITLE_CODEC_ID_XSUB
     110} SubtitleCodecId_t;
     111
     112typedef struct {
     113    SubtitleCodecId_t codecId;
     114    uint32_t          trackId;
     115    uint8_t           *data;
     116    uint32_t          len;
     117    int64_t           pts;
     118    int64_t           dts;
     119    uint8_t           *private_data;
     120    uint32_t          private_size;
     121
     122    int64_t           durationMS; // duration in miliseconds
     123
     124    uint32_t         width;
     125    uint32_t         height;
     126} WriterSubCallData_t;
     127
     128typedef struct SubWriter_s {
     129    int32_t           (* open) (SubtitleCodecId_t codecId, uint8_t *extradata, int extradata_size);
     130    int32_t           (* close) ();
     131    int32_t           (* reset) ();
     132    int32_t           (* write) (WriterSubCallData_t *);
     133} SubWriter_t;
     134
     135extern SubWriter_t WriterSubPGS;
     136
    89137#endif
  • titan/libeplayer3/main/exteplayer.c

    r42431 r44958  
    2424#include <sched.h>
    2525#include <signal.h>
     26#include <inttypes.h>
     27#include <stdarg.h>
    2628
    2729#include <sys/ioctl.h>
     
    4143#include "misc.h"
    4244
     45#include "debug.h"
     46
    4347#define DUMP_BOOL(x) 0 == x ? "false"  : "true"
    4448#define IPTV_MAX_FILE_PATH 1024
     
    5256extern void      eac3_software_decoder_set(const int32_t val);
    5357extern void       mp3_software_decoder_set(const int32_t val);
     58extern void       amr_software_decoder_set(const int32_t val);
     59extern void    vorbis_software_decoder_set(const int32_t val);
     60extern void      opus_software_decoder_set(const int32_t val);
     61
    5462extern void            rtmp_proto_impl_set(const int32_t val);
    5563extern void        flv2mpeg4_converter_set(const int32_t val);
     
    8593}
    8694
    87 static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread */
     95static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread and kbhit */
    8896static int isPlaybackStarted = 0;
    8997static pthread_mutex_t playbackStartMtx;
    9098
     99static int32_t g_windows_width = 1280;
     100static int32_t g_windows_height = 720;
     101static char *g_graphic_sub_path;
     102
     103const char* GetGraphicSubPath()
     104{
     105    return g_graphic_sub_path;
     106}
     107
     108int32_t GetGraphicWindowWidth()
     109{
     110    return g_windows_width;
     111}
     112
     113int32_t GetGraphicWindowHeight()
     114{
     115    return g_windows_height;
     116}
     117
     118void E2iSendMsg(const char *format, ...)
     119{
     120    va_list args;
     121    va_start(args, format);
     122    vfprintf(stderr, format, args);
     123    va_end(args);
     124}
     125
     126void E2iStartMsg(void)
     127{
     128    flockfile(stderr);
     129}
     130
     131void E2iEndMsg(void)
     132{
     133    funlockfile(stderr);
     134}
     135
     136
     137static void TerminateWakeUp()
     138{
     139    int ret = write(g_pfd[1], "x", 1);
     140    if (ret != 1) {
     141        printf("TerminateWakeUp write return %d\n", ret);
     142    }
     143}
     144
    91145static void *TermThreadFun(void *arg)
    92146{
    93     const char *socket_path = "/tmp/iptvplayer_extplayer_term_fd";
     147    const char *socket_path = "/tmp/.exteplayerterm.socket";
    94148    struct sockaddr_un addr;
    95149    int fd = -1;
     
    136190    if (FD_ISSET(fd, &readfds))
    137191    {
    138         /*
    139         if ( (cl = accept(fd, NULL, NULL)) == -1)
    140         {
    141             perror("TermThreadFun accept error");
    142             goto finish;
    143         }
    144         */
    145        
    146192        pthread_mutex_lock(&playbackStartMtx);
    147193        PlaybackDieNow(1);
     
    184230{
    185231    struct timeval tv;
    186     fd_set read_fd;
    187 
    188     tv.tv_sec=1;
    189     tv.tv_usec=0;
    190 
    191     FD_ZERO(&read_fd);
    192     FD_SET(0,&read_fd);
    193 
    194     if(-1 == select(1, &read_fd, NULL, NULL, &tv))
     232    fd_set readfds;
     233
     234    tv.tv_sec = 1;
     235    tv.tv_usec = 0;
     236
     237    FD_ZERO(&readfds);
     238    FD_SET(0,&readfds);
     239    FD_SET(g_pfd[0], &readfds);
     240
     241    if(-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv))
    195242    {
    196243        return 0;
    197244    }
    198245
    199     if(FD_ISSET(0,&read_fd))
     246    if(FD_ISSET(0, &readfds))
    200247    {
    201248        return 1;
     
    256303            {
    257304                int i = 0;
    258                 fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]);
     305                E2iStartMsg();
     306                E2iSendMsg("{\"%c_%c\": [", argvBuff[0], argvBuff[1]);
    259307                for (i = 0; TrackList[i].Id >= 0; ++i)
    260308                {
    261309                    if(0 < i)
    262310                    {
    263                         fprintf(stderr, ", ");
     311                        E2iSendMsg(", ");
    264312                    }
    265                     fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", TrackList[i].Id , TrackList[i].Encoding, TrackList[i].Name);
     313                    E2iSendMsg("{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", TrackList[i].Id , TrackList[i].Encoding, TrackList[i].Name);
    266314                    free(TrackList[i].Encoding);
    267315                    free(TrackList[i].Name);
    268316                }
    269                 fprintf(stderr, "]}\n");
     317                E2iSendMsg("]}\n");
     318                E2iEndMsg();
    270319                free(TrackList);
    271320            }
     
    273322            {
    274323                // not tracks
    275                 fprintf(stderr, "{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]);
     324                E2iSendMsg("{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]);
    276325            }
    277326            break;
     
    286335                if ('a' == argvBuff[0] || 's' == argvBuff[0])
    287336                {
    288                     fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name);
     337                    E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name);
    289338                }
    290339                else // video
    291340                {
    292                     fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \
     341                    E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \
    293342                    argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den);
    294343                }
     
    302351                if ('a' == argvBuff[0] || 's' == argvBuff[0])
    303352                {
    304                     fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", "");
     353                    E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", "");
    305354                }
    306355                else // video
    307356                {
    308                     fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1);
     357                    E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1);
    309358                }
    310359            }
     
    354403                {
    355404                    commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void*)&id);
    356                     fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal);
     405                    E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal);
    357406                }
    358407            }
     
    369418}
    370419
    371 static int ParseParams(int argc,char* argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx)
     420static int ParseParams(int argc,char* argv[], PlayFiles_t *playbackFiles, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB)
    372421{   
    373422    int ret = 0;
     
    376425    int aopt = 0, bopt = 0;
    377426    char *copt = 0, *dopt = 0;
    378     while ( (c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:")) != -1)
     427    while ( (c = getopt(argc, argv, "G:W:H:A:V:U:we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:F:S:O:")) != -1)
    379428    {
    380429        switch (c)
    381430        {
     431        case 'G':
     432            g_graphic_sub_path = optarg;
     433        case 'W':
     434        {
     435            int val = atoi(optarg);
     436            if (val) g_windows_width = val;
     437            break;
     438        }
     439        case 'H':
     440        {
     441            int val = atoi(optarg);
     442            if (val) g_windows_height = val;
     443            break;
     444        }
    382445        case 'a':
    383446        {
     
    392455            eac3_software_decoder_set(1);
    393456            break;
     457        case 'A':
     458            printf("Software decoder will be used for AMR codec\n");
     459            amr_software_decoder_set(atoi(optarg));
     460            break;
     461        case 'V':
     462            printf("Software decoder will be used for VORBIS codec\n");
     463            vorbis_software_decoder_set(atoi(optarg));
     464            break;
     465        case 'U':
     466            printf("Software decoder will be used for OPUS codec\n");
     467            vorbis_software_decoder_set(atoi(optarg));
     468            break;
    394469        case '3':
    395470            printf("Software decoder will be used for AC3 codec\n");
     
    437512            break;
    438513        case 'x':
    439             strncpy(audioFile, optarg, IPTV_MAX_FILE_PATH-1);
    440             map_inter_file_path(audioFile);
     514            if (optarg[0] != '\0')
     515            {
     516                playbackFiles->szSecondFile = malloc(IPTV_MAX_FILE_PATH);
     517                playbackFiles->szSecondFile[0] = '\0';
     518                strncpy(playbackFiles->szSecondFile, optarg, IPTV_MAX_FILE_PATH-1);
     519                playbackFiles->szSecondFile[IPTV_MAX_FILE_PATH] = '\0';
     520                map_inter_file_path(playbackFiles->szSecondFile);
     521            }
    441522            break;
    442523        case 'h':
     
    486567            break;
    487568        }
     569        case 'b':
     570            *linuxDvbBufferSizeMB = 1024 * 1024 * atoi(optarg);
     571            break;
     572        case 'S':
     573            playbackFiles->iFirstFileSize = (uint64_t) strtoull(optarg, (char **)NULL, 10);
     574            break;
     575        case 'O':
     576            playbackFiles->iFirstMoovAtomOffset = (uint64_t) strtoull(optarg, (char **)NULL, 10);
     577            break;
     578        case 'F':
     579            if (optarg[0] != '\0')
     580            {
     581                playbackFiles->szFirstMoovAtomFile = malloc(IPTV_MAX_FILE_PATH);
     582                playbackFiles->szFirstMoovAtomFile[0] = '\0';
     583                strncpy(playbackFiles->szFirstMoovAtomFile, optarg, IPTV_MAX_FILE_PATH-1);
     584                playbackFiles->szFirstMoovAtomFile[IPTV_MAX_FILE_PATH] = '\0';
     585                map_inter_file_path(playbackFiles->szFirstMoovAtomFile);
     586            }
     587            break;
    488588        default:
    489589            printf ("?? getopt returned character code 0%o ??\n", c);
     
    495595    {
    496596        ret = 0;
    497        
     597        playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH);
     598        playbackFiles->szFirstFile[0] = '\0';
    498599        if(NULL == strstr(argv[optind], "://"))
    499600        {
    500             strcpy(file, "file://");
    501         }
    502         strcat(file, argv[optind]);
    503         map_inter_file_path(file);
    504         printf("file: [%s]\n", file);
     601            strcpy(playbackFiles->szFirstFile, "file://");
     602        }
     603        strcat(playbackFiles->szFirstFile, argv[optind]);
     604        playbackFiles->szFirstFile[IPTV_MAX_FILE_PATH] = '\0';
     605        map_inter_file_path(playbackFiles->szFirstFile);
     606        printf("file: [%s]\n", playbackFiles->szFirstFile);
    505607        ++optind;
    506608    }
     
    516618    pthread_t termThread;
    517619    int isTermThreadStarted = 0;
    518     char file[IPTV_MAX_FILE_PATH];
    519     memset(file, '\0', sizeof(file));
    520    
    521     char audioFile[IPTV_MAX_FILE_PATH];
    522     memset(audioFile, '\0', sizeof(audioFile));
    523620   
    524621    int audioTrackIdx = -1;
    525622    int subtitleTrackIdx = -1;
     623   
     624    uint32_t linuxDvbBufferSizeMB = 0;
    526625   
    527626    char argvBuff[256];
    528627    memset(argvBuff, '\0', sizeof(argvBuff));
    529628    int commandRetVal = -1;
     629
    530630    /* inform client that we can handle additional commands */
    531     fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 36);
    532 
    533     if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx))
     631    E2iSendMsg("{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 68);
     632
     633    PlayFiles_t playbackFiles;
     634    memset(&playbackFiles, 0x00, sizeof(playbackFiles));
     635
     636    if (0 != ParseParams(argc, argv, &playbackFiles, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
    534637    {
    535638        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");
     639        printf("[-b size] Linux DVB output buffer size in MB\n");
    536640        printf("[-a 0|1|2|3] AAC software decoding - 1 bit - AAC ADTS, 2 - bit AAC LATM\n");
    537641        printf("[-e] EAC3 software decoding\n");
     
    539643        printf("[-d] DTS software decoding\n");
    540644        printf("[-m] MP3 software decoding\n");
    541         printf("[-w] WMA1, WMA2, WMA/PRO software decoding\n");
     645        printf("[-A 0|1] disable|enable AMR software decoding\n");
     646        printf("[-V 0|1] disable|enable VORBIS software decoding\n");
     647        printf("[-U 0|1] disable|enable AMR software decoding\n");
     648        printf("[-w] WMA2, WMA/PRO software decoding\n");
    542649        printf("[-l] software decoder use LPCM for injection (otherwise wav PCM will be used)\n");
    543650        printf("[-s] software decoding as stereo [downmix]\n");
     
    547654        printf("[-i] play in infinity loop\n");
    548655        printf("[-v] switch to live TS stream mode\n");
    549         printf("[-n 0|1|2] rtmp force protocol implementation auto(0) native/ffmpeg(1) or librtmp(2)\n");       
     656        printf("[-n 0|1|2] rtmp force protocol implementation auto(0) native/ffmpeg(1) or librtmp(2)\n");
    550657        printf("[-o 0|1] set progressive download\n");
    551658        printf("[-p value] nice value\n");
     
    560667        printf("[-1 idx] audio MPEG-DASH representation index\n");
    561668        printf("[-f ffopt=ffval] any other ffmpeg option\n");
    562        
     669        printf("[-F path to additional file with moov atom data (used for mp4 playback in progressive download mode)\n");
     670        printf("[-O moov atom offset in the original file (used for mp4 playback in progressive download mode)\n");
     671        printf("[-S remote file size (used for mp4 playback in progressive download mode)\n");
     672        printf("[-G path (directory where graphic subtitles frames will be saved)\n");
     673        printf("[-W osd window width (width of the window used to scale graphic subtitle frame)\n");
     674        printf("[-H osd window height (height of the window used to scale graphic subtitle frame)\n");
    563675        exit(1);
    564676    }
     
    599711            isTermThreadStarted = 1;
    600712    } while(0);
    601 
     713   
    602714    g_player->playback    = &PlaybackHandler;
    603715    g_player->output      = &OutputHandler;
     
    609721
    610722    SetBuffering();
    611    
     723
    612724    //Registrating output devices
    613725    g_player->output->Command(g_player, OUTPUT_ADD, "audio");
    614726    g_player->output->Command(g_player, OUTPUT_ADD, "video");
    615727    g_player->output->Command(g_player, OUTPUT_ADD, "subtitle");
    616 
     728   
     729    //Set LINUX DVB additional write buffer size
     730    if (linuxDvbBufferSizeMB)
     731        g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB);
     732   
    617733    g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
    618     if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
     734    if (strncmp(playbackFiles.szFirstFile, "rtmp", 4) && strncmp(playbackFiles.szFirstFile, "ffrtmp", 4))
    619735    {
    620736        g_player->playback->noprobe = 1;
    621737    }
    622738
    623     PlayFiles_t playbackFiles = {file, NULL};
    624     if('\0' != audioFile[0])
    625     {
    626         playbackFiles.szSecondFile = audioFile;
    627     }
    628    
    629739    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles);
    630     fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal);
     740    E2iSendMsg("{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, playbackFiles.szFirstFile, commandRetVal);
    631741    if(commandRetVal < 0)
    632742    {
     
    644754       
    645755        commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL);
    646         fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal);
     756        E2iSendMsg("{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal);
    647757        commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL);
    648         fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal);
     758        E2iSendMsg("{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal);
    649759       
    650760        if (g_player->playback->isPlaying)
    651761        {
     762            PlaybackDieNowRegisterCallback(TerminateWakeUp);
     763
    652764            HandleTracks(g_player->manager->video, (PlaybackCmd_t)-1, "vc");
    653765            HandleTracks(g_player->manager->audio, (PlaybackCmd_t)-1, "al");
     
    660772            HandleTracks(g_player->manager->audio, (PlaybackCmd_t)-1, "ac");
    661773           
     774           
    662775            HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t)-1, "sl");
    663776            if (subtitleTrackIdx >= 0)
     
    670783        }
    671784
    672         while(g_player->playback->isPlaying)
     785        while(g_player->playback->isPlaying && 0 == PlaybackDieNow(0))
    673786        {
    674787            /* we made fgets non blocking */
     
    705818            {
    706819                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_STOP, NULL);
    707                 fprintf(stderr, "{\"PLAYBACK_STOP\":{\"sts\":%d}}\n", commandRetVal);
     820                E2iSendMsg("{\"PLAYBACK_STOP\":{\"sts\":%d}}\n", commandRetVal);
    708821                break;
    709822            }
     
    711824            {
    712825                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_CONTINUE, NULL);
    713                 fprintf(stderr, "{\"PLAYBACK_CONTINUE\":{\"sts\":%d}}\n", commandRetVal);
     826                E2iSendMsg("{\"PLAYBACK_CONTINUE\":{\"sts\":%d}}\n", commandRetVal);
    714827                break;
    715828            }
     
    717830            {
    718831                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PAUSE, NULL);
    719                 fprintf(stderr, "{\"PLAYBACK_PAUSE\":{\"sts\":%d}}\n", commandRetVal);
     832                E2iSendMsg("{\"PLAYBACK_PAUSE\":{\"sts\":%d}}\n", commandRetVal);
    720833                break;
    721834            }
     
    726839
    727840                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed);
    728                 fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
     841                E2iSendMsg("{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
    729842                break;
    730843            }
     
    735848                {
    736849                    progressive_playback_set(flags);
    737                     fprintf(stderr, "{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags);
     850                    E2iSendMsg("{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags);
    738851                }
    739852                break;
     
    745858
    746859                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed);
    747                 fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
     860                E2iSendMsg("{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
    748861                break;
    749862            }
     
    754867
    755868                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed);
    756                 fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
     869                E2iSendMsg("{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
    757870                break;
    758871            }
     
    769882                {
    770883                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
    771                     fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
     884                    E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal);
    772885
    773886                    lengthInt = (int32_t)length;
     
    781894                       
    782895                        commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void*)&sec);
    783                         fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal);
     896                        E2iSendMsg("{\"PLAYBACK_SEEK_ABS\":{\"sec\":%"PRId64", \"sts\":%d}}\n", sec, commandRetVal);
    784897                    }
    785898                }
     
    802915                if (0 == commandRetVal)
    803916                {
    804                     fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal);
     917                    E2iSendMsg("{\"J\":{\"ms\":%"PRId64"}}\n", pts / 90);
    805918                }
    806919                if(0 == commandRetVal || force)
    807920                {                   
    808921                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
    809                     fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
     922                    E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal);
    810923                   
    811924                    lengthInt = (int32_t)length;
     
    831944                    }
    832945                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK, (void*)&sec);
    833                     fprintf(stderr, "{\"PLAYBACK_SEEK\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal);
     946                    E2iSendMsg("{\"PLAYBACK_SEEK\":{\"sec\":%"PRId64", \"sts\":%d}}\n", sec, commandRetVal);
    834947                }
    835948                break;
     
    839952                int64_t length = 0;
    840953                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
    841                 fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
     954                E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal);
    842955                break;
    843956            }
     
    848961                if (0 == commandRetVal)
    849962                {
    850                     fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal);
     963                    int64_t lastPts = 0;
     964                    commandRetVal = 1;
     965                    if (g_player->container && g_player->container->selectedContainer)
     966                    {
     967                        commandRetVal = g_player->container->selectedContainer->Command(g_player->container, CONTAINER_LAST_PTS, &lastPts);
     968                    }
     969                   
     970                    if (0 == commandRetVal && lastPts != INVALID_PTS_VALUE)
     971                    {
     972                        E2iSendMsg("{\"J\":{\"ms\":%"PRId64",\"lms\":%"PRId64"}}\n", pts / 90, lastPts / 90);
     973                    }
     974                    else
     975                    {
     976                        E2iSendMsg("{\"J\":{\"ms\":%"PRId64"}}\n", pts / 90);
     977                    }
    851978                }
    852979                break;
     
    857984                if(ptrP)
    858985                {
    859                     fprintf(stderr, "{\"PLAYBACK_INFO\":{ \"isPlaying\":%s, \"isPaused\":%s, \"isForwarding\":%s, \"isSeeking\":%s, \"isCreationPhase\":%s,", \
     986                    E2iSendMsg("{\"PLAYBACK_INFO\":{ \"isPlaying\":%s, \"isPaused\":%s, \"isForwarding\":%s, \"isSeeking\":%s, \"isCreationPhase\":%s,", \
    860987                    DUMP_BOOL(ptrP->isPlaying), DUMP_BOOL(ptrP->isPaused), DUMP_BOOL(ptrP->isForwarding), DUMP_BOOL(ptrP->isSeeking), DUMP_BOOL(ptrP->isCreationPhase) );
    861                     fprintf(stderr, "\"BackWard\":%d, \"SlowMotion\":%d, \"Speed\":%d, \"AVSync\":%d,", ptrP->BackWard, ptrP->SlowMotion, ptrP->Speed, ptrP->AVSync);
    862                     fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \
     988                    E2iSendMsg("\"BackWard\":%d, \"SlowMotion\":%d, \"Speed\":%d, \"AVSync\":%d,", ptrP->BackWard, ptrP->SlowMotion, ptrP->Speed, ptrP->AVSync);
     989                    E2iSendMsg(" \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \
    863990                    DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested) );
    864991                }
     
    8751002                    {
    8761003                        ptrP->isLoopMode = '1' == argvBuff[1] ? 1 : 0;
    877                         fprintf(stderr, "{\"N\":{ \"isLoop\":%s }}\n", DUMP_BOOL(ptrP->isLoopMode));
     1004                        E2iSendMsg("{\"N\":{ \"isLoop\":%s }}\n", DUMP_BOOL(ptrP->isLoopMode));
    8781005                    }
    8791006                }
     
    9051032    close(g_pfd[0]);
    9061033    close(g_pfd[1]);
    907 
    908     //printOutputCapabilities();
    909 
     1034   
    9101035    exit(0);
    9111036}
  • titan/libeplayer3/manager/audio.c

    r42431 r44958  
    2828#include "manager.h"
    2929#include "common.h"
     30#include "debug.h"
    3031
    3132/* ***************************** */
     
    3334/* ***************************** */
    3435#define TRACKWRAP 20
    35 
    36 //#define SAM_WITH_DEBUG
    37 #ifdef SAM_WITH_DEBUG
    38 #define AUDIO_MGR_DEBUG
    39 #else
    40 #define AUDIO_MGR_SILENT
    41 #endif
    42 
    43 #ifdef AUDIO_MGR_DEBUG
    44 
    45 static short debug_level = 40;
    46 
    47 #define audio_mgr_printf(level, fmt, x...) do { \
    48 if (debug_level >= level) printf("[%s:%s] \n" fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    49 #else
    50 #define audio_mgr_printf(level, x...)
    51 #endif
    52 
    53 #ifndef AUDIO_MGR_SILENT
    54 #define audio_mgr_err(x...) do { printf(x); } while (0)
    55 #else
    56 #define audio_mgr_err(x...)
    57 #endif
    5836
    5937/* Error Constants */
     
    220198        break;
    221199    }
     200    case MANAGER_REF_LIST:
     201    {
     202        *((Track_t **)argument) = Tracks;
     203        break;
     204    }
     205    case MANAGER_REF_LIST_SIZE:
     206    {
     207        *((int*)argument) = TrackCount;
     208        break;
     209    }
     210   
    222211    case MANAGER_GET:
    223212    {
  • titan/libeplayer3/manager/subtitle.c

    r40322 r44958  
    2424#include <stdlib.h>
    2525#include <string.h>
     26#include <assert.h>
    2627
    2728#include "manager.h"
    2829#include "common.h"
     30#include "debug.h"
    2931
    3032/* ***************************** */
    3133/* Makros/Constants              */
    3234/* ***************************** */
    33 #define TRACKWRAP 20
    34 
    35 //#define SAM_WITH_DEBUG
    36 #ifdef SAM_WITH_DEBUG
    37 #define SUBTITLE_MGR_DEBUG
    38 #else
    39 #define SUBTITLE_MGR_SILENT
    40 #endif
    41 
    42 
    43 #ifdef SUBTITLE_MGR_DEBUG
    44 
    45 static short debug_level = 10;
    46 
    47 #define subtitle_mgr_printf(level, x...) do { \
    48 if (debug_level >= level) printf(x); } while (0)
    49 #else
    50 #define subtitle_mgr_printf(level, x...)
    51 #endif
    52 
    53 #ifndef SUBTITLE_MGR_SILENT
    54 #define subtitle_mgr_err(x...) do { printf(x); } while (0)
    55 #else
    56 #define subtitle_mgr_err(x...)
    57 #endif
     35#define TRACKWRAP 10
    5836
    5937/* Error Constants */
     
    7250
    7351static Track_t * Tracks = NULL;
     52static int TrackSlotCount = 0;
    7453static int TrackCount = 0;
    7554static int CurrentTrack = -1; //no as default.
     
    8867    subtitle_mgr_printf(10, "%s::%s %s %s %d\n", FILENAME, __FUNCTION__, track.Name, track.Encoding, track.Id);
    8968
    90     if (Tracks == NULL)
    91     {
    92         Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
    93         for (i = 0; i < TRACKWRAP; ++i)
    94         {
    95             Tracks[i].Id = -1;
     69    if (TrackCount == TrackSlotCount)
     70    {
     71        static Track_t *t;
     72        t = realloc(Tracks, (TrackSlotCount + TRACKWRAP) * sizeof(Track_t));
     73        if (t)
     74        {
     75            Tracks = t;
     76            TrackSlotCount += TRACKWRAP;
     77            for (i = TrackCount; i < TrackSlotCount; ++i)
     78            {
     79                Tracks[i].Id = -1;
     80            }
     81        }
     82        else
     83        {
     84            subtitle_mgr_err("%s:%s realloc failed\n", FILENAME, __FUNCTION__);
     85            return cERR_SUBTITLE_MGR_ERROR;
    9686        }
    9787    }
     
    10494
    10595   
    106     for (i = 0; i < TRACKWRAP; ++i)
     96    for (i = 0; i < TrackSlotCount; ++i)
    10797    {
    10898        if (Tracks[i].Id == track.Id)
     
    113103    }
    114104
    115     if (TrackCount < TRACKWRAP)
     105    if (TrackCount < TrackSlotCount)
    116106    {
    117107        copyTrack(&Tracks[TrackCount], &track);
     
    120110    else
    121111    {
    122         subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
     112        subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TrackSlotCount);
    123113        return cERR_SUBTITLE_MGR_ERROR;
    124114    }
     
    189179        }
    190180        TrackCount = 0;
     181        TrackSlotCount = 0;
    191182        context->playback->isSubtitle = 0;
    192183    }
  • titan/libeplayer3/manager/video.c

    r40322 r44958  
    2727#include "manager.h"
    2828#include "common.h"
     29#include "debug.h"
    2930
    3031/* ***************************** */
     
    3233/* ***************************** */
    3334#define TRACKWRAP 4
    34 
    35 #ifdef SAM_WITH_DEBUG
    36 #define VIDEO_MGR_DEBUG
    37 #else
    38 #define VIDEO_MGR_SILENT
    39 #endif
    40 
    41 #ifdef VIDEO_MGR_DEBUG
    42 
    43 static short debug_level = 0;
    44 
    45 #define video_mgr_printf(level, x...) do { \
    46 if (debug_level >= level) printf(x); } while (0)
    47 #else
    48 #define video_mgr_printf(level, x...)
    49 #endif
    50 
    51 #ifndef VIDEO_MGR_SILENT
    52 #define video_mgr_err(x...) do { printf(x); } while (0)
    53 #else
    54 #define video_mgr_err(x...)
    55 #endif
    56 
    5735/* Error Constants */
    5836#define cERR_VIDEO_MGR_NO_ERROR        0
    5937#define cERR_VIDEO_MGR_ERROR          -1
    6038
    61 static const char FILENAME[] = __FILE__;
    62 
    6339/* ***************************** */
    6440/* Types                         */
     
    6844/* Varaibles                     */
    6945/* ***************************** */
    70 
    71 static Track_t * Tracks = NULL;
     46static Track_t *Tracks = NULL;
    7247static int TrackCount = 0;
    7348static int CurrentTrack = 0; //TRACK[0] as default.
    7449
    7550static void (* updatedTrackInfoFnc)(void) = NULL;
     51
    7652/* ***************************** */
    7753/* Prototypes                    */
     
    8359
    8460static int ManagerAdd(Context_t  *context, Track_t track) {
    85     video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
     61    video_mgr_printf(10, "\n");
    8662
    8763    if (Tracks == NULL)
     
    9773    if (Tracks == NULL)
    9874    {
    99         video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
     75        video_mgr_err("malloc failed\n");
    10076        return cERR_VIDEO_MGR_ERROR;
    10177    }
     
    11894    else
    11995    {
    120         video_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
     96        video_mgr_err("TrackCount out if range %d - %d\n", TrackCount, TRACKWRAP);
    12197        return cERR_VIDEO_MGR_ERROR;
    12298    }
     
    127103    }
    128104
    129     video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
     105    video_mgr_printf(10, "\n");
    130106    return cERR_VIDEO_MGR_NO_ERROR;
    131107}
     
    136112    char ** tracklist = NULL;
    137113
    138     video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
     114    video_mgr_printf(10, "\n");
    139115
    140116    if (Tracks != NULL)
     
    145121        if (tracklist == NULL)
    146122        {
    147             video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
     123            video_mgr_err("malloc failed\n");
    148124            return NULL;
    149125        }
     
    164140    }
    165141
    166     video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
     142    video_mgr_printf(10, "return %p (%d - %d)\n", tracklist, j, TrackCount);
    167143    return tracklist;
    168144}
     
    172148    int i = 0;
    173149
    174     video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
     150    video_mgr_printf(10, "\n");
    175151
    176152    if(Tracks != NULL)
     
    185161    else
    186162    {
    187         video_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
     163        video_mgr_err("nothing to delete!\n");
    188164        return cERR_VIDEO_MGR_ERROR;
    189165    }
     
    193169    context->playback->isVideo = 0;
    194170
    195     video_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
     171    video_mgr_printf(10, "return no error\n");
    196172    return cERR_VIDEO_MGR_NO_ERROR;
    197173}
     
    201177    int ret = cERR_VIDEO_MGR_NO_ERROR;
    202178
    203     video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
     179    video_mgr_printf(10, "\n");
    204180
    205181    switch(command)
     
    257233    case MANAGER_GET_TRACK:
    258234    {
    259         video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
     235        video_mgr_printf(20, "MANAGER_GET_TRACK\n");
    260236
    261237        if ((TrackCount > 0) && (CurrentTrack >=0))
     
    307283        if (i == TrackCount)
    308284        {
    309             video_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
     285            video_mgr_err("track id %d unknown\n", *((int*)argument));
    310286            ret = cERR_VIDEO_MGR_ERROR;
    311287        }
     
    338314    }
    339315    default:
    340         video_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
     316        video_mgr_err("ContainerCmd %d not supported!\n", command);
    341317        ret = cERR_VIDEO_MGR_ERROR;
    342318        break;
    343319    }
    344320
    345     video_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
     321    video_mgr_printf(10, "returning %d\n", ret);
    346322    return ret;
    347323}
  • titan/libeplayer3/output/linuxdvb_mipsel.c

    r42431 r44958  
    2323
    2424#include <stdio.h>
     25#include <inttypes.h>
    2526#include <string.h>
    2627#include <stdlib.h>
    2728#include <unistd.h>
     29#include <stdbool.h>
    2830#include <fcntl.h>
    2931#include <sys/types.h>
     
    4143
    4244#include "common.h"
     45#include "debug.h"
    4346#include "output.h"
    4447#include "writer.h"
     
    5053/* ***************************** */
    5154
    52 //#define LINUXDVB_DEBUG
    53 #define LINUXDVB_SILENT
    54 
    55 static unsigned short debug_level = 0;
    56 
    57 static const char FILENAME[] = __FILE__;
    58 
    59 #ifdef LINUXDVB_DEBUG
    60 #define linuxdvb_printf(level, fmt, x...) do { \
    61 if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); } while (0)
    62 #else
    63 #define linuxdvb_printf(x...)
    64 #endif
    65 
    66 #ifndef LINUXDVB_SILENT
    67 #define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    68 #else
    69 #define linuxdvb_err(x...)
    70 #endif
    71 
    7255#define cERR_LINUXDVB_NO_ERROR      0
    7356#define cERR_LINUXDVB_ERROR        -1
    7457
    75 static const char VIDEODEV[]    = "/dev/dvb/adapter0/video0";
    76 static const char AUDIODEV[]    = "/dev/dvb/adapter0/audio0";
     58static const char VIDEODEV[] = "/dev/dvb/adapter0/video0";
     59static const char AUDIODEV[] = "/dev/dvb/adapter0/audio0";
    7760
    7861static int videofd      = -1;
     
    8972
    9073unsigned long long int sCURRENT_PTS = 0;
     74bool isBufferedOutput = false;
    9175
    9276pthread_mutex_t LinuxDVBmutex;
     
    9579/* Prototypes                    */
    9680/* ***************************** */
     81int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx);
     82int32_t LinuxDvbBuffClose(Context_t *context);
     83int32_t LinuxDvbBuffFlush(Context_t *context);
     84int32_t LinuxDvbBuffResume(Context_t *context);
     85
     86ssize_t BufferingWriteV(int fd, const struct iovec *iov, int ic);
     87int32_t LinuxDvbBuffSetSize(const uint32_t bufferSize);
     88uint32_t LinuxDvbBuffGetSize();
     89
    9790int LinuxDvbStop(Context_t  *context, char * type);
    9891
     
    10194/* ***************************** */
    10295
    103 void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
    104 
    105     linuxdvb_printf(250, "requesting mutex\n");
    106 
    107     pthread_mutex_lock(&LinuxDVBmutex);
    108 
    109     linuxdvb_printf(250, "received mutex\n");
    110 }
    111 
    112 void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
    113     pthread_mutex_unlock(&LinuxDVBmutex);
    114 
    115     linuxdvb_printf(250, "released mutex\n");
    116 
    117 }
    118 
    119 static int LinuxDvbMapBypassMode(int bypass)
    120 {
    121     if( 0x30 == bypass && IsDreambox() )
    122     {
    123         return 0x0f;
    124     }
     96#define getLinuxDVBMutex() pthread_mutex_lock(&LinuxDVBmutex)
     97#define releaseLinuxDVBMutex() pthread_mutex_unlock(&LinuxDVBmutex)
     98
     99static int LinuxDvbMapBypassMode(int bypass, bool primary)
     100{
     101    if (STB_DREAMBOX == GetSTBType()) {
     102        primary = !primary;
     103    }
     104
     105    switch(bypass) {
     106        case AUDIOTYPE_RAW:
     107            bypass = primary ? 0x30 : 0xf;
     108            break;
     109        case AUDIOTYPE_AC3_PLUS:
     110            bypass = primary ? 0x22 : 7;
     111            break;
     112        case AUDIOTYPE_WMA:
     113            bypass = primary ? 0x20 : 0xd;
     114            break;
     115        case AUDIOTYPE_WMA_PRO:
     116            bypass = primary ? 0x21 : 0xe;
     117            break;
     118        default:
     119            break;
     120    };
     121
    125122    return bypass;
    126123}
    127124
    128 int LinuxDvbOpen(Context_t  *context __attribute__((unused)), char * type) {
    129     unsigned char video = !strcmp("video", type);
    130     unsigned char audio = !strcmp("audio", type);
     125static int LinuxDvbMapStreamType(int streamtype, bool primary)
     126{
     127    if (STB_DREAMBOX == GetSTBType()) {
     128        primary = !primary;
     129    }
     130
     131    switch(streamtype) {
     132        case STREAMTYPE_MPEG4_H265:
     133            streamtype = primary ? 7 : 22;
     134            break;
     135        case STREAMTYPE_VC1:
     136            streamtype = primary ? 3 : 16;
     137            break;
     138        case STREAMTYPE_VC1_SM:
     139            streamtype = primary ? 5 : 17;
     140            break;
     141        case STREAMTYPE_VB8:
     142            streamtype = primary ? 8 : 20;
     143            break;
     144        case STREAMTYPE_VB9:
     145            streamtype = primary ? 9 : 23;
     146            break;
     147        default:
     148            break;
     149    };
     150
     151    return streamtype;
     152}
     153
     154int LinuxDvbOpen(Context_t  *context __attribute__((unused)), char *type)
     155{
     156    uint8_t video = !strcmp("video", type);
     157    uint8_t audio = !strcmp("audio", type);
    131158
    132159    linuxdvb_printf(10, "v%d a%d\n", video, audio);
     
    138165        if (videofd < 0)
    139166        {
    140             linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno);
    141             linuxdvb_err("%s\n", strerror(errno));
     167            linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno));
    142168            return cERR_LINUXDVB_ERROR;
    143169        }
     
    145171        if (ioctl( videofd, VIDEO_CLEAR_BUFFER) == -1)
    146172        {
    147             linuxdvb_err("ioctl failed with errno %d\n", errno);
    148             linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
     173            linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    149174        }
    150175
    151176        if (ioctl( videofd, VIDEO_SELECT_SOURCE, (void*)VIDEO_SOURCE_MEMORY) == -1)
    152177        {
    153             linuxdvb_err("ioctl failed with errno %d\n", errno);
    154             linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno));
     178            linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
    155179        }
    156180       
    157181        if (ioctl(videofd, VIDEO_FREEZE) == -1)
    158182        {
    159             linuxdvb_err("ioctl failed with errno %d\n", errno);
    160             linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
    161         }
    162 
     183            linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno));
     184        }
     185
     186        if (isBufferedOutput)
     187            LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex);
    163188    }
    164189    if (audio && audiofd < 0)
     
    168193        if (audiofd < 0)
    169194        {
    170             linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno);
    171             linuxdvb_err("%s\n", strerror(errno));
    172            
     195            linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno));
    173196            return cERR_LINUXDVB_ERROR;
    174197        }
     
    176199        if (ioctl( audiofd, AUDIO_CLEAR_BUFFER) == -1)
    177200        {
    178             linuxdvb_err("ioctl failed with errno %d\n", errno);
    179             linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
     201            linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    180202        }
    181203
    182204        if (ioctl( audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1)
    183205        {
    184             linuxdvb_err("ioctl failed with errno %d\n", errno);
    185             linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno));
     206            linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
    186207        }
    187208       
    188209        if (ioctl( audiofd, AUDIO_PAUSE) == -1)
    189210        {
    190             linuxdvb_err("ioctl failed with errno %d\n", errno);
    191             linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
     211            linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno));
    192212        }
    193213       
     214        if (isBufferedOutput)
     215            LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex);
    194216    }
    195217
     
    197219}
    198220
    199 int LinuxDvbClose(Context_t  *context, char * type)
    200 {
    201     unsigned char video = !strcmp("video", type);
    202     unsigned char audio = !strcmp("audio", type);
     221int LinuxDvbClose(Context_t  *context, char *type)
     222{
     223    uint8_t video = !strcmp("video", type);
     224    uint8_t audio = !strcmp("audio", type);
    203225
    204226    linuxdvb_printf(10, "v%d a%d\n", video, audio);
     
    210232    LinuxDvbStop(context, type);
    211233
    212     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     234    getLinuxDVBMutex();
     235   
     236    if (isBufferedOutput)
     237        LinuxDvbBuffClose(context);
    213238
    214239    if (video && videofd != -1)
     
    223248    }
    224249
    225     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     250    releaseLinuxDVBMutex();
    226251    return cERR_LINUXDVB_NO_ERROR;
    227252}
    228253
    229 int LinuxDvbPlay(Context_t  *context, char * type) {
    230     int ret = cERR_LINUXDVB_NO_ERROR;
    231     Writer_t* writer;
    232 
    233     unsigned char video = !strcmp("video", type);
    234     unsigned char audio = !strcmp("audio", type);
     254int LinuxDvbPlay(Context_t  *context, char *type) {
     255    int32_t ret = cERR_LINUXDVB_NO_ERROR;
     256    Writer_t *writer;
     257
     258    uint8_t video = !strcmp("video", type);
     259    uint8_t audio = !strcmp("audio", type);
    235260
    236261    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    237262
    238263    if (video && videofd != -1) {
    239         char * Encoding = NULL;
     264        char *Encoding = NULL;
    240265        context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
    241266
     
    243268
    244269        writer = getWriter(Encoding);
    245        
    246         // SULGE VU 4K dont like this
    247         /*
    248         if (0 != ioctl(videofd, VIDEO_STOP))
    249         {
    250             linuxdvb_err("ioctl failed with errno %d\n", errno);
    251             linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
    252             ret = cERR_LINUXDVB_ERROR;
    253         }
    254         */
    255 
    256270        if (writer == NULL)
    257271        {
     
    262276        {
    263277            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    264             if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) writer->caps->dvbStreamType) == -1)
    265             {
    266                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    267                 linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
     278            ret = ioctl( videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, true));
     279            if (ret < 0) ret = ioctl( videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, false));
     280            if (ret < 0)
     281            {
     282                linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno));
    268283                ret = cERR_LINUXDVB_ERROR;
    269284            }
     
    273288        if (0 != ioctl(videofd, VIDEO_PLAY))
    274289        {
    275             linuxdvb_err("ioctl failed with errno %d\n", errno);
    276             linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
     290            linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
    277291            ret = cERR_LINUXDVB_ERROR;
    278292        }
     
    280294        if (ioctl(videofd, VIDEO_CONTINUE) == -1)
    281295        {
    282             linuxdvb_err("ioctl failed with errno %d\n", errno);
    283             linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
     296            linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
    284297        }
    285298       
    286299        if (ioctl( videofd, VIDEO_CLEAR_BUFFER) == -1)
    287300        {
    288             linuxdvb_err("ioctl failed with errno %d\n", errno);
    289             linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
     301            linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    290302        }
    291303    }
     
    298310        writer = getWriter(Encoding);
    299311       
    300         // SULGE VU 4K dont like this
    301         /*
    302         if (0 != ioctl(audiofd, AUDIO_STOP))
    303         {
    304             linuxdvb_err("ioctl failed with errno %d\n", errno);
    305             linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
    306             ret = cERR_LINUXDVB_ERROR;
    307         }
    308         */
    309 
    310312        if (writer == NULL)
    311313        {
     
    316318        {
    317319            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    318             if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) < 0)
    319             {
    320                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    321                 linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
     320            ret = ioctl( audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, true));
     321            if (ret < 0) ret = ioctl( audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, false));
     322            if (ret < 0)
     323            {
     324                linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno));
    322325                ret = cERR_LINUXDVB_ERROR;
    323326            }
     
    326329        if (ioctl(audiofd, AUDIO_PLAY) < 0)
    327330        {
    328             linuxdvb_err("ioctl failed with errno %d\n", errno);
    329             linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
     331            linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
    330332            ret = cERR_LINUXDVB_ERROR;
    331333        }
     
    333335        if (ioctl(audiofd, AUDIO_CONTINUE) < 0)
    334336        {
    335             linuxdvb_err("ioctl failed with errno %d\n", errno);
    336             linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
     337            linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
    337338            ret = cERR_LINUXDVB_ERROR;
    338339        }
     
    352353    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    353354
    354     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     355    getLinuxDVBMutex();
    355356
    356357    if (video && videofd != -1)
     
    358359        if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
    359360        {
    360             linuxdvb_err("ioctl failed with errno %d\n", errno);
    361             linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
     361            linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    362362        }
    363363       
    364364        if (ioctl(videofd, VIDEO_STOP) == -1)
    365365        {
    366             linuxdvb_err("ioctl failed with errno %d\n", errno);
    367             linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
     366            linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
    368367            ret = cERR_LINUXDVB_ERROR;
    369368        }
     
    371370        ioctl(videofd, VIDEO_SLOWMOTION, 0);
    372371        ioctl(videofd, VIDEO_FAST_FORWARD, 0);
    373 
    374372        ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
    375373    }
     
    377375        if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
    378376        {
    379             linuxdvb_err("ioctl failed with errno %d\n", errno);
    380             linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
    381         }
    382 
    383         /* set back to normal speed (end trickmodes) */
    384         // if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
    385         // {
    386             // linuxdvb_err("ioctl failed with errno %d\n", errno);
    387             // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
    388         // }
     377            linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
     378        }
     379
    389380        if (ioctl(audiofd, AUDIO_STOP) == -1)
    390381        {
    391             linuxdvb_err("ioctl failed with errno %d\n", errno);
    392             linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
     382            linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
    393383            ret = cERR_LINUXDVB_ERROR;
    394384        }
     
    396386    }
    397387
    398     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    399 
    400     return ret;
    401 }
    402 
    403 int LinuxDvbPause(Context_t  *context __attribute__((unused)), char * type) {
    404     int ret = cERR_LINUXDVB_NO_ERROR;
    405     unsigned char video = !strcmp("video", type);
    406     unsigned char audio = !strcmp("audio", type);
     388    releaseLinuxDVBMutex();
     389
     390    return ret;
     391}
     392
     393int LinuxDvbPause(Context_t  *context __attribute__((unused)), char *type) {
     394    int32_t ret = cERR_LINUXDVB_NO_ERROR;
     395    uint8_t video = !strcmp("video", type);
     396    uint8_t audio = !strcmp("audio", type);
    407397
    408398    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    409399
    410     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    411 
    412     if (video && videofd != -1) {
     400    getLinuxDVBMutex();
     401
     402    if (video && videofd != -1)
     403    {
    413404        if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1)
    414405        {
    415             linuxdvb_err("ioctl failed with errno %d\n", errno);
    416             linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
    417             ret = cERR_LINUXDVB_ERROR;
    418         }
    419     }
    420     if (audio && audiofd != -1) {
     406            linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno));
     407            ret = cERR_LINUXDVB_ERROR;
     408        }
     409    }
     410   
     411    if (audio && audiofd != -1)
     412    {
    421413        if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1)
    422414        {
    423             linuxdvb_err("ioctl failed with errno %d\n", errno);
    424             linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
    425             ret = cERR_LINUXDVB_ERROR;
    426         }
    427     }
    428 
    429     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     415            linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno));
     416            ret = cERR_LINUXDVB_ERROR;
     417        }
     418    }
     419
     420    releaseLinuxDVBMutex();
    430421
    431422    return ret;
     
    433424
    434425int LinuxDvbContinue(Context_t  *context __attribute__((unused)), char * type) {
    435     int ret = cERR_LINUXDVB_NO_ERROR;
    436     unsigned char video = !strcmp("video", type);
    437     unsigned char audio = !strcmp("audio", type);
     426    int32_t ret = cERR_LINUXDVB_NO_ERROR;
     427    uint8_t video = !strcmp("video", type);
     428    uint8_t audio = !strcmp("audio", type);
    438429
    439430    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    440431
    441     if (video && videofd != -1) {
     432    if (video && videofd != -1)
     433    {
    442434        if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1)
    443435        {
    444             linuxdvb_err("ioctl failed with errno %d\n", errno);
    445             linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
    446             ret = cERR_LINUXDVB_ERROR;
    447         }
    448     }
    449     if (audio && audiofd != -1) {
     436            linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
     437            ret = cERR_LINUXDVB_ERROR;
     438        }
     439    }
     440   
     441    if (audio && audiofd != -1)
     442    {
    450443        if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1)
    451444        {
    452             linuxdvb_err("ioctl failed with errno %d\n", errno);
    453             linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
    454             ret = cERR_LINUXDVB_ERROR;
    455         }
    456     }
     445            linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
     446            ret = cERR_LINUXDVB_ERROR;
     447        }
     448    }
     449   
     450    if (isBufferedOutput)
     451        LinuxDvbBuffResume(context);
    457452
    458453    linuxdvb_printf(10, "exiting\n");
    459 
    460 
    461     return ret;
    462 }
    463 
    464 int LinuxDvbReverseDiscontinuity(Context_t  *context __attribute__((unused)), int* surplus) {
    465     int ret = cERR_LINUXDVB_NO_ERROR;
    466     // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus;
    467454   
    468     // linuxdvb_printf(50, "\n");
    469 
    470     // if (ioctl( videofd, VIDEO_DISCONTINUITY, (void*) dis_type) == -1)
    471     // {
    472         // linuxdvb_err("ioctl failed with errno %d\n", errno);
    473         // linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno));
    474     // }
    475 
    476     // linuxdvb_printf(50, "exiting\n");
    477 
    478455    return ret;
    479456}
     
    487464        if(*flag == '1')
    488465        {
    489             //AUDIO_SET_MUTE has no effect with new player
    490             //if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1)
    491466            if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
    492467            {
    493                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    494                 //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
    495                 linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
     468                linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
    496469                ret = cERR_LINUXDVB_ERROR;
    497470            }
     
    499472        else
    500473        {
    501             //AUDIO_SET_MUTE has no effect with new player
    502             //if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1)
    503474            if (ioctl(audiofd, AUDIO_PLAY) == -1)
    504475            {
    505                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    506                 //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
    507                 linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
     476                linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
    508477                ret = cERR_LINUXDVB_ERROR;
    509478            }
     
    516485}
    517486
    518 
    519487int LinuxDvbFlush(Context_t  *context __attribute__((unused)), char * type)
    520488{
    521     // unsigned char video = !strcmp("video", type);
    522     // unsigned char audio = !strcmp("audio", type);
    523 
    524     // linuxdvb_printf(10, "v%d a%d\n", video, audio);
    525 
    526     // if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
    527         // getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    528 
    529         // if (video && videofd != -1) {
    530             // if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1)
    531             // {
    532                 // linuxdvb_err("ioctl failed with errno %d\n", errno);
    533                 // linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno));
    534             // }
    535         // }
    536 
    537         // if (audio && audiofd != -1) {
    538             // if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1)
    539             // {
    540                 // linuxdvb_err("ioctl failed with errno %d\n", errno);
    541                 // linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno));
    542             // }
    543         // }
    544 
    545         // releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    546     // }
    547 
    548     // linuxdvb_printf(10, "exiting\n");
    549 
    550489    return cERR_LINUXDVB_NO_ERROR;
    551490}
    552491
     492//obi
    553493#ifndef use_set_speed_instead_ff
    554494int LinuxDvbFastForward(Context_t  *context, char * type) {
     
    562502    if (video && videofd != -1) {
    563503
    564         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     504//        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     505        getLinuxDVBMutex();
    565506
    566507        /* konfetti comment: speed is a value given in skipped frames */
     
    573514        }
    574515
    575         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     516//        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     517                releaseLinuxDVBMutex();
    576518    }
    577519
     
    600542    if (video && videofd != -1) {
    601543
    602         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     544//        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     545                getLinuxDVBMutex();
    603546
    604547        speedIndex = context->playback->Speed % (sizeof (SpeedList) / sizeof (int));
     
    613556        // }
    614557
    615         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     558//        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     559                releaseLinuxDVBMutex();
    616560    }
    617561
    618562    if (audio && audiofd != -1) {
    619563
    620         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     564//        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     565                getLinuxDVBMutex();
    621566
    622567        speedIndex = context->playback->Speed % (sizeof (SpeedList) / sizeof (int));
     
    631576        // }
    632577
    633         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     578//        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     579        releaseLinuxDVBMutex();
    634580    }
    635581
     
    645591    return ret;
    646592}
     593//obi
    647594
    648595int LinuxDvbSlowMotion(Context_t  *context, char * type) {
    649     int ret = cERR_LINUXDVB_NO_ERROR;
    650 
    651     unsigned char video = !strcmp("video", type);
    652     unsigned char audio = !strcmp("audio", type);
     596    int32_t ret = cERR_LINUXDVB_NO_ERROR;
     597
     598    uint8_t video = !strcmp("video", type);
     599    uint8_t audio = !strcmp("audio", type);
    653600
    654601    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    655602
    656603    if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
    657         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     604        getLinuxDVBMutex();
    658605
    659606        if (video && videofd != -1) {
    660607            if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1)
    661608            {
    662                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    663                 linuxdvb_err("VIDEO_SLOWMOTION: %s\n", strerror(errno));
     609                linuxdvb_err("VIDEO_SLOWMOTION: ERROR %d, %s\n", errno, strerror(errno));
    664610                ret = cERR_LINUXDVB_ERROR;
    665611            }
    666612        }
    667613
    668         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     614        releaseLinuxDVBMutex();
    669615    }
    670616
     
    674620}
    675621
    676 int LinuxDvbAVSync(Context_t  *context, char * type __attribute__((unused))) {
    677     int ret = cERR_LINUXDVB_NO_ERROR;
     622int LinuxDvbAVSync(Context_t  *context, char *type __attribute__((unused))) {
     623    int32_t ret = cERR_LINUXDVB_NO_ERROR;
    678624    /* konfetti: this one is dedicated to audiofd so we
    679625     * are ignoring what is given by type! I think we should
     
    683629     */
    684630    if (audiofd != -1) {
    685         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     631        getLinuxDVBMutex();
    686632
    687633        if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1)
    688634        {
    689             linuxdvb_err("ioctl failed with errno %d\n", errno);
    690             linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno));
    691             ret = cERR_LINUXDVB_ERROR;
    692         }
    693 
    694         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    695     }
    696 
    697     return ret;
    698 }
    699 
    700 int LinuxDvbClear(Context_t  *context __attribute__((unused)), char * type)
     635            linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno));
     636            ret = cERR_LINUXDVB_ERROR;
     637        }
     638
     639        releaseLinuxDVBMutex();
     640    }
     641
     642    return ret;
     643}
     644
     645int LinuxDvbClear(Context_t  *context __attribute__((unused)), char *type)
    701646{
    702647    int32_t ret = cERR_LINUXDVB_NO_ERROR;
     
    704649    uint8_t audio = !strcmp("audio", type);
    705650
    706     linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio);
     651    linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio);
    707652
    708653    if ( (video && videofd != -1) || (audio && audiofd != -1) )
    709654    {
    710         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     655        getLinuxDVBMutex();
    711656
    712657        if (video && videofd != -1)
     
    714659            if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
    715660            {
    716                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    717                 linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
     661                linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    718662                ret = cERR_LINUXDVB_ERROR;
    719663            }
     
    723667            if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
    724668            {
    725                 linuxdvb_err("ioctl failed with errno %d\n", errno);
    726                 linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
     669                linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    727670                ret = cERR_LINUXDVB_ERROR;
    728671            }
    729672        }
    730673
    731         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     674        releaseLinuxDVBMutex();
    732675    }
    733676
     
    738681
    739682int LinuxDvbPts(Context_t  *context __attribute__((unused)), unsigned long long int* pts) {
    740     int ret = cERR_LINUXDVB_ERROR;
     683    int32_t ret = cERR_LINUXDVB_ERROR;
    741684   
    742685    linuxdvb_printf(50, "\n");
    743686
    744     // pts is a non writting requests and can be done in parallel to other requests
    745     //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    746 
     687    // GET_PTS is immutable call, so it can be done in parallel to other requests
    747688    if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void*)&sCURRENT_PTS))
    748689    {
     
    751692    else
    752693    {
    753         linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno));
     694        linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
    754695    }
    755696
     
    762703        else
    763704        {
    764             linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno));
     705            linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
    765706        }
    766707    }
     
    772713
    773714    *((unsigned long long int *)pts)=(unsigned long long int)sCURRENT_PTS;
    774 
    775     //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
    776 
    777715    return ret;
    778716}
     
    780718int LinuxDvbGetFrameCount(Context_t  *context __attribute__((unused)), unsigned long long int* frameCount)
    781719{
    782     int ret = cERR_LINUXDVB_NO_ERROR;
    783     return ret;
    784 }
    785 
    786 int LinuxDvbSwitch(Context_t  *context, char * type)
    787 {
    788     unsigned char audio = !strcmp("audio", type);
    789     unsigned char video = !strcmp("video", type);
    790     Writer_t* writer;
     720    return cERR_LINUXDVB_NO_ERROR;
     721}
     722
     723int LinuxDvbSwitch(Context_t  *context, char *type)
     724{
     725    uint8_t audio = !strcmp("audio", type);
     726    uint8_t video = !strcmp("video", type);
     727    Writer_t *writer;
     728    int ret = 0;
    791729
    792730    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    793731
    794732    if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
    795         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     733        getLinuxDVBMutex();
    796734
    797735        if (audio && audiofd != -1) {
     
    806744                if (ioctl(audiofd, AUDIO_STOP ,NULL) == -1)
    807745                {
    808                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    809                     linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
    810 
     746                    linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
    811747                }
    812748
    813749                if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
    814750                {
    815                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    816                     linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
    817 
     751                    linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    818752                }
    819753
     
    821755                {
    822756                    linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
    823                     // if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) AUDIO_ENCODING_MP3) == -1)
    824                     // {
    825                         // linuxdvb_err("ioctl failed with errno %d\n", errno);
    826                         // linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
    827                     // }
    828                 } else
     757                }
     758                else
    829759                {
    830760                    linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    831                     if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) == -1)
     761                    ret = ioctl( audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, true));
     762                    if (ret < 0) ret = ioctl( audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, false));
     763                    if (ret < 0)
    832764                    {
    833                         linuxdvb_err("ioctl failed with errno %d\n", errno);
    834                         linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
     765                        linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno));
    835766                    }
    836767                }
     
    838769                if (ioctl(audiofd, AUDIO_PLAY) == -1)
    839770                {
    840                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    841                     linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
     771                    linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
    842772                }
    843773                free(Encoding);
     
    854784                if (ioctl(videofd, VIDEO_STOP ,NULL) == -1)
    855785                {
    856                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    857                     linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
     786                    linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
    858787                }
    859788
    860789                if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
    861790                {
    862                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    863                     linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
     791                    linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
    864792                }
    865793
     
    871799                {
    872800                    linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
    873                     // if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) VIDEO_ENCODING_AUTO) == -1)
    874                     // {
    875                         // linuxdvb_err("ioctl failed with errno %d\n", errno);
    876                         // linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
    877                     // }
    878                 } else
     801                }
     802                else
    879803                {
    880804                    linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    881                     if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) writer->caps->dvbStreamType) == -1)
     805                    ret = ioctl( videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, true));
     806                    if (ret < 0) ret = ioctl( videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, false));
     807                    if (ret < 0)
    882808                    {
    883                         linuxdvb_err("ioctl failed with errno %d\n", errno);
    884                         linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
     809                        linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno));
    885810                    }
    886811                }
     
    891816                     * return an error here and stop the playback mode
    892817                     */
    893                     linuxdvb_err("ioctl failed with errno %d\n", errno);
    894                     linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
     818                    linuxdvb_err("VIDEO_PLAY:ERROR %d, %s\n", errno, strerror(errno));
    895819                }
    896820                free(Encoding);
     
    900824        }
    901825
    902         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     826        releaseLinuxDVBMutex();
    903827
    904828    }
     
    909833}
    910834
    911 static int Write(void  *_context, void* _out)
     835static int Write(void  *_context, void *_out)
    912836{
    913837    Context_t          *context  = (Context_t  *) _context;
    914838    AudioVideoOut_t    *out      = (AudioVideoOut_t*) _out;
    915     int                ret       = cERR_LINUXDVB_NO_ERROR;
    916     int                res       = 0;
    917     unsigned char      video     = 0;
    918     unsigned char      audio     = 0;
    919     Writer_t*          writer;
     839    int32_t            ret       = cERR_LINUXDVB_NO_ERROR;
     840    int32_t            res       = 0;
     841    uint8_t            video     = 0;
     842    uint8_t            audio     = 0;
     843    Writer_t           *writer   = NULL;
    920844    WriterAVCallData_t call;
    921845
     
    929853    audio = !strcmp("audio", out->type);
    930854 
    931     linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
     855    linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%"PRIu64" FrameRate=%d\n",
    932856                                                    out->len, out->extralen, out->pts, out->frameRate);
    933857    linuxdvb_printf(20, "v%d a%d\n", video, audio);
     
    935859    if (video)
    936860    {
    937         char * Encoding = NULL;
     861        char *Encoding = NULL;
    938862        context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
    939863
     
    969893                else
    970894                {
     895                    bool changed = false;
    971896                    if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
    972897                    {
    973                         linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED\n", evt.type);
     898                        linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED type: 0x%x\n", evt.type);
    974899                        linuxdvb_printf(10, "width  : %d\n", evt.u.size.w);
    975900                        linuxdvb_printf(10, "height : %d\n", evt.u.size.h);
     
    978903                        videoInfo.height = evt.u.size.h;
    979904                        videoInfo.aspect_ratio = evt.u.size.aspect_ratio;
     905                        changed = true;
    980906                    }
    981907                    else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
    982908                    {
    983                         linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED\n", evt.type);
     909                        linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED type: 0x%x\n", evt.type);
    984910                        linuxdvb_printf(10, "framerate : %d\n", evt.u.frame_rate);
    985911                        videoInfo.frame_rate = evt.u.frame_rate;
     912                        changed = true;
    986913                    }
    987914                    else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
    988915                    {
    989                         linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED\n", evt.type);
     916                        linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED type: 0x%x\n", evt.type);
    990917                        linuxdvb_printf(10, "progressive : %d\n", evt.u.frame_rate);
    991918                        videoInfo.progressive = evt.u.frame_rate;
    992919                        context->manager->video->Command(context, MANAGER_UPDATED_TRACK_INFO, NULL);
     920                        changed = true;
    993921                    }
    994922                    else
    995923                    {
    996924                        linuxdvb_err("unhandled DVBAPI Video Event %d\n", evt.type);
     925                    }
     926                   
     927                    if (changed &&
     928                        videoInfo.width != -1 &&
     929                        videoInfo.height != -1 &&
     930                        videoInfo.aspect_ratio != -1 &&
     931                        videoInfo.frame_rate != -1 &&
     932                        videoInfo.progressive != -1)
     933                    {
     934                        E2iSendMsg("{\"v_e\":{\"w\":%d,\"h\":%d,\"a\":%d,\"f\":%d,\"p\":%d}}\n",
     935                            videoInfo.width, videoInfo.height, videoInfo.aspect_ratio, videoInfo.frame_rate, videoInfo.progressive);
    997936                    }
    998937                }
     
    1011950            call.Height       = out->height;
    1012951            call.InfoFlags    = out->infoFlags;
    1013             call.Version      = 0; // is unsingned char
     952            call.Version      = 0;
     953            call.WriteV       = isBufferedOutput ? BufferingWriteV : writev_with_retry;
    1014954
    1015955            if (writer->writeData)
     
    1030970    else if (audio)
    1031971    {
    1032         char * Encoding = NULL;
     972        char *Encoding = NULL;
    1033973        context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
    1034974
    1035         linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding);
     975        linuxdvb_printf(20, "Encoding = %s\n", Encoding);
    1036976
    1037977        writer = getWriter(Encoding);
     
    10601000            call.FrameScale     = out->timeScale;
    10611001            call.InfoFlags      = out->infoFlags;
    1062             call.Version        = 0; /* -1; unsigned char cannot be negative */
     1002            call.Version        = 0;
     1003            call.WriteV         = isBufferedOutput ? BufferingWriteV : writev_with_retry;
    10631004
    10641005            if (writer->writeData)
     
    11171058    free(Encoding);
    11181059
     1060    if (isBufferedOutput)
     1061        LinuxDvbBuffFlush(context);
     1062   
    11191063    return ret;
    11201064}
     
    11621106        break;
    11631107    }
     1108//obi
    11641109    case OUTPUT_FASTFORWARD: {
    11651110        return LinuxDvbFastForward(context, (char*)argument);
     
    11701115        break;
    11711116    }
     1117//obi
    11721118    case OUTPUT_AVSYNC: {
    11731119        ret = LinuxDvbAVSync(context, (char*)argument);
     
    11751121    }
    11761122    case OUTPUT_CLEAR: {
     1123        reset(context);
    11771124        ret = LinuxDvbClear(context, (char*)argument);
    11781125        reset(context);
     
    11981145        break;
    11991146    }
    1200     case OUTPUT_DISCONTINUITY_REVERSE: {
    1201         return LinuxDvbReverseDiscontinuity(context, (int*)argument);
    1202         break;
    1203     }
    12041147    case OUTPUT_GET_FRAME_COUNT: {
    12051148        unsigned long long int frameCount = 0;
     
    12111154        ret = cERR_LINUXDVB_NO_ERROR;
    12121155        *((int*)argument) = videoInfo.progressive;
     1156        break;
     1157    }
     1158    case OUTPUT_SET_BUFFER_SIZE: {
     1159        ret = cERR_LINUXDVB_ERROR;
     1160        if (!isBufferedOutput)
     1161        {
     1162            uint32_t bufferSize = *((uint32_t*)argument);
     1163            ret = cERR_LINUXDVB_NO_ERROR;
     1164            if (bufferSize > 0)
     1165            {
     1166                LinuxDvbBuffSetSize(bufferSize);
     1167                isBufferedOutput = true;
     1168            }
     1169        }
     1170        break;
     1171    }
     1172    case OUTPUT_GET_BUFFER_SIZE: {
     1173        ret = cERR_LINUXDVB_NO_ERROR;
     1174        *((uint32_t*)argument) = LinuxDvbBuffGetSize();
    12131175        break;
    12141176    }
  • titan/libeplayer3/output/linuxdvb_sh4.c

    r40348 r44958  
    3232#include <linux/dvb/video.h>
    3333#include <linux/dvb/audio.h>
    34 #include <linux/dvb/stm_ioctls.h>
    3534#include <memory.h>
    3635#include <asm/types.h>
     
    3837#include <errno.h>
    3938#include <poll.h>
     39#include <sys/uio.h>
    4040
    4141#include "bcm_ioctls.h"
     42#include "stm_ioctls.h"
    4243
    4344#include "common.h"
     45#include "debug.h"
    4446#include "output.h"
    4547#include "writer.h"
     
    5052/* Makros/Constants              */
    5153/* ***************************** */
    52 
    53 //#define LINUXDVB_DEBUG
    54 #define LINUXDVB_SILENT
    55 
    56 static unsigned short debug_level = 0;
    57 
    58 static const char FILENAME[] = __FILE__;
    59 
    60 #ifdef LINUXDVB_DEBUG
    61 #define linuxdvb_printf(level, fmt, x...) do { \
    62 if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); } while (0)
    63 #else
    64 #define linuxdvb_printf(x...)
    65 #endif
    66 
    67 #ifndef LINUXDVB_SILENT
    68 #define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
    69 #else
    70 #define linuxdvb_err(x...)
    71 #endif
    72 
    73 
    7454#define cERR_LINUXDVB_NO_ERROR      0
    7555#define cERR_LINUXDVB_ERROR        -1
     
    9070
    9171unsigned long long int sCURRENT_PTS = 0;
     72bool isBufferedOutput = false;
    9273
    9374pthread_mutex_t LinuxDVBmutex;
     
    9677/* Prototypes                    */
    9778/* ***************************** */
     79int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx);
     80int32_t LinuxDvbBuffClose(Context_t *context);
     81int32_t LinuxDvbBuffFlush(Context_t *context);
     82int32_t LinuxDvbBuffResume(Context_t *context);
     83
     84ssize_t BufferingWriteV(int fd, const struct iovec *iov, int ic);
     85int32_t LinuxDvbBuffSetSize(const uint32_t bufferSize);
     86uint32_t LinuxDvbBuffGetSize();
     87
    9888int LinuxDvbStop(Context_t  *context, char * type);
    9989
     
    10292/* ***************************** */
    10393
    104 void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
    105 
    106     linuxdvb_printf(250, "requesting mutex\n");
    107 
    108     pthread_mutex_lock(&LinuxDVBmutex);
    109 
    110     linuxdvb_printf(250, "received mutex\n");
    111 }
    112 
    113 void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
    114     pthread_mutex_unlock(&LinuxDVBmutex);
    115 
    116     linuxdvb_printf(250, "released mutex\n");
    117 
    118 }
     94#define getLinuxDVBMutex() pthread_mutex_lock(&LinuxDVBmutex)
     95#define releaseLinuxDVBMutex() pthread_mutex_unlock(&LinuxDVBmutex)
    11996
    12097int LinuxDvbOpen(Context_t  *context __attribute__((unused)), char * type) {
     
    124101    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    125102
    126     if (video && videofd < 0) {
     103    if (video && videofd < 0)
     104    {
     105   
    127106        videofd = open(VIDEODEV, O_RDWR);
    128 
    129107        if (videofd < 0)
    130108        {
     
    158136        }
    159137
    160     }
    161     if (audio && audiofd < 0) {
     138        if (isBufferedOutput)
     139            LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex);
     140    }
     141    if (audio && audiofd < 0)
     142    {
    162143        audiofd = open(AUDIODEV, O_RDWR);
    163 
    164144        if (audiofd < 0)
    165145        {
     
    189169            linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno));
    190170        }
     171       
     172        if (isBufferedOutput)
     173            LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex);
    191174    }
    192175
     
    194177}
    195178
    196 int LinuxDvbClose(Context_t  *context, char * type) {
    197     unsigned char video = !strcmp("video", type);
    198     unsigned char audio = !strcmp("audio", type);
     179int LinuxDvbClose(Context_t  *context, char * type)
     180{
     181    uint8_t video = !strcmp("video", type);
     182    uint8_t audio = !strcmp("audio", type);
    199183
    200184    linuxdvb_printf(10, "v%d a%d\n", video, audio);
     
    206190    LinuxDvbStop(context, type);
    207191
    208     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     192    getLinuxDVBMutex();
     193
     194    if (isBufferedOutput)
     195        LinuxDvbBuffClose(context);
    209196
    210197    if (video && videofd != -1)
     
    219206    }
    220207
    221     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     208    releaseLinuxDVBMutex();
    222209    return cERR_LINUXDVB_NO_ERROR;
    223210}
     
    243230        {
    244231            linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
    245             if (ioctl( videofd, VIDEO_SET_ENCODING, (void*) VIDEO_ENCODING_AUTO) == -1)
     232            if (ioctl( videofd, VIDEO_SET_ENCODING, VIDEO_ENCODING_AUTO) == -1)
    246233            {
    247234                linuxdvb_err("ioctl failed with errno %d\n", errno);
     
    252239        {
    253240            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    254             if (ioctl( videofd, VIDEO_SET_ENCODING, (void*) writer->caps->dvbEncoding) == -1)
     241            if (ioctl( videofd, VIDEO_SET_ENCODING, writer->caps->dvbEncoding) == -1)
    255242            {
    256243                linuxdvb_err("ioctl failed with errno %d\n", errno);
     
    288275        {
    289276            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
    290             if (ioctl( audiofd, AUDIO_SET_ENCODING, (void*) writer->caps->dvbEncoding) == -1)
     277            if (ioctl( audiofd, AUDIO_SET_ENCODING, writer->caps->dvbEncoding) == -1)
    291278            {
    292279                linuxdvb_err("ioctl failed with errno %d\n", errno);
     
    315302    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    316303
    317     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     304    getLinuxDVBMutex();
    318305
    319306    if (video && videofd != -1) {
     
    358345    }
    359346
    360     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     347    releaseLinuxDVBMutex();
    361348
    362349    return ret;
     
    370357    linuxdvb_printf(10, "v%d a%d\n", video, audio);
    371358
    372     getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     359    getLinuxDVBMutex();
    373360
    374361    if (video && videofd != -1) {
     
    389376    }
    390377
    391     releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     378    releaseLinuxDVBMutex();
    392379
    393380    return ret;
     
    417404        }
    418405    }
     406   
     407    if (isBufferedOutput)
     408        LinuxDvbBuffResume(context);
    419409
    420410    linuxdvb_printf(10, "exiting\n");
     
    430420    linuxdvb_printf(50, "\n");
    431421
    432     if (ioctl( videofd, VIDEO_DISCONTINUITY, (void*) dis_type) == -1)
     422    if (ioctl( videofd, VIDEO_DISCONTINUITY, dis_type) == -1)
    433423    {
    434424        linuxdvb_err("ioctl failed with errno %d\n", errno);
     
    486476
    487477    if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
    488         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     478        getLinuxDVBMutex();
    489479
    490480        if (video && videofd != -1) {
     
    504494        }
    505495
    506         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     496        releaseLinuxDVBMutex();
    507497    }
    508498
     
    523513    if (video && videofd != -1) {
    524514
    525         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     515        getLinuxDVBMutex();
    526516
    527517        /* konfetti comment: speed is a value given in skipped frames */
     
    534524        }
    535525
    536         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     526        releaseLinuxDVBMutex();
    537527    }
    538528
     
    561551    if (video && videofd != -1) {
    562552
    563         getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     553        getLinuxDVBMutex();
    564554
    565555        speedIndex = context->playback->Speed % (sizeof (SpeedList) / sizeof (int));
     
    574564        }
    575565
    576         releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
     566        releaseLinuxDVBMutex();
    577567    }
    578568
    579569    if (audio && audiofd != -1) {
    580570<