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

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

reset libeplayer3 to v36

File size: 122.8 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                                        headers = string_replace_all("%3D", "=", headers, 1);
1965                                        headers = string_replace_all("%26", "&", headers, 1);
1966                                av_dict_set(&avio_opts, "headers", headers, 0);
1967                                        ffmpeg_printf(10, "set headers: %s\n", headers);
1968                                }
1969                                else
1970                                        ffmpeg_printf(10, "skip set headers: %s\n", headers);
1971
1972                            if(useragent == NULL)
1973                                        ffmpeg_printf(10, "skip set user-agent: %s\n", headers);
1974                        }
1975
1976                        free(useragent), useragent = NULL;
1977                        free(headers), headers = NULL;
1978                        free(ret1), ret1 = NULL;       
1979                        free(tmpstr1), tmpstr1 = NULL;
1980                        stringreplacechar(filename, '|', '\0');         
1981                        ffmpeg_printf(10, "changed filename: %s\n", filename);
1982
1983                }
1984                ffmpeg_printf(10, "check tslivemode\n");
1985
1986//              if (ostrstr(filename, ".m3u8") != NULL)
1987                if (usetslivemode == 1)
1988                {
1989                        ffmpeg_printf(10, "set tslivemode\n");
1990                        context->playback->isTSLiveMode = 1;
1991                }
1992//obi (end)
1993
1994        av_dict_set(&avio_opts, "reconnect", "1", 0);
1995        if (context->playback->isTSLiveMode) // special mode for live TS stream with skip packet
1996        {
1997            av_dict_set(&avio_opts, "seekable", "0", 0);
1998            av_dict_set(&avio_opts, "reconnect_at_eof", "1", 0);
1999            av_dict_set(&avio_opts, "reconnect_streamed", "1", 0);
2000        }
2001    }
2002
2003    pavio_opts = &avio_opts;
2004   
2005    if ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0)
2006    {
2007        if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN &&
2008            rtmpProtoImplType == RTMP_NATIVE &&
2009            numOfRTMPImpl > 1)
2010        {
2011            // retry with librtmp
2012            err = avformat_open_input(&avContextTab[AVIdx], filename+2, fmt, pavio_opts);
2013            // filename2 - another memory leak, and also only once, so does not matter
2014        }
2015       
2016        if (err != 0)
2017        {
2018            char error[512];
2019
2020            ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
2021            av_strerror(err, error, 512);
2022            fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
2023
2024            if(avio_opts != NULL)
2025            {
2026                av_dict_free(&avio_opts);
2027            }
2028
2029            //obi
2030            ffmpeg_buf_free();
2031            //obi (end)
2032
2033            releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2034            return cERR_CONTAINER_FFMPEG_OPEN;
2035        }
2036    }
2037
2038    avContextTab[AVIdx]->iformat->flags |= AVFMT_SEEK_TO_PTS;
2039    avContextTab[AVIdx]->flags = AVFMT_FLAG_GENPTS;
2040
2041    if (context->playback->noprobe)
2042    {
2043        wrapped_set_max_analyze_duration(avContextTab[AVIdx], 1);
2044    }
2045
2046    ffmpeg_printf(20, "find_streaminfo\n");
2047
2048    if (avformat_find_stream_info(avContextTab[AVIdx], NULL) < 0)
2049    {
2050        ffmpeg_err("Error avformat_find_stream_info\n");
2051    }
2052
2053//for buffered io
2054    if(avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL && !context->playback->isTSLiveMode)
2055    {
2056        ffmpeg_real_read_org = avContextTab[AVIdx]->pb->read_packet;
2057       
2058        if(0 ==AVIdx && strstr(filename, "://") != 0 &&
2059           strncmp(filename, "file://", 7) != 0)
2060        {
2061            if(ffmpeg_buf_size > 0 && ffmpeg_buf_size > FILLBUFDIFF + FILLBUFPAKET)
2062            {
2063                if(avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL)
2064                {
2065                    ffmpeg_buf = av_malloc(ffmpeg_buf_size);
2066
2067                    if(ffmpeg_buf != NULL)
2068                    {
2069                        ffmpeg_printf(10, "buffer size=%d\n", ffmpeg_buf_size);
2070                       
2071                        ffmpeg_read_org = avContextTab[AVIdx]->pb->read_packet;
2072                        avContextTab[AVIdx]->pb->read_packet = ffmpeg_read;
2073                        ffmpeg_seek_org = avContextTab[AVIdx]->pb->seek;
2074                        avContextTab[AVIdx]->pb->seek = ffmpeg_seek;
2075                        ffmpeg_buf_read = ffmpeg_buf;
2076                        ffmpeg_buf_write = ffmpeg_buf;
2077
2078                        //fill buffer
2079                        ffmpeg_filler(context, -1, NULL, 0);
2080                        ffmpeg_start_fillerTHREAD(context);
2081                    }
2082                }
2083            }
2084        }
2085        else if (progressive_playback)
2086        {
2087            avContextTab[AVIdx]->pb->read_packet = ffmpeg_read_wrapper;
2088        }
2089    }
2090//for buffered io (end)
2091   
2092    return 0;
2093}
2094
2095int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
2096{
2097    int32_t err = 0;
2098
2099    ffmpeg_printf(10, ">\n");
2100
2101    //obi
2102    ffmpeg_buf_free();
2103    //obi (end)
2104
2105    if (playFilesNames == NULL)
2106    {
2107        ffmpeg_err("playFilesNames NULL\n");
2108        return cERR_CONTAINER_FFMPEG_NULL;
2109    }
2110   
2111    if (playFilesNames->szFirstFile == NULL)
2112    {
2113        ffmpeg_err("playFilesNames->szFirstFile NULL\n");
2114        return cERR_CONTAINER_FFMPEG_NULL;
2115    }
2116
2117    if (context == NULL)
2118    {
2119        ffmpeg_err("context NULL\n");
2120        return cERR_CONTAINER_FFMPEG_NULL;
2121    }
2122
2123    ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile);
2124    if(playFilesNames->szSecondFile)
2125    {
2126        ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile);
2127    }
2128
2129    if (isContainerRunning)
2130    {
2131        ffmpeg_err("ups already running?\n");
2132        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2133        return cERR_CONTAINER_FFMPEG_RUNNING;
2134    }
2135
2136    /* initialize ffmpeg */
2137    avcodec_register_all();
2138    av_register_all();
2139    avformat_network_init();
2140
2141//obi
2142    char* tmpstr = NULL;
2143    tmpstr = readfiletomem("/mnt/config/titan.cfg", 1);
2144    if(ostrstr(tmpstr, "debuglevel=99") != NULL)
2145        av_log_set_level( AV_LOG_DEBUG );
2146    else
2147        av_log_set_callback(ffmpeg_silen_callback);
2148    free(tmpstr), tmpstr = NULL;
2149//obi (end)
2150    // SULGE DEBUG ENABLED
2151    // make ffmpeg silen
2152    //av_log_set_level( AV_LOG_DEBUG );
2153    //av_log_set_callback(ffmpeg_silen_callback);
2154 
2155    context->playback->abortRequested = 0;
2156    int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0);
2157    if(0 != res)
2158    {
2159        return res;
2160    }
2161
2162    if(playFilesNames->szSecondFile)
2163    {
2164        res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1);
2165    }
2166   
2167    if(0 != res)
2168    {
2169        return res;
2170    }
2171   
2172    terminating = 0;
2173    latestPts = 0;
2174    isContainerRunning = 1;
2175    res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1);
2176
2177    //obi
2178    //ReadSubtitles(context, playFilesNames->szFirstFile);
2179    //obi (end)
2180    return res;
2181}
2182
2183int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial)
2184{
2185    Track_t *audioTrack = NULL;
2186    Track_t *subtitleTrack = NULL;
2187   
2188    if (terminating)
2189    {
2190        return cERR_CONTAINER_FFMPEG_NO_ERROR;
2191    }
2192   
2193    if (initial && context->manager->subtitle)
2194    {
2195        context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack);
2196    }
2197
2198    if (context->manager->audio)
2199    {
2200        context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
2201    }
2202
2203    if (context->manager->video)
2204    {
2205        context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL);
2206    }
2207   
2208    if (context->manager->audio)
2209    {
2210        context->manager->audio->Command(context, MANAGER_INIT_UPDATE, NULL);
2211    }
2212   
2213#if 0
2214    if (context->manager->subtitle)
2215    {
2216        context->manager->subtitle->Command(context, MANAGER_INIT_UPDATE, NULL);
2217    }
2218#endif
2219
2220
2221    ffmpeg_printf(20, "dump format\n");
2222    av_dump_format(avContextTab[0], 0, filename, 0);
2223   
2224   
2225    uint32_t cAVIdx = 0;
2226    for(cAVIdx=0; cAVIdx<IPTV_AV_CONTEXT_MAX_NUM; cAVIdx+=1)
2227    {
2228        if(NULL == avContextTab[cAVIdx])
2229        {
2230            break;
2231        }
2232        AVFormatContext *avContext = avContextTab[cAVIdx];
2233        uint32_t *stream_index = NULL;
2234        uint32_t nb_stream_indexes = 0;
2235       
2236        ffmpeg_printf(1, "cAVIdx[%d]: number of streams: %d\n", cAVIdx, avContext->nb_streams);
2237       
2238        if (avContext->nb_programs > 0)
2239        {
2240            uint32_t n = 0;
2241            ffmpeg_printf(1, "cAVIdx[%d]: stream with multi programs: num of programs %d\n", cAVIdx, avContext->nb_programs);
2242            for (n = 0; n < avContext->nb_programs && (0 == nb_stream_indexes || stream_index == NULL); n++)
2243            {
2244                AVProgram *p = avContext->programs[n];
2245                if (p->nb_stream_indexes)
2246                {
2247                    if (g_sel_program_id > 0)
2248                    {
2249                        if (g_sel_program_id == p->id)
2250                        {
2251                            stream_index = p->stream_index;
2252                            nb_stream_indexes = p->nb_stream_indexes;
2253                            ffmpeg_printf(1, "cAVIdx[%d]: select PROGRAM ID: %d\n", cAVIdx, (int32_t)p->id);
2254                            break;
2255                        }
2256                    }
2257                    else
2258                    {
2259                        uint32_t m = 0;
2260                        for (m = 0; m < p->nb_stream_indexes; m++)
2261                        {
2262                            AVStream *s = avContext->streams[p->stream_index[m]];
2263                            if (get_codecpar(s)->codec_type == AVMEDIA_TYPE_VIDEO && get_codecpar(s)->width > 0)
2264                            {
2265                                ffmpeg_printf(1, "cAVIdx[%d]: PROGRAM ID: %d, width [%d]\n", cAVIdx, (int32_t)p->id, (int32_t)get_codecpar(s)->width);
2266                                stream_index = p->stream_index;
2267                                nb_stream_indexes = p->nb_stream_indexes;
2268                                break;
2269                            }
2270                        }
2271                    }
2272                }
2273            }
2274        }
2275       
2276        int32_t n = 0;
2277        for (n = 0; n < avContext->nb_streams; n++)
2278        {
2279            Track_t track;
2280            AVStream *stream = avContext->streams[n];
2281            int32_t version = 0;
2282            char *encoding = NULL;
2283           
2284            if (nb_stream_indexes > 0 && stream_index != NULL)
2285            {
2286                uint32_t isStreamFromSelProg = 0;
2287                uint32_t m = 0;
2288                for (m = 0; m < nb_stream_indexes; m++)
2289                {
2290                    if (n == stream_index[m])
2291                    {
2292                        isStreamFromSelProg = 1;
2293                        break;
2294                    }
2295                }
2296               
2297                if (!isStreamFromSelProg)
2298                    continue; // skip this stream
2299            }
2300
2301            encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \
2302                                      (uint8_t *)get_codecpar(stream)->extradata, \
2303                                      (int)get_codecpar(stream)->extradata_size, \
2304                                      (int)get_codecpar(stream)->profile, &version);
2305           
2306            if(encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm)
2307            {
2308                encoding = "A_LPCM";
2309            }
2310
2311            if (encoding != NULL)
2312            {
2313               ffmpeg_printf(1, "%d. encoding = %s - version %d\n", n, encoding, version);
2314            }
2315
2316            if (!stream->id)
2317            {
2318                stream->id = n;
2319            }
2320
2321            /* some values in track are unset and therefor copyTrack segfaults.
2322             * so set it by default to NULL!
2323             */
2324            memset(&track, 0, sizeof(track));
2325            track.AVIdx = cAVIdx;
2326
2327            switch (get_codecpar(stream)->codec_type)
2328            {
2329            case AVMEDIA_TYPE_VIDEO:
2330                ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
2331
2332                if (encoding != NULL)
2333                {
2334                    track.type           = eTypeES;
2335                    track.version        = version;
2336
2337                    track.width          = get_codecpar(stream)->width;
2338                    track.height         = get_codecpar(stream)->height;
2339                   
2340                    /* We will return here PAR (Pixel Aspect Ratio) client need to calculate DAR(Display Aspect Ratio)
2341                     * example: PAR 64:45 DAR 16:9
2342                     *          Resolution 720x576
2343                     * Display aspect ratio = (720*64)/(576*45) = 16/9
2344                     * 0:1 is the value for invalid/unset aspect ratio -> https://trac.ffmpeg.org/ticket/3798
2345                     */
2346                    track.aspect_ratio_num = stream->sample_aspect_ratio.num;
2347                    track.aspect_ratio_den = stream->sample_aspect_ratio.den;
2348                    if (0 == track.aspect_ratio_num  || 0 == track.aspect_ratio_den)
2349                    {
2350                        track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num;
2351                        track.aspect_ratio_den = get_codecpar(stream)->sample_aspect_ratio.den;
2352                    }
2353
2354                    track.extraData      = get_codecpar(stream)->extradata;
2355                    track.extraSize      = get_codecpar(stream)->extradata_size;
2356
2357                    track.aacbuf         = 0;
2358                    track.have_aacheader = -1;
2359                   
2360                    AVRational rateRational = get_frame_rate(stream);
2361                    if (rateRational.den!=0)
2362                    {
2363                        track.frame_rate = (uint32_t)(1000 * (int64_t)(rateRational.num) / (int64_t)(rateRational.den));
2364                    }
2365                   
2366                    /* fixme: revise this */
2367                    if (track.frame_rate < 23970)
2368                    {
2369                        track.TimeScale = 1001;
2370                    }
2371                    else
2372                    {
2373                        track.TimeScale = 1000;
2374                    }
2375                   
2376                    ffmpeg_printf(10, "bit_rate       [%d]\n", get_codecpar(stream)->bit_rate);
2377                    ffmpeg_printf(10, "time_base.den  [%d]\n", stream->time_base.den);
2378                    ffmpeg_printf(10, "time_base.num  [%d]\n", stream->time_base.num);
2379                    ffmpeg_printf(10, "width          [%d]\n", get_codecpar(stream)->width);
2380                    ffmpeg_printf(10, "height         [%d]\n", get_codecpar(stream)->height);
2381                    ffmpeg_printf(10, "frame_rate num [%d]\n", rateRational.num);
2382                    ffmpeg_printf(10, "frame_rate den [%d]\n", rateRational.den);
2383
2384                    ffmpeg_printf(10, "frame_rate     [%u]\n", track.frame_rate);
2385                    ffmpeg_printf(10, "TimeScale      [%d]\n", track.TimeScale);
2386
2387                    track.Name      = "und";
2388                    track.Encoding  = encoding;
2389                    track.stream    = stream;
2390                    track.Id        = ((AVStream *) (track.stream))->id;
2391
2392                    track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2393                    if(stream->duration == AV_NOPTS_VALUE || 0 == strncmp(avContext->iformat->name, "dash", 4))
2394                    {
2395                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2396                        track.duration = (int64_t) avContext->duration / 1000;
2397                    }
2398                   
2399                    if (context->manager->video)
2400                    {
2401                        if (get_codecpar(stream)->codec_id == AV_CODEC_ID_MPEG4)
2402                        {
2403                            track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
2404                        }
2405                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n");
2406                        if( context->manager->video->Command(context, MANAGER_ADD, &track) < 0)
2407                        {
2408                            /* konfetti: fixme: is this a reason to return with error? */
2409                            ffmpeg_err("failed to add track %d\n", n);
2410                        }
2411                    }
2412                }
2413                else
2414                {
2415                    ffmpeg_err("codec type video but codec unknown %d\n", get_codecpar(stream)->codec_id);
2416                }
2417                break;
2418            case AVMEDIA_TYPE_AUDIO:
2419                ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",get_codecpar(stream)->codec_type);
2420
2421                if (encoding != NULL)
2422                {
2423                    AVDictionaryEntry *lang;
2424                    track.type = eTypeES;
2425
2426                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
2427
2428                    track.Name = lang ? lang->value : "und";
2429
2430                    ffmpeg_printf(10, "Language %s\n", track.Name);
2431
2432                    track.Encoding       = encoding;
2433                    track.stream         = stream;
2434                    track.Id             = ((AVStream *) (track.stream))->id;
2435                    track.aacbuf         = 0;
2436                    track.have_aacheader = -1;
2437
2438                    track.duration       = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2439                    if(stream->duration == AV_NOPTS_VALUE)
2440                    {
2441                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2442                        track.duration = (int64_t) avContext->duration / 1000;
2443                    }
2444                   
2445                    if(!strncmp(encoding, "A_IPCM", 6) || !strncmp(encoding, "A_LPCM", 6))
2446                    {
2447                        track.inject_as_pcm = 1;
2448                        track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
2449                        if (track.avCodecCtx)
2450                        {
2451                            ffmpeg_printf(10, " Handle inject_as_pcm = %d\n", track.inject_as_pcm);
2452
2453                            AVCodec *codec = avcodec_find_decoder(get_codecpar(stream)->codec_id);
2454
2455                            int errorCode = avcodec_open2(track.avCodecCtx, codec, NULL);
2456                            if(codec != NULL && !errorCode)
2457                            {
2458                               ffmpeg_printf(10, "AVCODEC__INIT__SUCCESS\n");
2459                            }
2460                            else
2461                            {
2462                               ffmpeg_printf(10, "AVCODEC__INIT__FAILED error[%d]\n", errorCode);
2463                            }
2464                        }
2465                    }
2466                    else if(!strncmp(encoding, "A_PCM", 5))
2467                    {
2468                        track.inject_raw_pcm = 1;
2469                    }
2470                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC_LATM)
2471                    {
2472                        const char marker[] = "LATM";
2473                        track.aacbuflen = sizeof(marker)/sizeof(char);
2474                        track.aacbuf = malloc(track.aacbuflen);
2475                        memcpy(track.aacbuf, marker, track.aacbuflen);
2476                       
2477                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM no extradata ACC header should be available in each frame\n");
2478                        track.have_aacheader = 1;
2479                    }
2480                    else if(!strncmp(encoding, "A_AAC_LATM", 10))
2481                    {
2482                        ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM extradata will be used in aac writter\n");
2483                    }
2484                    else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC)
2485                    {
2486                        if( 0 == strncmp(avContext->iformat->name, "mpegts", 6) ||
2487                            0 == strncmp(avContext->iformat->name, "hls,", 4) )
2488                        {
2489                            const char marker[] = "ADTS";
2490                            track.aacbuflen = sizeof(marker)/sizeof(char);
2491                            track.aacbuf = malloc(track.aacbuflen);
2492                            memcpy(track.aacbuf, marker, track.aacbuflen);
2493                           
2494                            ffmpeg_printf(10, "AV_CODEC_ID_AAC no extradata ACC header should be available in each frame\n");
2495                            track.have_aacheader = 1;
2496                        }
2497                        else
2498                        {
2499                            ffmpeg_printf(10, "Create AAC ExtraData\n");
2500                            ffmpeg_printf(10, "get_codecpar(stream)->extradata_size %d\n", get_codecpar(stream)->extradata_size);
2501                            //Hexdump(get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
2502
2503                            /*  extradata:
2504                                13 10 56 e5 9d 48 00 (anderen cops)
2505                                object_type: 00010 2 = LC
2506                                sample_rate: 011 0 6 = 24000
2507                                chan_config: 0010 2 = Stereo
2508                                000 0
2509                                1010110 111 = 0x2b7
2510                                00101 = SBR
2511                                1
2512                                0011 = 48000
2513                                101 01001000 = 0x548
2514                                ps = 0
2515                                0000000
2516                            */
2517
2518                            int32_t object_type = 2; // LC
2519                            int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate);
2520                            int32_t chan_config = get_codecpar(stream)->channels - 1;
2521                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
2522                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
2523                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
2524                           
2525                            if (get_codecpar(stream)->extradata_size >= 2)
2526                            {
2527                                MPEG4AudioConfig m4ac;
2528                                int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
2529                                if (off >= 0)
2530                                {
2531                                    object_type  = m4ac.object_type;
2532                                    sample_index = m4ac.sampling_index;
2533                                    if (sample_index == 0x0f)
2534                                    {
2535                                        sample_index = aac_get_sample_rate_index(m4ac.sample_rate);
2536                                    }
2537                                    chan_config  = m4ac.chan_config;
2538                                }
2539                            }
2540                           
2541                            ffmpeg_printf(1,"aac object_type %d\n", object_type);
2542                            ffmpeg_printf(1,"aac sample_index %d\n", sample_index);
2543                            ffmpeg_printf(1,"aac chan_config %d\n", chan_config);
2544
2545                           
2546                            // https://wiki.multimedia.cx/index.php/ADTS
2547                            object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1
2548                           
2549                            track.aacbuflen = AAC_HEADER_LENGTH;
2550                            track.aacbuf = malloc(8);
2551                            track.aacbuf[0] = 0xFF;
2552                            track.aacbuf[1] = 0xF1;
2553                            //track.aacbuf[1] |=0x8;
2554                            track.aacbuf[2] = ((object_type & 0x03) << 6)  | (sample_index << 2) | ((chan_config >> 2) & 0x01);
2555                            track.aacbuf[3] = (chan_config & 0x03) << 6;
2556                            //track.aacbuf[3]|= 0x10;
2557                            track.aacbuf[4] = 0x00;
2558                            track.aacbuf[5] = 0x1F;
2559                            track.aacbuf[6] = 0xFC;
2560
2561                            //printf("AAC_HEADER -> ");
2562                            //Hexdump(track.aacbuf,7);
2563                            track.have_aacheader = 1;
2564                        }
2565                        /*
2566                        else
2567                        {
2568                            ffmpeg_err("AV_CODEC_ID_AAC extradata not available\n");
2569                        }
2570                        */
2571
2572                    }
2573                    else if(get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1
2574                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2
2575                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO
2576                        || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0)
2577                    {
2578                        ffmpeg_printf(10,"Create WMA ExtraData\n");
2579                        uint16_t channels = get_codecpar(stream)->channels;
2580                        uint32_t rate = get_codecpar(stream)->sample_rate;
2581                        uint32_t bitrate = get_codecpar(stream)->bit_rate;
2582                        uint16_t block_align = get_codecpar(stream)->block_align;
2583                        uint16_t depth = get_codecpar(stream)->bits_per_coded_sample;
2584                        uint32_t codec_data_size = get_codecpar(stream)->extradata_size;
2585                        uint8_t *codec_data_pointer = get_codecpar(stream)->extradata;
2586                       
2587                        // type_specific_data
2588                        #define WMA_VERSION_1           0x160
2589                        #define WMA_VERSION_2_9         0x161
2590                        #define WMA_VERSION_9_PRO       0x162
2591                        #define WMA_LOSSLESS            0x163
2592                        uint16_t codec_id = 0;
2593                        switch(get_codecpar(stream)->codec_id)
2594                        {
2595                            //TODO: What code for lossless ?
2596                            case AV_CODEC_ID_WMALOSSLESS:
2597                                codec_id = WMA_LOSSLESS;
2598                                break;
2599                            case AV_CODEC_ID_WMAPRO:
2600                                codec_id = WMA_VERSION_9_PRO;
2601                                break;
2602                            case AV_CODEC_ID_WMAV2:
2603                                codec_id = WMA_VERSION_2_9 ;
2604                                break;
2605                            case AV_CODEC_ID_WMAV1:
2606                            default:
2607                                codec_id = WMA_VERSION_1;
2608                                break;
2609                        }
2610#ifdef __sh__
2611                        track.aacbuflen = 104 + get_codecpar(stream)->extradata_size;
2612                        track.aacbuf = malloc(track.aacbuflen);
2613                        memset (track.aacbuf, 0, track.aacbuflen);
2614                       
2615                        uint8_t ASF_Stream_Properties_Object[16] =
2616                        {0x91,0x07,0xDC,0xB7,0xB7,0xA9,0xCF,0x11,0x8E,0xE6,0x00,0xC0,0x0C,0x20,0x53,0x65};
2617                       
2618                        memcpy(track.aacbuf + 0, ASF_Stream_Properties_Object, 16); // ASF_Stream_Properties_Object
2619                        memcpy(track.aacbuf + 16, &track.aacbuflen, 4); //FrameDateLength
2620
2621                        uint32_t sizehi = 0;
2622                        memcpy(track.aacbuf + 20, &sizehi, 4); // sizehi (not used)
2623
2624                        uint8_t ASF_Audio_Media[16] =
2625                        {0x40,0x9E,0x69,0xF8,0x4D,0x5B,0xCF,0x11,0xA8,0xFD,0x00,0x80,0x5F,0x5C,0x44,0x2B};
2626                       
2627                        memcpy(track.aacbuf + 24, ASF_Audio_Media, 16); //ASF_Audio_Media
2628
2629                        uint8_t ASF_Audio_Spread[16] =
2630                        {0x50,0xCD,0xC3,0xBF,0x8F,0x61,0xCF,0x11,0x8B,0xB2,0x00,0xAA,0x00,0xB4,0xE2,0x20};
2631                       
2632                        memcpy(track.aacbuf + 40, ASF_Audio_Spread, 16); //ASF_Audio_Spread
2633
2634                        memset(track.aacbuf + 56, 0, 4); // time_offset (not used)
2635                        memset(track.aacbuf + 60, 0, 4); // time_offset_hi (not used)
2636
2637                        uint8_t type_specific_data_length = 18 + get_codecpar(stream)->extradata_size;
2638                        memcpy(track.aacbuf + 64, &type_specific_data_length, 4); //type_specific_data_length
2639
2640                        uint8_t error_correction_data_length = 8;
2641                        memcpy(track.aacbuf + 68, &error_correction_data_length, 4); //error_correction_data_length
2642
2643                        uint16_t flags = 1; // stream_number
2644                        memcpy(track.aacbuf + 72, &flags, 2); //flags
2645
2646                        uint32_t reserved = 0;
2647                        memcpy(track.aacbuf + 74, &reserved, 4); // reserved
2648
2649                        memcpy(track.aacbuf + 78, &codec_id, 2); //codec_id
2650
2651                        uint16_t number_of_channels = get_codecpar(stream)->channels;
2652                        memcpy(track.aacbuf + 80, &number_of_channels, 2); //number_of_channels
2653
2654                        uint32_t samples_per_second = get_codecpar(stream)->sample_rate;
2655                        ffmpeg_printf(1, "samples_per_second = %d\n", samples_per_second);
2656                        memcpy(track.aacbuf + 82, &samples_per_second, 4); //samples_per_second
2657
2658                        uint32_t average_number_of_bytes_per_second = get_codecpar(stream)->bit_rate / 8;
2659                        ffmpeg_printf(1, "average_number_of_bytes_per_second = %d\n", average_number_of_bytes_per_second);
2660                        memcpy(track.aacbuf + 86, &average_number_of_bytes_per_second, 4); //average_number_of_bytes_per_second
2661
2662                        uint16_t block_alignment = get_codecpar(stream)->block_align;
2663                        ffmpeg_printf(1, "block_alignment = %d\n", block_alignment);
2664                        memcpy(track.aacbuf + 90, &block_alignment, 2); //block_alignment
2665
2666#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
2667                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->format;
2668#else
2669                        enum AVSampleFormat sample_fmt = get_codecpar(stream)->sample_fmt;
2670#endif
2671                        uint16_t bits_per_sample = sample_fmt>=0 ? (sample_fmt+1)*8 : 8;
2672                        ffmpeg_printf(1, "bits_per_sample = %d (%d)\n", bits_per_sample, sample_fmt);
2673                        memcpy(track.aacbuf + 92, &bits_per_sample, 2); //bits_per_sample
2674
2675                        memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample
2676
2677                        memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
2678#else
2679                        track.aacbuflen = 18 + get_codecpar(stream)->extradata_size;
2680                        track.aacbuf = malloc(track.aacbuflen);
2681                        memset (track.aacbuf, 0, track.aacbuflen);
2682                       
2683                        uint8_t *data = track.aacbuf;
2684                        /* codec tag */
2685                        *(data++) = codec_id & 0xff;
2686                        *(data++) = (codec_id >> 8) & 0xff;
2687                        /* channels */
2688                        *(data++) = channels & 0xff;
2689                        *(data++) = (channels >> 8) & 0xff;
2690                        /* sample rate */
2691                        *(data++) = rate & 0xff;
2692                        *(data++) = (rate >> 8) & 0xff;
2693                        *(data++) = (rate >> 16) & 0xff;
2694                        *(data++) = (rate >> 24) & 0xff;
2695                        /* byte rate */
2696                        bitrate /= 8;
2697                        *(data++) = bitrate & 0xff;
2698                        *(data++) = (bitrate >> 8) & 0xff;
2699                        *(data++) = (bitrate >> 16) & 0xff;
2700                        *(data++) = (bitrate >> 24) & 0xff;
2701                        /* block align */
2702                        *(data++) = block_align & 0xff;
2703                        *(data++) = (block_align >> 8) & 0xff;
2704                        /* word size */
2705                        *(data++) = depth & 0xff;
2706                        *(data++) = (depth >> 8) & 0xff;
2707                        /* codec data size */
2708                        *(data++) = codec_data_size & 0xff;
2709                        *(data++) = (codec_data_size >> 8) & 0xff;
2710                        memcpy(data, codec_data_pointer, codec_data_size);
2711#endif
2712                        ffmpeg_printf(1, "aacbuf:\n");
2713                        //Hexdump(track.aacbuf, track.aacbuflen);
2714
2715                        //ffmpeg_printf(1, "priv_data:\n");
2716                        //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen);
2717
2718                        track.have_aacheader = 1;
2719                    }
2720                   
2721                    if (context->manager->audio)
2722                    {
2723                        ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n");
2724                        if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0)
2725                        {
2726                            /* konfetti: fixme: is this a reason to return with error? */
2727                            ffmpeg_err("failed to add track %d\n", n);
2728                        }
2729                    }
2730                }
2731                else //encoding != NULL
2732                {
2733                    ffmpeg_err("codec type audio but codec unknown %d\n", get_codecpar(stream)->codec_id);
2734                }
2735                break;
2736            case AVMEDIA_TYPE_SUBTITLE:
2737            {
2738                if (get_codecpar(stream)->codec_id != AV_CODEC_ID_SSA &&
2739#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100)
2740                    get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS &&
2741#endif
2742                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
2743                    get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
2744                    get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT)
2745                {
2746                    ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id);
2747                }
2748                else if (initial && context->manager->subtitle)
2749                {
2750                    AVDictionaryEntry *lang = NULL;
2751                    memset(&track, 0, sizeof(track));
2752
2753                    ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type);
2754                   
2755                    lang = av_dict_get(stream->metadata, "language", NULL, 0);
2756                    track.Name = lang ? lang->value : "und";
2757                    ffmpeg_printf(10, "Language %s\n", track.Name);
2758
2759                    track.Encoding       = encoding;
2760                    track.stream         = stream;
2761                    track.Id             = ((AVStream *) (track.stream))->id;
2762                    track.duration       = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
2763                   
2764                    if(stream->duration == AV_NOPTS_VALUE)
2765                    {
2766                        ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
2767                        track.duration = (int64_t) avContext->duration / 1000;
2768                    }
2769
2770                    track.extraData      = get_codecpar(stream)->extradata;
2771                    track.extraSize      = get_codecpar(stream)->extradata_size;
2772
2773                    ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id);
2774                    ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width);
2775                    ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height);
2776                    ffmpeg_printf(1, "subtitle stream %p\n", stream);
2777
2778                    ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name);
2779                   
2780                    if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0)
2781                    {
2782                        ffmpeg_err("failed to add subtitle track %d\n", n);
2783                    }
2784                }
2785                break;
2786            }
2787            case AVMEDIA_TYPE_UNKNOWN:
2788            case AVMEDIA_TYPE_DATA:
2789            case AVMEDIA_TYPE_ATTACHMENT:
2790            case AVMEDIA_TYPE_NB:
2791            default:
2792                ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type);
2793             break;
2794            }
2795        } /* for */
2796   
2797    }
2798
2799    return cERR_CONTAINER_FFMPEG_NO_ERROR;
2800}
2801
2802static int32_t container_ffmpeg_play(Context_t *context)
2803{
2804    int32_t error = 0;
2805    int32_t ret = 0;
2806    pthread_attr_t attr;
2807
2808    ffmpeg_printf(10, "\n");
2809
2810    if ( context && context->playback && context->playback->isPlaying )
2811    {
2812        ffmpeg_printf(10, "is Playing\n");
2813    }
2814    else
2815    {
2816        ffmpeg_printf(10, "is NOT Playing\n");
2817    }
2818
2819    if (hasPlayThreadStarted == 0)
2820    {
2821        pthread_attr_init(&attr);
2822        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2823
2824        if((error = pthread_create(&PlayThread, &attr, (void *)&FFMPEGThread, context)) != 0)
2825        {
2826            ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error,strerror(error));
2827
2828            hasPlayThreadStarted = 0;
2829            ret = cERR_CONTAINER_FFMPEG_ERR;
2830        }
2831        else
2832        {
2833            ffmpeg_printf(10, "Created thread\n");
2834
2835            hasPlayThreadStarted = 1;
2836        }
2837    }
2838    else
2839    {
2840        ffmpeg_printf(10, "A thread already exists!\n");
2841        ret = cERR_CONTAINER_FFMPEG_ERR;
2842    }
2843
2844    ffmpeg_printf(10, "exiting with value %d\n", ret);
2845    return ret;
2846}
2847
2848static int32_t container_ffmpeg_stop(Context_t *context)
2849{
2850    int32_t ret = cERR_CONTAINER_FFMPEG_NO_ERROR;
2851    int32_t wait_time = 10; // we give 1s to close otherwise we will force close
2852
2853    ffmpeg_printf(10, "\n");
2854
2855    if (!isContainerRunning)
2856    {
2857        ffmpeg_err("Container not running\n");
2858        return cERR_CONTAINER_FFMPEG_ERR;
2859    }
2860
2861    //obi
2862    wait_time = 100;
2863    if(hasfillerThreadStarted[hasfillerThreadStartedID] == 1)
2864        hasfillerThreadStarted[hasfillerThreadStartedID] = 2; // should end
2865    while ( (hasfillerThreadStarted[hasfillerThreadStartedID] != 0) && (--wait_time) > 0 ) {
2866        ffmpeg_printf(10, "Waiting for ffmpeg filler thread to terminate itself, will try another %d times, ID=%d\n", wait_time, hasfillerThreadStartedID);
2867        usleep(100000);
2868    }
2869
2870    if (wait_time == 0) {
2871        ffmpeg_err( "Timeout waiting for filler thread!\n");
2872
2873        ret = cERR_CONTAINER_FFMPEG_ERR;
2874    }
2875    //obi (end)
2876
2877    if (context->playback)
2878    {
2879        context->playback->isPlaying = 0;
2880    }
2881
2882    while ( (hasPlayThreadStarted != 0) && (--wait_time) > 0 )
2883    {
2884        ffmpeg_printf(10, "Waiting for ffmpeg thread to terminate itself, will try another %d times\n", wait_time);
2885        usleep(100000);
2886    }
2887
2888    if (wait_time == 0)
2889    {
2890        /* force close */
2891        ffmpeg_err( "Timeout waiting for thread!\n");
2892        ret = cERR_CONTAINER_FFMPEG_ERR;
2893        /* to speed up close - we are in separate process for the moment this process will
2894         * be closed and whole resources will be free by the system 
2895         */
2896        return ret;
2897    }
2898
2899    hasPlayThreadStarted = 0;
2900    terminating = 1;
2901
2902    getMutex(__FILE__, __FUNCTION__,__LINE__);
2903   
2904    free_all_stored_avcodec_context();
2905   
2906    uint32_t i = 0;
2907    for(i=0; i<IPTV_AV_CONTEXT_MAX_NUM; i+=1)
2908    {
2909        if(NULL != avContextTab[i])
2910        {
2911            if(0 != use_custom_io[i])
2912            {
2913                /*
2914                 * Free custom IO independently to avoid segfault/bus error
2915                 * avformat_close_input do not expect custom io, so it try
2916                 * to release incorrectly
2917                 */
2918                av_freep(&(avContextTab[i]->pb->buffer));
2919                av_freep(&(avContextTab[i]->pb));
2920                use_custom_io[i] = 0;
2921            }
2922            avformat_close_input(&avContextTab[i]);
2923            //obi
2924            ffmpeg_buf_free();
2925            //obi (end)
2926            avContextTab[i] = NULL;
2927        }
2928        else
2929        {
2930            break;
2931        }
2932    }
2933
2934    if(avio_opts != NULL)
2935    {
2936        av_dict_free(&avio_opts);
2937    }
2938
2939    isContainerRunning = 0;
2940    avformat_network_deinit();
2941    ffmpeg_buf_free();
2942
2943    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
2944
2945    ffmpeg_printf(10, "ret %d\n", ret);
2946    return ret;
2947}
2948
2949static int32_t container_ffmpeg_seek_bytes(off_t pos)
2950{
2951    int32_t flag = AVSEEK_FLAG_BYTE;
2952    off_t current_pos = avio_tell(avContextTab[0]->pb);
2953
2954    ffmpeg_printf(20, "seeking to position %lld (bytes)\n", pos);
2955
2956    if (current_pos > pos)
2957    {
2958        flag |= AVSEEK_FLAG_BACKWARD;
2959    }
2960
2961    if (avformat_seek_file(avContextTab[0], -1, INT64_MIN, pos, INT64_MAX, flag) < 0)
2962    {
2963        ffmpeg_err( "Error seeking\n");
2964        return cERR_CONTAINER_FFMPEG_ERR;
2965    }
2966
2967    ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb));
2968
2969    return cERR_CONTAINER_FFMPEG_NO_ERROR;
2970}
2971
2972/* seeking relative to a given byteposition N seconds ->for reverse playback needed */
2973static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec)
2974{
2975    Track_t *videoTrack = NULL;
2976    Track_t *audioTrack = NULL;
2977    Track_t *current = NULL;
2978    seek_target_flag = 0;
2979
2980    ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
2981
2982    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
2983    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
2984
2985    if (videoTrack != NULL)
2986    {
2987        current = videoTrack;
2988    }
2989    else if (audioTrack != NULL)
2990    {
2991        current = audioTrack;
2992    }
2993   
2994    if (current == NULL)
2995    {
2996        ffmpeg_err( "no track avaibale to seek\n");
2997        return cERR_CONTAINER_FFMPEG_ERR;
2998    }
2999
3000    if (pos == -1)
3001    {
3002        pos = avio_tell(avContextTab[0]->pb);
3003    }
3004
3005    if (pts == -1)
3006    {
3007        pts = current->pts;
3008    }
3009   
3010    if (sec < 0)
3011    {
3012        seek_target_flag |= AVSEEK_FLAG_BACKWARD;
3013    }
3014
3015    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
3016#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
3017    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
3018    {
3019        if (avContextTab[0]->bit_rate)
3020        {
3021            sec *= avContextTab[0]->bit_rate / 8;
3022            ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
3023        }
3024        else
3025        {
3026            sec *= 180000;
3027        }
3028
3029        pos += sec;
3030
3031        if (pos < 0)
3032        {
3033           ffmpeg_err("end of file reached\n");
3034           releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3035           return cERR_CONTAINER_FFMPEG_END_OF_FILE;
3036        }
3037
3038        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
3039
3040        seek_target_bytes = pos;
3041        do_seek_target_bytes = 1;
3042
3043        return pos;
3044    }
3045    else
3046#endif
3047    {
3048        sec += pts / 90000;
3049
3050        if (sec < 0)
3051        {
3052            sec = 0;
3053        }
3054
3055        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);
3056
3057        seek_target_seconds = sec * AV_TIME_BASE;
3058        do_seek_target_seconds = 1;
3059    }
3060
3061    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3062    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3063}
3064
3065static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
3066{
3067    Track_t *videoTrack = NULL;
3068    Track_t *audioTrack = NULL;
3069    Track_t *current = NULL;
3070    seek_target_flag = 0;
3071
3072    if (!absolute)
3073    {
3074        ffmpeg_printf(10, "seeking %f sec\n", sec);
3075        if (sec == 0)
3076        {
3077            ffmpeg_err("sec = 0 ignoring\n");
3078            return cERR_CONTAINER_FFMPEG_ERR;
3079        }
3080        else
3081        {
3082            int64_t currPts = -1;
3083            int32_t ret = context->playback->Command(context, PLAYBACK_PTS, &currPts);
3084            if (ret != 0)
3085            {
3086                ffmpeg_err("fail to get current PTS\n");
3087                return cERR_CONTAINER_FFMPEG_ERR;
3088            }
3089            sec += currPts / 90000;
3090        }
3091    }
3092   
3093    ffmpeg_printf(10, "goto %d sec\n", sec);
3094    if (sec < 0)
3095    {
3096        sec = 0;
3097    }
3098   
3099    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3100    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3101
3102    if (videoTrack != NULL)
3103    {
3104        current = videoTrack;
3105    }
3106    else if (audioTrack != NULL)
3107    {
3108        current = audioTrack;
3109    }
3110    else
3111    {
3112        ffmpeg_err( "no track available to seek\n");
3113        return cERR_CONTAINER_FFMPEG_ERR;
3114    }
3115
3116    if (sec < 0)
3117    {
3118        seek_target_flag |= AVSEEK_FLAG_BACKWARD;
3119    }
3120
3121    getMutex(__FILE__, __FUNCTION__,__LINE__);
3122
3123    if (!context->playback || !context->playback->isPlaying)
3124    {
3125        releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3126        return cERR_CONTAINER_FFMPEG_NO_ERROR;
3127    }
3128
3129    ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
3130#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
3131    if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
3132    {
3133        /* konfetti: for ts streams seeking frame per seconds does not work (why?).
3134        * I take this algo partly from ffplay.c.
3135        *
3136        * seeking per HTTP does still not work very good. forward seeks everytime
3137        * about 10 seconds, backward does not work.
3138        */
3139
3140        off_t pos = avio_tell(avContextTab[0]->pb);
3141
3142        ffmpeg_printf(10, "pos %lld %d\n", pos, avContextTab[0]->bit_rate);
3143
3144        if (avContextTab[0]->bit_rate)
3145        {
3146            sec *= avContextTab[0]->bit_rate / 8;
3147            ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
3148        }
3149        else
3150        {
3151            sec *= 180000;
3152        }
3153       
3154        pos = sec;
3155       
3156        if (pos < 0)
3157        {
3158           pos = 0;
3159        }
3160       
3161        ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %d\n", pos, sec);
3162
3163        seek_target_bytes = pos;
3164        do_seek_target_bytes = 1;
3165
3166    }
3167    else
3168#endif
3169    {
3170        seek_target_seconds = sec * AV_TIME_BASE;
3171        do_seek_target_seconds = 1;
3172    }
3173
3174    releaseMutex(__FILE__, __FUNCTION__,__LINE__);
3175    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3176}
3177
3178static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length)
3179{
3180    ffmpeg_printf(50, "\n");
3181    Track_t * videoTrack = NULL;
3182    Track_t * audioTrack = NULL;
3183    Track_t * current = NULL;
3184
3185    if (length == NULL)
3186    {
3187        ffmpeg_err( "null pointer passed\n");
3188        return cERR_CONTAINER_FFMPEG_ERR;
3189    }
3190
3191    context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3192    context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3193
3194    if (videoTrack != NULL)
3195    {
3196        current = videoTrack;
3197    }
3198    else if (audioTrack != NULL)
3199    {
3200        current = audioTrack;
3201    }
3202   
3203    *length = 0;
3204
3205    if (current != NULL)
3206    {
3207        if (current->duration == 0)
3208        {
3209            return cERR_CONTAINER_FFMPEG_ERR;
3210        }
3211        else
3212        {
3213            *length = current->duration / 1000;
3214        }
3215    }
3216    else
3217    {
3218        if (avContextTab[0] != NULL)
3219        {
3220            *length = avContextTab[0]->duration / 1000;
3221        }
3222        else
3223        {
3224           ffmpeg_err( "no Track not context ->no problem :D\n");
3225           return cERR_CONTAINER_FFMPEG_ERR;
3226        }
3227    }
3228
3229    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3230}
3231
3232static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg)
3233{
3234    ffmpeg_printf(10, "track %d\n", *arg);
3235   
3236    /* Hellmaster1024: nothing to do here!*/
3237    int64_t sec = -5;
3238    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
3239    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3240}
3241
3242static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg)
3243{
3244    ffmpeg_printf(10, "track %d\n", *arg);
3245   
3246    /* This is made to flush inside the buffer because
3247     * subtitles frame was already read and ignored
3248     * we seek to force ffmpeg to read once again the same data
3249     * but now we will not ignore subtitle frame
3250     */
3251    int64_t sec = -5;
3252    context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec);
3253    //obi
3254    enablesub = 1;
3255    //obi (end)
3256    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3257}
3258
3259//obi
3260static int32_t container_ffmpeg_get_subtext(Context_t* context, char ** data)
3261{
3262
3263//    printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] start\n");
3264
3265    if(enablesub == 1 && subtext != NULL)
3266    {
3267//      printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] set data\n");
3268
3269        *data = ostrcat(subtext, NULL, 0, 0);
3270        free(subtext), subtext = NULL;
3271
3272    }
3273
3274
3275
3276
3277
3278
3279
3280//    printf("[LIBEPLAYER3/container_ffmpeg_get_subtext] end\n");
3281
3282
3283    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3284}
3285//obi (end)
3286
3287/* konfetti comment: I dont like the mechanism of overwriting
3288 * the pointer in infostring. This lead in most cases to
3289 * user errors, like it is in the current version (libeplayer2 <-->e2->servicemp3.cpp)
3290 * From e2 there is passed a tag=strdup here and we overwrite this
3291 * strdupped tag. This lead to dangling pointers which are never freed!
3292 * I do not free the string here because this is the wrong way. The mechanism
3293 * should be changed, or e2 should pass it in a different way...
3294 */
3295static int32_t container_ffmpeg_get_info(Context_t* context, char ** infoString)
3296{
3297    Track_t *videoTrack = NULL;
3298    Track_t *audioTrack = NULL;
3299    char     *meta = NULL;
3300
3301    ffmpeg_printf(20, ">\n");
3302
3303    if (avContextTab[0] != NULL)
3304    {
3305        if ((infoString == NULL) || (*infoString == NULL))
3306        {
3307            ffmpeg_err("infostring NULL\n");
3308            return cERR_CONTAINER_FFMPEG_ERR;
3309        }
3310
3311        ffmpeg_printf(20, "%s\n", *infoString);
3312
3313        context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
3314        context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
3315
3316        if ((meta = searchMeta(avContextTab[0]->metadata, *infoString)) == NULL)
3317        {
3318            if (audioTrack != NULL)
3319            {
3320                AVStream* stream = audioTrack->stream;
3321                meta = searchMeta(stream->metadata, *infoString);
3322            }
3323
3324            if ((meta == NULL) && (videoTrack != NULL))
3325            {
3326                AVStream* stream = videoTrack->stream;
3327                meta = searchMeta(stream->metadata, *infoString);
3328            }
3329        }
3330
3331        if (meta != NULL)
3332        {
3333            *infoString = strdup(meta);
3334        }
3335        else
3336        {
3337            ffmpeg_printf(1, "no metadata found for \"%s\"\n", *infoString);
3338            *infoString = strdup("not found");
3339        }
3340    }
3341    else
3342    {
3343        ffmpeg_err("avContext NULL\n");
3344        return cERR_CONTAINER_FFMPEG_ERR;
3345    }
3346
3347    return cERR_CONTAINER_FFMPEG_NO_ERROR;
3348}
3349
3350static int32_t Command(void  *_context, ContainerCmd_t command, void *argument)
3351{
3352    Context_t  *context = (Context_t*) _context;
3353    int ret = cERR_CONTAINER_FFMPEG_NO_ERROR;
3354
3355    ffmpeg_printf(50, "Command %d\n", command);
3356
3357    if(command != CONTAINER_SET_BUFFER_SEEK_TIME &&
3358       command != CONTAINER_SET_BUFFER_SIZE &&
3359       command != CONTAINER_GET_BUFFER_SIZE &&
3360       command != CONTAINER_GET_BUFFER_STATUS &&
3361       command != CONTAINER_STOP_BUFFER &&
3362       command != CONTAINER_GET_SUBTEXT &&
3363       command != CONTAINER_INIT && !avContextTab[0])
3364    {
3365        return cERR_CONTAINER_FFMPEG_ERR;
3366    }
3367   
3368   
3369    switch(command)
3370    {
3371    case CONTAINER_INIT:
3372    {
3373        PlayFiles_t *playFilesNames = (PlayFiles_t *)argument;
3374        ret = container_ffmpeg_init(context, playFilesNames);
3375        break;
3376    }
3377    case CONTAINER_PLAY: 
3378    {
3379        ret = container_ffmpeg_play(context);
3380        break;
3381    }
3382    case CONTAINER_STOP:
3383    {
3384        ret = container_ffmpeg_stop(context);
3385        break;
3386    }
3387    case CONTAINER_SEEK:
3388    {
3389        ret = container_ffmpeg_seek(context, (int64_t)*((int64_t*)argument), 0);
3390        break;
3391    }
3392    case CONTAINER_SEEK_ABS:
3393    {
3394        ret = container_ffmpeg_seek(context, (int64_t)*((int64_t*)argument), -1);
3395        break;
3396    }
3397    case CONTAINER_LENGTH:
3398    {
3399        int64_t length = 0;
3400        ret = container_ffmpeg_get_length(context, &length);
3401        *((int64_t*)argument) = (int64_t)length;
3402        break;
3403    }
3404    case CONTAINER_SWITCH_AUDIO:
3405    {
3406        ret = container_ffmpeg_switch_audio(context, (int32_t*) argument);
3407        break;
3408    }
3409    case CONTAINER_SWITCH_SUBTITLE:
3410    {
3411        ret = container_ffmpeg_switch_subtitle(context, (int32_t*) argument);
3412        break;
3413    }
3414    case CONTAINER_INFO:
3415    {
3416        ret = container_ffmpeg_get_info(context, (char **)argument);
3417        break;
3418    }
3419    case CONTAINER_STATUS:
3420    {
3421        *((int32_t*)argument) = hasPlayThreadStarted;
3422        break;
3423    }
3424    case CONTAINER_LAST_PTS:
3425    {
3426        *((int64_t*)argument) = latestPts;
3427        break;
3428    }
3429    //obi
3430    case CONTAINER_SET_BUFFER_SEEK_TIME:
3431    {
3432        ret = container_set_ffmpeg_buf_seek_time((int*) argument);
3433            break;
3434    }
3435    //obi (end)
3436    case CONTAINER_SET_BUFFER_SIZE:
3437    {
3438        ret = container_set_ffmpeg_buf_size((int32_t *) argument);
3439        break;
3440    }
3441    case CONTAINER_GET_BUFFER_SIZE:
3442    {
3443        int32_t size = 0;
3444        ret = container_get_ffmpeg_buf_size(&size);
3445        *((int32_t*)argument) = size;
3446        break;
3447    }
3448    //obi
3449    case CONTAINER_GET_BUFFER_STATUS:
3450    {
3451            int32_t size = 0;
3452            ret = container_get_fillbufstatus(&size);
3453            *((int32_t*)argument) = size;
3454            break;
3455    }
3456    case CONTAINER_STOP_BUFFER:
3457    {
3458            ret = container_stop_buffer();
3459            break;
3460    }
3461    case CONTAINER_GET_SUBTEXT:
3462    {
3463        ret = container_ffmpeg_get_subtext(context, (char **)argument);
3464
3465
3466
3467        break;
3468    }
3469    //obi (end)
3470    default:
3471        ffmpeg_err("ContainerCmd %d not supported!\n", command);
3472        ret = cERR_CONTAINER_FFMPEG_ERR;
3473        break;
3474    }
3475
3476    ffmpeg_printf(50, "exiting with value %d\n", ret);
3477    return ret;
3478}
3479
3480static 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 };
3481
3482Container_t FFMPEGContainer = {
3483    "FFMPEG",
3484    &Command,
3485    FFMPEG_Capabilities
3486};
Note: See TracBrowser for help on using the repository browser.