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