2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
24 #include "DynamicDll.h"
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"
36 #if defined(TARGET_ANDROID)
37 #include "android/activity/AndroidFeatures.h"
38 #include "utils/BitstreamConverter.h"
45 #include <semaphore.h>
49 #include <sys/ioctl.h>
53 #include <amcodec/codec.h>
60 stream_type_t stream_type;
68 unsigned long long ratio64;
72 class DllLibamCodecInterface
75 virtual ~DllLibamCodecInterface() {};
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;
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;
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;
97 // grab this from amffmpeg so we do not have to load DllAvUtil
98 virtual AVRational av_d2q(double d, int max)=0;
101 class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
103 // libamcodec is static linked into libamplayer.so
104 DECLARE_DLL_WRAPPER(DllLibAmCodec, "libamplayer.so")
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))
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))
122 DEFINE_METHOD4(int, h263vld, (unsigned char *p1, unsigned char *p2, int p3, int p4))
123 DEFINE_METHOD1(int, decodeble_h263, (unsigned char *p1))
125 DEFINE_METHOD2(AVRational, av_d2q, (double p1, int p2))
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)
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)
144 RESOLVE_METHOD(h263vld)
145 RESOLVE_METHOD(decodeble_h263)
147 RESOLVE_METHOD(av_d2q)
151 void codec_init_para(aml_generic_param *p_in, codec_para_t *p_out)
153 memset(p_out, 0x00, sizeof(codec_para_t));
155 #ifdef TARGET_ANDROID
156 bits_writer_t bs = {0};
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);
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
167 // added in JellyBean 4.2
168 if (CAndroidFeatures::GetVersion() > 16)
169 CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE audio_utils_handle
171 CBitstreamConverter::write_bits(&bs, 32, p_in->stream_type); // stream_type_t stream_type
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
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
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
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
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);
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
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);
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;
241 //-----------------------------------------------------------------------------------
242 //-----------------------------------------------------------------------------------
243 // AppContext - Application state
244 #define PTS_FREQ 90000
245 #define UNIT_FREQ 96000
246 #define AV_SYNC_THRESH PTS_FREQ*30
248 #define TRICKMODE_NONE 0x00
249 #define TRICKMODE_I 0x01
250 #define TRICKMODE_FFFB 0x02
252 // same as AV_NOPTS_VALUE
253 #define INT64_0 INT64_C(0x8000000000000000)
255 #define EXTERNAL_PTS (1)
256 #define SYNC_OUTSIDE (2)
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)
267 #define RW_WAIT_TIME (20 * 1000) // 20ms
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))
276 #define PLAYER_WR_FAILED (-(P_PRE|0x21))
277 #define PLAYER_WR_EMPTYP (-(P_PRE|0x22))
278 #define PLAYER_WR_FINISH (P_PRE|0x1)
280 #define PLAYER_PTS_ERROR (-(P_PRE|0x31))
281 #define PLAYER_UNSUPPORT (-(P_PRE|0x35))
282 #define PLAYER_CHECK_CODEC_ERROR (-(P_PRE|0x39))
284 #define HDR_BUF_SIZE 1024
285 typedef struct hdr_buf {
290 typedef struct am_packet {
307 AM_STREAM_UNKNOWN = 0,
316 typedef struct am_private_t
319 aml_generic_param gcodec;
322 pstream_type stream_type;
325 vformat_t video_format;
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;
340 DllLibAmCodec *m_dll;
346 /*************************************************************************/
347 /*************************************************************************/
348 void dumpfile_open(am_private_t *para)
352 static int amcodec_dumpid = 0;
353 char dump_path[128] = {0};
354 sprintf(dump_path, "/temp/dump_amcodec-%d.dat", amcodec_dumpid++);
356 para->dumpfile = open(dump_path, O_CREAT | O_RDWR, 0666);
359 void dumpfile_close(am_private_t *para)
361 if (para->dumpdemux && para->dumpfile != -1)
362 close(para->dumpfile), para->dumpfile = -1;
364 void dumpfile_write(am_private_t *para, void* buf, int bufsiz)
368 CLog::Log(LOGERROR, "dumpfile_write: wtf ? buf is null, bufsiz(%d)", bufsiz);
372 if (para->dumpdemux && para->dumpfile != -1)
373 write(para->dumpfile, buf, bufsiz);
376 /*************************************************************************/
377 /*************************************************************************/
378 static int64_t get_pts_video()
380 int fd = open("/sys/class/tsync/pts_video", O_RDONLY);
384 int size = read(fd, pts_str, sizeof(pts_str));
388 unsigned long pts = strtoul(pts_str, NULL, 16);
393 CLog::Log(LOGERROR, "get_pts_video: open /tsync/event error");
397 static int set_pts_pcrscr(int64_t value)
399 int fd = open("/sys/class/tsync/pts_pcrscr", O_WRONLY);
403 unsigned long pts = (unsigned long)value;
404 sprintf(pts_str, "0x%lx", pts);
405 write(fd, pts_str, strlen(pts_str));
410 CLog::Log(LOGERROR, "set_pts_pcrscr: open pts_pcrscr error");
414 static vformat_t codecid_to_vformat(enum AVCodecID id)
419 case AV_CODEC_ID_MPEG1VIDEO:
420 case AV_CODEC_ID_MPEG2VIDEO:
421 case AV_CODEC_ID_MPEG2VIDEO_XVMC:
422 format = VFORMAT_MPEG12;
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;
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;
439 case AV_CODEC_ID_H264:
440 format = VFORMAT_H264;
443 case AV_CODEC_ID_H264MVC:
444 // H264 Multiview Video Coding (3d blurays)
445 format = VFORMAT_H264MVC;
448 case AV_CODEC_ID_MJPEG:
449 format = VFORMAT_MJPEG;
451 case AV_CODEC_ID_VC1:
452 case AV_CODEC_ID_WMV3:
453 format = VFORMAT_VC1;
455 case AV_CODEC_ID_AVS:
456 case AV_CODEC_ID_CAVS:
457 format = VFORMAT_AVS;
461 format = VFORMAT_UNSUPPORT;
465 CLog::Log(LOGDEBUG, "codecid_to_vformat, id(%d) -> vformat(%d)", (int)id, format);
469 static vdec_type_t codec_tag_to_vdec_type(unsigned int codec_tag)
471 vdec_type_t dec_type;
474 case CODEC_TAG_MJPEG:
475 case CODEC_TAG_mjpeg:
479 dec_type = VIDEO_DEC_FORMAT_MJPEG;
485 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
491 dec_type = VIDEO_DEC_FORMAT_MPEG4_3;
496 dec_type = VIDEO_DEC_FORMAT_MPEG4_4;
503 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
507 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
513 case AV_CODEC_ID_MPEG4:
515 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
517 case AV_CODEC_ID_H263:
523 dec_type = VIDEO_DEC_FORMAT_H263;
529 case AV_CODEC_ID_H264:
531 dec_type = VIDEO_DEC_FORMAT_H264;
534 case AV_CODEC_ID_H264MVC:
535 dec_type = VIDEO_DEC_FORMAT_H264;
538 case AV_CODEC_ID_RV30:
541 dec_type = VIDEO_DEC_FORMAT_REAL_8;
543 case AV_CODEC_ID_RV40:
546 dec_type = VIDEO_DEC_FORMAT_REAL_9;
550 dec_type = VIDEO_DEC_FORMAT_WMV3;
552 case AV_CODEC_ID_VC1:
557 dec_type = VIDEO_DEC_FORMAT_WVC1;
559 case AV_CODEC_ID_VP6F:
561 dec_type = VIDEO_DEC_FORMAT_SW;
563 case AV_CODEC_ID_CAVS:
564 case AV_CODEC_ID_AVS:
566 dec_type = VIDEO_DEC_FORMAT_AVS;
569 dec_type = VIDEO_DEC_FORMAT_UNKNOW;
573 CLog::Log(LOGDEBUG, "codec_tag_to_vdec_type, codec_tag(%d) -> vdec_type(%d)", codec_tag, dec_type);
577 static void am_packet_init(am_packet_t *pkt)
579 memset(&pkt->avpkt, 0, sizeof(AVPacket));
594 void am_packet_release(am_packet_t *pkt)
596 if (pkt->buf != NULL)
597 free(pkt->buf), pkt->buf= NULL;
598 if (pkt->hdr != NULL)
600 if (pkt->hdr->data != NULL)
601 free(pkt->hdr->data), pkt->hdr->data = NULL;
602 free(pkt->hdr), pkt->hdr = NULL;
608 int check_in_pts(am_private_t *para, am_packet_t *pkt)
610 int last_duration = 0;
611 static int last_v_duration = 0;
614 last_duration = last_v_duration;
616 if (para->stream_type == AM_STREAM_ES) {
617 if ((int64_t)INT64_0 != pkt->avpts) {
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;
625 } else if ((int64_t)INT64_0 != pkt->avdts) {
626 pts = pkt->avdts * last_duration;
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;
633 last_v_duration = pkt->avduration ? pkt->avduration : 1;
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;
642 if (!para->check_first_pts) {
643 para->check_first_pts = 1;
649 return PLAYER_SUCCESS;
652 static int write_header(am_private_t *para, am_packet_t *pkt)
654 int write_bytes = 0, len = 0;
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;
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;
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;
679 dumpfile_write(para, pkt->hdr->data, write_bytes);
681 if (len == pkt->hdr->size) {
687 return PLAYER_SUCCESS;
690 int check_avbuffer_enough(am_private_t *para, am_packet_t *pkt)
695 int write_av_packet(am_private_t *para, am_packet_t *pkt)
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);
700 int write_bytes = 0, len = 0, ret;
704 // do we need to check in pts or write the header ?
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;
713 if (write_header(para, pkt) == PLAYER_WR_FAILED) {
714 CLog::Log(LOGDEBUG, "[%s]write header failed!", __FUNCTION__);
715 return PLAYER_WR_FAILED;
721 size = pkt->data_size ;
722 if (size == 0 && pkt->isvalid) {
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;
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.
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;
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.
749 if (len == pkt->data_size) {
753 } else if (len < pkt->data_size) {
757 // writing more that we should is a failure.
758 return PLAYER_WR_FAILED;
763 return PLAYER_SUCCESS;
766 /*************************************************************************/
767 static int m4s2_dx50_mp4v_add_header(unsigned char *buf, int size, am_packet_t *pkt)
769 if (size > pkt->hdr->size) {
770 free(pkt->hdr->data), pkt->hdr->data = NULL;
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;
780 pkt->hdr->size = size;
781 memcpy(pkt->hdr->data, buf, size);
783 return PLAYER_SUCCESS;
786 static int m4s2_dx50_mp4v_write_header(am_private_t *para, am_packet_t *pkt)
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) {
792 pkt->codec = ¶->vcodec;
794 CLog::Log(LOGDEBUG, "[m4s2_dx50_mp4v_add_header]invalid video codec!");
795 return PLAYER_EMPTY_P;
798 ret = write_av_packet(para, pkt);
803 static int mjpeg_data_prefeeding(am_packet_t *pkt)
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
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);
845 CLog::Log(LOGDEBUG, "[mjpeg_data_prefeeding]No enough memory!");
846 return PLAYER_FAILED;
848 return PLAYER_SUCCESS;
851 static int mjpeg_write_header(am_private_t *para, am_packet_t *pkt)
853 mjpeg_data_prefeeding(pkt);
855 pkt->codec = ¶->vcodec;
857 CLog::Log(LOGDEBUG, "[mjpeg_write_header]invalid codec!");
858 return PLAYER_EMPTY_P;
861 write_av_packet(para, pkt);
862 return PLAYER_SUCCESS;
865 static int divx3_data_prefeeding(am_packet_t *pkt, unsigned w, unsigned h)
867 unsigned i = (w << 12) | (h & 0xfff);
868 unsigned char divx311_add[10] = {
869 0x00, 0x00, 0x00, 0x01,
870 0x20, 0x00, 0x00, 0x00,
873 divx311_add[5] = (i >> 16) & 0xff;
874 divx311_add[6] = (i >> 8) & 0xff;
875 divx311_add[7] = i & 0xff;
877 if (pkt->hdr->data) {
878 memcpy(pkt->hdr->data, divx311_add, sizeof(divx311_add));
879 pkt->hdr->size = sizeof(divx311_add);
881 CLog::Log(LOGDEBUG, "[divx3_data_prefeeding]No enough memory!");
882 return PLAYER_FAILED;
884 return PLAYER_SUCCESS;
887 static int divx3_write_header(am_private_t *para, am_packet_t *pkt)
889 CLog::Log(LOGDEBUG, "divx3_write_header");
890 divx3_data_prefeeding(pkt, para->video_width, para->video_height);
892 pkt->codec = ¶->vcodec;
894 CLog::Log(LOGDEBUG, "[divx3_write_header]invalid codec!");
895 return PLAYER_EMPTY_P;
898 write_av_packet(para, pkt);
899 return PLAYER_SUCCESS;
902 static int h264_add_header(unsigned char *buf, int size, am_packet_t *pkt)
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;
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;
919 return PLAYER_FAILED;
921 static int h264_write_header(am_private_t *para, am_packet_t *pkt)
923 // CLog::Log(LOGDEBUG, "h264_write_header");
926 ret = h264_add_header(para->extradata, para->extrasize, pkt);
927 if (ret == PLAYER_SUCCESS) {
930 pkt->codec = ¶->vcodec;
932 //CLog::Log(LOGDEBUG, "[pre_header_feeding]invalid video codec!");
933 return PLAYER_EMPTY_P;
937 ret = write_av_packet(para, pkt);
942 static int wmv3_write_header(am_private_t *para, am_packet_t *pkt)
944 CLog::Log(LOGDEBUG, "wmv3_write_header");
945 unsigned i, check_sum = 0;
946 unsigned data_len = para->extrasize + 4;
948 pkt->hdr->data[0] = 0;
949 pkt->hdr->data[1] = 0;
950 pkt->hdr->data[2] = 1;
951 pkt->hdr->data[3] = 0x10;
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;
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;
967 for (i = 4 ; i < 16 ; i++) {
968 check_sum += pkt->hdr->data[i];
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;
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;
983 memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
984 pkt->hdr->size = para->extrasize + 26;
986 pkt->codec = ¶->vcodec;
988 CLog::Log(LOGDEBUG, "[wmv3_write_header]invalid codec!");
989 return PLAYER_EMPTY_P;
992 return write_av_packet(para, pkt);
995 static int wvc1_write_header(am_private_t *para, am_packet_t *pkt)
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;
1001 pkt->codec = ¶->vcodec;
1003 CLog::Log(LOGDEBUG, "[wvc1_write_header]invalid codec!");
1004 return PLAYER_EMPTY_P;
1007 return write_av_packet(para, pkt);
1010 static int mpeg_add_header(am_private_t *para, am_packet_t *pkt)
1012 CLog::Log(LOGDEBUG, "mpeg_add_header");
1013 #define STUFF_BYTES_LENGTH (256)
1015 unsigned char packet_wrapper[] = {
1016 0x00, 0x00, 0x01, 0xe0,
1017 0x00, 0x00, /* pes packet length */
1019 0x20, 0x00, 0x00, 0x00, 0x00, /* PTS */
1020 0x1f, 0xff, 0xff, 0xff, 0xff, /* DTS */
1021 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
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);
1038 pkt->codec = ¶->vcodec;
1040 CLog::Log(LOGDEBUG, "[mpeg_add_header]invalid codec!");
1041 return PLAYER_EMPTY_P;
1045 return write_av_packet(para, pkt);
1048 int pre_header_feeding(am_private_t *para, am_packet_t *pkt)
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;
1061 if (VFORMAT_H264 == para->video_format /*|| VFORMAT_H264MVC == para->video_format*/) {
1062 ret = h264_write_header(para, pkt);
1063 if (ret != PLAYER_SUCCESS) {
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) {
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) {
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) {
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) {
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) {
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) {
1111 } else if (VFORMAT_MJPEG == para->video_format) {
1112 ret = mjpeg_write_header(para, pkt);
1113 if (ret != PLAYER_SUCCESS) {
1119 if (pkt->hdr->data) {
1120 free(pkt->hdr->data);
1121 pkt->hdr->data = NULL;
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;
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) {
1145 if (pkt->hdr->data) {
1146 free(pkt->hdr->data);
1147 pkt->hdr->data = NULL;
1153 return PLAYER_SUCCESS;
1156 int divx3_prefix(am_packet_t *pkt)
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'
1162 if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1163 free(pkt->hdr->data);
1164 pkt->hdr->data = NULL;
1167 if (pkt->hdr == NULL) {
1168 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1170 CLog::Log(LOGDEBUG, "[divx3_prefix] NOMEM!");
1171 return PLAYER_FAILED;
1174 pkt->hdr->data = NULL;
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;
1184 memcpy(pkt->hdr->data, divx311_chunk_prefix, DIVX311_CHUNK_HEAD_SIZE);
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;
1191 pkt->hdr->size = DIVX311_CHUNK_HEAD_SIZE + 4;
1194 return PLAYER_SUCCESS;
1197 int set_header_info(am_private_t *para)
1199 am_packet_t *pkt = ¶->am_pkt;
1204 // pkt->hdr->size = 0;
1206 if (para->video_format == VFORMAT_MPEG4)
1208 if (para->video_codec_type == VIDEO_DEC_FORMAT_MPEG4_3)
1210 return divx3_prefix(pkt);
1212 else if (para->video_codec_type == VIDEO_DEC_FORMAT_H263)
1214 return PLAYER_UNSUPPORT;
1215 unsigned char *vld_buf;
1216 int vld_len, vld_buf_size = para->video_width * para->video_height * 2;
1218 if (!pkt->data_size) {
1219 return PLAYER_SUCCESS;
1222 if ((pkt->data[0] == 0) && (pkt->data[1] == 0) && (pkt->data[2] == 1) && (pkt->data[3] == 0xb6)) {
1223 return PLAYER_SUCCESS;
1226 vld_buf = (unsigned char*)malloc(vld_buf_size);
1228 return PLAYER_NOMEM;
1231 if (para->flv_flag) {
1232 vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 1);
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;
1241 vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 0);
1249 pkt->buf_size = vld_buf_size;
1250 pkt->data = pkt->buf;
1251 pkt->data_size = vld_len;
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;
1261 if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1262 free(pkt->hdr->data);
1263 pkt->hdr->data = NULL;
1266 if (pkt->hdr == NULL) {
1267 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1269 return PLAYER_FAILED;
1272 pkt->hdr->data = NULL;
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;
1282 pkt->hdr->data[0] = 0;
1283 pkt->hdr->data[1] = 0;
1284 pkt->hdr->data[2] = 1;
1285 pkt->hdr->data[3] = 0x10;
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;
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;
1302 for (i = 4 ; i < 16 ; i++) {
1303 check_sum += pkt->hdr->data[i];
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;
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;
1318 memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
1321 data_len = para->extrasize + 26;
1323 pkt->hdr->data = (char*)malloc(22);
1324 if (pkt->hdr->data == NULL) {
1325 return PLAYER_FAILED;
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;
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;
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;
1348 for (i = data_len + 4 ; i < data_len + 16 ; i++) {
1349 check_sum += pkt->hdr->data[i];
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;
1359 pkt->hdr->size = data_len + 22;
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;
1367 if (pkt->hdr == NULL) {
1368 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1370 CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1371 return PLAYER_FAILED;
1374 pkt->hdr->data = NULL;
1378 pkt->hdr->data = (char*)malloc(4);
1379 if (pkt->hdr->data == NULL) {
1380 CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1381 return PLAYER_FAILED;
1384 pkt->hdr->data[0] = 0;
1385 pkt->hdr->data[1] = 0;
1386 pkt->hdr->data[2] = 1;
1387 pkt->hdr->data[3] = 0xd;
1393 return PLAYER_SUCCESS;
1396 /*************************************************************************/
1397 CAMLCodec::CAMLCodec() : CThread("CAMLCodec")
1400 am_private = new am_private_t;
1401 memset(am_private, 0, sizeof(am_private_t));
1402 m_dll = new DllLibAmCodec;
1404 am_private->m_dll = m_dll;
1408 CAMLCodec::~CAMLCodec()
1413 delete m_dll, m_dll = NULL;
1416 bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
1418 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion());
1420 m_speed = DVD_PLAYSPEED_NORMAL;
1425 m_dst_rect.SetRect(0, 0, 0, 0);
1429 m_vbufsize = 500000 * 2;
1434 ShowMainVideo(false);
1436 am_packet_init(&am_private->am_pkt);
1437 // default stream type
1438 am_private->stream_type = AM_STREAM_ES;
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;
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;
1453 // handle video rate
1454 if (hints.rfpsrate > 0 && hints.rfpsscale != 0)
1456 // check ffmpeg r_frame_rate 1st
1457 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.rfpsscale / hints.rfpsrate;
1459 else if (hints.fpsrate > 0 && hints.fpsscale != 0)
1461 // then ffmpeg avg_frame_rate next
1462 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.fpsscale / hints.fpsrate;
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)
1469 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1470 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 25000;
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)
1477 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1478 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
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)
1485 if (am_private->video_rate >= 3200 && am_private->video_rate <= 3210)
1487 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1488 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
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;
1501 am_private->video_format = codecid_to_vformat(hints.codec);
1502 switch (am_private->video_format)
1505 am_private->extrasize = hints.extrasize;
1506 am_private->extradata = (uint8_t*)malloc(hints.extrasize);
1507 memcpy(am_private->extradata, hints.extradata, hints.extrasize);
1510 case VFORMAT_MPEG12:
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);
1517 am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_id);
1519 am_private->flv_flag = 0;
1520 if (am_private->video_codec_id == AV_CODEC_ID_FLV1)
1522 am_private->video_codec_tag = CODEC_TAG_F263;
1523 am_private->flv_flag = 1;
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);
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;
1549 switch(am_private->video_format)
1554 am_private->gcodec.param = (void*)EXTERNAL_PTS;
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);
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;
1571 static unsigned short tbl[9] = {0};
1572 if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type)
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);
1578 for (unsigned int i = 1; i <= am_private->gcodec.extra; i++)
1581 tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff);
1584 am_private->gcodec.param = &tbl;
1588 // vc1 in an avi file
1589 if (m_hints.ptsinvalid)
1590 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1593 am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16));
1595 // translate from generic to firemware version dependent
1596 m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec);
1598 int ret = m_dll->codec_init(&am_private->vcodec);
1599 if (ret != CODEC_ERROR_NONE)
1601 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
1604 am_private->dumpdemux = false;
1605 dumpfile_open(am_private);
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);
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);
1616 am_private->am_pkt.codec = &am_private->vcodec;
1617 pre_header_feeding(am_private, &am_private->am_pkt);
1621 g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1622 g_renderManager.RegisterRenderFeaturesCallBack((const void*)this, RenderFeaturesCallBack);
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);
1632 aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0);
1636 // vcodec is open, update speed if it was
1637 // changed before dvdplayer called OpenDecoder.
1643 void CAMLCodec::CloseDecoder()
1645 CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
1648 g_renderManager.RegisterRenderUpdateCallBack((const void*)NULL, NULL);
1649 g_renderManager.RegisterRenderFeaturesCallBack((const void*)NULL, NULL);
1651 // never leave vcodec ff/rw or paused.
1652 if (m_speed != DVD_PLAYSPEED_NORMAL)
1654 m_dll->codec_resume(&am_private->vcodec);
1655 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1657 m_dll->codec_close(&am_private->vcodec);
1658 dumpfile_close(am_private);
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);
1667 ShowMainVideo(false);
1671 void CAMLCodec::Reset()
1673 CLog::Log(LOGDEBUG, "CAMLCodec::Reset");
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);
1682 // restore the speed (some amcodec versions require this)
1683 if (m_speed != DVD_PLAYSPEED_NORMAL)
1685 m_dll->codec_resume(&am_private->vcodec);
1686 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1688 // reset the decoder
1689 m_dll->codec_reset(&am_private->vcodec);
1690 dumpfile_close(am_private);
1691 dumpfile_open(am_private);
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);
1699 // restore the saved system blackout_policy value
1700 aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy);
1702 // reset some interal vars
1710 int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
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);
1722 am_private->am_pkt.data = pData;
1723 am_private->am_pkt.data_size = iSize;
1725 am_private->am_pkt.newflag = 1;
1726 am_private->am_pkt.isvalid = 1;
1727 am_private->am_pkt.avduration = 0;
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;
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;
1739 if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
1740 am_private->am_pkt.avpts -= m_start_pts;
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;
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;
1753 if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
1754 am_private->am_pkt.avdts -= m_start_dts;
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);
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);
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)
1769 // abort on any errors.
1770 if (write_av_packet(am_private, &am_private->am_pkt) != PLAYER_SUCCESS)
1773 if (am_private->am_pkt.isvalid)
1774 CLog::Log(LOGDEBUG, "CAMLCodec::Decode: write_av_packet looping");
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.
1783 m_1st_pts = am_private->am_pkt.lastpts;
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;
1790 target_timesize = 2.0;
1792 // keep hw buffered demux above 1 second
1793 if (GetTimeSize() < target_timesize && m_speed == DVD_PLAYSPEED_NORMAL)
1796 // wait until we get a new frame or 25ms,
1797 if (m_old_pictcnt == m_cur_pictcnt)
1798 m_ready_event.WaitMSec(25);
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)
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)
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());
1821 bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
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;
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;
1839 void CAMLCodec::SetSpeed(int speed)
1841 CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
1843 // update internal vars regardless
1844 // of if we are open or not.
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);
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);
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);
1865 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
1870 int CAMLCodec::GetDataSize()
1875 struct buf_status vbuf ={0};
1876 if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
1877 m_vbufsize = vbuf.size;
1879 return vbuf.data_len;
1882 double CAMLCodec::GetTimeSize()
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.
1891 m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
1893 m_timesize = (double)(am_private->am_pkt.lastpts - m_cur_pts) / PTS_FREQ;
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;
1900 else if (timesize > 7.0)
1906 void CAMLCodec::Process()
1908 CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
1910 // bump our priority to be level with SoftAE
1911 SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
1914 int64_t pts_video = 0;
1915 if (am_private->am_pkt.lastpts > 0)
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)
1922 CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
1926 pts_video = get_pts_video();
1927 if (m_cur_pts != pts_video)
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));
1932 // other threads look at these, do them first
1933 m_cur_pts = pts_video;
1935 m_ready_event.Set();
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;
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
1949 //CLog::Log(LOGDEBUG, "CAMLCodec::Process: app_pts(%f), pts_video/PTS_FREQ(%f)",
1950 // app_pts, (double)pts_video/PTS_FREQ);
1952 double error = app_pts - (double)pts_video/PTS_FREQ;
1953 double abs_error = fabs(error);
1954 if (abs_error > 0.125)
1956 //CLog::Log(LOGDEBUG, "CAMLCodec::Process pts diff = %f", error);
1957 if (abs_error > 0.150)
1959 // big error so try to reset pts_pcrscr
1960 SetVideoPtsSeconds(app_pts);
1964 // small error so try to avoid a frame jump
1965 SetVideoPtsSeconds((double)pts_video/PTS_FREQ + error/4);
1975 SetPriority(THREAD_PRIORITY_NORMAL);
1976 CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
1979 double CAMLCodec::GetPlayerPtsSeconds()
1981 double clock_pts = 0.0;
1982 CDVDClock *playerclock = CDVDClock::GetMasterClock();
1984 clock_pts = playerclock->GetClock() / DVD_TIME_BASE;
1989 void CAMLCodec::SetVideoPtsSeconds(const double pts)
1991 //CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoPtsSeconds: pts(%f)", pts);
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;
2000 set_pts_pcrscr(pts_video);
2004 void CAMLCodec::ShowMainVideo(const bool show)
2006 static int saved_disable_video = -1;
2008 int disable_video = show ? 0:1;
2009 if (saved_disable_video == disable_video)
2012 aml_set_sysfs_int("/sys/class/video/disable_video", disable_video);
2013 saved_disable_video = disable_video;
2016 void CAMLCodec::SetVideoZoom(const float zoom)
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));
2024 void CAMLCodec::SetVideoContrast(const int contrast)
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);
2031 void CAMLCodec::SetVideoBrightness(const int brightness)
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);
2038 void CAMLCodec::SetVideoSaturation(const int saturation)
2040 // output saturation range is -127 to 127 with default of 127.
2041 aml_set_sysfs_int("/sys/class/video/saturation", saturation);
2044 void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
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);
2054 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
2056 CAMLCodec *codec = (CAMLCodec*)ctx;
2058 codec->GetRenderFeatures(renderFeatures);
2061 void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
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.
2067 // video zoom adjustment.
2068 float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
2069 if ((int)(zoom * 1000) != (int)(m_zoom * 1000))
2073 // video contrast adjustment.
2074 int contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast;
2075 if (contrast != m_contrast)
2077 SetVideoContrast(contrast);
2078 m_contrast = contrast;
2080 // video brightness adjustment.
2081 int brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness;
2082 if (brightness != m_brightness)
2084 SetVideoBrightness(brightness);
2085 m_brightness = brightness;
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))
2091 m_dst_rect = DestRect;
2092 m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
2096 // mainvideo 'should' be showing already if we get here, make sure.
2097 ShowMainVideo(true);
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;
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;
2118 ShowMainVideo(false);
2120 // goofy 0/1 based difference in aml axis coordinates.
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);
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());
2139 // we only get called once gui has changed to something
2140 // that would show video playback, so show it.
2141 ShowMainVideo(true);
2144 void CAMLCodec::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
2146 CAMLCodec *codec = (CAMLCodec*)ctx;
2147 codec->SetVideoRect(SrcRect, DestRect);