Merge pull request #3816 from amet/manualSearch
[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   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion());
1419
1420   m_speed = DVD_PLAYSPEED_NORMAL;
1421   m_1st_pts = 0;
1422   m_cur_pts = 0;
1423   m_cur_pictcnt = 0;
1424   m_old_pictcnt = 0;
1425   m_dst_rect.SetRect(0, 0, 0, 0);
1426   m_zoom = -1;
1427   m_contrast = -1;
1428   m_brightness = -1;
1429   m_vbufsize = 500000 * 2;
1430   m_start_dts = 0;
1431   m_start_pts = 0;
1432   m_hints = hints;
1433
1434   ShowMainVideo(false);
1435
1436   am_packet_init(&am_private->am_pkt);
1437   // default stream type
1438   am_private->stream_type      = AM_STREAM_ES;
1439   // handle hints.
1440   am_private->video_width      = hints.width;
1441   am_private->video_height     = hints.height;
1442   am_private->video_codec_id   = hints.codec;
1443   am_private->video_codec_tag  = hints.codec_tag;
1444   am_private->video_pid        = hints.pid;
1445
1446   // handle video ratio
1447   AVRational video_ratio       = m_dll->av_d2q(1, SHRT_MAX);
1448   //if (!hints.forced_aspect)
1449   //  video_ratio = m_dll->av_d2q(hints.aspect, SHRT_MAX);
1450   am_private->video_ratio      = ((int32_t)video_ratio.num << 16) | video_ratio.den;
1451   am_private->video_ratio64    = ((int64_t)video_ratio.num << 32) | video_ratio.den;
1452
1453   // handle video rate
1454   if (hints.rfpsrate > 0 && hints.rfpsscale != 0)
1455   {
1456     // check ffmpeg r_frame_rate 1st
1457     am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.rfpsscale / hints.rfpsrate;
1458   }
1459   else if (hints.fpsrate > 0 && hints.fpsscale != 0)
1460   {
1461     // then ffmpeg avg_frame_rate next
1462     am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.fpsscale / hints.fpsrate;
1463   }
1464
1465   // check for 1920x1080, interlaced, 25 fps
1466   // incorrectly reported as 50 fps (yes, video_rate == 1920)
1467   if (hints.width == 1920 && am_private->video_rate == 1920)
1468   {
1469     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1470     am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 25000;
1471   }
1472
1473   // check for SD h264 content incorrectly reported as 60 fsp
1474   // mp4/avi containers :(
1475   if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720 && am_private->video_rate == 1602)
1476   {
1477     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1478     am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1479   }
1480
1481   // check for SD h264 content incorrectly reported as some form of 30 fsp
1482   // mp4/avi containers :(
1483   if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720)
1484   {
1485     if (am_private->video_rate >= 3200 && am_private->video_rate <= 3210)
1486     {
1487       CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1488       am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1489     }
1490   }
1491
1492   // handle orientation
1493   am_private->video_rotation_degree = 0;
1494   if (hints.orientation == 90)
1495     am_private->video_rotation_degree = 1;
1496   else if (hints.orientation == 180)
1497     am_private->video_rotation_degree = 2;
1498   else if (hints.orientation == 270)
1499     am_private->video_rotation_degree = 3;
1500   // handle extradata
1501   am_private->video_format      = codecid_to_vformat(hints.codec);
1502   switch (am_private->video_format)
1503   {
1504     default:
1505       am_private->extrasize       = hints.extrasize;
1506       am_private->extradata       = (uint8_t*)malloc(hints.extrasize);
1507       memcpy(am_private->extradata, hints.extradata, hints.extrasize);
1508       break;
1509     case VFORMAT_REAL:
1510     case VFORMAT_MPEG12:
1511       break;
1512   }
1513
1514   if (am_private->stream_type == AM_STREAM_ES && am_private->video_codec_tag != 0)
1515     am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_tag);
1516   else
1517     am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_id);
1518
1519   am_private->flv_flag = 0;
1520   if (am_private->video_codec_id == AV_CODEC_ID_FLV1)
1521   {
1522     am_private->video_codec_tag = CODEC_TAG_F263;
1523     am_private->flv_flag = 1;
1524   }
1525
1526   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder "
1527     "hints.width(%d), hints.height(%d), hints.codec(%d), hints.codec_tag(%d), hints.pid(%d)",
1528     hints.width, hints.height, hints.codec, hints.codec_tag, hints.pid);
1529   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.fpsrate(%d), hints.fpsscale(%d), hints.rfpsrate(%d), hints.rfpsscale(%d), video_rate(%d)",
1530     hints.fpsrate, hints.fpsscale, hints.rfpsrate, hints.rfpsscale, am_private->video_rate);
1531   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.aspect(%f), video_ratio.num(%d), video_ratio.den(%d)",
1532     hints.aspect, video_ratio.num, video_ratio.den);
1533   CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.orientation(%d), hints.forced_aspect(%d), hints.extrasize(%d)",
1534     hints.orientation, hints.forced_aspect, hints.extrasize);
1535
1536   // default video codec params
1537   am_private->gcodec.noblock     = 0;
1538   am_private->gcodec.video_pid   = am_private->video_pid;
1539   am_private->gcodec.video_type  = am_private->video_format;
1540   am_private->gcodec.stream_type = STREAM_TYPE_ES_VIDEO;
1541   am_private->gcodec.format      = am_private->video_codec_type;
1542   am_private->gcodec.width       = am_private->video_width;
1543   am_private->gcodec.height      = am_private->video_height;
1544   am_private->gcodec.rate        = am_private->video_rate;
1545   am_private->gcodec.ratio       = am_private->video_ratio;
1546   am_private->gcodec.ratio64     = am_private->video_ratio64;
1547   am_private->gcodec.param       = NULL;
1548
1549   switch(am_private->video_format)
1550   {
1551     default:
1552       break;
1553     case VFORMAT_MPEG4:
1554       am_private->gcodec.param = (void*)EXTERNAL_PTS;
1555       break;
1556     case VFORMAT_H264:
1557     case VFORMAT_H264MVC:
1558       am_private->gcodec.format = VIDEO_DEC_FORMAT_H264;
1559       am_private->gcodec.param  = (void*)EXTERNAL_PTS;
1560       // h264 in an avi file
1561       if (m_hints.ptsinvalid)
1562         am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
1563       break;
1564     case VFORMAT_REAL:
1565       am_private->stream_type = AM_STREAM_RM;
1566       am_private->vcodec.noblock = 1;
1567       am_private->vcodec.stream_type = STREAM_TYPE_RM;
1568       am_private->vcodec.am_sysinfo.ratio = 0x100;
1569       am_private->vcodec.am_sysinfo.ratio64 = 0;
1570       {
1571         static unsigned short tbl[9] = {0};
1572         if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type)
1573         {
1574           am_private->gcodec.extra = am_private->extradata[1] & 7;
1575           tbl[0] = (((am_private->gcodec.width  >> 2) - 1) << 8)
1576                  | (((am_private->gcodec.height >> 2) - 1) & 0xff);
1577           unsigned int j;
1578           for (unsigned int i = 1; i <= am_private->gcodec.extra; i++)
1579           {
1580             j = 2 * (i - 1);
1581             tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff);
1582           }
1583         }
1584         am_private->gcodec.param = &tbl;
1585       }
1586       break;
1587     case VFORMAT_VC1:
1588       // vc1 in an avi file
1589       if (m_hints.ptsinvalid)
1590         am_private->gcodec.param = (void*)EXTERNAL_PTS;
1591       break;
1592   }
1593   am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16));
1594
1595   // translate from generic to firemware version dependent
1596   m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec);
1597
1598   int ret = m_dll->codec_init(&am_private->vcodec);
1599   if (ret != CODEC_ERROR_NONE)
1600   {
1601     CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
1602     return false;
1603   }
1604   am_private->dumpdemux = false;
1605   dumpfile_open(am_private);
1606
1607   // make sure we are not stuck in pause (amcodec bug)
1608   m_dll->codec_resume(&am_private->vcodec);
1609   m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1610
1611   m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
1612   m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
1613   // disable tsync, we are playing video disconnected from audio.
1614   aml_set_sysfs_int("/sys/class/tsync/enable", 0);
1615
1616   am_private->am_pkt.codec = &am_private->vcodec;
1617   pre_header_feeding(am_private, &am_private->am_pkt);
1618
1619   Create();
1620
1621   g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1622   g_renderManager.RegisterRenderFeaturesCallBack((const void*)this, RenderFeaturesCallBack);
1623
1624 /*
1625   // if display is set to 1080xxx, then disable deinterlacer for HD content
1626   // else bandwidth usage is too heavy and it will slow down video decoder.
1627   char display_mode[256] = {0};
1628   aml_get_sysfs_str("/sys/class/display/mode", display_mode, 255);
1629   if (strstr(display_mode,"1080"))
1630     aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 1);
1631   else
1632     aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0);
1633 */
1634
1635   m_opened = true;
1636   // vcodec is open, update speed if it was
1637   // changed before dvdplayer called OpenDecoder.
1638   SetSpeed(m_speed);
1639
1640   return true;
1641 }
1642
1643 void CAMLCodec::CloseDecoder()
1644 {
1645   CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
1646   StopThread();
1647
1648   g_renderManager.RegisterRenderUpdateCallBack((const void*)NULL, NULL);
1649   g_renderManager.RegisterRenderFeaturesCallBack((const void*)NULL, NULL);
1650
1651   // never leave vcodec ff/rw or paused.
1652   if (m_speed != DVD_PLAYSPEED_NORMAL)
1653   {
1654     m_dll->codec_resume(&am_private->vcodec);
1655     m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1656   }
1657   m_dll->codec_close(&am_private->vcodec);
1658   dumpfile_close(am_private);
1659   m_opened = false;
1660
1661   am_packet_release(&am_private->am_pkt);
1662   free(am_private->extradata);
1663   am_private->extradata = NULL;
1664   // return tsync to default so external apps work
1665   aml_set_sysfs_int("/sys/class/tsync/enable", 1);
1666
1667   ShowMainVideo(false);
1668
1669 }
1670
1671 void CAMLCodec::Reset()
1672 {
1673   CLog::Log(LOGDEBUG, "CAMLCodec::Reset");
1674
1675   if (!m_opened)
1676     return;
1677
1678   // set the system blackout_policy to leave the last frame showing
1679   int blackout_policy = aml_get_sysfs_int("/sys/class/video/blackout_policy");
1680   aml_set_sysfs_int("/sys/class/video/blackout_policy", 0);
1681
1682   // restore the speed (some amcodec versions require this)
1683   if (m_speed != DVD_PLAYSPEED_NORMAL)
1684   {
1685     m_dll->codec_resume(&am_private->vcodec);
1686     m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1687   }
1688   // reset the decoder
1689   m_dll->codec_reset(&am_private->vcodec);
1690   dumpfile_close(am_private);
1691   dumpfile_open(am_private);
1692
1693   // re-init our am_pkt
1694   am_packet_release(&am_private->am_pkt);
1695   am_packet_init(&am_private->am_pkt);
1696   am_private->am_pkt.codec = &am_private->vcodec;
1697   pre_header_feeding(am_private, &am_private->am_pkt);
1698
1699   // restore the saved system blackout_policy value
1700   aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy);
1701
1702   // reset some interal vars
1703   m_1st_pts = 0;
1704   m_cur_pts = 0;
1705   m_cur_pictcnt = 0;
1706   m_old_pictcnt = 0;
1707   SetSpeed(m_speed);
1708 }
1709
1710 int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
1711 {
1712   if (!m_opened)
1713     return VC_BUFFER;
1714
1715   // grr, m_RenderUpdateCallBackFn in g_renderManager is NULL'ed during
1716   // g_renderManager.Configure call by player, which happens after the codec
1717   // OpenDecoder call. So we need to restore it but it does not seem to stick :)
1718   g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1719
1720   if (pData)
1721   {
1722     am_private->am_pkt.data = pData;
1723     am_private->am_pkt.data_size = iSize;
1724
1725     am_private->am_pkt.newflag    = 1;
1726     am_private->am_pkt.isvalid    = 1;
1727     am_private->am_pkt.avduration = 0;
1728
1729     // handle pts, including 31bit wrap, aml can only handle 31
1730     // bit pts as it uses an int in kernel.
1731     if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
1732       am_private->am_pkt.avpts = AV_NOPTS_VALUE;
1733     else
1734     {
1735       am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
1736       if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
1737         m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
1738     }
1739     if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
1740       am_private->am_pkt.avpts -= m_start_pts;
1741
1742
1743     // handle dts, including 31bit wrap, aml can only handle 31
1744     // bit dts as it uses an int in kernel.
1745     if (dts == DVD_NOPTS_VALUE)
1746       am_private->am_pkt.avdts = AV_NOPTS_VALUE;
1747     else
1748     {
1749       am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
1750       if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
1751         m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
1752     }
1753     if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
1754       am_private->am_pkt.avdts -= m_start_dts;
1755
1756     //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
1757     //  iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
1758
1759     // some formats need header/data tweaks.
1760     // the actual write occurs once in write_av_packet
1761     // and is controlled by am_pkt.newflag.
1762     set_header_info(am_private);
1763
1764     // loop until we write all into codec, am_pkt.isvalid
1765     // will get set to zero once everything is consumed.
1766     // PLAYER_SUCCESS means all is ok, not all bytes were written.
1767     while (am_private->am_pkt.isvalid)
1768     {
1769       // abort on any errors.
1770       if (write_av_packet(am_private, &am_private->am_pkt) != PLAYER_SUCCESS)
1771         break;
1772
1773       if (am_private->am_pkt.isvalid)
1774         CLog::Log(LOGDEBUG, "CAMLCodec::Decode: write_av_packet looping");
1775     }
1776
1777     // if we seek, then GetTimeSize is wrong as
1778     // reports lastpts - cur_pts and hw decoder has
1779     // not started outputing new pts values yet.
1780     // so we grab the 1st pts sent into driver and
1781     // use that to calc GetTimeSize.
1782     if (m_1st_pts == 0)
1783       m_1st_pts = am_private->am_pkt.lastpts;
1784   }
1785
1786   // if we have still frames, demux size will be small
1787   // and we need to pre-buffer more.
1788   double target_timesize = 1.0;
1789   if (iSize < 20)
1790     target_timesize = 2.0;
1791
1792   // keep hw buffered demux above 1 second
1793   if (GetTimeSize() < target_timesize && m_speed == DVD_PLAYSPEED_NORMAL)
1794     return VC_BUFFER;
1795
1796   // wait until we get a new frame or 25ms,
1797   if (m_old_pictcnt == m_cur_pictcnt)
1798     m_ready_event.WaitMSec(25);
1799
1800   // we must return VC_BUFFER or VC_PICTURE,
1801   // default to VC_BUFFER.
1802   int rtn = VC_BUFFER;
1803   if (m_old_pictcnt != m_cur_pictcnt)
1804   {
1805     m_old_pictcnt++;
1806     rtn = VC_PICTURE;
1807     // we got a new pict, try and keep hw buffered demux above 2 seconds.
1808     // this, combined with the above 1 second check, keeps hw buffered demux between 1 and 2 seconds.
1809     // we also check to make sure we keep from filling hw buffer.
1810     if (GetTimeSize() < 2.0 && GetDataSize() < m_vbufsize/3)
1811       rtn |= VC_BUFFER;
1812   }
1813 /*
1814   CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
1815     "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
1816     rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
1817 */
1818   return rtn;
1819 }
1820
1821 bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
1822 {
1823   if (!m_opened)
1824     return false;
1825
1826   pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
1827   pDvdVideoPicture->format = RENDER_FMT_BYPASS;
1828   pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
1829
1830   pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
1831   pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
1832   // video pts cannot be late or dvdplayer goes nuts,
1833   // so run it one frame ahead
1834   pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
1835
1836   return true;
1837 }
1838
1839 void CAMLCodec::SetSpeed(int speed)
1840 {
1841   CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
1842
1843   // update internal vars regardless
1844   // of if we are open or not.
1845   m_speed = speed;
1846
1847   if (!m_opened)
1848     return;
1849
1850   switch(speed)
1851   {
1852     case DVD_PLAYSPEED_PAUSE:
1853       m_dll->codec_pause(&am_private->vcodec);
1854       m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1855       break;
1856     case DVD_PLAYSPEED_NORMAL:
1857       m_dll->codec_resume(&am_private->vcodec);
1858       m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1859       break;
1860     default:
1861       m_dll->codec_resume(&am_private->vcodec);
1862       if (am_private->video_format == VFORMAT_H264)
1863         m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
1864       else
1865         m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
1866       break;
1867   }
1868 }
1869
1870 int CAMLCodec::GetDataSize()
1871 {
1872   if (!m_opened)
1873     return 0;
1874
1875   struct buf_status vbuf ={0};
1876   if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
1877     m_vbufsize = vbuf.size;
1878
1879   return vbuf.data_len;
1880 }
1881
1882 double CAMLCodec::GetTimeSize()
1883 {
1884   if (!m_opened)
1885     return 0;
1886
1887   // if m_cur_pts is zero, hw decoder was not started yet
1888   // so we use the pts of the 1st demux packet that was send
1889   // to hw decoder to calc timesize.
1890   if (m_cur_pts == 0)
1891     m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
1892   else
1893     m_timesize = (double)(am_private->am_pkt.lastpts - m_cur_pts) / PTS_FREQ;
1894
1895   // lie to DVDPlayer, it is hardcoded to a max of 8 seconds,
1896   // if you buffer more than 8 seconds, it goes nuts.
1897   double timesize = m_timesize;
1898   if (timesize < 0.0)
1899     timesize = 0.0;
1900   else if (timesize > 7.0)
1901     timesize = 7.0;
1902
1903   return timesize;
1904 }
1905
1906 void CAMLCodec::Process()
1907 {
1908   CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
1909
1910   // bump our priority to be level with SoftAE
1911   SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
1912   while (!m_bStop)
1913   {
1914     int64_t pts_video = 0;
1915     if (am_private->am_pkt.lastpts > 0)
1916     {
1917       // this is a blocking poll that returns every vsync.
1918       // since we are running at a higher priority, make sure
1919       // we sleep if the call fails or does a timeout.
1920       if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
1921       {
1922         CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
1923         Sleep(10);
1924       }
1925
1926       pts_video = get_pts_video();
1927       if (m_cur_pts != pts_video)
1928       {
1929         //CLog::Log(LOGDEBUG, "CAMLCodec::Process: pts_video(%lld), pts_video/PTS_FREQ(%f), duration(%f)",
1930         //  pts_video, (double)pts_video/PTS_FREQ, 1.0/((double)(pts_video - m_cur_pts)/PTS_FREQ));
1931
1932         // other threads look at these, do them first
1933         m_cur_pts = pts_video;
1934         m_cur_pictcnt++;
1935         m_ready_event.Set();
1936
1937         // correct video pts by starting pts.
1938         if (m_start_pts != 0)
1939           pts_video += m_start_pts;
1940         else if (m_start_dts != 0)
1941           pts_video += m_start_dts;
1942
1943         double app_pts = GetPlayerPtsSeconds();
1944         // add in audio delay/display latency contribution
1945         double offset  = g_renderManager.GetDisplayLatency() - CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay;
1946         // correct video pts by user set delay and rendering delay
1947         app_pts += offset;
1948
1949         //CLog::Log(LOGDEBUG, "CAMLCodec::Process: app_pts(%f), pts_video/PTS_FREQ(%f)",
1950         //  app_pts, (double)pts_video/PTS_FREQ);
1951
1952         double error = app_pts - (double)pts_video/PTS_FREQ;
1953         double abs_error = fabs(error);
1954         if (abs_error > 0.125)
1955         {
1956           //CLog::Log(LOGDEBUG, "CAMLCodec::Process pts diff = %f", error);
1957           if (abs_error > 0.150)
1958           {
1959             // big error so try to reset pts_pcrscr
1960             SetVideoPtsSeconds(app_pts);
1961           }
1962           else
1963           {
1964             // small error so try to avoid a frame jump
1965             SetVideoPtsSeconds((double)pts_video/PTS_FREQ + error/4);
1966           }
1967         }
1968       }
1969     }
1970     else
1971     {
1972       Sleep(100);
1973     }
1974   }
1975   SetPriority(THREAD_PRIORITY_NORMAL);
1976   CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
1977 }
1978
1979 double CAMLCodec::GetPlayerPtsSeconds()
1980 {
1981   double clock_pts = 0.0;
1982   CDVDClock *playerclock = CDVDClock::GetMasterClock();
1983   if (playerclock)
1984     clock_pts = playerclock->GetClock() / DVD_TIME_BASE;
1985
1986   return clock_pts;
1987 }
1988
1989 void CAMLCodec::SetVideoPtsSeconds(const double pts)
1990 {
1991   //CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoPtsSeconds: pts(%f)", pts);
1992   if (pts >= 0.0)
1993   {
1994     int64_t pts_video = (int64_t)(pts * PTS_FREQ);
1995     if (m_start_pts != 0)
1996       pts_video -= m_start_pts;
1997     else if (m_start_dts != 0)
1998       pts_video -= m_start_dts;
1999
2000     set_pts_pcrscr(pts_video);
2001   }
2002 }
2003
2004 void CAMLCodec::ShowMainVideo(const bool show)
2005 {
2006   static int saved_disable_video = -1;
2007
2008   int disable_video = show ? 0:1;
2009   if (saved_disable_video == disable_video)
2010     return;
2011
2012   aml_set_sysfs_int("/sys/class/video/disable_video", disable_video);
2013   saved_disable_video = disable_video;
2014 }
2015
2016 void CAMLCodec::SetVideoZoom(const float zoom)
2017 {
2018   // input zoom range is 0.5 to 2.0 with a default of 1.0.
2019   // output zoom range is 2 to 300 with default of 100.
2020   // we limit that to a range of 50 to 200 with default of 100.
2021   aml_set_sysfs_int("/sys/class/video/zoom", (int)(100 * zoom));
2022 }
2023
2024 void CAMLCodec::SetVideoContrast(const int contrast)
2025 {
2026   // input contrast range is 0 to 100 with default of 50.
2027   // output contrast range is -255 to 255 with default of 0.
2028   int aml_contrast = (255 * (contrast - 50)) / 50;
2029   aml_set_sysfs_int("/sys/class/video/contrast", aml_contrast);
2030 }
2031 void CAMLCodec::SetVideoBrightness(const int brightness)
2032 {
2033   // input brightness range is 0 to 100 with default of 50.
2034   // output brightness range is -127 to 127 with default of 0.
2035   int aml_brightness = (127 * (brightness - 50)) / 50;
2036   aml_set_sysfs_int("/sys/class/video/brightness", aml_brightness);
2037 }
2038 void CAMLCodec::SetVideoSaturation(const int saturation)
2039 {
2040   // output saturation range is -127 to 127 with default of 127.
2041   aml_set_sysfs_int("/sys/class/video/saturation", saturation);
2042 }
2043
2044 void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
2045 {
2046   renderFeatures.push_back(RENDERFEATURE_ZOOM);
2047   renderFeatures.push_back(RENDERFEATURE_CONTRAST);
2048   renderFeatures.push_back(RENDERFEATURE_BRIGHTNESS);
2049   renderFeatures.push_back(RENDERFEATURE_STRETCH);
2050   renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
2051   return;
2052 }
2053
2054 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
2055 {
2056   CAMLCodec *codec = (CAMLCodec*)ctx;
2057   if (codec)
2058     codec->GetRenderFeatures(renderFeatures);
2059 }
2060
2061 void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
2062 {
2063   // this routine gets called every video frame
2064   // and is in the context of the renderer thread so
2065   // do not do anything stupid here.
2066
2067   // video zoom adjustment.
2068   float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
2069   if ((int)(zoom * 1000) != (int)(m_zoom * 1000))
2070   {
2071     m_zoom = zoom;
2072   }
2073   // video contrast adjustment.
2074   int contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast;
2075   if (contrast != m_contrast)
2076   {
2077     SetVideoContrast(contrast);
2078     m_contrast = contrast;
2079   }
2080   // video brightness adjustment.
2081   int brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness;
2082   if (brightness != m_brightness)
2083   {
2084     SetVideoBrightness(brightness);
2085     m_brightness = brightness;
2086   }
2087
2088   // check if destination rect or video view mode has changed
2089   if ((m_dst_rect != DestRect) || (m_view_mode != CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode))
2090   {
2091     m_dst_rect  = DestRect;
2092     m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
2093   }
2094   else
2095   {
2096     // mainvideo 'should' be showing already if we get here, make sure.
2097     ShowMainVideo(true);
2098     return;
2099   }
2100
2101   CRect gui, display, dst_rect;
2102   gui = g_graphicsContext.GetViewWindow();
2103   // when display is at 1080p, we have freescale enabled
2104   // and that scales all layers into 1080p display including video,
2105   // so we have to setup video axis for 720p instead of 1080p... Boooo.
2106   display = g_graphicsContext.GetViewWindow();
2107   dst_rect = m_dst_rect;
2108   if (gui != display)
2109   {
2110     float xscale = display.Width()  / gui.Width();
2111     float yscale = display.Height() / gui.Height();
2112     dst_rect.x1 *= xscale;
2113     dst_rect.x2 *= xscale;
2114     dst_rect.y1 *= yscale;
2115     dst_rect.y2 *= yscale;
2116   }
2117
2118   ShowMainVideo(false);
2119
2120   // goofy 0/1 based difference in aml axis coordinates.
2121   // fix them.
2122   dst_rect.x2--;
2123   dst_rect.y2--;
2124
2125   char video_axis[256] = {0};
2126   sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
2127   aml_set_sysfs_str("/sys/class/video/axis", video_axis);
2128   // make sure we are in 'full stretch' so we can stretch
2129   aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
2130
2131 /*
2132   CStdString rectangle;
2133   rectangle.Format("%i,%i,%i,%i",
2134     (int)dst_rect.x1, (int)dst_rect.y1,
2135     (int)dst_rect.Width(), (int)dst_rect.Height());
2136   CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
2137 */
2138
2139   // we only get called once gui has changed to something
2140   // that would show video playback, so show it.
2141   ShowMainVideo(true);
2142 }
2143
2144 void CAMLCodec::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
2145 {
2146   CAMLCodec *codec = (CAMLCodec*)ctx;
2147   codec->SetVideoRect(SrcRect, DestRect);
2148 }