source: titan/libeplayer3/container/container_ffmpeg.c @ 41347

Last change on this file since 41347 was 41347, checked in by obi, 5 years ago

cleanup and lost files

File size: 122.7 KB
Line 
1/*
2 * Container handling for all stream's handled by ffmpeg
3 * konfetti 2010; based on code from crow
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 /* Support Large File */
23#define _FILE_OFFSET_BITS 64
24
25/* ***************************** */
26/* Includes                      */
27/* ***************************** */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <sys/ioctl.h>
32#include <fcntl.h>
33#include <unistd.h>
34#include <memory.h>
35#include <string.h>
36
37#include <sys/stat.h>
38#include <fcntl.h>
39#include <errno.h>
40#include <sys/poll.h>
41#include <pthread.h>
42#include <sys/prctl.h>
43#include <stdint.h>
44
45#include <libavutil/avutil.h>
46#include <libavutil/time.h>
47#include <libavformat/avformat.h>
48#include <libswresample/swresample.h>
49#include <libavutil/opt.h>
50
51#include <ffmpeg/mpeg4audio.h>
52
53#include "common.h"
54#include "misc.h"
55#include "debug.h"
56#include "aac.h"
57#include "pcm.h"
58#include "ffmpeg_metadata.h"
59/* ***************************** */
60/* Makros/Constants              */
61/* ***************************** */
62#if (LIBAVFORMAT_VERSION_MAJOR > 57)
63#define TS_BYTES_SEEKING 0
64#else
65#define TS_BYTES_SEEKING 1
66#endif
67
68/* Some STB with old kernels have problem with default
69 * read/write functions in ffmpeg which use open/read
70 * due to this we set own which use fopen/fread from
71 * std library.
72 */
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
86static short debug_level = 10;
87//obi (end)
88
89#define ffmpeg_printf(level, fmt, x...) do { \
90if (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
100
101/* Error Constants */
102#define cERR_CONTAINER_FFMPEG_NO_ERROR        0
103#define cERR_CONTAINER_FFMPEG_INIT           -1
104#define cERR_CONTAINER_FFMPEG_NOT_SUPPORTED  -2
105#define cERR_CONTAINER_FFMPEG_INVALID_FILE   -3
106#define cERR_CONTAINER_FFMPEG_RUNNING        -4
107#define cERR_CONTAINER_FFMPEG_NOMEM          -5
108#define cERR_CONTAINER_FFMPEG_OPEN           -6
109#define cERR_CONTAINER_FFMPEG_STREAM         -7
110#define cERR_CONTAINER_FFMPEG_NULL           -8
111#define cERR_CONTAINER_FFMPEG_ERR            -9
112#define cERR_CONTAINER_FFMPEG_END_OF_FILE    -10
113
114#define IPTV_AV_CONTEXT_MAX_NUM 2
115/* ***************************** */
116/* Types                         */
117/* ***************************** */
118typedef enum {RTMP_NATIVE, RTMP_LIBRTMP, RTMP_NONE} eRTMPProtoImplType;
119
120/* ***************************** */
121/* Varaibles                     */
122/* ***************************** */
123
124static pthread_mutex_t mutex;
125
126static pthread_t PlayThread;
127static int32_t hasPlayThreadStarted = 0;
128
129static AVFormatContext *avContextTab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL};
130static int32_t use_custom_io[IPTV_AV_CONTEXT_MAX_NUM] = {0, 0};
131static AVDictionary *avio_opts = NULL;
132
133static uint8_t isContainerRunning = 0;
134
135static int64_t latestPts = 0;
136
137static int32_t restart_audio_resampling = 0;
138
139static off_t seek_target_bytes = 0;
140static int32_t do_seek_target_bytes = 0;
141
142static int64_t seek_target_seconds = 0;
143static int8_t do_seek_target_seconds = 0;
144static int64_t prev_seek_time_sec = -1;
145
146static int32_t seek_target_flag = 0;
147
148/* ***************************** */
149/* Prototypes                    */
150/* ***************************** */
151static int32_t container_ffmpeg_seek_bytes(off_t pos);
152static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute);
153static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec);
154static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length);
155static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts);
156
157/* Progressive playback means that we play local file
158 * but this local file can grows up, for example
159 * we start playback before download was finished
160 */
161static int32_t progressive_playback = 0;
162void progressive_playback_set(int32_t val)
163{
164    progressive_playback = val;
165}
166
167#include "buff_ffmpeg.c"
168#include "wrapped_ffmpeg.c"
169//obi
170#include "tools_ffmpeg.c"
171//obi (end)
172#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
173#include "mpeg4p2_ffmpeg.c"
174#endif
175
176#ifdef HAVE_FLV2MPEG4_CONVERTER
177#include "flv2mpeg4_ffmpeg.c"
178#endif
179
180/* This is also bad solution
181 * such configuration should passed maybe
182 * via struct
183 */
184static int32_t wma_software_decode = 0;
185static int32_t aac_software_decode = 0;
186#ifdef __sh__
187static int32_t aac_latm_software_decode = 1;
188#else
189static int32_t aac_latm_software_decode = 0;
190#endif
191
192static int32_t ac3_software_decode = 0;
193static int32_t eac3_software_decode = 0;
194static int32_t dts_software_decode = 0;
195static int32_t pcm_resampling = 1;
196static int32_t stereo_software_decoder = 0;
197static int32_t insert_pcm_as_lpcm = 0;
198static int32_t mp3_software_decode = 0;
199static int32_t rtmp_proto_impl = 0; // 0 - auto, 1 - native, 2 - librtmp
200
201static int32_t g_sel_program_id = -1;
202
203#ifdef HAVE_FLV2MPEG4_CONVERTER
204static int32_t flv2mpeg4_converter = 1;
205#else
206static int32_t flv2mpeg4_converter = 0;
207#endif
208
209/* ***************************** */
210/* MISC Functions                */
211/* ***************************** */
212
213//obi
214    uint32_t         tmptrackId;
215//    uint8_t         *tmpdata;
216    char         *tmpdata;
217
218    uint32_t         tmplen;
219    int64_t          tmppts;
220    int64_t          tmpduration; // duration in miliseconds
221    char            *tmptype;
222    int              enablesub = 0;
223
224void dvbsub_ass_write(Context_t *context, AVCodecContext *c, AVSubtitle *sub, int pid, AVPacket *packet)
225{
226   unsigned int i;
227
228   ffmpeg_printf(0, "format %d\n", sub->format);
229   ffmpeg_printf(0, "start_display_time %d\n", sub->start_display_time);
230   ffmpeg_printf(0, "end_display_time %d\n", sub->end_display_time);
231   ffmpeg_printf(0, "num_rects %d\n", sub->num_rects);
232   //ffmpeg_printf(0, "pts %lld\n", sub->pts);
233
234   for (i = 0; i < sub->num_rects; i++)
235   {
236
237                ffmpeg_printf(0, "x %d\n", sub->rects[i]->x);
238                ffmpeg_printf(0, "y %d\n", sub->rects[i]->y);
239                ffmpeg_printf(0, "w %d\n", sub->rects[i]->w);
240                ffmpeg_printf(0, "h %d\n", sub->rects[i]->h);
241                ffmpeg_printf(0, "nb_colors %d\n", sub->rects[i]->nb_colors);
242                ffmpeg_printf(0, "type %d\n", sub->rects[i]->type);
243                ffmpeg_printf(0, "text %s\n", sub->rects[i]->text);
244                ffmpeg_printf(0, "ass %s\n", sub->rects[i]->ass);
245               
246               
247                ffmpeg_printf(0, "packet->data %s\n", packet->data);
248                ffmpeg_printf(0, "packet->data[0] %x\n", packet->data[0]);
249                ffmpeg_printf(0, "packet->data[1] %x\n", packet->data[1]);
250
251                subtext = ostrcat(subtext, (char *)sub->rects[i]->ass, 1, 0);   
252
253                int ret, horIni, minIni, secIni, milIni, horFim, minFim, secFim, milFim;
254                double Duration = 0;
255                unsigned long long int Pts = 0;
256
257                ret = sscanf((char *)sub->rects[i]->ass, "Dialogue: 0,%d:%d:%d.%d,%d:%d:%d.%d,", &horIni, &minIni, &secIni, &milIni, &horFim, &minFim, &secFim, &milFim);
258
259                if (ret!=8) continue; /* Data is not in correct format */
260                ffmpeg_printf(0, "ret %d\n", ret);
261
262                ffmpeg_printf(0, "horIni %d\n", horIni);
263                ffmpeg_printf(0, "minIni %d\n", minIni);
264                ffmpeg_printf(0, "secIni %d\n", secIni);
265                ffmpeg_printf(0, "milIni %d\n", milIni);
266
267                ffmpeg_printf(0, "horFim %d\n", horFim);
268                ffmpeg_printf(0, "minFim %d\n", minFim);
269                ffmpeg_printf(0, "secFim %d\n", secFim);
270                ffmpeg_printf(0, "milFim %d\n", milFim);
271/*
272                Pts = (horIni*3600 + minIni*60 + secIni)*1000 + milIni;
273                Duration = ((horFim*3600 + minFim*60 + secFim) * 1000  + milFim - Pts) / 1000.0;
274                ffmpeg_printf(0, "new Pts %llu\n", Pts);
275                ffmpeg_printf(0, "new Duration %f\n", Duration);
276
277*/
278                tmppts = (horIni*3600 + minIni*60 + secIni)*1000 + milIni;
279                tmpduration = ((horFim*3600 + minFim*60 + secFim) * 1000  + milFim - Pts) / 1000.0;
280                tmpdata = packet->data;
281
282                ffmpeg_printf(0, "new Pts %llu\n", tmppts);
283                ffmpeg_printf(0, "new Duration %d\n", tmpduration);
284                ffmpeg_printf(0, "new Data %s\n", tmpdata);
285
286                // pict ->AVPicture
287   }
288}
289
290//int ReadSubtitle(Context_t *context, const char *filename, const char *format, int pid)
291int ReadSubtitle(Context_t *context, const char *filename, char *format, int pid)
292{
293        int ret = 0;
294        const char *lastDot = strrchr(filename, '.');
295        if (!lastDot)
296                return ret;
297        char subfile[strlen(filename) + strlen(format)];
298        strcpy(subfile, filename);
299        strcpy(subfile + (lastDot + 1 - filename), format);
300
301        if (access(subfile, R_OK))
302                return ret;
303
304        AVFormatContext *subavfc = avformat_alloc_context();
305        int err = avformat_open_input(&subavfc, subfile, av_find_input_format(format), 0);
306//      if (averror(err, avformat_open_input)) {
307        if (err != 0)
308    {
309                avformat_free_context(subavfc);
310                return ret;
311        }
312
313        avformat_find_stream_info(subavfc, NULL);
314        if (subavfc->nb_streams != 1) {
315                avformat_free_context(subavfc);
316                return ret;
317        }
318
319        AVCodecContext *c = subavfc->streams[0]->codec;
320        AVCodec *codec = avcodec_find_decoder(c->codec_id);
321        if (!codec) {
322                avformat_free_context(subavfc);
323                return ret;
324        }
325
326        err = avcodec_open2(c, codec, NULL);
327//      if (averror(err, avcodec_open2)) {
328        if (err != 0)
329    {
330                avformat_free_context(subavfc);
331                return ret;
332        }
333
334        AVPacket packet;
335        av_init_packet(&packet);
336
337        free(subtext), subtext = NULL;
338
339        while (av_read_frame(subavfc, &packet) > -1) {
340                AVSubtitle sub;
341                memset(&sub, 0, sizeof(sub));
342                int got_sub = 0;
343                avcodec_decode_subtitle2(c, &sub, &got_sub, &packet);
344                if (got_sub)
345                {
346                        dvbsub_ass_write(context, c, &sub, pid, &packet);
347
348                        char* tmpstr = NULL;
349                        tmpstr = ostrcat(tmpstr, "duration=", 1, 0);
350                        tmpstr = ostrcat(tmpstr, ollutoa(tmpduration), 1, 1);
351                        tmpstr = ostrcat(tmpstr, ";pts=", 1, 0);;
352                        tmpstr = ostrcat(tmpstr, ollutoa(tmppts), 1, 0);;
353                        tmpstr = ostrcat(tmpstr, ";trackid=", 1, 0);;
354                        tmpstr = ostrcat(tmpstr, oitoa(tmptrackId), 1, 0);
355                        tmpstr = ostrcat(tmpstr, ";subtext=", 1, 0);;
356                        tmpstr = ostrcat(tmpstr, tmpdata, 1, 0);;
357                        tmpstr = ostrcat(tmpstr, "\n", 1, 0);;
358
359                        subtext = ostrcat(subtext, tmpstr, 1, 0);
360                        free(tmpstr), tmpstr = NULL;
361
362                        tmpduration = 0;
363                        tmppts = 0;
364                        tmptrackId = 0;
365
366
367                }
368                av_free_packet(&packet);
369        }
370
371//      free(subtext), subtext = NULL;
372
373        avcodec_close(c);
374        avformat_close_input(&subavfc);
375        avformat_free_context(subavfc);
376
377        ffmpeg_printf(1, "format=%s\n", format);
378        ffmpeg_printf(1, "pid=%d\n", pid);
379
380        if(pid != -1)
381        {
382                Track_t Subtitle;
383                memset(&Subtitle, 0, sizeof(Subtitle));
384                Subtitle.Name = ostrcat("External Sub: ", format, 0, 0);
385                if(ostrstr(format, "srt") != NULL)
386                        Subtitle.Encoding = "S_TEXT/SRT";
387                else if(ostrstr(format, "ass") != NULL)
388                        Subtitle.Encoding = "S_TEXT/ASS";
389                else if(ostrstr(format, "ssa") != NULL)
390                        Subtitle.Encoding = "S_TEXT/SSA";
391                else if(ostrstr(format, "sub") != NULL)
392                        Subtitle.Encoding = "S_TEXT/SUBRIP";
393                else if(ostrstr(format, "idx") != NULL)
394                        Subtitle.Encoding = "S_TEXT/SUBRIP";
395                Subtitle.File       = strdup(subfile); 
396                Subtitle.Id = pid,
397                context->manager->subtitle->Command(context, MANAGER_ADD, &Subtitle);
398        }
399
400//      Track track;
401//      track.title = format;
402//      track.is_static = 1;
403//      track.pid = pid;
404//      player->manager.addSubtitleTrack(track);
405        return 1;
406}
407
408int ReadSubtitles(Context_t *context, const char *filename)
409{
410        int ret = 0;
411        if (strncmp(filename, "file://", 7))
412                return ret;
413        filename += 7;
414        ret |= ReadSubtitle(context, filename, "srt", 0xFFFF);
415        ret |= ReadSubtitle(context, filename, "ass", 0xFFFE);
416        ret |= ReadSubtitle(context, filename, "ssa", 0xFFFD);
417        ret |= ReadSubtitle(context, filename, "sub", 0xFFFC);
418        ret |= ReadSubtitle(context, filename, "idx", 0xFFFB);
419        return ret;
420}
421//obi (end)
422
423static void ffmpeg_silen_callback(void * avcl, int level, const char * fmt, va_list vl)
424{
425    return;
426}
427
428static int32_t mutexInitialized = 0;
429
430void sel_program_id_set(const int32_t val)
431{
432    g_sel_program_id = val;
433}
434
435void wma_software_decoder_set(const int32_t val)
436{
437    wma_software_decode = val;
438}
439
440void aac_software_decoder_set(const int32_t val)
441{
442    aac_software_decode = val;
443}
444
445void aac_latm_software_decoder_set(const int32_t val)
446{
447    aac_latm_software_decode = val;
448}
449
450void ac3_software_decoder_set(const int32_t val)
451{
452    ac3_software_decode = val;
453}
454
455void eac3_software_decoder_set(const int32_t val)
456{
457    eac3_software_decode = val;
458}
459
460void dts_software_decoder_set(const int32_t val)
461{
462    dts_software_decode = val;
463}
464
465void stereo_software_decoder_set(const int32_t val)
466{
467    stereo_software_decoder = val;
468}
469
470void insert_pcm_as_lpcm_set(const int32_t val)
471{
472    insert_pcm_as_lpcm = val;
473}
474
475void pcm_resampling_set(const int32_t val)
476{
477    pcm_resampling = val;
478}
479
480void mp3_software_decoder_set(const int32_t val)
481{
482    mp3_software_decode = val;
483}
484
485void rtmp_proto_impl_set(const int32_t val)
486{
487    rtmp_proto_impl = val;
488}
489
490void flv2mpeg4_converter_set(const int32_t val)
491{
492    flv2mpeg4_converter = val;
493}
494
495int32_t ffmpeg_av_dict_set(const char *key, const char *value, int32_t flags)
496{
497    return av_dict_set(&avio_opts, key, value, flags);
498}
499
500static void initMutex(void)
501{
502    pthread_mutex_init(&mutex, NULL);
503    mutexInitialized = 1;
504}
505
506static 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
520static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line)
521{
522    pthread_mutex_unlock(&mutex);
523
524    ffmpeg_printf(100, "::%d released mutex\n", line);
525}
526
527static char* Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile, int32_t *version)
528{
529    ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id);
530    switch (codec_id)
531    {
532    case AV_CODEC_ID_MPEG1VIDEO:
533        return "V_MPEG1";
534    case AV_CODEC_ID_MPEG2VIDEO:
535        return "V_MPEG1";
536    case AV_CODEC_ID_H263:
537    case AV_CODEC_ID_H263P:
538    case AV_CODEC_ID_H263I:
539        return "V_H263";
540    case AV_CODEC_ID_FLV1:
541        return flv2mpeg4_converter ? "V_MPEG4" : "V_FLV";
542    case AV_CODEC_ID_VP5:
543    case AV_CODEC_ID_VP6:
544    case AV_CODEC_ID_VP6F:
545        return "V_VP6";
546    case AV_CODEC_ID_VP8:
547        return "V_VP8";
548#if LIBAVCODEC_VERSION_MAJOR > 54
549    case AV_CODEC_ID_VP9:
550        return "V_VP9";
551#endif
552    case AV_CODEC_ID_RV10:
553    case AV_CODEC_ID_RV20:
554        return "V_RMV";
555    case AV_CODEC_ID_MPEG4:
556        return "V_MPEG4";
557#if LIBAVCODEC_VERSION_MAJOR < 53
558    case AV_CODEC_ID_XVID:
559#endif
560    case AV_CODEC_ID_MSMPEG4V1:
561    case AV_CODEC_ID_MSMPEG4V2:
562    case AV_CODEC_ID_MSMPEG4V3:
563        return "V_DIVX3";
564    case AV_CODEC_ID_WMV1:
565        *version = 1;
566        return "V_WMV";
567    case AV_CODEC_ID_WMV2:
568        *version = 2;
569        return "V_WMV";
570    case AV_CODEC_ID_WMV3:
571        *version = 3;
572        return "V_WMV";
573    case AV_CODEC_ID_VC1:
574        return "V_VC1";
575    case AV_CODEC_ID_H264:
576#if LIBAVCODEC_VERSION_MAJOR < 54
577    case AV_CODEC_ID_FFH264:
578#endif
579        return "V_MPEG4/ISO/AVC";
580#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(55, 92, 100)
581    case AV_CODEC_ID_HEVC:
582    // case AV_CODEC_ID_H265:
583        return "V_HEVC";
584#endif
585    case AV_CODEC_ID_AVS:
586        return "V_AVS";
587    case AV_CODEC_ID_MP2:
588        return "A_MPEG/L3";
589    case AV_CODEC_ID_MP3:
590        return (mp3_software_decode) ? "A_IPCM" : "A_MP3";
591    case AV_CODEC_ID_AAC:
592        if (extradata_size >= 2)
593        {
594            MPEG4AudioConfig m4ac;
595            int off = avpriv_mpeg4audio_get_config(&m4ac, extradata, extradata_size * 8, 1);
596            ffmpeg_printf(1,"aac [%d] off[%d]\n", m4ac.object_type, off);
597            if (off < 0 || 2 != m4ac.object_type)
598            {
599                return "A_IPCM";
600            }
601        }
602        return (aac_software_decode) ? "A_IPCM" : "A_AAC"; 
603    case AV_CODEC_ID_AAC_LATM:
604        return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM";
605    case AV_CODEC_ID_AC3:
606        return  (ac3_software_decode) ? "A_IPCM" : "A_AC3";
607    case AV_CODEC_ID_EAC3:
608        return  (eac3_software_decode) ? "A_IPCM" : "A_EAC3";
609    case AV_CODEC_ID_DTS:
610        return (dts_software_decode) ? "A_IPCM" : "A_DTS";
611    case AV_CODEC_ID_WMAV1:
612    case AV_CODEC_ID_WMAV2:
613            return (wma_software_decode) ? "A_IPCM" : "A_WMA";
614    case 86056:
615    case AV_CODEC_ID_WMAPRO:
616        return (wma_software_decode) ? "A_IPCM" : "A_WMA/PRO";
617    case AV_CODEC_ID_WMALOSSLESS:
618        return "A_IPCM";
619    case AV_CODEC_ID_MLP:
620        return "A_IPCM";
621    case AV_CODEC_ID_RA_144:
622        return "A_IPCM";
623    case AV_CODEC_ID_RA_288:
624        return "A_IPCM";
625    case AV_CODEC_ID_VORBIS:
626        return "A_IPCM";
627    case AV_CODEC_ID_FLAC:
628        return "A_IPCM";
629    case AV_CODEC_ID_PCM_S8:
630    case AV_CODEC_ID_PCM_U8:
631    case AV_CODEC_ID_PCM_S16LE:
632    case AV_CODEC_ID_PCM_S16BE:
633    case AV_CODEC_ID_PCM_U16LE:
634    case AV_CODEC_ID_PCM_U16BE:
635    case AV_CODEC_ID_PCM_S24LE:
636    case AV_CODEC_ID_PCM_S24BE:
637    case AV_CODEC_ID_PCM_U24LE:
638    case AV_CODEC_ID_PCM_U24BE:
639    case AV_CODEC_ID_PCM_S32LE:
640    case AV_CODEC_ID_PCM_S32BE:
641    case AV_CODEC_ID_PCM_U32LE:
642    case AV_CODEC_ID_PCM_U32BE:
643        return pcm_resampling ? "A_IPCM" : "A_PCM";
644    case AV_CODEC_ID_AMR_NB:
645        return "A_IPCM";//return "A_AMR";
646
647/* In exteplayer3 embedded text subtitle simple printed
648 * to output like other data.  Maybe worth to consider is to use
649 * linux socket or pipe to put
650 */
651
652/* subtitle */
653    case AV_CODEC_ID_SSA:
654#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100)
655    case AV_CODEC_ID_ASS:
656#endif
657        return "S_TEXT/ASS"; /* Hellmaster1024: seems to be ASS instead of SSA */
658    case AV_CODEC_ID_DVD_SUBTITLE:
659    case AV_CODEC_ID_DVB_SUBTITLE:
660    case AV_CODEC_ID_XSUB:
661    case AV_CODEC_ID_MOV_TEXT:
662    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
663    case AV_CODEC_ID_DVB_TELETEXT:
664//    case CODEC_ID_DVB_TELETEXT:
665//        return "S_TEXT/SRT"; /* fixme */
666    case AV_CODEC_ID_TEXT: ///< raw UTF-8 text
667        return "S_TEXT/UTF-8";
668    case AV_CODEC_ID_SRT:
669        return "S_TEXT/SRT";
670    case AV_CODEC_ID_SUBRIP:
671        return "S_TEXT/SUBRIP";
672    default:
673        ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
674        // Default to injected-pcm for unhandled audio types.
675        if (media_type == AVMEDIA_TYPE_AUDIO)
676        {
677            return "A_IPCM";
678        }
679        ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
680    }
681    return NULL;
682}
683
684static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts)
685{
686    if (!stream || pts == (int64_t)AV_NOPTS_VALUE)
687    {
688        ffmpeg_err("stream / packet null\n");
689        return INVALID_PTS_VALUE;
690    }
691    else if (stream->time_base.den > 0)
692    {
693        pts = av_rescale(pts, (int64_t)stream->time_base.num * 90000, stream->time_base.den);
694    }
695   
696    if (avContextTab[avContextIdx]->start_time != AV_NOPTS_VALUE)
697    {
698        pts -= 90000 * avContextTab[avContextIdx]->start_time / AV_TIME_BASE;
699    }
700
701    if (pts & 0x8000000000000000ull)
702    {
703        pts = INVALID_PTS_VALUE;
704    }
705
706    return pts;
707}
708
709/* search for metatdata in context and stream
710 * and map it to our metadata.
711 */
712
713static char* searchMeta(void * metadata, char* ourTag)
714{
715#if LIBAVCODEC_VERSION_MAJOR < 54
716   AVMetadataTag *tag = NULL;
717#else
718   AVDictionaryEntry *tag = NULL;
719#endif
720   int i = 0;
721
722   while (metadata_map[i] != NULL)
723   {
724      if (strcmp(ourTag, metadata_map[i]) == 0)
725      {
726#if LIBAVCODEC_VERSION_MAJOR < 54
727          while ((tag = av_metadata_get(metadata, "", tag, AV_METADATA_IGNORE_SUFFIX)))
728#else
729          while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
730#endif
731          {
732              if (strcmp(tag->key, metadata_map[ i + 1 ]) == 0)
733              {
734                  return tag->value;
735              }
736          }
737      }
738      i++;
739   }
740
741   return NULL;
742}
743
744/* **************************** */
745/* Worker Thread                */
746/* **************************** */
747
748static void FFMPEGThread(Context_t *context)
749{
750    char threadname[17];
751    strncpy(threadname, __func__, sizeof(threadname));
752    threadname[16] = 0;
753    prctl (PR_SET_NAME, (unsigned long)&threadname);
754    AVPacket   packet;
755    off_t   lastSeek = -1;
756    int64_t lastPts = -1;
757    int64_t currentVideoPts = -1;
758    int64_t currentAudioPts = -1;
759   
760    /* lastVideoDts and lastAudioDts
761     * used in isTSLiveMode
762     */
763    int64_t lastVideoDts = -1;
764    int64_t lastAudioDts = -1;
765   
766    int64_t showtime = 0;
767    int64_t bofcount = 0;
768    int32_t       err = 0;
769    AudioVideoOut_t avOut;
770   
771    g_context = context;
772
773    SwrContext *swr = NULL;
774    AVFrame *decoded_frame = NULL;
775    int32_t out_sample_rate = 44100;
776    int32_t out_channels = 2;
777    uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
778    uint32_t cAVIdx = 0;
779
780#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
781    Mpeg4P2Context mpeg4p2_context;
782    memset(&mpeg4p2_context, 0, sizeof(Mpeg4P2Context));
783    AVBitStreamFilterContext *mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
784#endif
785#ifdef HAVE_FLV2MPEG4_CONVERTER
786    Flv2Mpeg4Context flv2mpeg4_context;
787    memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context));
788#endif
789    ffmpeg_printf(10, "\n");
790    while ( context->playback->isCreationPhase )
791    {
792        ffmpeg_err("Thread waiting for end of init phase...\n");
793        usleep(1000);
794    }
795    ffmpeg_printf(10, "Running!\n");
796
797    int8_t isWaitingForFinish = 0;
798    while ( context && context->playback && context->playback->isPlaying )
799    {
800        //IF MOVIE IS PAUSED, WAIT
801        if (context->playback->isPaused)
802        {
803            ffmpeg_printf(20, "paused\n");
804            reset_finish_timeout();
805            usleep(10000);
806            continue;
807        }
808
809        if (context->playback->isSeeking)
810        {
811            ffmpeg_printf(10, "seeking\n");
812            reset_finish_timeout();
813            usleep(10000);
814            continue;
815        }
816
817        getMutex(__FILE__, __FUNCTION__,__LINE__);
818
819        if (!context->playback || !context->playback->isPlaying)
820        {
821            releaseMutex(__FILE__, __FUNCTION__,__LINE__);
822            if(!isWaitingForFinish)
823            {
824                reset_finish_timeout();
825            }
826            continue;
827        }
828
829        if (do_seek_target_seconds || do_seek_target_bytes)
830        {
831            isWaitingForFinish = 0;
832            if (do_seek_target_seconds)
833            {
834                ffmpeg_printf(10, "seek_target_seconds[%lld]\n", seek_target_seconds);
835                uint32_t i = 0;
836                for(; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
837                {
838                    if(NULL != avContextTab[i])
839                    {
840                        if (i == 1)
841                        {
842                            prev_seek_time_sec = seek_target_seconds;
843                        }
844                        if (avContextTab[i]->start_time != AV_NOPTS_VALUE)
845                        {
846                            seek_target_seconds += avContextTab[i]->start_time;
847                            printf("SEEK SECONDS [%lld]\n", seek_target_seconds);
848                        }
849                        //av_seek_frame(avContextTab[i], -1, seek_target_seconds, 0);
850                        avformat_seek_file(avContextTab[i], -1, INT64_MIN, seek_target_seconds, INT64_MAX, 0);
851                    }
852                    else
853                    {
854                        break;
855                    }
856                }
857                reset_finish_timeout();
858            }
859            else
860            {
861                container_ffmpeg_seek_bytes(seek_target_bytes);
862            }
863            do_seek_target_seconds = 0;
864            do_seek_target_bytes = 0;
865           
866            restart_audio_resampling = 1;
867            currentVideoPts = -1;
868            currentAudioPts = -1;
869            latestPts = 0;
870            seek_target_flag = 0;
871
872            // flush streams
873            uint32_t i = 0;
874            for(i=0; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
875            {
876                if(NULL != avContextTab[i])
877                {
878                    if (i != 1)
879                    {
880                        wrapped_avcodec_flush_buffers(i);
881                    }
882                }
883                else
884                {
885                    break;
886                }
887            }
888#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
889            mpeg4p2_context_reset(&mpeg4p2_context);
890            if (NULL != mpeg4p2_bsf_context)
891            {
892                av_bitstream_filter_close(mpeg4p2_bsf_context);
893                mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
894            }
895#endif
896#ifdef HAVE_FLV2MPEG4_CONVERTER
897            flv2mpeg4_context_reset(&flv2mpeg4_context);
898#endif
899        }
900
901        int ffmpegStatus = 0;
902        if(!isWaitingForFinish)
903        {
904            if(NULL != avContextTab[1])
905            {
906                cAVIdx = currentVideoPts <= currentAudioPts ? 0 : 1;
907                if (1 == cAVIdx && prev_seek_time_sec >= 0 )
908                {
909                    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);
910                    prev_seek_time_sec = -1;
911                    wrapped_avcodec_flush_buffers(1);
912                }
913            }
914            else
915            {
916                cAVIdx = 0;
917            }
918        }
919       
920        if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0 )
921        {
922            int64_t pts = 0;
923            int64_t dts = 0;
924            Track_t *videoTrack = NULL;
925            Track_t *audioTrack = NULL;
926            Track_t *subtitleTrack = NULL;
927
928            int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id;
929           
930            reset_finish_timeout();
931
932            if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0)
933            {
934                ffmpeg_err("error getting video track\n");
935            }
936           
937            if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0)
938            {
939                ffmpeg_err("error getting audio track\n");
940            }
941           
942            if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0)
943            {
944                ffmpeg_err("error getting subtitle track\n");
945            }
946
947            ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid);
948
949            if (videoTrack && (videoTrack->AVIdx == cAVIdx) && (videoTrack->Id == pid))
950            {
951#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
952                AVCodecContext *codec_context = videoTrack->avCodecCtx;
953                if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context)
954                {
955                    // should never happen, if it does print error and exit immediately, so we can easily spot it
956                    if (filter_packet(mpeg4p2_bsf_context, codec_context, &packet) < 0)
957                    {
958                        ffmpeg_err("cannot filter mpegp2 packet\n");
959                        exit(1);
960                    }
961                    if (mpeg4p2_write_packet(context, &mpeg4p2_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet) < 0)
962                    {
963                        ffmpeg_err("cannot write mpeg4p2 packet\n");
964                        exit(1);
965                    }
966                    update_max_injected_pts(latestPts);
967                }
968                else
969#endif
970#ifdef HAVE_FLV2MPEG4_CONVERTER
971                if (get_codecpar(avContextTab[cAVIdx]->streams[packet.stream_index])->codec_id == AV_CODEC_ID_FLV1 &&
972                    0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7) )
973                {
974                    flv2mpeg4_write_packet(context, &flv2mpeg4_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet);
975                    update_max_injected_pts(latestPts);
976                }
977                else
978#endif
979                {
980                    uint8_t skipPacket = 0;
981                    currentVideoPts = videoTrack->pts = pts = calcPts(cAVIdx, videoTrack->stream, packet.pts);
982                    videoTrack->dts = dts = calcPts(cAVIdx, videoTrack->stream, packet.dts);
983
984                    if ((currentVideoPts != INVALID_PTS_VALUE) && (currentVideoPts > latestPts))
985                    {
986                        latestPts = currentVideoPts;
987                        update_max_injected_pts(latestPts);
988                    }
989                   
990                    if (context->playback->isTSLiveMode)
991                    {
992                        if (dts != INVALID_PTS_VALUE)
993                        {   
994                            if (dts > lastVideoDts)
995                            {
996                                lastVideoDts = dts;
997                            }
998                            else
999                            {
1000                                // skip already injected VIDEO packet
1001                                ffmpeg_printf(200, "skip already injected VIDEO packet\n");
1002                                skipPacket = 1;
1003                            }
1004                        }
1005                        else
1006                        {
1007                            // skip VIDEO packet with unknown DTS
1008                            ffmpeg_printf(200, "skip VIDEO packet with unknown DTS\n");
1009                            skipPacket = 1;
1010                        }
1011                    }
1012                   
1013                    if (skipPacket)
1014                    {   
1015                        wrapped_packet_unref(&packet);
1016                        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
1017                        continue;
1018                    }
1019                   
1020                    ffmpeg_printf(200, "VideoTrack index = %d %lld\n",pid, currentVideoPts);
1021
1022                    avOut.data       = packet.data;
1023                    avOut.len        = packet.size;
1024                    avOut.pts        = pts;
1025                    avOut.dts        = dts;
1026                    avOut.extradata  = videoTrack->extraData;
1027                    avOut.extralen   = videoTrack->extraSize;
1028                    avOut.frameRate  = videoTrack->frame_rate;
1029                    avOut.timeScale  = videoTrack->TimeScale;
1030                    avOut.width      = videoTrack->width;
1031                    avOut.height     = videoTrack->height;
1032                    avOut.type       = "video";
1033                   
1034                    if (avContextTab[cAVIdx]->iformat->flags & AVFMT_TS_DISCONT)
1035                    {
1036                        avOut.infoFlags = 1; // TS container
1037                    }
1038
1039                    if (context->output->video->Write(context, &avOut) < 0)
1040                    {
1041                        ffmpeg_err("writing data to video device failed\n");
1042                    }
1043                }
1044            }
1045            else if (audioTrack && (audioTrack->AVIdx == cAVIdx) && (audioTrack->Id == pid))
1046            {
1047                uint8_t skipPacket = 0;
1048                currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, packet.pts);
1049                dts = calcPts(cAVIdx, audioTrack->stream, packet.dts);
1050
1051                if ((currentAudioPts != INVALID_PTS_VALUE) && (currentAudioPts > latestPts) && (!videoTrack))
1052                {
1053                    latestPts = currentAudioPts;
1054                    update_max_injected_pts(latestPts);
1055                }
1056               
1057                if (context->playback->isTSLiveMode)
1058                {
1059                    if (dts != INVALID_PTS_VALUE)
1060                    {
1061                        if (dts > lastAudioDts)
1062                        {
1063                            lastAudioDts = dts;
1064                        }
1065                        else
1066                        {
1067                            // skip already injected AUDIO packet
1068                            ffmpeg_printf(200, "skip already injected AUDIO packet\n");
1069                            skipPacket = 1;
1070                        }
1071                    }
1072                    else
1073                    {
1074                        // skip AUDIO packet with unknown PTS
1075                        ffmpeg_printf(200, "skip AUDIO packet with unknown PTS\n");
1076                        skipPacket = 1;
1077                    }
1078                }
1079               
1080                if (skipPacket)
1081                {
1082                    wrapped_packet_unref(&packet);
1083                    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
1084                    continue;
1085                }
1086               
1087                pcmPrivateData_t pcmExtradata;
1088                pcmExtradata.channels              = get_codecpar(audioTrack->stream)->channels;
1089                pcmExtradata.bits_per_coded_sample = get_codecpar(audioTrack->stream)->bits_per_coded_sample;
1090                pcmExtradata.sample_rate           = get_codecpar(audioTrack->stream)->sample_rate;
1091                pcmExtradata.bit_rate              = get_codecpar(audioTrack->stream)->bit_rate;
1092                pcmExtradata.ffmpeg_codec_id       = get_codecpar(audioTrack->stream)->codec_id;
1093                pcmExtradata.bResampling           = restart_audio_resampling;
1094               
1095                uint8_t *pAudioExtradata    = get_codecpar(audioTrack->stream)->extradata;
1096                uint32_t audioExtradataSize = get_codecpar(audioTrack->stream)->extradata_size;
1097                   
1098                ffmpeg_printf(200, "AudioTrack index = %d\n",pid);
1099                if (audioTrack->inject_raw_pcm == 1)
1100                {
1101                    ffmpeg_printf(200,"write audio raw pcm\n");
1102                    restart_audio_resampling = 0;
1103
1104                    avOut.data       = packet.data;
1105                    avOut.len        = packet.size;
1106                    avOut.pts        = pts;
1107                    avOut.extradata  = (uint8_t *) &pcmExtradata;
1108                    avOut.extralen   = sizeof(pcmExtradata);
1109                    avOut.frameRate  = 0;
1110                    avOut.timeScale  = 0;
1111                    avOut.width      = 0;
1112                    avOut.height     = 0;
1113                    avOut.type       = "audio";
1114
1115                    if (context->output->audio->Write(context, &avOut) < 0)
1116                    {
1117                        ffmpeg_err("(raw pcm) writing data to audio device failed\n");
1118                    }
1119                }
1120                else if (audioTrack->inject_as_pcm == 1 && audioTrack->avCodecCtx)
1121                {
1122                    AVCodecContext *c = audioTrack->avCodecCtx;
1123
1124                    if (restart_audio_resampling)
1125                    {
1126                        restart_audio_resampling = 0;
1127                        if (swr)
1128                        {
1129                            swr_free(&swr);
1130                            swr = NULL;
1131                        }
1132                        if (decoded_frame)
1133                        {
1134                            wrapped_frame_free(&decoded_frame);
1135                            decoded_frame = NULL;
1136                        }
1137                    }
1138#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
1139                    while (packet.size > 0 || (!packet.size && !packet.data))
1140#else
1141                    while(packet.size > 0)
1142#endif
1143                    {
1144                        if(do_seek_target_seconds || do_seek_target_bytes)
1145                        {
1146                            break;
1147                        }
1148                       
1149                        if (!decoded_frame)
1150                        {
1151                            decoded_frame = wrapped_frame_alloc();
1152                            if (!decoded_frame)
1153                            {
1154                                ffmpeg_err("out of memory\n");
1155                                exit(1);
1156                            }
1157                        }
1158                        else
1159                        {
1160                            wrapped_frame_unref(decoded_frame);
1161                        }
1162#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
1163                        int ret = avcodec_send_packet(c, &packet);
1164                        if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
1165                        {
1166                            restart_audio_resampling = 1;
1167                            break;
1168                        }
1169                       
1170                        if (ret >= 0)
1171                        {
1172                            packet.size = 0;
1173                        }
1174                       
1175                        ret = avcodec_receive_frame(c, decoded_frame);
1176                        if (ret < 0)
1177                        {
1178                            if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
1179                            {
1180                                restart_audio_resampling = 1;
1181                                break;
1182                            }
1183                            else
1184                            {
1185                                continue;
1186                            }
1187                        }
1188#else
1189                        int32_t got_frame = 0;
1190                        int32_t len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &packet);
1191                        if (len < 0)
1192                        {
1193                            ffmpeg_err("avcodec_decode_audio4: %d\n", len);
1194                            break;
1195                        }
1196
1197                        packet.data += len;
1198                        packet.size -= len;
1199                       
1200                        if (!got_frame)
1201                        {
1202                            continue;
1203                        }
1204#endif
1205                        int32_t e = 0;
1206                        if (!swr)
1207                        {
1208                            if(insert_pcm_as_lpcm)
1209                            {
1210                                out_sample_rate = 48000;
1211                            }
1212                            else
1213                            {
1214                                int32_t rates[] = { 48000, 96000, 192000, 44100, 88200, 176400, 0 };
1215                                int32_t *rate = rates;
1216                                int32_t in_rate = c->sample_rate;
1217                                while (*rate && ((*rate / in_rate) * in_rate != *rate) && (in_rate / *rate) * *rate != in_rate)
1218                                {
1219                                    rate++;
1220                                }
1221                                out_sample_rate = *rate ? *rate : 44100;
1222                            }
1223                           
1224                            swr = swr_alloc();
1225                            out_channels = c->channels;
1226                           
1227                            if (c->channel_layout == 0)
1228                            {
1229                                c->channel_layout = av_get_default_channel_layout( c->channels );
1230                            }
1231                            out_channel_layout = c->channel_layout;
1232                           
1233                            uint8_t downmix = stereo_software_decoder && out_channels > 2 ? 1 : 0;
1234#ifdef __sh__
1235                            // player2 won't play mono
1236                            if (out_channel_layout == AV_CH_LAYOUT_MONO)
1237                            {
1238                                downmix = 1;
1239                            }
1240#endif
1241                            if(downmix)
1242                            {
1243                                out_channel_layout = AV_CH_LAYOUT_STEREO_DOWNMIX;
1244                                out_channels = 2;
1245                            }
1246                           
1247                            av_opt_set_int(swr, "in_channel_layout",    c->channel_layout,      0);
1248                            av_opt_set_int(swr, "out_channel_layout",   out_channel_layout,     0);
1249                            av_opt_set_int(swr, "in_sample_rate",               c->sample_rate,         0);
1250                            av_opt_set_int(swr, "out_sample_rate",              out_sample_rate,        0);
1251                            av_opt_set_int(swr, "in_sample_fmt",                c->sample_fmt,          0);
1252                            av_opt_set_int(swr, "out_sample_fmt",               AV_SAMPLE_FMT_S16,      0);
1253       
1254
1255                            e = swr_init(swr);
1256                            if (e < 0)
1257                            {
1258                                ffmpeg_err("swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n",
1259                                    -e, (int32_t)c->channel_layout, (int32_t)out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16);
1260                                swr_free(&swr);
1261                                swr = NULL;
1262                            }
1263                        }
1264                       
1265                        uint8_t *output[8] = {NULL};
1266                        int32_t in_samples = decoded_frame->nb_samples;
1267                        int32_t out_samples = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) + in_samples, out_sample_rate, c->sample_rate, AV_ROUND_UP);
1268                        e = av_samples_alloc(&output[0], NULL, out_channels, out_samples, AV_SAMPLE_FMT_S16, 1);
1269                        if (e < 0)
1270                        {
1271                            ffmpeg_err("av_samples_alloc: %d\n", -e);
1272                            continue;
1273                        }
1274                        int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame),
1275                                         ((AVStream*) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate,
1276                                         ((AVStream*) audioTrack->stream)->time_base.den);
1277                        int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts),
1278                                         ((AVStream*) audioTrack->stream)->time_base.den,
1279                                         ((AVStream*) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate);
1280                       
1281                        currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, next_out_pts);
1282                        out_samples = swr_convert(swr, &output[0], out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples);
1283                       
1284                        //////////////////////////////////////////////////////////////////////
1285                        // Update pcmExtradata according to decode parameters
1286                        pcmExtradata.channels              = av_get_channel_layout_nb_channels(out_channel_layout);
1287                        pcmExtradata.bits_per_coded_sample = 16;
1288                        pcmExtradata.sample_rate           = out_sample_rate;
1289                        // The data described by the sample format is always in native-endian order
1290#ifdef WORDS_BIGENDIAN
1291                        pcmExtradata.ffmpeg_codec_id       = AV_CODEC_ID_PCM_S16BE;
1292#else
1293                        pcmExtradata.ffmpeg_codec_id       = AV_CODEC_ID_PCM_S16LE;
1294#endif
1295
1296                        //////////////////////////////////////////////////////////////////////
1297
1298                        avOut.data       = output[0];
1299                        avOut.len        = out_samples * sizeof(int16_t) * out_channels;
1300
1301                        avOut.pts        = pts;
1302                        avOut.extradata  = (unsigned char *) &pcmExtradata;
1303                        avOut.extralen   = sizeof(pcmExtradata);
1304                        avOut.frameRate  = 0;
1305                        avOut.timeScale  = 0;
1306                        avOut.width      = 0;
1307                        avOut.height     = 0;
1308                        avOut.type       = "audio";
1309
1310                        if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
1311                        {
1312                            ffmpeg_err("writing data to audio device failed\n");
1313                        }
1314                        av_freep(&output[0]);
1315                    }
1316                }
1317                else if (audioTrack->have_aacheader == 1)
1318                {
1319                    ffmpeg_printf(200, "write audio aac\n");
1320                    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]);
1321
1322                    avOut.data       = packet.data;
1323                    avOut.len        = packet.size;
1324                    avOut.pts        = pts;
1325                    avOut.extradata  = audioTrack->aacbuf;
1326                    avOut.extralen   = audioTrack->aacbuflen;
1327                    avOut.frameRate  = 0;
1328                    avOut.timeScale  = 0;
1329                    avOut.width      = 0;
1330                    avOut.height     = 0;
1331                    avOut.type       = "audio";
1332
1333                    if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
1334                    {
1335                        ffmpeg_err("(aac) writing data to audio device failed\n");
1336                    }
1337                }
1338                else
1339                {
1340                    avOut.data       = packet.data;
1341                    avOut.len        = packet.size;
1342                    avOut.pts        = pts;
1343                    avOut.extradata  = pAudioExtradata;
1344                    avOut.extralen   = audioExtradataSize;
1345                    avOut.frameRate  = 0;
1346                    avOut.timeScale  = 0;
1347                    avOut.width      = 0;
1348                    avOut.height     = 0;
1349                    avOut.type       = "audio";
1350
1351                    if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
1352                    {
1353                        ffmpeg_err("writing data to audio device failed\n");
1354                    }
1355                }
1356            }
1357            else if (subtitleTrack && (subtitleTrack->Id == pid))
1358            {
1359                int64_t duration = -1;
1360                int64_t pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts);
1361                AVStream *stream = subtitleTrack->stream;
1362               
1363                if (packet.duration != 0)
1364                {
1365                    // duration in milliseconds
1366                    duration = (int64_t)av_rescale(packet.duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
1367                }
1368                else if(get_packet_duration(&packet) != 0 && get_packet_duration(&packet) != AV_NOPTS_VALUE )
1369                {
1370                    // duration in milliseconds
1371                    duration = (int64_t)av_rescale(get_packet_duration(&packet), (int64_t)stream->time_base.num * 1000, stream->time_base.den);
1372                }
1373
1374                if (duration > 0)
1375                {
1376//                  printf("[LIBEPLAYER3/FFMPEGThread] start\n");
1377
1378                    SubtitleOut_t subOut;
1379                    memset(&subOut, 0, sizeof(subOut));
1380                    subOut.trackId = pid;
1381                    subOut.data = (uint8_t *)packet.data;
1382                    subOut.pts = pts;
1383                    subOut.durationMS = duration;
1384                    //obi
1385                    tmptrackId = pid;
1386                    tmpdata = (uint8_t *)packet.data;
1387//                  tmpdata = (uint8_t *)&packet.data;
1388                    //tmplen;
1389                    tmppts = pts;
1390                    tmpduration = duration;
1391                    tmpdata = ostrcat(subOut.data, NULL, 0, 0);
1392
1393                    //*tmptype;
1394//                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpdata=%s\n", tmpdata);
1395//                  printf("[LIBEPLAYER3/FFMPEGThread] set tmppts=%lld\n", tmppts);
1396//                  printf("[LIBEPLAYER3/FFMPEGThread] set tmpduration=%lld\n", tmpduration);
1397                    //obi (end)
1398
1399                    if (context->output->subtitle->Write(context, &subOut) < 0)
1400                    {
1401                        ffmpeg_err("writing data to teletext fifo failed\n");
1402                    }
1403                    //obi
1404                    char* tmpstr = NULL;
1405                    tmpstr = ostrcat(tmpstr, "duration=", 1, 0);
1406                    tmpstr = ostrcat(tmpstr, ollutoa(tmpduration), 1, 1);
1407                    tmpstr = ostrcat(tmpstr, ";pts=", 1, 0);;
1408                    tmpstr = ostrcat(tmpstr, ollutoa(tmppts), 1, 0);;
1409                    tmpstr = ostrcat(tmpstr, ";trackid=", 1, 0);;
1410                    tmpstr = ostrcat(tmpstr, oitoa(tmptrackId), 1, 0);
1411                    tmpstr = ostrcat(tmpstr, ";subtext=", 1, 0);;
1412                    tmpstr = ostrcat(tmpstr, tmpdata, 1, 0);;
1413
1414                    free(subtext), subtext = NULL;
1415                    subtext = ostrcat(subtext, tmpstr, 1, 0);
1416                    free(tmpstr), tmpstr = NULL;
1417
1418//                  tmpduration = 0;
1419                    tmppts = 0;
1420                    tmptrackId = 0;
1421
1422//                    printf("[LIBEPLAYER3/FFMPEGThread] set subtext: %s\n", subtext);
1423                    //obi (end)
1424                }
1425            }
1426        }
1427        else
1428        {
1429            if( 0 != ffmpegStatus )
1430            {
1431                static char errbuf[256];
1432               
1433                if( 0 == av_strerror(ffmpegStatus, errbuf, sizeof(errbuf)) )
1434                {
1435                    /* In this way we inform user about error within the core
1436                     */
1437                    printf("{\"log\":\"Frame read error: '%s'\"}\n", errbuf);
1438                }
1439               
1440                /*
1441                if( ffmpegStatus == AVERROR(EAGAIN) )
1442                {
1443                    continue;
1444                }
1445                */
1446                ffmpegStatus = 0;
1447            }
1448           
1449            if(!is_finish_timeout() && !context->playback->isTSLiveMode)
1450            {
1451                isWaitingForFinish = 1;
1452                update_finish_timeout();
1453                releaseMutex(__FILE__, __FUNCTION__,__LINE__);
1454                usleep(100000);
1455                continue;
1456            }
1457            else
1458            {
1459                uint8_t bEndProcess = 1;
1460                if (context->playback->isTSLiveMode)
1461                {
1462                    seek_target_bytes = 0;
1463                    do_seek_target_bytes = 1;
1464                    bEndProcess = 0;
1465                }
1466                else if( 1 == context->playback->isLoopMode )
1467                {
1468                    int64_t tmpLength = 0;
1469                    if( 0 == container_ffmpeg_get_length(context, &tmpLength) && tmpLength > 0 && get_play_pts() > 0)
1470                    {
1471#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
1472                        if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
1473                        {
1474                            seek_target_bytes = 0;
1475                            do_seek_target_bytes = 1;
1476                        }
1477                        else
1478#endif
1479                        {
1480                            seek_target_seconds = 0;
1481                            do_seek_target_seconds = 1;
1482                        }
1483                        bEndProcess = 0;
1484                        context->output->Command(context, OUTPUT_CLEAR, NULL);
1485                        context->output->Command(context, OUTPUT_PLAY, NULL);
1486                        printf("{\"log\":\"Loop mode: jump to the start.\"}\n");
1487                    }
1488                }
1489               
1490                // av_read_frame failed
1491                ffmpeg_err("no data ->end of file reached ? \n");
1492                wrapped_packet_unref(&packet);
1493                releaseMutex(__FILE__, __FUNCTION__,__LINE__);
1494                if( bEndProcess )
1495                {
1496                    break; // while
1497                }
1498                else
1499                {
1500                    continue;
1501                }
1502            }
1503        }
1504        wrapped_packet_unref(&packet);
1505        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
1506    } /* while */
1507
1508    if (swr)
1509    {
1510        swr_free(&swr);
1511    }
1512   
1513    if (decoded_frame)
1514    {
1515        wrapped_frame_free(&decoded_frame);
1516    }
1517   
1518#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
1519    mpeg4p2_context_reset(&mpeg4p2_context);
1520    if (NULL != mpeg4p2_bsf_context)
1521    {
1522        av_bitstream_filter_close(mpeg4p2_bsf_context);
1523    }
1524#endif
1525
1526    hasPlayThreadStarted = 0;
1527    context->playback->isPlaying = 0;
1528    PlaybackDieNow(1);
1529    ffmpeg_printf(10, "terminating\n");
1530}
1531
1532/* **************************** */
1533/* Container part for ffmpeg    */
1534/* **************************** */
1535
1536static int32_t terminating = 0;
1537static int32_t interrupt_cb(void *ctx)
1538{
1539    PlaybackHandler_t *p = (PlaybackHandler_t *)ctx;
1540//obi
1541//    return p->abortRequested || PlaybackDieNow(0);
1542    return p->abortRequested;
1543//obi (end)
1544}
1545
1546#ifdef SAM_CUSTOM_IO
1547int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize)
1548{
1549    size_t ret = fread ( (void *) buffer, (size_t) 1, (size_t) lSize, (FILE *)ptr );
1550    return (int)ret;
1551}
1552
1553// whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE
1554int64_t SAM_SeekFunc(void* ptr, int64_t pos, int whence)
1555{   
1556    if( AVSEEK_SIZE == whence )
1557    {
1558        return -1;
1559    }
1560    int ret = fseeko((FILE *)ptr, (off_t)pos, whence);
1561    if(0 == ret)
1562    {
1563        return (off_t)ftello((FILE *)ptr);
1564    }
1565    return ret;
1566}
1567
1568AVIOContext* container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_buffer_size)
1569{
1570        if(strstr(filename, "file://") == filename)
1571        {
1572            filename += 7;
1573        }
1574       
1575        FILE *pFile = fopen(filename, "rb");
1576        if(NULL == pFile)
1577        {
1578            return NULL;
1579        }
1580       
1581        AVIOContext *avio_ctx = NULL;
1582        uint8_t *avio_ctx_buffer = NULL;
1583       
1584        avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
1585        if (!avio_ctx_buffer)
1586        {
1587            return NULL;
1588        }
1589        avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, pFile, &SAM_ReadFunc, NULL, &SAM_SeekFunc);
1590        if (!avio_ctx)
1591        {
1592            return NULL;
1593        }
1594        return avio_ctx;
1595}
1596#endif
1597
1598int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int32_t AVIdx)
1599{
1600    int32_t err = 0;
1601    AVInputFormat *fmt = NULL;
1602    avContextTab[AVIdx] = avformat_alloc_context();
1603    avContextTab[AVIdx]->interrupt_callback.callback = interrupt_cb;
1604    avContextTab[AVIdx]->interrupt_callback.opaque = context->playback;
1605
1606#ifdef SAM_CUSTOM_IO
1607    if(0 == strstr(filename, "://") ||
1608       0 == strncmp(filename, "file://", 7))
1609    {
1610        AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096);
1611        if(avio_ctx)
1612        {
1613            avContextTab[AVIdx]->pb = avio_ctx;
1614            use_custom_io[AVIdx] = 1;
1615        }
1616        else
1617        {
1618            return cERR_CONTAINER_FFMPEG_OPEN;
1619        }
1620    }
1621#endif
1622
1623    AVDictionary **pavio_opts = NULL;
1624    eRTMPProtoImplType rtmpProtoImplType = RTMP_NONE;
1625    uint8_t numOfRTMPImpl = 0;
1626    if (0 == strncmp(filename, "ffrtmp", 6))
1627    {
1628        filename = filename + 2;
1629        rtmpProtoImplType = RTMP_NATIVE;
1630    }
1631   
1632    if (1 == rtmp_proto_impl)
1633    {
1634        rtmpProtoImplType = RTMP_NATIVE;
1635    }
1636    else if (2 == rtmp_proto_impl)
1637    {
1638        rtmpProtoImplType = RTMP_LIBRTMP;
1639    }
1640
1641    if (0 == strncmp(filename, "rtmp://", 7) ||
1642        0 == strncmp(filename, "rtmpe://", 8) ||
1643        0 == strncmp(filename, "rtmps://", 8) ||
1644        0 == strncmp(filename, "rtmpt://", 8) ||
1645        0 == strncmp(filename, "rtmpte://", 9) ||
1646        0 == strncmp(filename, "rtmpts://", 9))
1647    {
1648        /* At first we need to check which protocol
1649         * implementations we have
1650         */
1651        void *opaque = NULL;
1652        const char *protoName = NULL;
1653        uint8_t haveNativeProto = 0;
1654       
1655        while (protoName = avio_enum_protocols(&opaque, 1))
1656        {
1657            if (0 == strcmp("rtmp", protoName))
1658            {
1659                ++numOfRTMPImpl;
1660            }
1661            else if (0 == strcmp("ffrtmp", protoName))
1662            {
1663                // ffmpeg has patch to have both native and librtmp implementations
1664                ++numOfRTMPImpl;
1665                haveNativeProto = 2;
1666            }
1667            else if (0 == strncmp("rtmpts", protoName, 6))
1668            {
1669                // rtmpts is only available in native implementation
1670                // rtmpts is listed after rtmp
1671                haveNativeProto = 1;
1672            }
1673        }
1674       
1675        if (haveNativeProto > 0)
1676        {
1677            if (numOfRTMPImpl > 1) // we have both
1678            {
1679                if (rtmpProtoImplType == RTMP_NONE)
1680                {
1681                    /* if we have both impl, we will prefer native
1682                     * unless uri contain param wich can be understandable
1683                     * only by librtmp
1684                     */
1685                    if (strstr(filename, " token=") ||
1686                        strstr(filename, " jtv="))
1687                    {
1688                        rtmpProtoImplType = RTMP_LIBRTMP;
1689                    }
1690                    else
1691                    {
1692                        rtmpProtoImplType = RTMP_NATIVE;
1693                    }
1694                }
1695            }
1696            else
1697            {
1698                rtmpProtoImplType = RTMP_NATIVE;
1699            }
1700        }
1701        else
1702        {
1703            rtmpProtoImplType = RTMP_LIBRTMP;
1704        }
1705       
1706        if (RTMP_NATIVE == rtmpProtoImplType)
1707        {
1708            char *baseUri = strdup(filename);
1709            char *token  = NULL;
1710           
1711            // check if uri have additional params
1712            if ((token = strtok(baseUri, " ")) != NULL )
1713            {
1714                char *conn = malloc(strlen(filename));
1715                char *swfUrl = malloc(strlen(filename));
1716                char *swfVfy = malloc(strlen(filename));
1717                char *poseq, *key, *value;
1718                conn[0] = '\0';
1719                swfUrl[0] = '\0';
1720                swfVfy[0] = '\0';
1721                token = NULL;
1722                while((token = strtok(token, " ")) != NULL)
1723                {
1724                    if ((poseq = strchr(token, '=')) != NULL)
1725                    {
1726                        *poseq = '\0';
1727                        key = token;
1728                        value = poseq + 1;
1729                        ffmpeg_printf(20, "rtmp_key = \"%s\", rtmp_value = \"%s\"\n", key, value);
1730                        /* translate librtmp connection parameters to ffmpeg ones routin provided by @mx3L
1731                         *
1732                         * librtmp parameters     - https://rtmpdump.mplayerhq.hu/librtmp.3.html
1733                         * ffmpeg rtmp parameters - https://ffmpeg.org/ffmpeg-protocols.html#rtmp
1734                         */
1735                        if (!strcasecmp(key, "app"))
1736                        {
1737                            av_dict_set(&avio_opts, "rtmp_app", value, 0);
1738                        }
1739                        else if (!strcasecmp(key, "conn"))
1740                        {
1741                            if (conn[0] != '\0')
1742                            {
1743                                strcat(conn, " ");
1744                            }
1745                            strcat(conn, value);
1746                        }
1747                        else if (!strcasecmp(key, "buffer"))
1748                        {
1749                            av_dict_set(&avio_opts, "rtmp_buffer", value, 0);
1750                        }
1751                        else if (!strcasecmp(key, "flashVer"))
1752                        {
1753                            av_dict_set(&avio_opts, "rtmp_flashver", value, 0);
1754                        }
1755                        else if (!strcasecmp(key, "live"))
1756                        {
1757                            av_dict_set(&avio_opts, "rtmp_live", value, 0);
1758                        }
1759                        else if (!strcasecmp(key, "pageUrl"))
1760                        {
1761                            av_dict_set(&avio_opts, "rtmp_pageurl", value, 0);
1762                        }
1763                        else if (!strcasecmp(key, "playpath"))
1764                        {
1765                            av_dict_set(&avio_opts, "rtmp_playpath", value, 0);
1766                        }
1767                        else if (!strcasecmp(key, "subscribe"))
1768                        {
1769                            av_dict_set(&avio_opts, "rtmp_subscribe", value, 0);
1770                        }
1771                        else if (!strcasecmp(key, "swfUrl"))
1772                        {
1773                            strcpy(swfUrl, value);
1774                        }
1775                        // ffmpeg expects this value to contain url to player swf
1776                        // not a 1|0|TRUE like librtmp
1777                        else if (!strcasecmp(key, "swfVfy"))
1778                        {
1779                            strcpy(swfVfy, value);
1780                        }
1781                        else if (!strcasecmp(key, "tcUrl"))
1782                        {
1783                            av_dict_set(&avio_opts, "rtmp_tcurl", value, 0);
1784                        }
1785                        // timeout is ment for incoming connections
1786                        else if (!strcasecmp(key, "timeout"))
1787                        {
1788                        }
1789                        else
1790                        {
1791                            // threat as direct options
1792                            // for example rtmp_swfhash, rtmp_swfsize
1793                            av_dict_set(&avio_opts, key, value, 0);
1794                        }
1795                    }
1796                    token = NULL;
1797                }
1798               
1799                if (conn[0] != '\0')
1800                {
1801                    av_dict_set(&avio_opts, "rtmp_conn", conn, 0);
1802                }
1803                free(conn);
1804
1805                if (swfUrl[0] != '\0')
1806                {
1807                    if (swfVfy[0] == '1' || !strncasecmp(swfVfy, "true", 4))
1808                    {
1809                        av_dict_set(&avio_opts, "rtmp_swfverify", swfUrl, 0);
1810                    }
1811                    else
1812                    {
1813                        av_dict_set(&avio_opts, "rtmp_swfurl", swfUrl, 0);
1814                    }
1815                }
1816                free(swfUrl);
1817                free(swfVfy);
1818            }
1819           
1820            if (2 == haveNativeProto)
1821            {
1822                filename = malloc(strlen(baseUri) + 2 + 1);
1823                strncpy(filename, "ff", 2);
1824                strcpy(filename+2, baseUri);
1825                free(baseUri);
1826                // memory leak, only once, so does not matter
1827            }
1828            else
1829            {
1830                filename = baseUri;
1831                // memory leak, only once, so does not matter
1832            }
1833        }
1834    }
1835    else if(0 == strncmp(filename, "http://", 7) ||
1836            0 == strncmp(filename, "https://", 8))
1837    {
1838        av_dict_set(&avio_opts, "timeout", "20000000", 0); //20sec
1839//obi
1840                char* cookie = NULL, *tmpstr1 = NULL, *tmpstr2 = NULL, *tmpstr3 = NULL, *tmpstr4 = NULL, *headers = NULL, *useragent = NULL;
1841                int count = 0, count1 = 0, count2 = 0, count3 = 0, i = 0, i1 = 0, i2 = 0, i3 = 0, usetslivemode = 0;
1842
1843                struct splitstr* ret1 = NULL;
1844                struct splitstr* ret2 = NULL;
1845
1846                ffmpeg_printf(10, "check cookie\n");
1847
1848                if(file_exist("/mnt/network/cookies"))
1849                {
1850                        tmpstr1 = readfiletomem("/mnt/network/cookies", 1);
1851                        if(tmpstr1 != NULL)
1852                        {
1853                                tmpstr1 = string_replace_all("\t", " ", tmpstr1, 1);
1854                                string_strip_whitechars(tmpstr1);
1855                                strstrip(tmpstr1);
1856                                ret1 = strsplit(tmpstr1, "\n", &count);
1857                                for(i = 0; i < count; i++)
1858                                {
1859                                        count2 = 0;
1860                                        tmpstr2 = ostrcat((&ret1[i])->part, NULL, 0, 0);
1861                                        ret2 = strsplit(tmpstr2, " ", &count2);
1862
1863                                        if(count2 == 6)
1864                                        {
1865                                                cookie = ostrcat(cookie, (&ret2[4])->part, 1, 0);
1866                                                cookie = ostrcat(cookie, "=", 1, 0);
1867                                                cookie = ostrcat(cookie, (&ret2[5])->part, 1, 0);
1868                                                cookie = ostrcat(cookie, "; domain=", 1, 0);
1869                                                cookie = ostrcat(cookie, (&ret2[0])->part, 1, 0);
1870                                                cookie = ostrcat(cookie, "; path=", 1, 0);
1871                                                cookie = ostrcat(cookie, (&ret2[2])->part, 1, 0); 
1872                                                cookie = ostrcat(cookie, "\n", 1, 0);
1873                                        }
1874
1875                                        if(count2 == 7)
1876                                        {
1877                                                cookie = ostrcat(cookie, (&ret2[5])->part, 1, 0);
1878                                                cookie = ostrcat(cookie, "=", 1, 0);
1879                                                cookie = ostrcat(cookie, (&ret2[6])->part, 1, 0);
1880                                                cookie = ostrcat(cookie, "; domain=", 1, 0);
1881                                                cookie = ostrcat(cookie, (&ret2[0])->part, 1, 0);
1882                                                cookie = ostrcat(cookie, "; path=", 1, 0);
1883                                                cookie = ostrcat(cookie, (&ret2[2])->part, 1, 0); 
1884                                                cookie = ostrcat(cookie, "\n", 1, 0);
1885                                        }
1886                                       
1887                                        free(ret2), ret2 = NULL;
1888                                        free(tmpstr2), tmpstr2 = NULL;
1889                                }
1890                                free(ret1), ret1 = NULL;
1891                                free(tmpstr1), tmpstr1 = NULL;
1892                        }
1893                }
1894                if(cookie != NULL)
1895                {
1896                        ffmpeg_printf(10, "set cookies: %s\n", cookie);
1897                av_dict_set(&avio_opts, "cookies", cookie, 0);
1898                }
1899                else
1900                        ffmpeg_printf(10, "skip set cookies : %s\n", cookie);
1901
1902                ffmpeg_printf(10, "check user-agent and header\n");
1903
1904                if (ostrstr(filename, "&tslivemode=1") != NULL)
1905                        usetslivemode = 1;
1906
1907                if(ostrstr(filename, "|") != NULL)
1908                {
1909                        tmpstr1 = ostrcat(filename, NULL, 0, 0);
1910                        ret1 = strsplit(tmpstr1, "|", &count1);
1911               
1912                        if(ret1 != NULL)
1913                        {
1914                                for(i1 = 0; i1 < count1; i1++)
1915                                {
1916                                        if(i1 == 0) continue;
1917
1918                                        count2 = 0;
1919                                        i2 = 0;
1920
1921                                        tmpstr2 = ostrcat(ret1[i1].part, NULL, 0, 0);
1922                                        ret2 = strsplit(tmpstr2, "&", &count2);
1923
1924                                        if(ret2 != NULL)
1925                                        {
1926                                                for(i2 = 0; i2 < count2; i2++)
1927                                                {
1928                                                        count3 = 0;
1929                                                        i3 = 0;
1930                                                        struct splitstr* ret3 = NULL;
1931                                                        tmpstr3 = ostrcat(ret2[i2].part, NULL, 0, 0);
1932                                                        ret3 = strsplit(tmpstr3, "=", &count3);
1933                                       
1934                                                        if(ret3 != NULL && count3 > 0)
1935                                                        {
1936                                                                int max = count3 - 1;
1937                                                                for(i3 = 0; i3 < max; i3++)
1938                                                                {
1939                                                                        if(ostrcmp("User-Agent", ret3[i3].part) == 0)
1940                                                                        {
1941                                                                                av_dict_set(&avio_opts, "user-agent", ret3[i3 + 1].part, 0);
1942                                                                                ffmpeg_printf(10, "set user-agent: %s\n", ret3[i3 + 1].part);
1943                                                                                useragent = ostrcat(useragent, ret3[i3 + 1].part, 1, 0);
1944                                                                        }
1945                                                                        else
1946                                                                        {
1947                                                                            headers = ostrcat(headers, ret3[i3].part, 1, 0);
1948                                                                            headers = ostrcat(headers, ": ", 1, 0);
1949                                                                            headers = ostrcat(headers, ret3[i3 + 1].part, 1, 0);
1950                                                                            headers = ostrcat(headers, "\r\n", 1, 0);
1951                                                                        }
1952                                                                }
1953                                                        }
1954                                                        free(ret3), ret3 = NULL;
1955                                                        free(tmpstr3), tmpstr3 = NULL;
1956                                                }
1957                                        }
1958                                        free(ret2), ret2 = NULL;
1959                                        free(tmpstr2), tmpstr2 = NULL;
1960                                }
1961
1962                            if(headers != NULL)
1963                                {
1964                                av_dict_set(&avio_opts, "headers", headers, 0);
1965                                        ffmpeg_printf(10, "set headers: %s\n", headers);
1966                                }
1967                                else
1968                                        ffmpeg_printf(10, "skip set headers: %s\n", headers);
1969
1970                            if(useragent == NULL)
1971                                        ffmpeg_printf(10, "skip set user-agent: %s\n", headers);
1972                        }
1973
1974                        free(useragent), useragent = NULL;
1975                        free(headers), headers = NULL;
1976                        free(ret1), ret1 = NULL;       
1977                        free(tmpstr1), tmpstr1 = NULL;
1978                        stringreplacechar(filename, '|', '\0');         
1979                        ffmpeg_printf(10, "changed filename: %s\n", filename);
1980
1981                }
1982                ffmpeg_printf(10, "check tslivemode\n");
1983
1984//              if (ostrstr(filename, ".m3u8") != NULL)
1985                if (usetslivemode == 1)
1986                {
1987                        ffmpeg_printf(10, "set tslivemode\n");
1988                        context->playback->isTSLiveMode = 1;
1989                }
1990//obi (end)
1991
1992        av_dict_set(&avio_opts, "reconnect", "1", 0);
1993        if (context->playback->isTSLiveMode) // special mode for live TS stream with skip packet
1994        {
1995            av_dict_set(&avio_opts, "seekable", "0", 0);
1996            av_dict_set(&avio_opts, "reconnect_at_eof", "1", 0);
1997            av_dict_set(&avio_opts, "reconnect_streamed", "1", 0);
1998        }
1999    }
2000
2001    pavio_opts = &avio_opts;
2002   
2003    if ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0)
2004    {
2005        if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN &&
2006            rtmpProtoImplType == RTMP_NATIVE &&
2007            numOfRTMPImpl > 1)
2008        {
2009            // retry with librtmp
2010            err = avformat_open_input(&avContextTab[AVIdx], filename+2, fmt, pavio_opts);
2011            // filename2 - another memory leak, and also only once, so does not matter
2012        }
2013       
2014        if (err != 0)
2015        {
2016            char error[512];
2017
2018            ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
2019            av_strerror(err, error, 512);
2020            fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
2021
2022            if(avio_opts != NULL)
2023            {
2024                av_dict_free(&avio_opts);
2025            }
2026
2027            //obi
2028            ffmpeg_buf_free();
2029            //obi (end)
2030
2031            releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2032            return cERR_CONTAINER_FFMPEG_OPEN;
2033        }
2034    }
2035
2036    avContextTab[AVIdx]->iformat->flags |= AVFMT_SEEK_TO_PTS;
2037    avContextTab[AVIdx]->flags = AVFMT_FLAG_GENPTS;
2038
2039    if (context->playback->noprobe)
2040    {
2041        wrapped_set_max_analyze_duration(avContextTab[AVIdx], 1);
2042    }
2043
2044    ffmpeg_printf(20, "find_streaminfo\n");
2045
2046    if (avformat_find_stream_info(avContextTab[AVIdx], NULL) < 0)
2047    {
2048        ffmpeg_err("Error avformat_find_stream_info\n");
2049    }
2050
2051//for buffered io
2052    if(avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL && !context->playback->isTSLiveMode)
2053    {
2054        ffmpeg_real_read_org = avContextTab[AVIdx]->pb->read_packet;
2055       
2056        if(0 ==AVIdx && strstr(filename, "://") != 0 &&
2057           strncmp(filename, "file://", 7) != 0)
2058        {
2059            if(ffmpeg_buf_size > 0 && ffmpeg_buf_size > FILLBUFDIFF + FILLBUFPAKET)
2060            {
2061                if(avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL)
2062                {
2063                    ffmpeg_buf = av_malloc(ffmpeg_buf_size);
2064
2065                    if(ffmpeg_buf != NULL)
2066                    {
2067                        ffmpeg_printf(10, "buffer size=%d\n", ffmpeg_buf_size);
2068                       
2069                        ffmpeg_read_org = avContextTab[AVIdx]->pb->read_packet;
2070                        avContextTab[AVIdx]->pb->read_packet = ffmpeg_read;
2071                        ffmpeg_seek_org = avContextTab[AVIdx]->pb->seek;
2072                        avContextTab[AVIdx]->pb->seek = ffmpeg_seek;
2073                        ffmpeg_buf_read = ffmpeg_buf;
2074                        ffmpeg_buf_write = ffmpeg_buf;
2075
2076                        //fill buffer
2077                        ffmpeg_filler(context, -1, NULL, 0);
2078                        ffmpeg_start_fillerTHREAD(context);
2079                    }
2080                }
2081            }
2082        }
2083        else if (progressive_playback)
2084        {
2085            avContextTab[AVIdx]->pb->read_packet = ffmpeg_read_wrapper;
2086        }
2087    }
2088//for buffered io (end)
2089   
2090    return 0;
2091}
2092
2093int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
2094{
2095    int32_t err = 0;
2096
2097    ffmpeg_printf(10, ">\n");
2098
2099    //obi
2100    ffmpeg_buf_free();
2101    //obi (end)
2102
2103    if (playFilesNames == NULL)
2104    {
2105        ffmpeg_err("playFilesNames NULL\n");
2106        return cERR_CONTAINER_FFMPEG_NULL;
2107    }
2108   
2109    if (playFilesNames->szFirstFile == NULL)
2110    {
2111        ffmpeg_err("playFilesNames->szFirstFile NULL\n");
2112        return cERR_CONTAINER_FFMPEG_NULL;
2113    }
2114
2115    if (context == NULL)
2116    {
2117        ffmpeg_err("context NULL\n");
2118        return cERR_CONTAINER_FFMPEG_NULL;
2119    }
2120
2121    ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile);
2122    if(playFilesNames->szSecondFile)
2123    {
2124        ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile);
2125    }
2126
2127    if (isContainerRunning)
2128    {
2129        ffmpeg_err("ups already running?\n");
2130        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2131        return cERR_CONTAINER_FFMPEG_RUNNING;
2132    }
2133
2134    /* initialize ffmpeg */
2135    avcodec_register_all();
2136    av_register_all();
2137    avformat_network_init();
2138
2139//obi
2140    char* tmpstr = NULL;
2141    tmpstr = readfiletomem("/mnt/config/titan.cfg", 1);
2142    if(ostrstr(tmpstr, "debuglevel=99") != NULL)
2143        av_log_set_level( AV_LOG_DEBUG );
2144    else
2145        av_log_set_callback(ffmpeg_silen_callback);
2146    free(tmpstr), tmpstr = NULL;
2147//obi (end)
2148    // SULGE DEBUG ENABLED
2149    // make ffmpeg silen
2150    //av_log_set_level( AV_LOG_DEBUG );
2151    //av_log_set_callback(ffmpeg_silen_callback);
2152 
2153    context->playback->abortRequested = 0;
2154    int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0);
2155    if(0 != res)
2156    {
2157        return res;
2158    }
2159
2160    if(playFilesNames->szSecondFile)
2161    {
2162        res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1);
2163    }
2164   
2165    if(0 != res)
2166    {
2167        return res;
2168    }
2169   
2170    terminating = 0;
2171    latestPts = 0;
2172    isContainerRunning = 1;
2173    res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1);
2174
2175    //obi
2176    //ReadSubtitles(context, playFilesNames->szFirstFile);
2177    //obi (end)
2178    return res;
2179}
2180
2181int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial)
2182{
2183    Track_t *audioTrack = NULL;
2184    Track_t *subtitleTrack = NULL;
2185   
2186    if (terminating)
2187    {
2188        return cERR_CONTAINER_FFMPEG_NO_ERROR;
2189    }
2190   
2191    if (initial && context->manager->subtitle)
2192    {
2193        context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack);
2194    }
2195
2196    if (context->manager->audio)
2197    {
2198        context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
2199    }
2200
2201    if (context->manager->video)
2202    {
2203        context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL);
2204    }
2205   
2206    if (context->manager->audio)
2207    {
2208        context->manager->audio->Command(context, MANAGER_INIT_UPDATE, NULL);
2209    }
2210   
2211#if 0
2212    if (context->manager->subtitle)
2213    {
2214        context->manager->subtitle->Command(context, MANAGER_INIT_UPDATE, NULL);
2215    }
2216#endif
2217
2218
2219    ffmpeg_printf(20, "dump format\n");
2220    av_dump_format(avContextTab[0], 0, filename, 0);
2221   
2222   
2223    uint32_t cAVIdx = 0;
2224    for(cAVIdx=0; cAVIdx<IPTV_AV_CONTEXT_MAX_NUM; cAVIdx+=1)
2225    {
2226        if(NULL == avContextTab[cAVIdx])
2227        {
2228            break;
2229        }
2230        AVFormatContext *avContext = avContextTab[cAVIdx];
2231        uint32_t *stream_index = NULL;
2232        uint32_t nb_stream_indexes = 0;
2233       
2234        ffmpeg_printf(1, "cAVIdx[%d]: number of streams: %d\n", cAVIdx, avContext->nb_streams);
2235       
2236        if (avContext->nb_programs > 0)
2237        {
2238            uint32_t n = 0;
2239            ffmpeg_printf(1, "cAVIdx[%d]: stream with multi programs: num of programs %d\n", cAVIdx, avContext->nb_programs);
2240            for (n = 0; n < avContext->nb_programs && (0 == nb_stream_indexes || stream_index == NULL); n++)
2241            {
2242                AVProgram *p = avContext->programs[n];
2243                if (p->nb_stream_indexes)
2244                {
2245                    if (g_sel_program_id > 0)
2246                    {
2247                        if (g_sel_program_id == p->id)
2248                        {
2249                            stream_index = p->stream_index;
2250                            nb_stream_indexes = p->nb_stream_indexes;
2251                            ffmpeg_printf(1, "cAVIdx[%d]: select PROGRAM ID: %d\n", cAVIdx, (int32_t)p->id);
2252                            break;
2253                        }
2254                    }
2255                    else
2256                    {
2257                        uint32_t m = 0;
2258                        for (m = 0; m < p->nb_stream_indexes; m++)
2259                        {
2260                            AVStream *s = avContext->streams[p->stream_index[m]];
2261                            if (get_codecpar(s)->codec_type == AVMEDIA_TYPE_VIDEO && get_codecpar(s)->width > 0)
2262                            {
2263                                ffmpeg_printf(1, "cAVIdx[%d]: PROGRAM ID: %d, width [%d]\n", cAVIdx, (int32_t)p->id, (int32_t)get_codecpar(s)->width);
2264                                stream_index = p->stream_index;
2265                                nb_stream_indexes = p->nb_stream_indexes;
2266                                break;
2267                            }
2268                        }
2269                    }
2270                }
2271            }
2272        }
2273       
2274        int32_t n = 0;
2275        for (n = 0; n < avContext->nb_streams; n++)
2276        {
2277            Track_t track;
2278            AVStream *stream = avContext->streams[n];
2279            int32_t version = 0;
2280            char *encoding = NULL;
2281           
2282            if (nb_stream_indexes > 0 && stream_index != NULL)
2283            {
2284                uint32_t isStreamFromSelProg = 0;
2285                uint32_t m = 0;
2286                for (m = 0; m < nb_stream_indexes; m++)
2287                {
2288                    if (n == stream_index[m])
2289                    {
2290                        isStreamFromSelProg = 1;
2291                        break;
2292                    }
2293                }
2294               
2295                if (!isStreamFromSelProg)
2296                    continue; // skip this stream
2297            }
2298
2299            encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \
2300                                      (uint8_t *)get_codecpar(stream)->extradata, \
2301                                      (int)get_codecpar(stream)->extradata_size, \
2302                                      (int)get_codecpar(stream)->profile, &version);
2303           
2304            if(encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm)
2305            {
2306                encoding = "A_LPCM";
2307            }
2308
2309            if (encoding != NULL)
2310            {
2311               ffmpeg_printf(1, "%d. encoding = %s - version %d\n", n, encoding, version);
2312            }
2313
2314            if (!stream->id)
2315            {
2316                stream->id = n;
2317            }
2318
2319            /* some values in track are unset and therefor copyTrack segfaults.
2320             * so set it by default to NULL!
2321             */
2322            memset(&track, 0, sizeof(track));
2323            track.AVIdx = cAVIdx;
2324
2325            switch (get_codecpar(stream)->codec_type)
2326            {
2327            case AVMEDIA_TYPE_VIDEO:
2328                ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
2329
2330                if (encoding != NULL)
2331                {
2332                    track.type           = eTypeES;
2333                    track.version        = version;
2334
2335                    track.width          = get_codecpar(stream)->width;
2336                    track.height         = get_codecpar(stream)->height;
2337                   
2338                    /* We will return here PAR (Pixel Aspect Ratio) client need to calculate DAR(Display Aspect Ratio)
2339                     * example: PAR 64:45 DAR 16:9
2340                     *          Resolution 720x576
2341                     * Display aspect ratio = (720*64)/(576*45) = 16/9
2342                     * 0:1 is the value for invalid/unset aspect ratio -> https://trac.ffmpeg.org/ticket/3798
2343                     */
2344                    track.aspect_ratio_num = stream->sample_aspect_ratio.num;
2345                    track.aspect_ratio_den = stream->sample_aspect_ratio.den;
2346                    if (0 == track.aspect_ratio_num  || 0 == track.aspect_ratio_den)
2347                    {
2348                        track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num;
2349                        track.aspect_ratio_den = get_codecpar(stream)->sample_aspect_ratio.den;
2350                    }
2351
2352                    track.extraData      = get_codecpar(stream)->extradata;
2353                    track.extraSize      = get_codecpar(stream)->extradata_size;
2354
2355                    track.aacbuf         = 0;
2356                    track.have_aacheader = -1;
2357                   
2358                    AVRational rateRational = get_frame_rate(stream);
2359                    if (rateRational.den!=0)
2360                    {
2361                        track.frame_rate = (uint32_t)(1000 * (int64_t)(rateRational.num) / (int64_t)(rateRational.den));
2362                    }
2363                   
2364                    /* fixme: revise this */
2365                    if (track.frame_rate < 23970)
2366                    {
2367                        track.TimeScale = 1001;
2368                    }
2369                    else
2370                    {
2371                        track.TimeScale = 1000;
2372                    }
2373                   
2374                    ffmpeg_printf(10, "bit_rate       [%d]\n", get_codecpar(stream)->bit_rate);
2375                    ffmpeg_printf(10, "time_base.den  [%d]\n", stream->time_base.den);
2376                    ffmpeg_printf(10, "time_base.num  [%d]\n", stream->time_base.num);
2377                    ffmpeg_printf(10, "width          [%d]\n", get_codecpar(stream)->width);
2378                    ffmpeg_printf(10, "height         [%d]\n", get_codecpar(stream)->height);
2379                    ffmpeg_printf(10, "frame_rate num [%d]\n", rateRational.num);
2380                    ffmpeg_printf(10, "frame_rate den [%d]\n", rateRational.den);
2381
2382                    ffmpeg_printf(10, "frame_rate     [%u]\n", track.frame_rate);
2383                    ffmpeg_printf(10, "TimeScale      [%d]\n", track.TimeScale);
2384
2385                    track.Name      = "und";
2386                    track.Encoding  = encoding;
2387                    track.stream    = stream;
2388                    track.Id        = ((AVStream *) (track.stream))->id;
2389
2390                    track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2391                    if(stream->duration == AV_NOPTS_VALUE || 0 == strncmp(avContext->iformat->name, "dash", 4))
2392                    {
2393                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2394                        track.duration = (int64_t) avContext->duration / 1000;
2395                    }
2396                   
2397                    if (context->manager->video)
2398                    {
2399                        if (get_codecpar(stream)->codec_id == AV_CODEC_ID_MPEG4)
2400                        {
2401                            track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
2402                        }
2403                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n");
2404                        if( context->manager->video->Command(context, MANAGER_ADD, &track) < 0)
2405                        {
2406                            /* konfetti: fixme: is this a reason to return with error? */
2407                            ffmpeg_err("failed to add track %d\n", n);
2408                        }
2409                    }
2410                }
2411                else
2412                {
2413                    ffmpeg_err("codec type video but codec unknown %d\n", get_codecpar(stream)->codec_id);
2414                }
2415                break;
2416            case AVMEDIA_TYPE_AUDIO:
2417                ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",get_codecpar(stream)->codec_type);
2418
2419                if (encoding != NULL)
2420                {
2421                    AVDictionaryEntry *lang;
2422                    track.type = eTypeES;
2423
2424                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
2425
2426                    track.Name = lang ? lang->value : "und";
2427
2428                    ffmpeg_printf(10, "Language %s\n", track.Name);
2429
2430                    track.Encoding       = encoding;
2431                    track.stream         = stream;
2432                    track.Id             = ((AVStream *) (track.stream))->id;
2433                    track.aacbuf         = 0;
2434                    track.have_aacheader = -1;
2435
2436                    track.duration       = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2437                    if(stream->duration == AV_NOPTS_VALUE)
2438                    {
2439                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2440                        track.duration = (int64_t) avContext->duration / 1000;
2441                    }
2442                   
2443                    if(!strncmp(encoding, "A_IPCM", 6) || !strncmp(encoding, "A_LPCM", 6))
2444                    {
2445                        track.inject_as_pcm = 1;
2446                        track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
2447                        if (track.avCodecCtx)
2448                        {
2449                            ffmpeg_printf(10, " Handle inject_as_pcm = %d\n", track.inject_as_pcm);
2450
2451                            AVCodec *codec = avcodec_find_decoder(get_codecpar(stream)->codec_id);
2452
2453                            int errorCode = avcodec_open2(track.avCodecCtx, codec, NULL);
2454                            if(codec != NULL && !errorCode)
2455                            {
2456                               ffmpeg_printf(10, "AVCODEC__INIT__SUCCESS\n");
2457                            }
2458                            else
2459                            {
2460                               ffmpeg_printf(10, "AVCODEC__INIT__FAILED error[%d]\n", errorCode);
2461                            }
2462                        }
2463                    }
2464                    else if(!strncmp(encoding, "A_PCM", 5))
2465                    {
2466                        track.inject_raw_pcm = 1;
2467                    }
2468                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC_LATM)
2469                    {
2470                        const char marker[] = "LATM";
2471                        track.aacbuflen = sizeof(marker)/sizeof(char);
2472                        track.aacbuf = malloc(track.aacbuflen);
2473                        memcpy(track.aacbuf, marker, track.aacbuflen);
2474                       
2475                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM no extradata ACC header should be available in each frame\n");
2476                        track.have_aacheader = 1;
2477                    }
2478                    else if(!strncmp(encoding, "A_AAC_LATM", 10))
2479                    {
2480                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM extradata will be used in aac writter\n");
2481                    }
2482                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC)
2483                    {
2484                        if( 0 == strncmp(avContext->iformat->name, "mpegts", 6) ||
2485                            0 == strncmp(avContext->iformat->name, "hls,", 4) )
2486                        {
2487                            const char marker[] = "ADTS";
2488                            track.aacbuflen = sizeof(marker)/sizeof(char);
2489                            track.aacbuf = malloc(track.aacbuflen);
2490                            memcpy(track.aacbuf, marker, track.aacbuflen);
2491                           
2492                            ffmpeg_printf(10, "AV_CODEC_ID_AAC no extradata ACC header should be available in each frame\n");
2493                            track.have_aacheader = 1;
2494                        }
2495                        else
2496                        {
2497                            ffmpeg_printf(10, "Create AAC ExtraData\n");
2498                            ffmpeg_printf(10, "get_codecpar(stream)->extradata_size %d\n", get_codecpar(stream)->extradata_size);
2499                            //Hexdump(get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
2500
2501                            /*  extradata:
2502                                13 10 56 e5 9d 48 00 (anderen cops)
2503                                object_type: 00010 2 = LC
2504                                sample_rate: 011 0 6 = 24000
2505                                chan_config: 0010 2 = Stereo
2506                                000 0
2507                                1010110 111 = 0x2b7
2508                                00101 = SBR
2509                                1
2510                                0011 = 48000
2511                                101 01001000 = 0x548
2512                                ps = 0
2513                                0000000
2514                            */
2515
2516                            int32_t object_type = 2; // LC
2517                            int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate);
2518                            int32_t chan_config = get_codecpar(stream)->channels - 1;
2519                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
2520                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
2521                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
2522                           
2523                            if (get_codecpar(stream)->extradata_size >= 2)
2524                            {
2525                                MPEG4AudioConfig m4ac;
2526                                int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
2527                                if (off >= 0)
2528                                {
2529                                    object_type  = m4ac.object_type;
2530                                    sample_index = m4ac.sampling_index;
2531                                    if (sample_index == 0x0f)
2532                                    {
2533                                        sample_index = aac_get_sample_rate_index(m4ac.sample_rate);
2534                                    }
2535                                    chan_config  = m4ac.chan_config;
2536                                }
2537                            }
2538                           
2539                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
2540                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
2541                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
2542
2543                           
2544                            // https://wiki.multimedia.cx/index.php/ADTS
2545                            object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1
2546                           
2547                            track.aacbuflen = AAC_HEADER_LENGTH;
2548                            track.aacbuf = malloc(8);
2549                            track.aacbuf[0] = 0xFF;
2550                            track.aacbuf[1] = 0xF1;
2551                            //track.aacbuf[1] |=0x8;
2552                            track.aacbuf[2] = ((object_type & 0x03) << 6)  | (sample_index << 2) | ((chan_config >> 2) & 0x01);
2553                            track.aacbuf[3] = (chan_config & 0x03) << 6;
2554                            //track.aacbuf[3]|= 0x10;
2555                            track.aacbuf[4] = 0x00;
2556                            track.aacbuf[5] = 0x1F;
2557                            track.aacbuf[6] = 0xFC;
2558
2559                            //printf("AAC_HEADER -> ");
2560                            //Hexdump(track.aacbuf,7);
2561                            track.have_aacheader = 1;
2562                        }
2563                        /*
2564                        else
2565                        {
2566                            ffmpeg_err("AV_CODEC_ID_AAC extradata not available\n");
2567                        }
2568                        */
2569
2570                    }
2571                    else if(get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1
2572                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2
2573                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO
2574                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0)
2575                    {
2576                        ffmpeg_printf(10,"Create WMA ExtraData\n");
2577                        uint16_t channels = get_codecpar(stream)->channels;
2578                        uint32_t rate = get_codecpar(stream)->sample_rate;
2579                        uint32_t bitrate = get_codecpar(stream)->bit_rate;
2580                        uint16_t block_align = get_codecpar(stream)->block_align;
2581                        uint16_t depth = get_codecpar(stream)->bits_per_coded_sample;
2582                        uint32_t codec_data_size = get_codecpar(stream)->extradata_size;
2583                        uint8_t *codec_data_pointer = get_codecpar(stream)->extradata;
2584                       
2585                        // type_specific_data
2586                        #define WMA_VERSION_1           0x160
2587                        #define WMA_VERSION_2_9         0x161
2588                        #define WMA_VERSION_9_PRO       0x162
2589                        #define WMA_LOSSLESS            0x163
2590                        uint16_t codec_id = 0;
2591                        switch(get_codecpar(stream)->codec_id)
2592                        {
2593                            //TODO: What code for lossless ?
2594                            case AV_CODEC_ID_WMALOSSLESS:
2595                                codec_id = WMA_LOSSLESS;
2596                                break;
2597                            case AV_CODEC_ID_WMAPRO:
2598                                codec_id = WMA_VERSION_9_PRO;
2599                                break;
2600                            case AV_CODEC_ID_WMAV2:
2601                                codec_id = WMA_VERSION_2_9 ;
2602                                break;
2603                            case AV_CODEC_ID_WMAV1:
2604                            default:
2605                                codec_id = WMA_VERSION_1;
2606                                break;
2607                        }
2608#ifdef __sh__
2609                        track.aacbuflen = 104 + get_codecpar(stream)->extradata_size;
2610                        track.aacbuf = malloc(track.aacbuflen);
2611                        memset (track.aacbuf, 0, track.aacbuflen);
2612                       
2613                        uint8_t ASF_Stream_Properties_Object[16] =
2614                        {0x91,0x07,0xDC,0xB7,0xB7,0xA9,0xCF,0x11,0x8E,0xE6,0x00,0xC0,0x0C,0x20,0x53,0x65};
2615                       
2616                        memcpy(track.aacbuf + 0, ASF_Stream_Properties_Object, 16); // ASF_Stream_Properties_Object
2617                        memcpy(track.aacbuf + 16, &track.aacbuflen, 4); //FrameDateLength
2618
2619                        uint32_t sizehi = 0;
2620                        memcpy(track.aacbuf + 20, &sizehi, 4); // sizehi (not used)
2621
2622                        uint8_t ASF_Audio_Media[16] =
2623                        {0x40,0x9E,0x69,0xF8,0x4D,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B};
2624                       
2625                        memcpy(track.aacbuf + 24, ASF_Audio_Media, 16); //ASF_Audio_Media
2626
2627                        uint8_t ASF_Audio_Spread[16] =
2628                        {0x50,0xCD,0xC3,0xBF,0x8F,0x61,0xCF,0x11,0x8B,0xB2,0x00,0xAA,0x00,0xB4,0xE2,0x20};
2629                       
2630                        memcpy(track.aacbuf + 40, ASF_Audio_Spread, 16); //ASF_Audio_Spread
2631
2632                        memset(track.aacbuf + 56, 0, 4); // time_offset (not used)
2633                        memset(track.aacbuf + 60, 0, 4); // time_offset_hi (not used)
2634
2635                        uint8_t type_specific_data_length = 18 + get_codecpar(stream)->extradata_size;
2636                        memcpy(track.aacbuf + 64, &type_specific_data_length, 4); //type_specific_data_length
2637
2638                        uint8_t error_correction_data_length = 8;
2639                        memcpy(track.aacbuf + 68, &error_correction_data_length, 4); //error_correction_data_length
2640
2641                        uint16_t flags = 1; // stream_number
2642                        memcpy(track.aacbuf + 72, &flags, 2); //flags
2643
2644                        uint32_t reserved = 0;
2645                        memcpy(track.aacbuf + 74, &reserved, 4); // reserved
2646
2647                        memcpy(track.aacbuf + 78, &codec_id, 2); //codec_id
2648
2649                        uint16_t number_of_channels = get_codecpar(stream)->channels;
2650                        memcpy(track.aacbuf + 80, &number_of_channels, 2); //number_of_channels
2651
2652                        uint32_t samples_per_second = get_codecpar(stream)->sample_rate;
2653                        ffmpeg_printf(1, "samples_per_second = %d\n", samples_per_second);
2654                        memcpy(track.aacbuf + 82, &samples_per_second, 4); //samples_per_second
2655
2656                        uint32_t average_number_of_bytes_per_second = get_codecpar(stream)->bit_rate / 8;
2657                        ffmpeg_printf(1, "average_number_of_bytes_per_second = %d\n", average_number_of_bytes_per_second);
2658                        memcpy(track.aacbuf + 86, &average_number_of_bytes_per_second, 4); //average_number_of_bytes_per_second
2659
2660                        uint16_t block_alignment = get_codecpar(stream)->block_align;
2661                        ffmpeg_printf(1, "block_alignment = %d\n", block_alignment);
2662                        memcpy(track.aacbuf + 90, &block_alignment, 2); //block_alignment
2663
2664#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
2665                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->format;
2666#else
2667                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->sample_fmt;
2668#endif
2669                        uint16_t bits_per_sample = sample_fmt>=0 ? (sample_fmt+1)*8 : 8;
2670                        ffmpeg_printf(1, "bits_per_sample = %d (%d)\n", bits_per_sample, sample_fmt);
2671                        memcpy(track.aacbuf + 92, &bits_per_sample, 2); //bits_per_sample
2672
2673                        memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample
2674
2675                        memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
2676#else
2677                        track.aacbuflen = 18 + get_codecpar(stream)->extradata_size;
2678                        track.aacbuf = malloc(track.aacbuflen);
2679                        memset (track.aacbuf, 0, track.aacbuflen);
2680                       
2681                        uint8_t *data = track.aacbuf;
2682                        /* codec tag */
2683                        *(data++) = codec_id & 0xff;
2684                        *(data++) = (codec_id >> 8) & 0xff;
2685                        /* channels */
2686                        *(data++) = channels & 0xff;
2687                        *(data++) = (channels >> 8) & 0xff;
2688                        /* sample rate */
2689                        *(data++) = rate & 0xff;
2690                        *(data++) = (rate >> 8) & 0xff;
2691                        *(data++) = (rate >> 16) & 0xff;
2692                        *(data++) = (rate >> 24) & 0xff;
2693                        /* byte rate */
2694                        bitrate /= 8;
2695                        *(data++) = bitrate & 0xff;
2696                        *(data++) = (bitrate >> 8) & 0xff;
2697                        *(data++) = (bitrate >> 16) & 0xff;
2698                        *(data++) = (bitrate >> 24) & 0xff;
2699                        /* block align */
2700                        *(data++) = block_align & 0xff;
2701                        *(data++) = (block_align >> 8) & 0xff;
2702                        /* word size */
2703                        *(data++) = depth & 0xff;
2704                        *(data++) = (depth >> 8) & 0xff;
2705                        /* codec data size */
2706                        *(data++) = codec_data_size & 0xff;
2707                        *(data++) = (codec_data_size >> 8) & 0xff;
2708                        memcpy(data, codec_data_pointer, codec_data_size);
2709#endif
2710                        ffmpeg_printf(1, "aacbuf:\n");
2711                        //Hexdump(track.aacbuf, track.aacbuflen);
2712
2713                        //ffmpeg_printf(1, "priv_data:\n");
2714                        //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen);
2715
2716                        track.have_aacheader = 1;
2717                    }
2718                   
2719                    if (context->manager->audio)
2720                    {
2721                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n");
2722                        if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0)
2723                        {
2724                            /* konfetti: fixme: is this a reason to return with error? */
2725                            ffmpeg_err("failed to add track %d\n", n);
2726                        }
2727                    }
2728                }
2729                else //encoding != NULL
2730                {
2731                    ffmpeg_err("codec type audio but codec unknown %d\n", get_codecpar(stream)->codec_id);
2732                }
2733                break;
2734            case AVMEDIA_TYPE_SUBTITLE:
2735            {
2736                if (get_codecpar(stream)->codec_id != AV_CODEC_ID_SSA &&
2737#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100)
2738                    get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS &&
2739#endif
2740                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
2741                    get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
2742                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT)
2743                {
2744                    ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id);
2745                }
2746                else if (initial && context->manager->subtitle)
2747                {
2748                    AVDictionaryEntry *lang = NULL;
2749                    memset(&track, 0, sizeof(track));
2750
2751                    ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type);
2752                   
2753                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
2754                    track.Name = lang ? lang->value : "und";
2755                    ffmpeg_printf(10, "Language %s\n", track.Name);
2756
2757                    track.Encoding       = encoding;
2758                    track.stream         = stream;
2759                    track.Id             = ((AVStream *) (track.stream))->id;
2760                    track.duration       = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2761                   
2762                    if(stream->duration == AV_NOPTS_VALUE)
2763                    {
2764                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2765                        track.duration = (int64_t) avContext->duration / 1000;
2766                    }
2767
2768                    track.extraData      = get_codecpar(stream)->extradata;
2769                    track.extraSize      = get_codecpar(stream)->extradata_size;
2770
2771                    ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id);
2772                    ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width);
2773                    ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height);
2774                    ffmpeg_printf(1, "subtitle stream %p\n", stream);
2775
2776                    ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name);
2777                   
2778                    if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0)
2779                    {
2780                        ffmpeg_err("failed to add subtitle track %d\n", n);
2781                    }
2782                }
2783                break;
2784            }
2785            case AVMEDIA_TYPE_UNKNOWN:
2786            case AVMEDIA_TYPE_DATA:
2787            case AVMEDIA_TYPE_ATTACHMENT:
2788            case AVMEDIA_TYPE_NB:
2789            default:
2790                ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type);
2791             break;
2792            }
2793        } /* for */
2794   
2795    }
2796
2797    return cERR_CONTAINER_FFMPEG_NO_ERROR;
2798}
2799
2800static int32_t container_ffmpeg_play(Context_t *context)
2801{
2802    int32_t error = 0;
2803    int32_t ret = 0;
2804    pthread_attr_t attr;
2805
2806    ffmpeg_printf(10, "\n");
2807
2808    if ( context && context->playback && context->playback->isPlaying )
2809    {
2810        ffmpeg_printf(10, "is Playing\n");
2811    }
2812    else
2813    {
2814        ffmpeg_printf(10, "is NOT Playing\n");
2815    }
2816
2817    if (hasPlayThreadStarted == 0)
2818    {
2819        pthread_attr_init(&attr);
2820        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2821
2822        if((error = pthread_create(&PlayThread, &attr, (void *)&FFMPEGThread, context)) != 0)
2823        {
2824            ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error,strerror(error));
2825
2826            hasPlayThreadStarted = 0;
2827            ret = cERR_CONTAINER_FFMPEG_ERR;
2828        }
2829        else
2830        {
2831            ffmpeg_printf(10, "Created thread\n");
2832
2833            hasPlayThreadStarted = 1;
2834        }
2835    }
2836    else
2837    {
2838        ffmpeg_printf(10, "A thread already exists!\n");
2839        ret = cERR_CONTAINER_FFMPEG_ERR;
2840    }
2841
2842    ffmpeg_printf(10, "exiting with value %d\n", ret);
2843    return ret;
2844}
2845
2846static int32_t container_ffmpeg_stop(Context_t *context)
2847{
2848    int32_t ret = cERR_CONTAINER_FFMPEG_NO_ERROR;
2849    int32_t wait_time = 10; // we give 1s to close otherwise we will force close
2850
2851    ffmpeg_printf(10, "\n");
2852
2853    if (!isContainerRunning)
2854    {
2855        ffmpeg_err("Container not running\n");
2856        return cERR_CONTAINER_FFMPEG_ERR;
2857    }
2858
2859    //obi
2860    wait_time = 100;
2861    if(hasfillerThreadStarted[hasfillerThreadStartedID] == 1)
2862        hasfillerThreadStarted[hasfillerThreadStartedID] = 2; // should end
2863    while ( (hasfillerThreadStarted[hasfillerThreadStartedID] != 0) && (--wait_time) > 0 ) {
2864        ffmpeg_printf(10, "Waiting for ffmpeg filler thread to terminate itself, will try another %d times, ID=%d\n", wait_time, hasfillerThreadStartedID);
2865        usleep(100000);
2866    }
2867
2868    if (wait_time == 0) {
2869        ffmpeg_err( "Timeout waiting for filler thread!\n");
2870
2871        ret = cERR_CONTAINER_FFMPEG_ERR;
2872    }
2873    //obi (end)
2874
2875    if (context->playback)
2876    {
2877        context->playback->isPlaying = 0;
2878    }
2879
2880    while ( (hasPlayThreadStarted != 0) && (--wait_time) > 0 )
2881    {
2882        ffmpeg_printf(10, "Waiting for ffmpeg thread to terminate itself, will try another %d times\n", wait_time);
2883        usleep(100000);
2884    }
2885
2886    if (wait_time == 0)
2887    {
2888        /* force close */
2889        ffmpeg_err( "Timeout waiting for thread!\n");
2890        ret = cERR_CONTAINER_FFMPEG_ERR;
2891        /* to speed up close - we are in separate process for the moment this process will
2892         * be closed and whole resources will be free by the system 
2893         */
2894        return ret;
2895    }
2896
2897    hasPlayThreadStarted = 0;
2898    terminating = 1;
2899
2900    getMutex(__FILE__, __FUNCTION__,__LINE__);
2901   
2902    free_all_stored_avcodec_context();
2903   
2904    uint32_t i = 0;
2905    for(i=0; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
2906    {
2907        if(NULL != avContextTab[i])
2908        {
2909            if(0 != use_custom_io[i])
2910            {
2911                /*
2912                 * Free custom IO independently to avoid segfault/bus error
2913                 * avformat_close_input do not expect custom io, so it try
2914                 * to release incorrectly
2915                 */
2916                av_freep(&(avContextTab[i]->pb->buffer));
2917                av_freep(&(avContextTab[i]->pb));
2918                use_custom_io[i] = 0;
2919            }
2920            avformat_close_input(&avContextTab[i]);
2921            //obi
2922            ffmpeg_buf_free();
2923            //obi (end)
2924            avContextTab[i] = NULL;
2925        }
2926        else
2927        {
2928            break;
2929        }
2930    }
2931
2932    if(avio_opts != NULL)
2933    {
2934        av_dict_free(&avio_opts);
2935    }
2936
2937    isContainerRunning = 0;
2938    avformat_network_deinit();
2939    ffmpeg_buf_free();
2940
2941    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2942
2943    ffmpeg_printf(10, "ret %d\n", ret);
2944    return ret;
2945}
2946
2947static int32_t container_ffmpeg_seek_bytes(off_t pos)
2948{
2949    int32_t flag = AVSEEK_FLAG_BYTE;
2950    off_t current_pos = avio_tell(avContextTab[0]->pb);
2951
2952    ffmpeg_printf(20, "seeking to position %lld (bytes)\n", pos);
2953
2954    if (current_pos > pos)
2955    {
2956        flag |= AVSEEK_FLAG_BACKWARD;
2957    }
2958
2959    if (avformat_seek_file(avContextTab[0], -1, INT64_MIN, pos, INT64_MAX, flag) < 0)
2960    {
2961        ffmpeg_err( "Error seeking\n");
2962        return cERR_CONTAINER_FFMPEG_ERR;
2963    }
2964
2965    ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb));
2966
2967    return cERR_CONTAINER_FFMPEG_NO_ERROR;
2968}
2969
2970/* seeking relative to a given byteposition N seconds ->for reverse playback needed */
2971static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec)
2972{
2973    Track_t *videoTrack = NULL;
2974    Track_t *audioTrack = NULL;
2975    Track_t *current = NULL;
2976    seek_target_flag = 0;
2977
2978    ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
2979
2980    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
2981    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
2982
2983    if (videoTrack != NULL)
2984    {
2985        current = videoTrack;
2986    }
2987    else if (audioTrack != NULL)
2988    {
2989        current = audioTrack;
2990    }
2991   
2992    if (current == NULL)
2993    {
2994        ffmpeg_err( "no track avaibale to seek\n");
2995        return cERR_CONTAINER_FFMPEG_ERR;
2996    }
2997
2998    if (pos == -1)
2999    {
3000        pos = avio_tell(avContextTab[0]->pb);
3001    }
3002
3003    if (pts == -1)
3004    {
3005        pts = current->pts;
3006    }
3007   
3008    if (sec < 0)
3009    {
3010        seek_target_flag |= AVSEEK_FLAG_BACKWARD;
3011    }
3012
3013    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
3014#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
3015    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
3016    {
3017        if (avContextTab[0]->bit_rate)
3018        {
3019            sec *= avContextTab[0]->bit_rate / 8;
3020            ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
3021        }
3022        else
3023        {
3024            sec *= 180000;
3025        }
3026
3027        pos += sec;
3028
3029        if (pos < 0)
3030        {
3031           ffmpeg_err("end of file reached\n");
3032           releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3033           return cERR_CONTAINER_FFMPEG_END_OF_FILE;
3034        }
3035
3036        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
3037
3038        seek_target_bytes = pos;
3039        do_seek_target_bytes = 1;
3040
3041        return pos;
3042    }
3043    else
3044#endif
3045    {
3046        sec += pts / 90000;
3047
3048        if (sec < 0)
3049        {
3050            sec = 0;
3051        }
3052
3053        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);
3054
3055        seek_target_seconds = sec * AV_TIME_BASE;
3056        do_seek_target_seconds = 1;
3057    }
3058
3059    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3060    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3061}
3062
3063static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
3064{
3065    Track_t *videoTrack = NULL;
3066    Track_t *audioTrack = NULL;
3067    Track_t *current = NULL;
3068    seek_target_flag = 0;
3069
3070    if (!absolute)
3071    {
3072        ffmpeg_printf(10, "seeking %f sec\n", sec);
3073        if (sec == 0)
3074        {
3075            ffmpeg_err("sec = 0 ignoring\n");
3076            return cERR_CONTAINER_FFMPEG_ERR;
3077        }
3078        else
3079        {
3080            int64_t currPts = -1;
3081            int32_t ret = context->playback->Command(context, PLAYBACK_PTS, &currPts);
3082            if (ret != 0)
3083            {
3084                ffmpeg_err("fail to get current PTS\n");
3085                return cERR_CONTAINER_FFMPEG_ERR;
3086            }
3087            sec += currPts / 90000;
3088        }
3089    }
3090   
3091    ffmpeg_printf(10, "goto %d sec\n", sec);
3092    if (sec < 0)
3093    {
3094        sec = 0;
3095    }
3096   
3097    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3098    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3099
3100    if (videoTrack != NULL)
3101    {
3102        current = videoTrack;
3103    }
3104    else if (audioTrack != NULL)
3105    {
3106        current = audioTrack;
3107    }
3108    else
3109    {
3110        ffmpeg_err( "no track available to seek\n");
3111        return cERR_CONTAINER_FFMPEG_ERR;
3112    }
3113
3114    if (sec < 0)
3115    {
3116        seek_target_flag |= AVSEEK_FLAG_BACKWARD;
3117    }
3118
3119    getMutex(__FILE__, __FUNCTION__,__LINE__);
3120
3121    if (!context->playback || !context->playback->isPlaying)
3122    {
3123        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3124        return cERR_CONTAINER_FFMPEG_NO_ERROR;
3125    }
3126
3127    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
3128#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
3129    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
3130    {
3131        /* konfetti: for ts streams seeking frame per seconds does not work (why?).
3132        * I take this algo partly from ffplay.c.
3133        *
3134        * seeking per HTTP does still not work very good. forward seeks everytime
3135        * about 10 seconds, backward does not work.
3136        */
3137
3138        off_t pos = avio_tell(avContextTab[0]->pb);
3139
3140        ffmpeg_printf(10, "pos %lld %d\n", pos, avContextTab[0]->bit_rate);
3141
3142        if (avContextTab[0]->bit_rate)
3143        {
3144            sec *= avContextTab[0]->bit_rate / 8;
3145            ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
3146        }
3147        else
3148        {
3149            sec *= 180000;
3150        }
3151       
3152        pos = sec;
3153       
3154        if (pos < 0)
3155        {
3156           pos = 0;
3157        }
3158       
3159        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %d\n", pos, sec);
3160
3161        seek_target_bytes = pos;
3162        do_seek_target_bytes = 1;
3163
3164    }
3165    else
3166#endif
3167    {
3168        seek_target_seconds = sec * AV_TIME_BASE;
3169        do_seek_target_seconds = 1;
3170    }
3171
3172    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3173    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3174}
3175
3176static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length)
3177{
3178    ffmpeg_printf(50, "\n");
3179    Track_t * videoTrack = NULL;
3180    Track_t * audioTrack = NULL;
3181    Track_t * current = NULL;
3182
3183    if (length == NULL)
3184    {
3185        ffmpeg_err( "null pointer passed\n");
3186        return cERR_CONTAINER_FFMPEG_ERR;
3187    }
3188
3189    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3190    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3191
3192    if (videoTrack != NULL)
3193    {
3194        current = videoTrack;
3195    }
3196    else if (audioTrack != NULL)
3197    {
3198        current = audioTrack;
3199    }
3200   
3201    *length = 0;
3202
3203    if (current != NULL)
3204    {
3205        if (current->duration == 0)
3206        {
3207            return cERR_CONTAINER_FFMPEG_ERR;
3208        }
3209        else
3210        {
3211            *length = current->duration / 1000;
3212        }
3213    }
3214    else
3215    {
3216        if (avContextTab[0] != NULL)
3217        {
3218            *length = avContextTab[0]->duration / 1000;
3219        }
3220        else
3221        {
3222           ffmpeg_err( "no Track not context ->no problem :D\n");
3223           return cERR_CONTAINER_FFMPEG_ERR;
3224        }
3225    }
3226
3227    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3228}
3229
3230static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg)
3231{
3232    ffmpeg_printf(10, "track %d\n", *arg);
3233   
3234    /* Hellmaster1024: nothing to do here!*/
3235    int64_t sec = -5;
3236    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
3237    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3238}
3239
3240static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg)
3241{
3242    ffmpeg_printf(10, "track %d\n", *arg);
3243   
3244    /* This is made to flush inside the buffer because
3245     * subtitles frame was already read and ignored
3246     * we seek to force ffmpeg to read once again the same data
3247     * but now we will not ignore subtitle frame
3248     */
3249    int64_t sec = -5;
3250    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
3251    //obi
3252    enablesub = 1;
3253    //obi (end)
3254    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3255}
3256
3257//obi
3258static int32_t container_ffmpeg_get_subtext(Context_t* context, char ** data)
3259{
3260
3261//    printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] start\n");
3262
3263    if(enablesub == 1 && subtext != NULL)
3264    {
3265//      printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] set data\n");
3266
3267        *data = ostrcat(subtext, NULL, 0, 0);
3268        free(subtext), subtext = NULL;
3269
3270    }
3271
3272
3273
3274
3275
3276
3277
3278//    printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] end\n");
3279
3280
3281    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3282}
3283//obi (end)
3284
3285/* konfetti comment: I dont like the mechanism of overwriting
3286 * the pointer in infostring. This lead in most cases to
3287 * user errors, like it is in the current version (libeplayer2 <-->e2->servicemp3.cpp)
3288 * From e2 there is passed a tag=strdup here and we overwrite this
3289 * strdupped tag. This lead to dangling pointers which are never freed!
3290 * I do not free the string here because this is the wrong way. The mechanism
3291 * should be changed, or e2 should pass it in a different way...
3292 */
3293static int32_t container_ffmpeg_get_info(Context_t* context, char ** infoString)
3294{
3295    Track_t *videoTrack = NULL;
3296    Track_t *audioTrack = NULL;
3297    char     *meta = NULL;
3298
3299    ffmpeg_printf(20, ">\n");
3300
3301    if (avContextTab[0] != NULL)
3302    {
3303        if ((infoString == NULL) || (*infoString == NULL))
3304        {
3305            ffmpeg_err("infostring NULL\n");
3306            return cERR_CONTAINER_FFMPEG_ERR;
3307        }
3308
3309        ffmpeg_printf(20, "%s\n", *infoString);
3310
3311        context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3312        context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3313
3314        if ((meta = searchMeta(avContextTab[0]->metadata, *infoString)) == NULL)
3315        {
3316            if (audioTrack != NULL)
3317            {
3318                AVStream* stream = audioTrack->stream;
3319                meta = searchMeta(stream->metadata, *infoString);
3320            }
3321
3322            if ((meta == NULL) && (videoTrack != NULL))
3323            {
3324                AVStream* stream = videoTrack->stream;
3325                meta = searchMeta(stream->metadata, *infoString);
3326            }
3327        }
3328
3329        if (meta != NULL)
3330        {
3331            *infoString = strdup(meta);
3332        }
3333        else
3334        {
3335            ffmpeg_printf(1, "no metadata found for \"%s\"\n", *infoString);
3336            *infoString = strdup("not found");
3337        }
3338    }
3339    else
3340    {
3341        ffmpeg_err("avContext NULL\n");
3342        return cERR_CONTAINER_FFMPEG_ERR;
3343    }
3344
3345    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3346}
3347
3348static int32_t Command(void  *_context, ContainerCmd_t command, void *argument)
3349{
3350    Context_t  *context = (Context_t*) _context;
3351    int ret = cERR_CONTAINER_FFMPEG_NO_ERROR;
3352
3353    ffmpeg_printf(50, "Command %d\n", command);
3354
3355    if(command != CONTAINER_SET_BUFFER_SEEK_TIME &&
3356       command != CONTAINER_SET_BUFFER_SIZE &&
3357       command != CONTAINER_GET_BUFFER_SIZE &&
3358       command != CONTAINER_GET_BUFFER_STATUS &&
3359       command != CONTAINER_STOP_BUFFER &&
3360       command != CONTAINER_GET_SUBTEXT &&
3361       command != CONTAINER_INIT && !avContextTab[0])
3362    {
3363        return cERR_CONTAINER_FFMPEG_ERR;
3364    }
3365   
3366   
3367    switch(command)
3368    {
3369    case CONTAINER_INIT:
3370    {
3371        PlayFiles_t *playFilesNames = (PlayFiles_t *)argument;
3372        ret = container_ffmpeg_init(context, playFilesNames);
3373        break;
3374    }
3375    case CONTAINER_PLAY: 
3376    {
3377        ret = container_ffmpeg_play(context);
3378        break;
3379    }
3380    case CONTAINER_STOP:
3381    {
3382        ret = container_ffmpeg_stop(context);
3383        break;
3384    }
3385    case CONTAINER_SEEK:
3386    {
3387        ret = container_ffmpeg_seek(context, (int64_t)*((int64_t*)argument), 0);
3388        break;
3389    }
3390    case CONTAINER_SEEK_ABS:
3391    {
3392        ret = container_ffmpeg_seek(context, (int64_t)*((int64_t*)argument), -1);
3393        break;
3394    }
3395    case CONTAINER_LENGTH:
3396    {
3397        int64_t length = 0;
3398        ret = container_ffmpeg_get_length(context, &length);
3399        *((int64_t*)argument) = (int64_t)length;
3400        break;
3401    }
3402    case CONTAINER_SWITCH_AUDIO:
3403    {
3404        ret = container_ffmpeg_switch_audio(context, (int32_t*) argument);
3405        break;
3406    }
3407    case CONTAINER_SWITCH_SUBTITLE:
3408    {
3409        ret = container_ffmpeg_switch_subtitle(context, (int32_t*) argument);
3410        break;
3411    }
3412    case CONTAINER_INFO:
3413    {
3414        ret = container_ffmpeg_get_info(context, (char **)argument);
3415        break;
3416    }
3417    case CONTAINER_STATUS:
3418    {
3419        *((int32_t*)argument) = hasPlayThreadStarted;
3420        break;
3421    }
3422    case CONTAINER_LAST_PTS:
3423    {
3424        *((int64_t*)argument) = latestPts;
3425        break;
3426    }
3427    //obi
3428    case CONTAINER_SET_BUFFER_SEEK_TIME:
3429    {
3430        ret = container_set_ffmpeg_buf_seek_time((int*) argument);
3431            break;
3432    }
3433    //obi (end)
3434    case CONTAINER_SET_BUFFER_SIZE:
3435    {
3436        ret = container_set_ffmpeg_buf_size((int32_t *) argument);
3437        break;
3438    }
3439    case CONTAINER_GET_BUFFER_SIZE:
3440    {
3441        int32_t size = 0;
3442        ret = container_get_ffmpeg_buf_size(&size);
3443        *((int32_t*)argument) = size;
3444        break;
3445    }
3446    //obi
3447    case CONTAINER_GET_BUFFER_STATUS:
3448    {
3449            int32_t size = 0;
3450            ret = container_get_fillbufstatus(&size);
3451            *((int32_t*)argument) = size;
3452            break;
3453    }
3454    case CONTAINER_STOP_BUFFER:
3455    {
3456            ret = container_stop_buffer();
3457            break;
3458    }
3459    case CONTAINER_GET_SUBTEXT:
3460    {
3461        ret = container_ffmpeg_get_subtext(context, (char **)argument);
3462
3463
3464
3465        break;
3466    }
3467    //obi (end)
3468    default:
3469        ffmpeg_err("ContainerCmd %d not supported!\n", command);
3470        ret = cERR_CONTAINER_FFMPEG_ERR;
3471        break;
3472    }
3473
3474    ffmpeg_printf(50, "exiting with value %d\n", ret);
3475    return ret;
3476}
3477
3478static 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 };
3479
3480Container_t FFMPEGContainer = {
3481    "FFMPEG",
3482    &Command,
3483    FFMPEG_Capabilities
3484};
Note: See TracBrowser for help on using the repository browser.