Merge pull request #4001 from sraue/lirc-devinput
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDCodecs / Video / AMLCodec.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "system.h"
22
23 #include "AMLCodec.h"
24 #include "DynamicDll.h"
25
26 #include "cores/dvdplayer/DVDClock.h"
27 #include "cores/VideoRenderers/RenderManager.h"
28 #include "guilib/GraphicContext.h"
29 #include "settings/MediaSettings.h"
30 #include "settings/Settings.h"
31 #include "utils/AMLUtils.h"
32 #include "utils/log.h"
33 #include "utils/StringUtils.h"
34 #include "utils/TimeUtils.h"
35
36 #if defined(TARGET_ANDROID)
37 #include "android/activity/AndroidFeatures.h"
38 #include "utils/BitstreamConverter.h"
39 #endif
40
41 #include <unistd.h>
42 #include <queue>
43 #include <vector>
44 #include <signal.h>
45 #include <semaphore.h>
46 #include <fcntl.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <sys/ioctl.h>
50
51 // amcodec include
52 extern "C" {
53 #include <amcodec/codec.h>
54 }  // extern "C"
55
56 typedef struct {
57   bool          noblock;
58   int           video_pid;
59   int           video_type;
60   stream_type_t stream_type;
61   unsigned int  format;
62   unsigned int  width;
63   unsigned int  height;
64   unsigned int  rate;
65   unsigned int  extra;
66   unsigned int  status;
67   unsigned int  ratio;
68   unsigned long long ratio64;
69   void *param;
70 } aml_generic_param;
71
72 class DllLibamCodecInterface
73 {
74 public:
75   virtual ~DllLibamCodecInterface() {};
76
77   virtual int codec_init(codec_para_t *pcodec)=0;
78   virtual int codec_close(codec_para_t *pcodec)=0;
79   virtual int codec_reset(codec_para_t *pcodec)=0;
80   virtual int codec_pause(codec_para_t *pcodec)=0;
81   virtual int codec_resume(codec_para_t *pcodec)=0;
82   virtual int codec_write(codec_para_t *pcodec, void *buffer, int len)=0;
83   virtual int codec_checkin_pts(codec_para_t *pcodec, unsigned long pts)=0;
84   virtual int codec_get_vbuf_state(codec_para_t *pcodec, struct buf_status *buf)=0;
85   virtual int codec_get_vdec_state(codec_para_t *pcodec, struct vdec_status *vdec)=0;
86
87   virtual int codec_init_cntl(codec_para_t *pcodec)=0;
88   virtual int codec_poll_cntl(codec_para_t *pcodec)=0;
89   virtual int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode)=0;
90   virtual int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh)=0;
91   virtual int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh)=0;
92
93   // grab these from libamplayer
94   virtual int h263vld(unsigned char *inbuf, unsigned char *outbuf, int inbuf_len, int s263)=0;
95   virtual int decodeble_h263(unsigned char *buf)=0;
96
97   // grab this from amffmpeg so we do not have to load DllAvUtil
98   virtual AVRational av_d2q(double d, int max)=0;
99 };
100
101 class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
102 {
103   // libamcodec is static linked into libamplayer.so
104   DECLARE_DLL_WRAPPER(DllLibAmCodec, "libamplayer.so")
105
106   DEFINE_METHOD1(int, codec_init,               (codec_para_t *p1))
107   DEFINE_METHOD1(int, codec_close,              (codec_para_t *p1))
108   DEFINE_METHOD1(int, codec_reset,              (codec_para_t *p1))
109   DEFINE_METHOD1(int, codec_pause,              (codec_para_t *p1))
110   DEFINE_METHOD1(int, codec_resume,             (codec_para_t *p1))
111   DEFINE_METHOD3(int, codec_write,              (codec_para_t *p1, void *p2, int p3))
112   DEFINE_METHOD2(int, codec_checkin_pts,        (codec_para_t *p1, unsigned long p2))
113   DEFINE_METHOD2(int, codec_get_vbuf_state,     (codec_para_t *p1, struct buf_status * p2))
114   DEFINE_METHOD2(int, codec_get_vdec_state,     (codec_para_t *p1, struct vdec_status * p2))
115
116   DEFINE_METHOD1(int, codec_init_cntl,          (codec_para_t *p1))
117   DEFINE_METHOD1(int, codec_poll_cntl,          (codec_para_t *p1))
118   DEFINE_METHOD2(int, codec_set_cntl_mode,      (codec_para_t *p1, unsigned int p2))
119   DEFINE_METHOD2(int, codec_set_cntl_avthresh,  (codec_para_t *p1, unsigned int p2))
120   DEFINE_METHOD2(int, codec_set_cntl_syncthresh,(codec_para_t *p1, unsigned int p2))
121
122   DEFINE_METHOD4(int, h263vld,                  (unsigned char *p1, unsigned char *p2, int p3, int p4))
123   DEFINE_METHOD1(int, decodeble_h263,           (unsigned char *p1))
124
125   DEFINE_METHOD2(AVRational, av_d2q,            (double p1, int p2))
126
127   BEGIN_METHOD_RESOLVE()
128     RESOLVE_METHOD(codec_init)
129     RESOLVE_METHOD(codec_close)
130     RESOLVE_METHOD(codec_reset)
131     RESOLVE_METHOD(codec_pause)
132     RESOLVE_METHOD(codec_resume)
133     RESOLVE_METHOD(codec_write)
134     RESOLVE_METHOD(codec_checkin_pts)
135     RESOLVE_METHOD(codec_get_vbuf_state)
136     RESOLVE_METHOD(codec_get_vdec_state)
137
138     RESOLVE_METHOD(codec_init_cntl)
139     RESOLVE_METHOD(codec_poll_cntl)
140     RESOLVE_METHOD(codec_set_cntl_mode)
141     RESOLVE_METHOD(codec_set_cntl_avthresh)
142     RESOLVE_METHOD(codec_set_cntl_syncthresh)
143
144     RESOLVE_METHOD(h263vld)
145     RESOLVE_METHOD(decodeble_h263)
146
147     RESOLVE_METHOD(av_d2q)
148   END_METHOD_RESOLVE()
149
150 public:
151   void codec_init_para(aml_generic_param *p_in, codec_para_t *p_out)
152   {
153     memset(p_out, 0x00, sizeof(codec_para_t));
154
155 #ifdef TARGET_ANDROID
156     bits_writer_t bs = {0};
157
158     // we are always as large as codec_para_t from headers.
159     CBitstreamConverter::init_bits_writer(&bs, (uint8_t*)p_out, sizeof(codec_para_t), 1);
160
161     // order matters, so pay attention
162     // to codec_para_t in codec_types.h
163     CBitstreamConverter::write_bits(&bs, 32, 0);                   // CODEC_HANDLE handle
164     CBitstreamConverter::write_bits(&bs, 32, 0);                   // CODEC_HANDLE cntl_handle
165     CBitstreamConverter::write_bits(&bs, 32, 0);                   // CODEC_HANDLE sub_handle
166
167     // added in JellyBean 4.2
168     if (CAndroidFeatures::GetVersion() > 16)
169       CBitstreamConverter::write_bits(&bs, 32, 0);                 // CODEC_HANDLE audio_utils_handle
170
171     CBitstreamConverter::write_bits(&bs, 32, p_in->stream_type);   // stream_type_t stream_type
172
173     // watch these, using bit fields (which is stupid)
174     CBitstreamConverter::write_bits(&bs,  1, 1);                   // unsigned int has_video:1
175     CBitstreamConverter::write_bits(&bs,  1, 0);                   // unsigned int has_audio:1
176     CBitstreamConverter::write_bits(&bs,  1, 0);                   // unsigned int has_sub:1
177     unsigned int value =  p_in->noblock > 0 ? 1:0;
178     CBitstreamConverter::write_bits(&bs,  1, value);               // unsigned int noblock:1
179     CBitstreamConverter::write_bits(&bs, 28, 0);                   // align back to next word boundary
180
181     CBitstreamConverter::write_bits(&bs, 32, p_in->video_type);    // int video_type
182     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int audio_type
183     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int sub_type
184
185     CBitstreamConverter::write_bits(&bs, 32, p_in->video_pid);     // int video_pid
186     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int audio_pid
187     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int sub_pid
188
189     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int audio_channels
190     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int audio_samplerate
191     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int vbuf_size
192     CBitstreamConverter::write_bits(&bs, 32, 0);                   // int abuf_size
193
194     // ARM requires 8-byte alignment for 64-bit members (ratio64)
195     // and this will force am_sysinfo to be also have 8-byte alignment.
196     // Since the inclusion of audio_utils_handle for JellyBean 4.2
197     // 'naturally' aligns am_sysinfo to 8-byte, we need to compensate
198     // when we are NOT JellyBean 4.2. If these member values get changed,
199     // then make sure you check that am_sysinfo has 8-byte alignment.
200     if (CAndroidFeatures::GetVersion() < 17)
201       CBitstreamConverter::write_bits(&bs, 32, 0);
202
203     CBitstreamConverter::write_bits(&bs, 32, p_in->format);        // am_sysinfo, unsigned int format
204     CBitstreamConverter::write_bits(&bs, 32, p_in->width);         // am_sysinfo, unsigned int width
205     CBitstreamConverter::write_bits(&bs, 32, p_in->height);        // am_sysinfo, unsigned int height
206     CBitstreamConverter::write_bits(&bs, 32, p_in->rate);          // am_sysinfo, unsigned int rate
207     CBitstreamConverter::write_bits(&bs, 32, p_in->extra);         // am_sysinfo, unsigned int extra
208     CBitstreamConverter::write_bits(&bs, 32, p_in->status);        // am_sysinfo, unsigned int status
209     CBitstreamConverter::write_bits(&bs, 32, p_in->ratio);         // am_sysinfo, unsigned int ratio
210     CBitstreamConverter::write_bits(&bs, 32, (unsigned int)p_in->param); // am_sysinfo, unsigned int param
211     unsigned int lo = 0x00000000ffffffff & p_in->ratio64;
212     unsigned int hi = p_in->ratio64 >> 32;
213     CBitstreamConverter::write_bits(&bs, 32, lo);                  // am_sysinfo, unsigned long long ratio64
214     CBitstreamConverter::write_bits(&bs, 32, hi);                  // am_sysinfo, unsigned long long ratio64
215
216     // we do not care about the rest, flush and go.
217     // FYI there are 4.0 to 4.1 differences here.
218     CBitstreamConverter::flush_bits(&bs);
219     //CLog::MemDump((char*)p_out, 0xFF);
220 #else
221     // direct struct usage, we do not know which flavor
222     // so just use what we get from headers and pray.
223     p_out->has_video          = 1;
224     p_out->noblock            = p_in->noblock;
225     p_out->video_pid          = p_in->video_pid;
226     p_out->video_type         = p_in->video_type;
227     p_out->stream_type        = p_in->stream_type;
228     p_out->am_sysinfo.format  = p_in->format;
229     p_out->am_sysinfo.width   = p_in->width;
230     p_out->am_sysinfo.height  = p_in->height;
231     p_out->am_sysinfo.rate    = p_in->rate;
232     p_out->am_sysinfo.extra   = p_in->extra;
233     p_out->am_sysinfo.status  = p_in->status;
234     p_out->am_sysinfo.ratio   = p_in->ratio;
235     p_out->am_sysinfo.ratio64 = p_in->ratio64;
236     p_out->am_sysinfo.param   = p_in->param;
237 #endif
238   }
239 };
240
241 //-----------------------------------------------------------------------------------
242 //-----------------------------------------------------------------------------------
243 // AppContext - Application state
244 #define PTS_FREQ        90000
245 #define UNIT_FREQ       96000
246 #define AV_SYNC_THRESH  PTS_FREQ*30
247
248 #define TRICKMODE_NONE  0x00
249 #define TRICKMODE_I     0x01
250 #define TRICKMODE_FFFB  0x02
251
252 // same as AV_NOPTS_VALUE
253 #define INT64_0         INT64_C(0x8000000000000000)
254
255 #define EXTERNAL_PTS    (1)
256 #define SYNC_OUTSIDE    (2)
257
258 // missing tags
259 #define CODEC_TAG_VC_1  (0x312D4356)
260 #define CODEC_TAG_RV30  (0x30335652)
261 #define CODEC_TAG_RV40  (0x30345652)
262 #define CODEC_TAG_MJPEG (0x47504a4d)
263 #define CODEC_TAG_mjpeg (0x47504a4c)
264 #define CODEC_TAG_jpeg  (0x6765706a)
265 #define CODEC_TAG_mjpa  (0x61706a6d)
266
267 #define RW_WAIT_TIME    (20 * 1000) // 20ms
268
269 #define P_PRE           (0x02000000)
270 #define F_PRE           (0x03000000)
271 #define PLAYER_SUCCESS          (0)
272 #define PLAYER_FAILED           (-(P_PRE|0x01))
273 #define PLAYER_NOMEM            (-(P_PRE|0x02))
274 #define PLAYER_EMPTY_P          (-(P_PRE|0x03))
275
276 #define PLAYER_WR_FAILED        (-(P_PRE|0x21))
277 #define PLAYER_WR_EMPTYP        (-(P_PRE|0x22))
278 #define PLAYER_WR_FINISH        (P_PRE|0x1)
279
280 #define PLAYER_PTS_ERROR        (-(P_PRE|0x31))
281 #define PLAYER_UNSUPPORT        (-(P_PRE|0x35))
282 #define PLAYER_CHECK_CODEC_ERROR  (-(P_PRE|0x39))
283
284 #define HDR_BUF_SIZE 1024
285 typedef struct hdr_buf {
286     char *data;
287     int size;
288 } hdr_buf_t;
289
290 typedef struct am_packet {
291     AVPacket      avpkt;
292     int64_t       avpts;
293     int64_t       avdts;
294     int           avduration;
295     int           isvalid;
296     int           newflag;
297     int64_t       lastpts;
298     unsigned char *data;
299     unsigned char *buf;
300     int           data_size;
301     int           buf_size;
302     hdr_buf_t     *hdr;
303     codec_para_t  *codec;
304 } am_packet_t;
305
306 typedef enum {
307     AM_STREAM_UNKNOWN = 0,
308     AM_STREAM_TS,
309     AM_STREAM_PS,
310     AM_STREAM_ES,
311     AM_STREAM_RM,
312     AM_STREAM_AUDIO,
313     AM_STREAM_VIDEO,
314 } pstream_type;
315
316 typedef struct am_private_t
317 {
318   am_packet_t       am_pkt;
319   aml_generic_param gcodec;
320   codec_para_t      vcodec;
321
322   pstream_type      stream_type;
323   int               check_first_pts;
324
325   vformat_t         video_format;
326   int               video_pid;
327   unsigned int      video_codec_id;
328   unsigned int      video_codec_tag;
329   vdec_type_t       video_codec_type;
330   unsigned int      video_width;
331   unsigned int      video_height;
332   unsigned int      video_ratio;
333   unsigned int      video_ratio64;
334   unsigned int      video_rate;
335   unsigned int      video_rotation_degree;
336   int               flv_flag;
337   int               h263_decodable;
338   int               extrasize;
339   uint8_t           *extradata;
340   DllLibAmCodec     *m_dll;
341
342   int               dumpfile;
343   bool              dumpdemux;
344 } am_private_t;
345
346 /*************************************************************************/
347 /*************************************************************************/
348 void dumpfile_open(am_private_t *para)
349 {
350   if (para->dumpdemux)
351   {
352     static int amcodec_dumpid = 0;
353     char dump_path[128] = {0};
354     sprintf(dump_path, "/temp/dump_amcodec-%d.dat", amcodec_dumpid++);
355
356     para->dumpfile = open(dump_path, O_CREAT | O_RDWR, 0666);
357   }
358 }
359 void dumpfile_close(am_private_t *para)
360 {
361   if (para->dumpdemux && para->dumpfile != -1)
362     close(para->dumpfile), para->dumpfile = -1;
363 }
364 void dumpfile_write(am_private_t *para, void* buf, int bufsiz)
365 {
366   if (!buf)
367   {
368     CLog::Log(LOGERROR, "dumpfile_write: wtf ? buf is null, bufsiz(%d)", bufsiz);
369     return;
370   }
371
372   if (para->dumpdemux && para->dumpfile != -1)
373     write(para->dumpfile, buf, bufsiz);
374 }
375
376 /*************************************************************************/
377 /*************************************************************************/
378 static int64_t get_pts_video()
379 {
380   int fd = open("/sys/class/tsync/pts_video", O_RDONLY);
381   if (fd >= 0)
382   {
383     char pts_str[16];
384     int size = read(fd, pts_str, sizeof(pts_str));
385     close(fd);
386     if (size > 0)
387     {
388       unsigned long pts = strtoul(pts_str, NULL, 16);
389       return pts;
390     }
391   }
392
393   CLog::Log(LOGERROR, "get_pts_video: open /tsync/event error");
394   return -1;
395 }
396
397 static int set_pts_pcrscr(int64_t value)
398 {
399   int fd = open("/sys/class/tsync/pts_pcrscr", O_WRONLY);
400   if (fd >= 0)
401   {
402     char pts_str[64];
403     unsigned long pts = (unsigned long)value;
404     sprintf(pts_str, "0x%lx", pts);
405     write(fd, pts_str, strlen(pts_str));
406     close(fd);
407     return 0;
408   }
409
410   CLog::Log(LOGERROR, "set_pts_pcrscr: open pts_pcrscr error");
411   return -1;
412 }
413
414 static vformat_t codecid_to_vformat(enum AVCodecID id)
415 {
416   vformat_t format;
417   switch (id)
418   {
419     case AV_CODEC_ID_MPEG1VIDEO:
420     case AV_CODEC_ID_MPEG2VIDEO:
421     case AV_CODEC_ID_MPEG2VIDEO_XVMC:
422       format = VFORMAT_MPEG12;
423       break;
424     case AV_CODEC_ID_H263:
425     case AV_CODEC_ID_MPEG4:
426     case AV_CODEC_ID_H263P:
427     case AV_CODEC_ID_H263I:
428     case AV_CODEC_ID_MSMPEG4V2:
429     case AV_CODEC_ID_MSMPEG4V3:
430     case AV_CODEC_ID_FLV1:
431       format = VFORMAT_MPEG4;
432       break;
433     case AV_CODEC_ID_RV10:
434     case AV_CODEC_ID_RV20:
435     case AV_CODEC_ID_RV30:
436     case AV_CODEC_ID_RV40:
437       format = VFORMAT_REAL;
438       break;
439     case AV_CODEC_ID_H264:
440       format = VFORMAT_H264;
441       break;
442     /*
443     case AV_CODEC_ID_H264MVC:
444       // H264 Multiview Video Coding (3d blurays)
445       format = VFORMAT_H264MVC;
446       break;
447     */
448     case AV_CODEC_ID_MJPEG:
449       format = VFORMAT_MJPEG;
450       break;
451     case AV_CODEC_ID_VC1:
452     case AV_CODEC_ID_WMV3:
453       format = VFORMAT_VC1;
454       break;
455     case AV_CODEC_ID_AVS:
456     case AV_CODEC_ID_CAVS:
457       format = VFORMAT_AVS;
458       break;
459
460     default:
461       format = VFORMAT_UNSUPPORT;
462       break;
463   }
464
465   CLog::Log(LOGDEBUG, "codecid_to_vformat, id(%d) -> vformat(%d)", (int)id, format);
466   return format;
467 }
468
469 static vdec_type_t codec_tag_to_vdec_type(unsigned int codec_tag)
470 {
471   vdec_type_t dec_type;
472   switch (codec_tag)
473   {
474     case CODEC_TAG_MJPEG:
475     case CODEC_TAG_mjpeg:
476     case CODEC_TAG_jpeg:
477     case CODEC_TAG_mjpa:
478       // mjpeg
479       dec_type = VIDEO_DEC_FORMAT_MJPEG;
480       break;
481     case CODEC_TAG_XVID:
482     case CODEC_TAG_xvid:
483     case CODEC_TAG_XVIX:
484       // xvid
485       dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
486       break;
487     case CODEC_TAG_COL1:
488     case CODEC_TAG_DIV3:
489     case CODEC_TAG_MP43:
490       // divx3.11
491       dec_type = VIDEO_DEC_FORMAT_MPEG4_3;
492       break;
493     case CODEC_TAG_DIV4:
494     case CODEC_TAG_DIVX:
495       // divx4
496       dec_type = VIDEO_DEC_FORMAT_MPEG4_4;
497       break;
498     case CODEC_TAG_DIV5:
499     case CODEC_TAG_DX50:
500     case CODEC_TAG_M4S2:
501     case CODEC_TAG_FMP4:
502       // divx5
503       dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
504       break;
505     case CODEC_TAG_DIV6:
506       // divx6
507       dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
508       break;
509     case CODEC_TAG_MP4V:
510     case CODEC_TAG_RMP4:
511     case CODEC_TAG_MPG4:
512     case CODEC_TAG_mp4v:
513     case AV_CODEC_ID_MPEG4:
514       // mp4
515       dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
516       break;
517     case AV_CODEC_ID_H263:
518     case CODEC_TAG_H263:
519     case CODEC_TAG_h263:
520     case CODEC_TAG_s263:
521     case CODEC_TAG_F263:
522       // h263
523       dec_type = VIDEO_DEC_FORMAT_H263;
524       break;
525     case CODEC_TAG_AVC1:
526     case CODEC_TAG_avc1:
527     case CODEC_TAG_H264:
528     case CODEC_TAG_h264:
529     case AV_CODEC_ID_H264:
530       // h264
531       dec_type = VIDEO_DEC_FORMAT_H264;
532       break;
533     /*
534     case AV_CODEC_ID_H264MVC:
535       dec_type = VIDEO_DEC_FORMAT_H264;
536       break;
537     */
538     case AV_CODEC_ID_RV30:
539     case CODEC_TAG_RV30:
540       // realmedia 3
541       dec_type = VIDEO_DEC_FORMAT_REAL_8;
542       break;
543     case AV_CODEC_ID_RV40:
544     case CODEC_TAG_RV40:
545       // realmedia 4
546       dec_type = VIDEO_DEC_FORMAT_REAL_9;
547       break;
548     case CODEC_TAG_WMV3:
549       // wmv3
550       dec_type = VIDEO_DEC_FORMAT_WMV3;
551       break;
552     case AV_CODEC_ID_VC1:
553     case CODEC_TAG_VC_1:
554     case CODEC_TAG_WVC1:
555     case CODEC_TAG_WMVA:
556       // vc1
557       dec_type = VIDEO_DEC_FORMAT_WVC1;
558       break;
559     case AV_CODEC_ID_VP6F:
560       // vp6
561       dec_type = VIDEO_DEC_FORMAT_SW;
562       break;
563     case AV_CODEC_ID_CAVS:
564     case AV_CODEC_ID_AVS:
565       // avs
566       dec_type = VIDEO_DEC_FORMAT_AVS;
567       break;
568     default:
569       dec_type = VIDEO_DEC_FORMAT_UNKNOW;
570       break;
571   }
572
573   CLog::Log(LOGDEBUG, "codec_tag_to_vdec_type, codec_tag(%d) -> vdec_type(%d)", codec_tag, dec_type);
574   return dec_type;
575 }
576
577 static void am_packet_init(am_packet_t *pkt)
578 {
579   memset(&pkt->avpkt, 0, sizeof(AVPacket));
580   pkt->avpts      = 0;
581   pkt->avdts      = 0;
582   pkt->avduration = 0;
583   pkt->isvalid    = 0;
584   pkt->newflag    = 0;
585   pkt->lastpts    = 0;
586   pkt->data       = NULL;
587   pkt->buf        = NULL;
588   pkt->data_size  = 0;
589   pkt->buf_size   = 0;
590   pkt->hdr        = NULL;
591   pkt->codec      = NULL;
592 }
593
594 void am_packet_release(am_packet_t *pkt)
595 {
596   if (pkt->buf != NULL)
597     free(pkt->buf), pkt->buf= NULL;
598   if (pkt->hdr != NULL)
599   {
600     if (pkt->hdr->data != NULL)
601       free(pkt->hdr->data), pkt->hdr->data = NULL;
602     free(pkt->hdr), pkt->hdr = NULL;
603   }
604
605   pkt->codec = NULL;
606 }
607
608 int check_in_pts(am_private_t *para, am_packet_t *pkt)
609 {
610     int last_duration = 0;
611     static int last_v_duration = 0;
612     int64_t pts = 0;
613
614     last_duration = last_v_duration;
615
616     if (para->stream_type == AM_STREAM_ES) {
617         if ((int64_t)INT64_0 != pkt->avpts) {
618             pts = pkt->avpts;
619
620             if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
621                 CLog::Log(LOGDEBUG, "ERROR check in pts error!");
622                 return PLAYER_PTS_ERROR;
623             }
624
625         } else if ((int64_t)INT64_0 != pkt->avdts) {
626             pts = pkt->avdts * last_duration;
627
628             if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
629                 CLog::Log(LOGDEBUG, "ERROR check in dts error!");
630                 return PLAYER_PTS_ERROR;
631             }
632
633             last_v_duration = pkt->avduration ? pkt->avduration : 1;
634         } else {
635             if (!para->check_first_pts) {
636                 if (para->m_dll->codec_checkin_pts(pkt->codec, 0) != 0) {
637                     CLog::Log(LOGDEBUG, "ERROR check in 0 to video pts error!");
638                     return PLAYER_PTS_ERROR;
639                 }
640             }
641         }
642         if (!para->check_first_pts) {
643             para->check_first_pts = 1;
644         }
645     }
646     if (pts > 0)
647       pkt->lastpts = pts;
648
649     return PLAYER_SUCCESS;
650 }
651
652 static int write_header(am_private_t *para, am_packet_t *pkt)
653 {
654     int write_bytes = 0, len = 0;
655
656     if (pkt->hdr && pkt->hdr->size > 0) {
657         if ((NULL == pkt->codec) || (NULL == pkt->hdr->data)) {
658             CLog::Log(LOGDEBUG, "[write_header]codec null!");
659             return PLAYER_EMPTY_P;
660         }
661         //some wvc1 es data not need to add header
662         if (para->video_format == VFORMAT_VC1 && para->video_codec_type == VIDEO_DEC_FORMAT_WVC1) {
663             if ((pkt->data) && (pkt->data_size >= 4)
664               && (pkt->data[0] == 0) && (pkt->data[1] == 0)
665               && (pkt->data[2] == 1) && (pkt->data[3] == 0xd || pkt->data[3] == 0xf)) {
666                 return PLAYER_SUCCESS;
667             }
668         }
669         while (1) {
670             write_bytes = para->m_dll->codec_write(pkt->codec, pkt->hdr->data + len, pkt->hdr->size - len);
671             if (write_bytes < 0 || write_bytes > (pkt->hdr->size - len)) {
672                 if (-errno != AVERROR(EAGAIN)) {
673                     CLog::Log(LOGDEBUG, "ERROR:write header failed!");
674                     return PLAYER_WR_FAILED;
675                 } else {
676                     continue;
677                 }
678             } else {
679                 dumpfile_write(para, pkt->hdr->data, write_bytes);
680                 len += write_bytes;
681                 if (len == pkt->hdr->size) {
682                     break;
683                 }
684             }
685         }
686     }
687     return PLAYER_SUCCESS;
688 }
689
690 int check_avbuffer_enough(am_private_t *para, am_packet_t *pkt)
691 {
692     return 1;
693 }
694
695 int write_av_packet(am_private_t *para, am_packet_t *pkt)
696 {
697   //CLog::Log(LOGDEBUG, "write_av_packet, pkt->isvalid(%d), pkt->data(%p), pkt->data_size(%d)",
698   //  pkt->isvalid, pkt->data, pkt->data_size);
699
700     int write_bytes = 0, len = 0, ret;
701     unsigned char *buf;
702     int size;
703
704     // do we need to check in pts or write the header ?
705     if (pkt->newflag) {
706         if (pkt->isvalid) {
707             ret = check_in_pts(para, pkt);
708             if (ret != PLAYER_SUCCESS) {
709                 CLog::Log(LOGDEBUG, "check in pts failed");
710                 return PLAYER_WR_FAILED;
711             }
712         }
713         if (write_header(para, pkt) == PLAYER_WR_FAILED) {
714             CLog::Log(LOGDEBUG, "[%s]write header failed!", __FUNCTION__);
715             return PLAYER_WR_FAILED;
716         }
717         pkt->newflag = 0;
718     }
719         
720     buf = pkt->data;
721     size = pkt->data_size ;
722     if (size == 0 && pkt->isvalid) {
723         pkt->isvalid = 0;
724         pkt->data_size = 0;
725     }
726
727     while (size > 0 && pkt->isvalid) {
728         write_bytes = para->m_dll->codec_write(pkt->codec, buf, size);
729         if (write_bytes < 0 || write_bytes > size) {
730             CLog::Log(LOGDEBUG, "write codec data failed, write_bytes(%d), errno(%d), size(%d)", write_bytes, errno, size);
731             if (-errno != AVERROR(EAGAIN)) {
732                 CLog::Log(LOGDEBUG, "write codec data failed!");
733                 return PLAYER_WR_FAILED;
734             } else {
735                 // adjust for any data we already wrote into codec.
736                 // we sleep a bit then exit as we will get called again
737                 // with the same pkt because pkt->isvalid has not been cleared.
738                 pkt->data += len;
739                 pkt->data_size -= len;
740                 usleep(RW_WAIT_TIME);
741                 CLog::Log(LOGDEBUG, "usleep(RW_WAIT_TIME), len(%d)", len);
742                 return PLAYER_SUCCESS;
743             }
744         } else {
745             dumpfile_write(para, buf, write_bytes);
746             // keep track of what we write into codec from this pkt
747             // in case we get hit with EAGAIN.
748             len += write_bytes;
749             if (len == pkt->data_size) {
750                 pkt->isvalid = 0;
751                 pkt->data_size = 0;
752                 break;
753             } else if (len < pkt->data_size) {
754                 buf += write_bytes;
755                 size -= write_bytes;
756             } else {
757                 // writing more that we should is a failure.
758                 return PLAYER_WR_FAILED;
759             }
760         }
761     }
762
763     return PLAYER_SUCCESS;
764 }
765
766 /*************************************************************************/
767 static int m4s2_dx50_mp4v_add_header(unsigned char *buf, int size,  am_packet_t *pkt)
768 {
769     if (size > pkt->hdr->size) {
770         free(pkt->hdr->data), pkt->hdr->data = NULL;
771         pkt->hdr->size = 0;
772
773         pkt->hdr->data = (char*)malloc(size);
774         if (!pkt->hdr->data) {
775             CLog::Log(LOGDEBUG, "[m4s2_dx50_add_header] NOMEM!");
776             return PLAYER_FAILED;
777         }
778     }
779
780     pkt->hdr->size = size;
781     memcpy(pkt->hdr->data, buf, size);
782
783     return PLAYER_SUCCESS;
784 }
785
786 static int m4s2_dx50_mp4v_write_header(am_private_t *para, am_packet_t *pkt)
787 {
788     CLog::Log(LOGDEBUG, "m4s2_dx50_mp4v_write_header");
789     int ret = m4s2_dx50_mp4v_add_header(para->extradata, para->extrasize, pkt);
790     if (ret == PLAYER_SUCCESS) {
791         if (1) {
792             pkt->codec = &para->vcodec;
793         } else {
794             CLog::Log(LOGDEBUG, "[m4s2_dx50_mp4v_add_header]invalid video codec!");
795             return PLAYER_EMPTY_P;
796         }
797         pkt->newflag = 1;
798         ret = write_av_packet(para, pkt);
799     }
800     return ret;
801 }
802
803 static int mjpeg_data_prefeeding(am_packet_t *pkt)
804 {
805     const unsigned char mjpeg_addon_data[] = {
806         0xff, 0xd8, 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
807         0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
808         0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01,
809         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
810         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10,
811         0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
812         0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31,
813         0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1,
814         0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
815         0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29,
816         0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
817         0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
818         0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
819         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
820         0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
821         0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4,
822         0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
823         0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
824         0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02, 0x01,
825         0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
826         0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
827         0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
828         0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,
829         0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a,
830         0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
831         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
832         0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82,
833         0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
834         0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
835         0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
836         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
837         0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
838         0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
839     };
840
841     if (pkt->hdr->data) {
842         memcpy(pkt->hdr->data, &mjpeg_addon_data, sizeof(mjpeg_addon_data));
843         pkt->hdr->size = sizeof(mjpeg_addon_data);
844     } else {
845         CLog::Log(LOGDEBUG, "[mjpeg_data_prefeeding]No enough memory!");
846         return PLAYER_FAILED;
847     }
848     return PLAYER_SUCCESS;
849 }
850
851 static int mjpeg_write_header(am_private_t *para, am_packet_t *pkt)
852 {
853     mjpeg_data_prefeeding(pkt);
854     if (1) {
855         pkt->codec = &para->vcodec;
856     } else {
857         CLog::Log(LOGDEBUG, "[mjpeg_write_header]invalid codec!");
858         return PLAYER_EMPTY_P;
859     }
860     pkt->newflag = 1;
861     write_av_packet(para, pkt);
862     return PLAYER_SUCCESS;
863 }
864
865 static int divx3_data_prefeeding(am_packet_t *pkt, unsigned w, unsigned h)
866 {
867     unsigned i = (w << 12) | (h & 0xfff);
868     unsigned char divx311_add[10] = {
869         0x00, 0x00, 0x00, 0x01,
870         0x20, 0x00, 0x00, 0x00,
871         0x00, 0x00
872     };
873     divx311_add[5] = (i >> 16) & 0xff;
874     divx311_add[6] = (i >> 8) & 0xff;
875     divx311_add[7] = i & 0xff;
876
877     if (pkt->hdr->data) {
878         memcpy(pkt->hdr->data, divx311_add, sizeof(divx311_add));
879         pkt->hdr->size = sizeof(divx311_add);
880     } else {
881         CLog::Log(LOGDEBUG, "[divx3_data_prefeeding]No enough memory!");
882         return PLAYER_FAILED;
883     }
884     return PLAYER_SUCCESS;
885 }
886
887 static int divx3_write_header(am_private_t *para, am_packet_t *pkt)
888 {
889     CLog::Log(LOGDEBUG, "divx3_write_header");
890     divx3_data_prefeeding(pkt, para->video_width, para->video_height);
891     if (1) {
892         pkt->codec = &para->vcodec;
893     } else {
894         CLog::Log(LOGDEBUG, "[divx3_write_header]invalid codec!");
895         return PLAYER_EMPTY_P;
896     }
897     pkt->newflag = 1;
898     write_av_packet(para, pkt);
899     return PLAYER_SUCCESS;
900 }
901
902 static int h264_add_header(unsigned char *buf, int size, am_packet_t *pkt)
903 {
904     // h264 annex-b
905           if ((buf[0]==0 && buf[1]==0 && buf[2]==0 && buf[3]==1) && size < HDR_BUF_SIZE) {
906         CLog::Log(LOGDEBUG, "add four byte NAL 264 header in stream before header len=%d",size);
907         memcpy(pkt->hdr->data, buf, size);
908         pkt->hdr->size = size;
909         return PLAYER_SUCCESS;
910     }
911
912     if ((buf[0]==0 && buf[1]==0 && buf[2]==1) && size < HDR_BUF_SIZE) {
913         CLog::Log(LOGDEBUG, "add three byte NAL 264 header in stream before header len=%d",size);
914         memcpy(pkt->hdr->data, buf, size);
915         pkt->hdr->size = size;
916         return PLAYER_SUCCESS;
917     }
918
919     return PLAYER_FAILED;
920 }
921 static int h264_write_header(am_private_t *para, am_packet_t *pkt)
922 {
923     // CLog::Log(LOGDEBUG, "h264_write_header");
924     int ret = -1;
925
926     ret = h264_add_header(para->extradata, para->extrasize, pkt);
927     if (ret == PLAYER_SUCCESS) {
928         //if (ctx->vcodec) {
929         if (1) {
930             pkt->codec = &para->vcodec;
931         } else {
932             //CLog::Log(LOGDEBUG, "[pre_header_feeding]invalid video codec!");
933             return PLAYER_EMPTY_P;
934         }
935
936         pkt->newflag = 1;
937         ret = write_av_packet(para, pkt);
938     }
939     return ret;
940 }
941
942 static int wmv3_write_header(am_private_t *para, am_packet_t *pkt)
943 {
944     CLog::Log(LOGDEBUG, "wmv3_write_header");
945     unsigned i, check_sum = 0;
946     unsigned data_len = para->extrasize + 4;
947
948     pkt->hdr->data[0] = 0;
949     pkt->hdr->data[1] = 0;
950     pkt->hdr->data[2] = 1;
951     pkt->hdr->data[3] = 0x10;
952
953     pkt->hdr->data[4] = 0;
954     pkt->hdr->data[5] = (data_len >> 16) & 0xff;
955     pkt->hdr->data[6] = 0x88;
956     pkt->hdr->data[7] = (data_len >> 8) & 0xff;
957     pkt->hdr->data[8] = data_len & 0xff;
958     pkt->hdr->data[9] = 0x88;
959
960     pkt->hdr->data[10] = 0xff;
961     pkt->hdr->data[11] = 0xff;
962     pkt->hdr->data[12] = 0x88;
963     pkt->hdr->data[13] = 0xff;
964     pkt->hdr->data[14] = 0xff;
965     pkt->hdr->data[15] = 0x88;
966
967     for (i = 4 ; i < 16 ; i++) {
968         check_sum += pkt->hdr->data[i];
969     }
970
971     pkt->hdr->data[16] = (check_sum >> 8) & 0xff;
972     pkt->hdr->data[17] =  check_sum & 0xff;
973     pkt->hdr->data[18] = 0x88;
974     pkt->hdr->data[19] = (check_sum >> 8) & 0xff;
975     pkt->hdr->data[20] =  check_sum & 0xff;
976     pkt->hdr->data[21] = 0x88;
977
978     pkt->hdr->data[22] = (para->video_width >> 8) & 0xff;
979     pkt->hdr->data[23] =  para->video_width & 0xff;
980     pkt->hdr->data[24] = (para->video_height >> 8) & 0xff;
981     pkt->hdr->data[25] =  para->video_height & 0xff;
982
983     memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
984     pkt->hdr->size = para->extrasize + 26;
985     if (1) {
986         pkt->codec = &para->vcodec;
987     } else {
988         CLog::Log(LOGDEBUG, "[wmv3_write_header]invalid codec!");
989         return PLAYER_EMPTY_P;
990     }
991     pkt->newflag = 1;
992     return write_av_packet(para, pkt);
993 }
994
995 static int wvc1_write_header(am_private_t *para, am_packet_t *pkt)
996 {
997     CLog::Log(LOGDEBUG, "wvc1_write_header");
998     memcpy(pkt->hdr->data, para->extradata + 1, para->extrasize - 1);
999     pkt->hdr->size = para->extrasize - 1;
1000     if (1) {
1001         pkt->codec = &para->vcodec;
1002     } else {
1003         CLog::Log(LOGDEBUG, "[wvc1_write_header]invalid codec!");
1004         return PLAYER_EMPTY_P;
1005     }
1006     pkt->newflag = 1;
1007     return write_av_packet(para, pkt);
1008 }
1009
1010 static int mpeg_add_header(am_private_t *para, am_packet_t *pkt)
1011 {
1012     CLog::Log(LOGDEBUG, "mpeg_add_header");
1013 #define STUFF_BYTES_LENGTH     (256)
1014     int size;
1015     unsigned char packet_wrapper[] = {
1016         0x00, 0x00, 0x01, 0xe0,
1017         0x00, 0x00,                                /* pes packet length */
1018         0x81, 0xc0, 0x0d,
1019         0x20, 0x00, 0x00, 0x00, 0x00, /* PTS */
1020         0x1f, 0xff, 0xff, 0xff, 0xff, /* DTS */
1021         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1022     };
1023
1024     size = para->extrasize + sizeof(packet_wrapper);
1025     packet_wrapper[4] = size >> 8 ;
1026     packet_wrapper[5] = size & 0xff ;
1027     memcpy(pkt->hdr->data, packet_wrapper, sizeof(packet_wrapper));
1028     size = sizeof(packet_wrapper);
1029     //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]wrapper size=%d\n",__LINE__,size);
1030     memcpy(pkt->hdr->data + size, para->extradata, para->extrasize);
1031     size += para->extrasize;
1032     //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]wrapper+seq size=%d\n",__LINE__,size);
1033     memset(pkt->hdr->data + size, 0xff, STUFF_BYTES_LENGTH);
1034     size += STUFF_BYTES_LENGTH;
1035     pkt->hdr->size = size;
1036     //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]hdr_size=%d\n",__LINE__,size);
1037     if (1) {
1038         pkt->codec = &para->vcodec;
1039     } else {
1040         CLog::Log(LOGDEBUG, "[mpeg_add_header]invalid codec!");
1041         return PLAYER_EMPTY_P;
1042     }
1043
1044     pkt->newflag = 1;
1045     return write_av_packet(para, pkt);
1046 }
1047
1048 int pre_header_feeding(am_private_t *para, am_packet_t *pkt)
1049 {
1050     int ret;
1051     if (para->stream_type == AM_STREAM_ES) {
1052         if (pkt->hdr == NULL) {
1053             pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1054             pkt->hdr->data = (char *)malloc(HDR_BUF_SIZE);
1055             if (!pkt->hdr->data) {
1056                 //CLog::Log(LOGDEBUG, "[pre_header_feeding] NOMEM!");
1057                 return PLAYER_NOMEM;
1058             }
1059         }
1060
1061         if (VFORMAT_H264 == para->video_format /*|| VFORMAT_H264MVC == para->video_format*/) {
1062             ret = h264_write_header(para, pkt);
1063             if (ret != PLAYER_SUCCESS) {
1064                 return ret;
1065             }
1066         } else if ((VFORMAT_MPEG4 == para->video_format) && (VIDEO_DEC_FORMAT_MPEG4_3 == para->video_codec_type)) {
1067             ret = divx3_write_header(para, pkt);
1068             if (ret != PLAYER_SUCCESS) {
1069                 return ret;
1070             }
1071         } else if ((CODEC_TAG_M4S2 == para->video_codec_tag)
1072                 || (CODEC_TAG_DX50 == para->video_codec_tag)
1073                 || (CODEC_TAG_mp4v == para->video_codec_tag)) {
1074             ret = m4s2_dx50_mp4v_write_header(para, pkt);
1075             if (ret != PLAYER_SUCCESS) {
1076                 return ret;
1077             }
1078         /*
1079         } else if ((AVI_FILE == para->file_type)
1080                 && (VIDEO_DEC_FORMAT_MPEG4_3 != para->vstream_info.video_codec_type)
1081                 && (VFORMAT_H264 != para->vstream_info.video_format)
1082                 && (VFORMAT_VC1 != para->vstream_info.video_format)) {
1083             ret = avi_write_header(para);
1084             if (ret != PLAYER_SUCCESS) {
1085                 return ret;
1086             }
1087         */
1088         } else if (CODEC_TAG_WMV3 == para->video_codec_tag) {
1089             CLog::Log(LOGDEBUG, "CODEC_TAG_WMV3 == para->video_codec_tag");
1090             ret = wmv3_write_header(para, pkt);
1091             if (ret != PLAYER_SUCCESS) {
1092                 return ret;
1093             }
1094         } else if ((CODEC_TAG_WVC1 == para->video_codec_tag)
1095                 || (CODEC_TAG_VC_1 == para->video_codec_tag)
1096                 || (CODEC_TAG_WMVA == para->video_codec_tag)) {
1097             CLog::Log(LOGDEBUG, "CODEC_TAG_WVC1 == para->video_codec_tag");
1098             ret = wvc1_write_header(para, pkt);
1099             if (ret != PLAYER_SUCCESS) {
1100                 return ret;
1101             }
1102         /*
1103         } else if ((MKV_FILE == para->file_type) &&
1104                   ((VFORMAT_MPEG4 == para->vstream_info.video_format)
1105                 || (VFORMAT_MPEG12 == para->vstream_info.video_format))) {
1106             ret = mkv_write_header(para, pkt);
1107             if (ret != PLAYER_SUCCESS) {
1108                 return ret;
1109             }
1110         */
1111         } else if (VFORMAT_MJPEG == para->video_format) {
1112             ret = mjpeg_write_header(para, pkt);
1113             if (ret != PLAYER_SUCCESS) {
1114                 return ret;
1115             }
1116         }
1117
1118         if (pkt->hdr) {
1119             if (pkt->hdr->data) {
1120                 free(pkt->hdr->data);
1121                 pkt->hdr->data = NULL;
1122             }
1123             free(pkt->hdr);
1124             pkt->hdr = NULL;
1125         }
1126     }
1127     else if (para->stream_type == AM_STREAM_PS) {
1128         if (pkt->hdr == NULL) {
1129             pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1130             pkt->hdr->data = (char*)malloc(HDR_BUF_SIZE);
1131             if (!pkt->hdr->data) {
1132                 CLog::Log(LOGDEBUG, "[pre_header_feeding] NOMEM!");
1133                 return PLAYER_NOMEM;
1134             }
1135         }
1136         if (( AV_CODEC_ID_MPEG1VIDEO == para->video_codec_id)
1137           || (AV_CODEC_ID_MPEG2VIDEO == para->video_codec_id)
1138           || (AV_CODEC_ID_MPEG2VIDEO_XVMC == para->video_codec_id)) {
1139             ret = mpeg_add_header(para, pkt);
1140             if (ret != PLAYER_SUCCESS) {
1141                 return ret;
1142             }
1143         }
1144         if (pkt->hdr) {
1145             if (pkt->hdr->data) {
1146                 free(pkt->hdr->data);
1147                 pkt->hdr->data = NULL;
1148             }
1149             free(pkt->hdr);
1150             pkt->hdr = NULL;
1151         }
1152     }
1153     return PLAYER_SUCCESS;
1154 }
1155
1156 int divx3_prefix(am_packet_t *pkt)
1157 {
1158 #define DIVX311_CHUNK_HEAD_SIZE 13
1159     const unsigned char divx311_chunk_prefix[DIVX311_CHUNK_HEAD_SIZE] = {
1160         0x00, 0x00, 0x00, 0x01, 0xb6, 'D', 'I', 'V', 'X', '3', '.', '1', '1'
1161     };
1162     if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1163         free(pkt->hdr->data);
1164         pkt->hdr->data = NULL;
1165     }
1166
1167     if (pkt->hdr == NULL) {
1168         pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1169         if (!pkt->hdr) {
1170             CLog::Log(LOGDEBUG, "[divx3_prefix] NOMEM!");
1171             return PLAYER_FAILED;
1172         }
1173
1174         pkt->hdr->data = NULL;
1175         pkt->hdr->size = 0;
1176     }
1177
1178     pkt->hdr->data = (char*)malloc(DIVX311_CHUNK_HEAD_SIZE + 4);
1179     if (pkt->hdr->data == NULL) {
1180         CLog::Log(LOGDEBUG, "[divx3_prefix] NOMEM!");
1181         return PLAYER_FAILED;
1182     }
1183
1184     memcpy(pkt->hdr->data, divx311_chunk_prefix, DIVX311_CHUNK_HEAD_SIZE);
1185
1186     pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 0] = (pkt->data_size >> 24) & 0xff;
1187     pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 1] = (pkt->data_size >> 16) & 0xff;
1188     pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 2] = (pkt->data_size >>  8) & 0xff;
1189     pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 3] = pkt->data_size & 0xff;
1190
1191     pkt->hdr->size = DIVX311_CHUNK_HEAD_SIZE + 4;
1192     pkt->newflag = 1;
1193
1194     return PLAYER_SUCCESS;
1195 }
1196
1197 int set_header_info(am_private_t *para)
1198 {
1199   am_packet_t *pkt = &para->am_pkt;
1200
1201   //if (pkt->newflag)
1202   {
1203     //if (pkt->hdr)
1204     //  pkt->hdr->size = 0;
1205
1206     if (para->video_format == VFORMAT_MPEG4)
1207     {
1208       if (para->video_codec_type == VIDEO_DEC_FORMAT_MPEG4_3)
1209       {
1210         return divx3_prefix(pkt);
1211       }
1212       else if (para->video_codec_type == VIDEO_DEC_FORMAT_H263)
1213       {
1214         return PLAYER_UNSUPPORT;
1215         unsigned char *vld_buf;
1216         int vld_len, vld_buf_size = para->video_width * para->video_height * 2;
1217
1218         if (!pkt->data_size) {
1219             return PLAYER_SUCCESS;
1220         }
1221
1222         if ((pkt->data[0] == 0) && (pkt->data[1] == 0) && (pkt->data[2] == 1) && (pkt->data[3] == 0xb6)) {
1223             return PLAYER_SUCCESS;
1224         }
1225
1226         vld_buf = (unsigned char*)malloc(vld_buf_size);
1227         if (!vld_buf) {
1228             return PLAYER_NOMEM;
1229         }
1230
1231         if (para->flv_flag) {
1232             vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 1);
1233         } else {
1234             if (0 == para->h263_decodable) {
1235                 para->h263_decodable = para->m_dll->decodeble_h263(pkt->data);
1236                 if (0 == para->h263_decodable) {
1237                     CLog::Log(LOGDEBUG, "[%s]h263 unsupport video and audio, exit", __FUNCTION__);
1238                     return PLAYER_UNSUPPORT;
1239                 }
1240             }
1241             vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 0);
1242         }
1243
1244         if (vld_len > 0) {
1245             if (pkt->buf) {
1246                 free(pkt->buf);
1247             }
1248             pkt->buf = vld_buf;
1249             pkt->buf_size = vld_buf_size;
1250             pkt->data = pkt->buf;
1251             pkt->data_size = vld_len;
1252         } else {
1253             free(vld_buf);
1254             pkt->data_size = 0;
1255         }
1256       }
1257     } else if (para->video_format == VFORMAT_VC1) {
1258         if (para->video_codec_type == VIDEO_DEC_FORMAT_WMV3) {
1259             unsigned i, check_sum = 0, data_len = 0;
1260
1261             if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1262                 free(pkt->hdr->data);
1263                 pkt->hdr->data = NULL;
1264             }
1265
1266             if (pkt->hdr == NULL) {
1267                 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1268                 if (!pkt->hdr) {
1269                     return PLAYER_FAILED;
1270                 }
1271
1272                 pkt->hdr->data = NULL;
1273                 pkt->hdr->size = 0;
1274             }
1275
1276             if (pkt->avpkt.flags) {
1277                 pkt->hdr->data = (char*)malloc(para->extrasize + 26 + 22);
1278                 if (pkt->hdr->data == NULL) {
1279                     return PLAYER_FAILED;
1280                 }
1281
1282                 pkt->hdr->data[0] = 0;
1283                 pkt->hdr->data[1] = 0;
1284                 pkt->hdr->data[2] = 1;
1285                 pkt->hdr->data[3] = 0x10;
1286
1287                 data_len = para->extrasize + 4;
1288                 pkt->hdr->data[4] = 0;
1289                 pkt->hdr->data[5] = (data_len >> 16) & 0xff;
1290                 pkt->hdr->data[6] = 0x88;
1291                 pkt->hdr->data[7] = (data_len >> 8) & 0xff;
1292                 pkt->hdr->data[8] =  data_len & 0xff;
1293                 pkt->hdr->data[9] = 0x88;
1294
1295                 pkt->hdr->data[10] = 0xff;
1296                 pkt->hdr->data[11] = 0xff;
1297                 pkt->hdr->data[12] = 0x88;
1298                 pkt->hdr->data[13] = 0xff;
1299                 pkt->hdr->data[14] = 0xff;
1300                 pkt->hdr->data[15] = 0x88;
1301
1302                 for (i = 4 ; i < 16 ; i++) {
1303                     check_sum += pkt->hdr->data[i];
1304                 }
1305
1306                 pkt->hdr->data[16] = (check_sum >> 8) & 0xff;
1307                 pkt->hdr->data[17] =  check_sum & 0xff;
1308                 pkt->hdr->data[18] = 0x88;
1309                 pkt->hdr->data[19] = (check_sum >> 8) & 0xff;
1310                 pkt->hdr->data[20] =  check_sum & 0xff;
1311                 pkt->hdr->data[21] = 0x88;
1312
1313                 pkt->hdr->data[22] = (para->video_width  >> 8) & 0xff;
1314                 pkt->hdr->data[23] =  para->video_width  & 0xff;
1315                 pkt->hdr->data[24] = (para->video_height >> 8) & 0xff;
1316                 pkt->hdr->data[25] =  para->video_height & 0xff;
1317
1318                 memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
1319
1320                 check_sum = 0;
1321                 data_len = para->extrasize + 26;
1322             } else {
1323                 pkt->hdr->data = (char*)malloc(22);
1324                 if (pkt->hdr->data == NULL) {
1325                     return PLAYER_FAILED;
1326                 }
1327             }
1328
1329             pkt->hdr->data[data_len + 0]  = 0;
1330             pkt->hdr->data[data_len + 1]  = 0;
1331             pkt->hdr->data[data_len + 2]  = 1;
1332             pkt->hdr->data[data_len + 3]  = 0xd;
1333
1334             pkt->hdr->data[data_len + 4]  = 0;
1335             pkt->hdr->data[data_len + 5]  = (pkt->data_size >> 16) & 0xff;
1336             pkt->hdr->data[data_len + 6]  = 0x88;
1337             pkt->hdr->data[data_len + 7]  = (pkt->data_size >> 8) & 0xff;
1338             pkt->hdr->data[data_len + 8]  =  pkt->data_size & 0xff;
1339             pkt->hdr->data[data_len + 9]  = 0x88;
1340
1341             pkt->hdr->data[data_len + 10] = 0xff;
1342             pkt->hdr->data[data_len + 11] = 0xff;
1343             pkt->hdr->data[data_len + 12] = 0x88;
1344             pkt->hdr->data[data_len + 13] = 0xff;
1345             pkt->hdr->data[data_len + 14] = 0xff;
1346             pkt->hdr->data[data_len + 15] = 0x88;
1347
1348             for (i = data_len + 4 ; i < data_len + 16 ; i++) {
1349                 check_sum += pkt->hdr->data[i];
1350             }
1351
1352             pkt->hdr->data[data_len + 16] = (check_sum >> 8) & 0xff;
1353             pkt->hdr->data[data_len + 17] =  check_sum & 0xff;
1354             pkt->hdr->data[data_len + 18] = 0x88;
1355             pkt->hdr->data[data_len + 19] = (check_sum >> 8) & 0xff;
1356             pkt->hdr->data[data_len + 20] =  check_sum & 0xff;
1357             pkt->hdr->data[data_len + 21] = 0x88;
1358
1359             pkt->hdr->size = data_len + 22;
1360             pkt->newflag = 1;
1361         } else if (para->video_codec_type == VIDEO_DEC_FORMAT_WVC1) {
1362             if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1363                 free(pkt->hdr->data);
1364                 pkt->hdr->data = NULL;
1365             }
1366
1367             if (pkt->hdr == NULL) {
1368                 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1369                 if (!pkt->hdr) {
1370                     CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1371                     return PLAYER_FAILED;
1372                 }
1373
1374                 pkt->hdr->data = NULL;
1375                 pkt->hdr->size = 0;
1376             }
1377
1378             pkt->hdr->data = (char*)malloc(4);
1379             if (pkt->hdr->data == NULL) {
1380                 CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1381                 return PLAYER_FAILED;
1382             }
1383
1384             pkt->hdr->data[0] = 0;
1385             pkt->hdr->data[1] = 0;
1386             pkt->hdr->data[2] = 1;
1387             pkt->hdr->data[3] = 0xd;
1388             pkt->hdr->size = 4;
1389             pkt->newflag = 1;
1390         }
1391     }
1392   }
1393   return PLAYER_SUCCESS;
1394 }
1395
1396 /*************************************************************************/
1397 CAMLCodec::CAMLCodec() : CThread("CAMLCodec")
1398 {
1399   m_opened = false;
1400   am_private = new am_private_t;
1401   memset(am_private, 0, sizeof(am_private_t));
1402   m_dll = new DllLibAmCodec;
1403   m_dll->Load();
1404   am_private->m_dll = m_dll;
1405 }
1406
1407
1408 CAMLCodec::~CAMLCodec()
1409 {
1410   StopThread();
1411   delete am_private;
1412   am_private = NULL;
1413   delete m_dll, m_dll = NULL;
1414 }
1415
1416 bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
1417 {
1418 #ifdef TARGET_ANDROID
1419   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion());
1420 #endif
1421
1422   m_speed = DVD_PLAYSPEED_NORMAL;
1423   m_1st_pts = 0;
1424   m_cur_pts = 0;
1425   m_cur_pictcnt = 0;
1426   m_old_pictcnt = 0;
1427   m_dst_rect.SetRect(0, 0, 0, 0);
1428   m_zoom = -1;
1429   m_contrast = -1;
1430   m_brightness = -1;
1431   m_vbufsize = 500000 * 2;
1432   m_start_dts = 0;
1433   m_start_pts = 0;
1434   m_hints = hints;
1435
1436   ShowMainVideo(false);
1437
1438   am_packet_init(&am_private->am_pkt);
1439   // default stream type
1440   am_private->stream_type      = AM_STREAM_ES;
1441   // handle hints.
1442   am_private->video_width      = hints.width;
1443   am_private->video_height     = hints.height;
1444   am_private->video_codec_id   = hints.codec;
1445   am_private->video_codec_tag  = hints.codec_tag;
1446   am_private->video_pid        = hints.pid;
1447
1448   // handle video ratio
1449   AVRational video_ratio       = m_dll->av_d2q(1, SHRT_MAX);
1450   //if (!hints.forced_aspect)
1451   //  video_ratio = m_dll->av_d2q(hints.aspect, SHRT_MAX);
1452   am_private->video_ratio      = ((int32_t)video_ratio.num << 16) | video_ratio.den;
1453   am_private->video_ratio64    = ((int64_t)video_ratio.num << 32) | video_ratio.den;
1454
1455   // handle video rate
1456   if (hints.rfpsrate > 0 && hints.rfpsscale != 0)
1457   {
1458     // check ffmpeg r_frame_rate 1st
1459     am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.rfpsscale / hints.rfpsrate;
1460   }
1461   else if (hints.fpsrate > 0 && hints.fpsscale != 0)
1462   {
1463     // then ffmpeg avg_frame_rate next
1464     am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.fpsscale / hints.fpsrate;
1465   }
1466
1467   // check for 1920x1080, interlaced, 25 fps
1468   // incorrectly reported as 50 fps (yes, video_rate == 1920)
1469   if (hints.width == 1920 && am_private->video_rate == 1920)
1470   {
1471     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1472     am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 25000;
1473   }
1474
1475   // check for SD h264 content incorrectly reported as 60 fsp
1476   // mp4/avi containers :(
1477   if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720 && am_private->video_rate == 1602)
1478   {
1479     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1480     am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1481   }
1482
1483   // check for SD h264 content incorrectly reported as some form of 30 fsp
1484   // mp4/avi containers :(
1485   if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720)
1486   {
1487     if (am_private->video_rate >= 3200 && am_private->video_rate <= 3210)
1488     {
1489       CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1490       am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1491     }
1492   }
1493
1494   // handle orientation
1495   am_private->video_rotation_degree = 0;
1496   if (hints.orientation == 90)
1497     am_private->video_rotation_degree = 1;
1498   else if (hints.orientation == 180)
1499     am_private->video_rotation_degree = 2;
1500   else if (hints.orientation == 270)
1501     am_private->video_rotation_degree = 3;
1502   // handle extradata
1503   am_private->video_format      = codecid_to_vformat(hints.codec);
1504   switch (am_private->video_format)
1505   {
1506     default:
1507       am_private->extrasize       = hints.extrasize;
1508       am_private->extradata       = (uint8_t*)malloc(hints.extrasize);
1509       memcpy(am_private->extradata, hints.extradata, hints.extrasize);
1510       break;
1511     case VFORMAT_REAL:
1512     case VFORMAT_MPEG12:
1513       break;
1514   }
1515
1516   if (am_private->stream_type == AM_STREAM_ES && am_private->video_codec_tag != 0)
1517     am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_tag);
1518   else
1519     am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_id);
1520
1521   am_private->flv_flag = 0;
1522   if (am_private->video_codec_id == AV_CODEC_ID_FLV1)
1523   {
1524     am_private->video_codec_tag = CODEC_TAG_F263;
1525     am_private->flv_flag = 1;
1526   }
1527
1528   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder "
1529     "hints.width(%d), hints.height(%d), hints.codec(%d), hints.codec_tag(%d), hints.pid(%d)",
1530     hints.width, hints.height, hints.codec, hints.codec_tag, hints.pid);
1531   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.fpsrate(%d), hints.fpsscale(%d), hints.rfpsrate(%d), hints.rfpsscale(%d), video_rate(%d)",
1532     hints.fpsrate, hints.fpsscale, hints.rfpsrate, hints.rfpsscale, am_private->video_rate);
1533   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.aspect(%f), video_ratio.num(%d), video_ratio.den(%d)",
1534     hints.aspect, video_ratio.num, video_ratio.den);
1535   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.orientation(%d), hints.forced_aspect(%d), hints.extrasize(%d)",
1536     hints.orientation, hints.forced_aspect, hints.extrasize);
1537
1538   // default video codec params
1539   am_private->gcodec.noblock     = 0;
1540   am_private->gcodec.video_pid   = am_private->video_pid;
1541   am_private->gcodec.video_type  = am_private->video_format;
1542   am_private->gcodec.stream_type = STREAM_TYPE_ES_VIDEO;
1543   am_private->gcodec.format      = am_private->video_codec_type;
1544   am_private->gcodec.width       = am_private->video_width;
1545   am_private->gcodec.height      = am_private->video_height;
1546   am_private->gcodec.rate        = am_private->video_rate;
1547   am_private->gcodec.ratio       = am_private->video_ratio;
1548   am_private->gcodec.ratio64     = am_private->video_ratio64;
1549   am_private->gcodec.param       = NULL;
1550
1551   switch(am_private->video_format)
1552   {
1553     default:
1554       break;
1555     case VFORMAT_MPEG4:
1556       am_private->gcodec.param = (void*)EXTERNAL_PTS;
1557       break;
1558     case VFORMAT_H264:
1559     case VFORMAT_H264MVC:
1560       am_private->gcodec.format = VIDEO_DEC_FORMAT_H264;
1561       am_private->gcodec.param  = (void*)EXTERNAL_PTS;
1562       // h264 in an avi file
1563       if (m_hints.ptsinvalid)
1564         am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
1565       break;
1566     case VFORMAT_REAL:
1567       am_private->stream_type = AM_STREAM_RM;
1568       am_private->vcodec.noblock = 1;
1569       am_private->vcodec.stream_type = STREAM_TYPE_RM;
1570       am_private->vcodec.am_sysinfo.ratio = 0x100;
1571       am_private->vcodec.am_sysinfo.ratio64 = 0;
1572       {
1573         static unsigned short tbl[9] = {0};
1574         if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type)
1575         {
1576           am_private->gcodec.extra = am_private->extradata[1] & 7;
1577           tbl[0] = (((am_private->gcodec.width  >> 2) - 1) << 8)
1578                  | (((am_private->gcodec.height >> 2) - 1) & 0xff);
1579           unsigned int j;
1580           for (unsigned int i = 1; i <= am_private->gcodec.extra; i++)
1581           {
1582             j = 2 * (i - 1);
1583             tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff);
1584           }
1585         }
1586         am_private->gcodec.param = &tbl;
1587       }
1588       break;
1589     case VFORMAT_VC1:
1590       // vc1 in an avi file
1591       if (m_hints.ptsinvalid)
1592         am_private->gcodec.param = (void*)EXTERNAL_PTS;
1593       break;
1594   }
1595   am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16));
1596
1597   // translate from generic to firemware version dependent
1598   m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec);
1599
1600   int ret = m_dll->codec_init(&am_private->vcodec);
1601   if (ret != CODEC_ERROR_NONE)
1602   {
1603     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
1604     return false;
1605   }
1606   am_private->dumpdemux = false;
1607   dumpfile_open(am_private);
1608
1609   // make sure we are not stuck in pause (amcodec bug)
1610   m_dll->codec_resume(&am_private->vcodec);
1611   m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1612
1613   m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
1614   m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
1615   // disable tsync, we are playing video disconnected from audio.
1616   aml_set_sysfs_int("/sys/class/tsync/enable", 0);
1617
1618   am_private->am_pkt.codec = &am_private->vcodec;
1619   pre_header_feeding(am_private, &am_private->am_pkt);
1620
1621   Create();
1622
1623   g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1624   g_renderManager.RegisterRenderFeaturesCallBack((const void*)this, RenderFeaturesCallBack);
1625
1626 /*
1627   // if display is set to 1080xxx, then disable deinterlacer for HD content
1628   // else bandwidth usage is too heavy and it will slow down video decoder.
1629   char display_mode[256] = {0};
1630   aml_get_sysfs_str("/sys/class/display/mode", display_mode, 255);
1631   if (strstr(display_mode,"1080"))
1632     aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 1);
1633   else
1634     aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0);
1635 */
1636
1637   m_opened = true;
1638   // vcodec is open, update speed if it was
1639   // changed before dvdplayer called OpenDecoder.
1640   SetSpeed(m_speed);
1641
1642   return true;
1643 }
1644
1645 void CAMLCodec::CloseDecoder()
1646 {
1647   CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
1648   StopThread();
1649
1650   g_renderManager.RegisterRenderUpdateCallBack((const void*)NULL, NULL);
1651   g_renderManager.RegisterRenderFeaturesCallBack((const void*)NULL, NULL);
1652
1653   // never leave vcodec ff/rw or paused.
1654   if (m_speed != DVD_PLAYSPEED_NORMAL)
1655   {
1656     m_dll->codec_resume(&am_private->vcodec);
1657     m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1658   }
1659   m_dll->codec_close(&am_private->vcodec);
1660   dumpfile_close(am_private);
1661   m_opened = false;
1662
1663   am_packet_release(&am_private->am_pkt);
1664   free(am_private->extradata);
1665   am_private->extradata = NULL;
1666   // return tsync to default so external apps work
1667   aml_set_sysfs_int("/sys/class/tsync/enable", 1);
1668
1669   ShowMainVideo(false);
1670
1671 }
1672
1673 void CAMLCodec::Reset()
1674 {
1675   CLog::Log(LOGDEBUG, "CAMLCodec::Reset");
1676
1677   if (!m_opened)
1678     return;
1679
1680   // set the system blackout_policy to leave the last frame showing
1681   int blackout_policy = aml_get_sysfs_int("/sys/class/video/blackout_policy");
1682   aml_set_sysfs_int("/sys/class/video/blackout_policy", 0);
1683
1684   // restore the speed (some amcodec versions require this)
1685   if (m_speed != DVD_PLAYSPEED_NORMAL)
1686   {
1687     m_dll->codec_resume(&am_private->vcodec);
1688     m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1689   }
1690   // reset the decoder
1691   m_dll->codec_reset(&am_private->vcodec);
1692   dumpfile_close(am_private);
1693   dumpfile_open(am_private);
1694
1695   // re-init our am_pkt
1696   am_packet_release(&am_private->am_pkt);
1697   am_packet_init(&am_private->am_pkt);
1698   am_private->am_pkt.codec = &am_private->vcodec;
1699   pre_header_feeding(am_private, &am_private->am_pkt);
1700
1701   // restore the saved system blackout_policy value
1702   aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy);
1703
1704   // reset some interal vars
1705   m_1st_pts = 0;
1706   m_cur_pts = 0;
1707   m_cur_pictcnt = 0;
1708   m_old_pictcnt = 0;
1709   SetSpeed(m_speed);
1710 }
1711
1712 int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
1713 {
1714   if (!m_opened)
1715     return VC_BUFFER;
1716
1717   // grr, m_RenderUpdateCallBackFn in g_renderManager is NULL'ed during
1718   // g_renderManager.Configure call by player, which happens after the codec
1719   // OpenDecoder call. So we need to restore it but it does not seem to stick :)
1720   g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1721
1722   if (pData)
1723   {
1724     am_private->am_pkt.data = pData;
1725     am_private->am_pkt.data_size = iSize;
1726
1727     am_private->am_pkt.newflag    = 1;
1728     am_private->am_pkt.isvalid    = 1;
1729     am_private->am_pkt.avduration = 0;
1730
1731     // handle pts, including 31bit wrap, aml can only handle 31
1732     // bit pts as it uses an int in kernel.
1733     if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
1734       am_private->am_pkt.avpts = AV_NOPTS_VALUE;
1735     else
1736     {
1737       am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
1738       if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
1739         m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
1740     }
1741     if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
1742       am_private->am_pkt.avpts -= m_start_pts;
1743
1744
1745     // handle dts, including 31bit wrap, aml can only handle 31
1746     // bit dts as it uses an int in kernel.
1747     if (dts == DVD_NOPTS_VALUE)
1748       am_private->am_pkt.avdts = AV_NOPTS_VALUE;
1749     else
1750     {
1751       am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
1752       if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
1753         m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
1754     }
1755     if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
1756       am_private->am_pkt.avdts -= m_start_dts;
1757
1758     //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
1759     //  iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
1760
1761     // some formats need header/data tweaks.
1762     // the actual write occurs once in write_av_packet
1763     // and is controlled by am_pkt.newflag.
1764     set_header_info(am_private);
1765
1766     // loop until we write all into codec, am_pkt.isvalid
1767     // will get set to zero once everything is consumed.
1768     // PLAYER_SUCCESS means all is ok, not all bytes were written.
1769     while (am_private->am_pkt.isvalid)
1770     {
1771       // abort on any errors.
1772       if (write_av_packet(am_private, &am_private->am_pkt) != PLAYER_SUCCESS)
1773         break;
1774
1775       if (am_private->am_pkt.isvalid)
1776         CLog::Log(LOGDEBUG, "CAMLCodec::Decode: write_av_packet looping");
1777     }
1778
1779     // if we seek, then GetTimeSize is wrong as
1780     // reports lastpts - cur_pts and hw decoder has
1781     // not started outputing new pts values yet.
1782     // so we grab the 1st pts sent into driver and
1783     // use that to calc GetTimeSize.
1784     if (m_1st_pts == 0)
1785       m_1st_pts = am_private->am_pkt.lastpts;
1786   }
1787
1788   // if we have still frames, demux size will be small
1789   // and we need to pre-buffer more.
1790   double target_timesize = 1.0;
1791   if (iSize < 20)
1792     target_timesize = 2.0;
1793
1794   // keep hw buffered demux above 1 second
1795   if (GetTimeSize() < target_timesize && m_speed == DVD_PLAYSPEED_NORMAL)
1796     return VC_BUFFER;
1797
1798   // wait until we get a new frame or 25ms,
1799   if (m_old_pictcnt == m_cur_pictcnt)
1800     m_ready_event.WaitMSec(25);
1801
1802   // we must return VC_BUFFER or VC_PICTURE,
1803   // default to VC_BUFFER.
1804   int rtn = VC_BUFFER;
1805   if (m_old_pictcnt != m_cur_pictcnt)
1806   {
1807     m_old_pictcnt++;
1808     rtn = VC_PICTURE;
1809     // we got a new pict, try and keep hw buffered demux above 2 seconds.
1810     // this, combined with the above 1 second check, keeps hw buffered demux between 1 and 2 seconds.
1811     // we also check to make sure we keep from filling hw buffer.
1812     if (GetTimeSize() < 2.0 && GetDataSize() < m_vbufsize/3)
1813       rtn |= VC_BUFFER;
1814   }
1815 /*
1816   CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
1817     "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
1818     rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
1819 */
1820   return rtn;
1821 }
1822
1823 bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
1824 {
1825   if (!m_opened)
1826     return false;
1827
1828   pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
1829   pDvdVideoPicture->format = RENDER_FMT_BYPASS;
1830   pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
1831
1832   pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
1833   pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
1834   // video pts cannot be late or dvdplayer goes nuts,
1835   // so run it one frame ahead
1836   pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
1837
1838   return true;
1839 }
1840
1841 void CAMLCodec::SetSpeed(int speed)
1842 {
1843   CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
1844
1845   // update internal vars regardless
1846   // of if we are open or not.
1847   m_speed = speed;
1848
1849   if (!m_opened)
1850     return;
1851
1852   switch(speed)
1853   {
1854     case DVD_PLAYSPEED_PAUSE:
1855       m_dll->codec_pause(&am_private->vcodec);
1856       m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1857       break;
1858     case DVD_PLAYSPEED_NORMAL:
1859       m_dll->codec_resume(&am_private->vcodec);
1860       m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1861       break;
1862     default:
1863       m_dll->codec_resume(&am_private->vcodec);
1864       if (am_private->video_format == VFORMAT_H264)
1865         m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
1866       else
1867         m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
1868       break;
1869   }
1870 }
1871
1872 int CAMLCodec::GetDataSize()
1873 {
1874   if (!m_opened)
1875     return 0;
1876
1877   struct buf_status vbuf ={0};
1878   if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
1879     m_vbufsize = vbuf.size;
1880
1881   return vbuf.data_len;
1882 }
1883
1884 double CAMLCodec::GetTimeSize()
1885 {
1886   if (!m_opened)
1887     return 0;
1888
1889   // if m_cur_pts is zero, hw decoder was not started yet
1890   // so we use the pts of the 1st demux packet that was send
1891   // to hw decoder to calc timesize.
1892   if (m_cur_pts == 0)
1893     m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
1894   else
1895     m_timesize = (double)(am_private->am_pkt.lastpts - m_cur_pts) / PTS_FREQ;
1896
1897   // lie to DVDPlayer, it is hardcoded to a max of 8 seconds,
1898   // if you buffer more than 8 seconds, it goes nuts.
1899   double timesize = m_timesize;
1900   if (timesize < 0.0)
1901     timesize = 0.0;
1902   else if (timesize > 7.0)
1903     timesize = 7.0;
1904
1905   return timesize;
1906 }
1907
1908 void CAMLCodec::Process()
1909 {
1910   CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
1911
1912   // bump our priority to be level with SoftAE
1913   SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
1914   while (!m_bStop)
1915   {
1916     int64_t pts_video = 0;
1917     if (am_private->am_pkt.lastpts > 0)
1918     {
1919       // this is a blocking poll that returns every vsync.
1920       // since we are running at a higher priority, make sure
1921       // we sleep if the call fails or does a timeout.
1922       if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
1923       {
1924         CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
1925         Sleep(10);
1926       }
1927
1928       pts_video = get_pts_video();
1929       if (m_cur_pts != pts_video)
1930       {
1931         //CLog::Log(LOGDEBUG, "CAMLCodec::Process: pts_video(%lld), pts_video/PTS_FREQ(%f), duration(%f)",
1932         //  pts_video, (double)pts_video/PTS_FREQ, 1.0/((double)(pts_video - m_cur_pts)/PTS_FREQ));
1933
1934         // other threads look at these, do them first
1935         m_cur_pts = pts_video;
1936         m_cur_pictcnt++;
1937         m_ready_event.Set();
1938
1939         // correct video pts by starting pts.
1940         if (m_start_pts != 0)
1941           pts_video += m_start_pts;
1942         else if (m_start_dts != 0)
1943           pts_video += m_start_dts;
1944
1945         double app_pts = GetPlayerPtsSeconds();
1946         // add in audio delay/display latency contribution
1947         double offset  = g_renderManager.GetDisplayLatency() - CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay;
1948         // correct video pts by user set delay and rendering delay
1949         app_pts += offset;
1950
1951         //CLog::Log(LOGDEBUG, "CAMLCodec::Process: app_pts(%f), pts_video/PTS_FREQ(%f)",
1952         //  app_pts, (double)pts_video/PTS_FREQ);
1953
1954         double error = app_pts - (double)pts_video/PTS_FREQ;
1955         double abs_error = fabs(error);
1956         if (abs_error > 0.125)
1957         {
1958           //CLog::Log(LOGDEBUG, "CAMLCodec::Process pts diff = %f", error);
1959           if (abs_error > 0.150)
1960           {
1961             // big error so try to reset pts_pcrscr
1962             SetVideoPtsSeconds(app_pts);
1963           }
1964           else
1965           {
1966             // small error so try to avoid a frame jump
1967             SetVideoPtsSeconds((double)pts_video/PTS_FREQ + error/4);
1968           }
1969         }
1970       }
1971     }
1972     else
1973     {
1974       Sleep(100);
1975     }
1976   }
1977   SetPriority(THREAD_PRIORITY_NORMAL);
1978   CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
1979 }
1980
1981 double CAMLCodec::GetPlayerPtsSeconds()
1982 {
1983   double clock_pts = 0.0;
1984   CDVDClock *playerclock = CDVDClock::GetMasterClock();
1985   if (playerclock)
1986     clock_pts = playerclock->GetClock() / DVD_TIME_BASE;
1987
1988   return clock_pts;
1989 }
1990
1991 void CAMLCodec::SetVideoPtsSeconds(const double pts)
1992 {
1993   //CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoPtsSeconds: pts(%f)", pts);
1994   if (pts >= 0.0)
1995   {
1996     int64_t pts_video = (int64_t)(pts * PTS_FREQ);
1997     if (m_start_pts != 0)
1998       pts_video -= m_start_pts;
1999     else if (m_start_dts != 0)
2000       pts_video -= m_start_dts;
2001
2002     set_pts_pcrscr(pts_video);
2003   }
2004 }
2005
2006 void CAMLCodec::ShowMainVideo(const bool show)
2007 {
2008   static int saved_disable_video = -1;
2009
2010   int disable_video = show ? 0:1;
2011   if (saved_disable_video == disable_video)
2012     return;
2013
2014   aml_set_sysfs_int("/sys/class/video/disable_video", disable_video);
2015   saved_disable_video = disable_video;
2016 }
2017
2018 void CAMLCodec::SetVideoZoom(const float zoom)
2019 {
2020   // input zoom range is 0.5 to 2.0 with a default of 1.0.
2021   // output zoom range is 2 to 300 with default of 100.
2022   // we limit that to a range of 50 to 200 with default of 100.
2023   aml_set_sysfs_int("/sys/class/video/zoom", (int)(100 * zoom));
2024 }
2025
2026 void CAMLCodec::SetVideoContrast(const int contrast)
2027 {
2028   // input contrast range is 0 to 100 with default of 50.
2029   // output contrast range is -255 to 255 with default of 0.
2030   int aml_contrast = (255 * (contrast - 50)) / 50;
2031   aml_set_sysfs_int("/sys/class/video/contrast", aml_contrast);
2032 }
2033 void CAMLCodec::SetVideoBrightness(const int brightness)
2034 {
2035   // input brightness range is 0 to 100 with default of 50.
2036   // output brightness range is -127 to 127 with default of 0.
2037   int aml_brightness = (127 * (brightness - 50)) / 50;
2038   aml_set_sysfs_int("/sys/class/video/brightness", aml_brightness);
2039 }
2040 void CAMLCodec::SetVideoSaturation(const int saturation)
2041 {
2042   // output saturation range is -127 to 127 with default of 127.
2043   aml_set_sysfs_int("/sys/class/video/saturation", saturation);
2044 }
2045
2046 void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
2047 {
2048   renderFeatures.push_back(RENDERFEATURE_ZOOM);
2049   renderFeatures.push_back(RENDERFEATURE_CONTRAST);
2050   renderFeatures.push_back(RENDERFEATURE_BRIGHTNESS);
2051   renderFeatures.push_back(RENDERFEATURE_STRETCH);
2052   renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
2053   return;
2054 }
2055
2056 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
2057 {
2058   CAMLCodec *codec = (CAMLCodec*)ctx;
2059   if (codec)
2060     codec->GetRenderFeatures(renderFeatures);
2061 }
2062
2063 void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
2064 {
2065   // this routine gets called every video frame
2066   // and is in the context of the renderer thread so
2067   // do not do anything stupid here.
2068
2069   // video zoom adjustment.
2070   float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
2071   if ((int)(zoom * 1000) != (int)(m_zoom * 1000))
2072   {
2073     m_zoom = zoom;
2074   }
2075   // video contrast adjustment.
2076   int contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast;
2077   if (contrast != m_contrast)
2078   {
2079     SetVideoContrast(contrast);
2080     m_contrast = contrast;
2081   }
2082   // video brightness adjustment.
2083   int brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness;
2084   if (brightness != m_brightness)
2085   {
2086     SetVideoBrightness(brightness);
2087     m_brightness = brightness;
2088   }
2089
2090   // check if destination rect or video view mode has changed
2091   if ((m_dst_rect != DestRect) || (m_view_mode != CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode))
2092   {
2093     m_dst_rect  = DestRect;
2094     m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
2095   }
2096   else
2097   {
2098     // mainvideo 'should' be showing already if we get here, make sure.
2099     ShowMainVideo(true);
2100     return;
2101   }
2102
2103   CRect gui, display, dst_rect;
2104   gui = g_graphicsContext.GetViewWindow();
2105   // when display is at 1080p, we have freescale enabled
2106   // and that scales all layers into 1080p display including video,
2107   // so we have to setup video axis for 720p instead of 1080p... Boooo.
2108   display = g_graphicsContext.GetViewWindow();
2109   dst_rect = m_dst_rect;
2110   if (gui != display)
2111   {
2112     float xscale = display.Width()  / gui.Width();
2113     float yscale = display.Height() / gui.Height();
2114     dst_rect.x1 *= xscale;
2115     dst_rect.x2 *= xscale;
2116     dst_rect.y1 *= yscale;
2117     dst_rect.y2 *= yscale;
2118   }
2119
2120   ShowMainVideo(false);
2121
2122   // goofy 0/1 based difference in aml axis coordinates.
2123   // fix them.
2124   dst_rect.x2--;
2125   dst_rect.y2--;
2126
2127   char video_axis[256] = {0};
2128   sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
2129   aml_set_sysfs_str("/sys/class/video/axis", video_axis);
2130   // make sure we are in 'full stretch' so we can stretch
2131   aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
2132
2133 /*
2134   CStdString rectangle;
2135   rectangle.Format("%i,%i,%i,%i",
2136     (int)dst_rect.x1, (int)dst_rect.y1,
2137     (int)dst_rect.Width(), (int)dst_rect.Height());
2138   CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
2139 */
2140
2141   // we only get called once gui has changed to something
2142   // that would show video playback, so show it.
2143   ShowMainVideo(true);
2144 }
2145
2146 void CAMLCodec::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
2147 {
2148   CAMLCodec *codec = (CAMLCodec*)ctx;
2149   codec->SetVideoRect(SrcRect, DestRect);
2150 }