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 #ifdef TARGET_ANDROID
1419 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion());
1422 m_speed = DVD_PLAYSPEED_NORMAL;
1427 m_dst_rect.SetRect(0, 0, 0, 0);
1431 m_vbufsize = 500000 * 2;
1436 ShowMainVideo(false);
1438 am_packet_init(&am_private->am_pkt);
1439 // default stream type
1440 am_private->stream_type = AM_STREAM_ES;
1442 am_private->video_width = hints.width;
1443 am_private->video_height = hints.height;
1444 am_private->video_codec_id = hints.codec;
1445 am_private->video_codec_tag = hints.codec_tag;
1446 am_private->video_pid = hints.pid;
1448 // handle video ratio
1449 AVRational video_ratio = m_dll->av_d2q(1, SHRT_MAX);
1450 //if (!hints.forced_aspect)
1451 // video_ratio = m_dll->av_d2q(hints.aspect, SHRT_MAX);
1452 am_private->video_ratio = ((int32_t)video_ratio.num << 16) | video_ratio.den;
1453 am_private->video_ratio64 = ((int64_t)video_ratio.num << 32) | video_ratio.den;
1455 // handle video rate
1456 if (hints.rfpsrate > 0 && hints.rfpsscale != 0)
1458 // check ffmpeg r_frame_rate 1st
1459 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.rfpsscale / hints.rfpsrate;
1461 else if (hints.fpsrate > 0 && hints.fpsscale != 0)
1463 // then ffmpeg avg_frame_rate next
1464 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.fpsscale / hints.fpsrate;
1467 // check for 1920x1080, interlaced, 25 fps
1468 // incorrectly reported as 50 fps (yes, video_rate == 1920)
1469 if (hints.width == 1920 && am_private->video_rate == 1920)
1471 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1472 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 25000;
1475 // check for SD h264 content incorrectly reported as 60 fsp
1476 // mp4/avi containers :(
1477 if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720 && am_private->video_rate == 1602)
1479 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1480 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1483 // check for SD h264 content incorrectly reported as some form of 30 fsp
1484 // mp4/avi containers :(
1485 if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720)
1487 if (am_private->video_rate >= 3200 && am_private->video_rate <= 3210)
1489 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1490 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1494 // handle orientation
1495 am_private->video_rotation_degree = 0;
1496 if (hints.orientation == 90)
1497 am_private->video_rotation_degree = 1;
1498 else if (hints.orientation == 180)
1499 am_private->video_rotation_degree = 2;
1500 else if (hints.orientation == 270)
1501 am_private->video_rotation_degree = 3;
1503 am_private->video_format = codecid_to_vformat(hints.codec);
1504 switch (am_private->video_format)
1507 am_private->extrasize = hints.extrasize;
1508 am_private->extradata = (uint8_t*)malloc(hints.extrasize);
1509 memcpy(am_private->extradata, hints.extradata, hints.extrasize);
1512 case VFORMAT_MPEG12:
1516 if (am_private->stream_type == AM_STREAM_ES && am_private->video_codec_tag != 0)
1517 am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_tag);
1519 am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_id);
1521 am_private->flv_flag = 0;
1522 if (am_private->video_codec_id == AV_CODEC_ID_FLV1)
1524 am_private->video_codec_tag = CODEC_TAG_F263;
1525 am_private->flv_flag = 1;
1528 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder "
1529 "hints.width(%d), hints.height(%d), hints.codec(%d), hints.codec_tag(%d), hints.pid(%d)",
1530 hints.width, hints.height, hints.codec, hints.codec_tag, hints.pid);
1531 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.fpsrate(%d), hints.fpsscale(%d), hints.rfpsrate(%d), hints.rfpsscale(%d), video_rate(%d)",
1532 hints.fpsrate, hints.fpsscale, hints.rfpsrate, hints.rfpsscale, am_private->video_rate);
1533 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.aspect(%f), video_ratio.num(%d), video_ratio.den(%d)",
1534 hints.aspect, video_ratio.num, video_ratio.den);
1535 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.orientation(%d), hints.forced_aspect(%d), hints.extrasize(%d)",
1536 hints.orientation, hints.forced_aspect, hints.extrasize);
1538 // default video codec params
1539 am_private->gcodec.noblock = 0;
1540 am_private->gcodec.video_pid = am_private->video_pid;
1541 am_private->gcodec.video_type = am_private->video_format;
1542 am_private->gcodec.stream_type = STREAM_TYPE_ES_VIDEO;
1543 am_private->gcodec.format = am_private->video_codec_type;
1544 am_private->gcodec.width = am_private->video_width;
1545 am_private->gcodec.height = am_private->video_height;
1546 am_private->gcodec.rate = am_private->video_rate;
1547 am_private->gcodec.ratio = am_private->video_ratio;
1548 am_private->gcodec.ratio64 = am_private->video_ratio64;
1549 am_private->gcodec.param = NULL;
1551 switch(am_private->video_format)
1556 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1559 case VFORMAT_H264MVC:
1560 am_private->gcodec.format = VIDEO_DEC_FORMAT_H264;
1561 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1562 // h264 in an avi file
1563 if (m_hints.ptsinvalid)
1564 am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
1567 am_private->stream_type = AM_STREAM_RM;
1568 am_private->vcodec.noblock = 1;
1569 am_private->vcodec.stream_type = STREAM_TYPE_RM;
1570 am_private->vcodec.am_sysinfo.ratio = 0x100;
1571 am_private->vcodec.am_sysinfo.ratio64 = 0;
1573 static unsigned short tbl[9] = {0};
1574 if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type)
1576 am_private->gcodec.extra = am_private->extradata[1] & 7;
1577 tbl[0] = (((am_private->gcodec.width >> 2) - 1) << 8)
1578 | (((am_private->gcodec.height >> 2) - 1) & 0xff);
1580 for (unsigned int i = 1; i <= am_private->gcodec.extra; i++)
1583 tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff);
1586 am_private->gcodec.param = &tbl;
1590 // vc1 in an avi file
1591 if (m_hints.ptsinvalid)
1592 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1595 am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16));
1597 // translate from generic to firemware version dependent
1598 m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec);
1600 int ret = m_dll->codec_init(&am_private->vcodec);
1601 if (ret != CODEC_ERROR_NONE)
1603 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
1606 am_private->dumpdemux = false;
1607 dumpfile_open(am_private);
1609 // make sure we are not stuck in pause (amcodec bug)
1610 m_dll->codec_resume(&am_private->vcodec);
1611 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1613 m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
1614 m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
1615 // disable tsync, we are playing video disconnected from audio.
1616 aml_set_sysfs_int("/sys/class/tsync/enable", 0);
1618 am_private->am_pkt.codec = &am_private->vcodec;
1619 pre_header_feeding(am_private, &am_private->am_pkt);
1623 g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1624 g_renderManager.RegisterRenderFeaturesCallBack((const void*)this, RenderFeaturesCallBack);
1627 // if display is set to 1080xxx, then disable deinterlacer for HD content
1628 // else bandwidth usage is too heavy and it will slow down video decoder.
1629 char display_mode[256] = {0};
1630 aml_get_sysfs_str("/sys/class/display/mode", display_mode, 255);
1631 if (strstr(display_mode,"1080"))
1632 aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 1);
1634 aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0);
1638 // vcodec is open, update speed if it was
1639 // changed before dvdplayer called OpenDecoder.
1645 void CAMLCodec::CloseDecoder()
1647 CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
1650 g_renderManager.RegisterRenderUpdateCallBack((const void*)NULL, NULL);
1651 g_renderManager.RegisterRenderFeaturesCallBack((const void*)NULL, NULL);
1653 // never leave vcodec ff/rw or paused.
1654 if (m_speed != DVD_PLAYSPEED_NORMAL)
1656 m_dll->codec_resume(&am_private->vcodec);
1657 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1659 m_dll->codec_close(&am_private->vcodec);
1660 dumpfile_close(am_private);
1663 am_packet_release(&am_private->am_pkt);
1664 free(am_private->extradata);
1665 am_private->extradata = NULL;
1666 // return tsync to default so external apps work
1667 aml_set_sysfs_int("/sys/class/tsync/enable", 1);
1669 ShowMainVideo(false);
1673 void CAMLCodec::Reset()
1675 CLog::Log(LOGDEBUG, "CAMLCodec::Reset");
1680 // set the system blackout_policy to leave the last frame showing
1681 int blackout_policy = aml_get_sysfs_int("/sys/class/video/blackout_policy");
1682 aml_set_sysfs_int("/sys/class/video/blackout_policy", 0);
1684 // restore the speed (some amcodec versions require this)
1685 if (m_speed != DVD_PLAYSPEED_NORMAL)
1687 m_dll->codec_resume(&am_private->vcodec);
1688 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1690 // reset the decoder
1691 m_dll->codec_reset(&am_private->vcodec);
1692 dumpfile_close(am_private);
1693 dumpfile_open(am_private);
1695 // re-init our am_pkt
1696 am_packet_release(&am_private->am_pkt);
1697 am_packet_init(&am_private->am_pkt);
1698 am_private->am_pkt.codec = &am_private->vcodec;
1699 pre_header_feeding(am_private, &am_private->am_pkt);
1701 // restore the saved system blackout_policy value
1702 aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy);
1704 // reset some interal vars
1712 int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
1717 // grr, m_RenderUpdateCallBackFn in g_renderManager is NULL'ed during
1718 // g_renderManager.Configure call by player, which happens after the codec
1719 // OpenDecoder call. So we need to restore it but it does not seem to stick :)
1720 g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1724 am_private->am_pkt.data = pData;
1725 am_private->am_pkt.data_size = iSize;
1727 am_private->am_pkt.newflag = 1;
1728 am_private->am_pkt.isvalid = 1;
1729 am_private->am_pkt.avduration = 0;
1731 // handle pts, including 31bit wrap, aml can only handle 31
1732 // bit pts as it uses an int in kernel.
1733 if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
1734 am_private->am_pkt.avpts = AV_NOPTS_VALUE;
1737 am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
1738 if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
1739 m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
1741 if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
1742 am_private->am_pkt.avpts -= m_start_pts;
1745 // handle dts, including 31bit wrap, aml can only handle 31
1746 // bit dts as it uses an int in kernel.
1747 if (dts == DVD_NOPTS_VALUE)
1748 am_private->am_pkt.avdts = AV_NOPTS_VALUE;
1751 am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
1752 if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
1753 m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
1755 if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
1756 am_private->am_pkt.avdts -= m_start_dts;
1758 //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
1759 // iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
1761 // some formats need header/data tweaks.
1762 // the actual write occurs once in write_av_packet
1763 // and is controlled by am_pkt.newflag.
1764 set_header_info(am_private);
1766 // loop until we write all into codec, am_pkt.isvalid
1767 // will get set to zero once everything is consumed.
1768 // PLAYER_SUCCESS means all is ok, not all bytes were written.
1769 while (am_private->am_pkt.isvalid)
1771 // abort on any errors.
1772 if (write_av_packet(am_private, &am_private->am_pkt) != PLAYER_SUCCESS)
1775 if (am_private->am_pkt.isvalid)
1776 CLog::Log(LOGDEBUG, "CAMLCodec::Decode: write_av_packet looping");
1779 // if we seek, then GetTimeSize is wrong as
1780 // reports lastpts - cur_pts and hw decoder has
1781 // not started outputing new pts values yet.
1782 // so we grab the 1st pts sent into driver and
1783 // use that to calc GetTimeSize.
1785 m_1st_pts = am_private->am_pkt.lastpts;
1788 // if we have still frames, demux size will be small
1789 // and we need to pre-buffer more.
1790 double target_timesize = 1.0;
1792 target_timesize = 2.0;
1794 // keep hw buffered demux above 1 second
1795 if (GetTimeSize() < target_timesize && m_speed == DVD_PLAYSPEED_NORMAL)
1798 // wait until we get a new frame or 25ms,
1799 if (m_old_pictcnt == m_cur_pictcnt)
1800 m_ready_event.WaitMSec(25);
1802 // we must return VC_BUFFER or VC_PICTURE,
1803 // default to VC_BUFFER.
1804 int rtn = VC_BUFFER;
1805 if (m_old_pictcnt != m_cur_pictcnt)
1809 // we got a new pict, try and keep hw buffered demux above 2 seconds.
1810 // this, combined with the above 1 second check, keeps hw buffered demux between 1 and 2 seconds.
1811 // we also check to make sure we keep from filling hw buffer.
1812 if (GetTimeSize() < 2.0 && GetDataSize() < m_vbufsize/3)
1816 CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
1817 "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
1818 rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
1823 bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
1828 pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
1829 pDvdVideoPicture->format = RENDER_FMT_BYPASS;
1830 pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
1832 pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
1833 pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
1834 // video pts cannot be late or dvdplayer goes nuts,
1835 // so run it one frame ahead
1836 pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
1841 void CAMLCodec::SetSpeed(int speed)
1843 CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
1845 // update internal vars regardless
1846 // of if we are open or not.
1854 case DVD_PLAYSPEED_PAUSE:
1855 m_dll->codec_pause(&am_private->vcodec);
1856 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1858 case DVD_PLAYSPEED_NORMAL:
1859 m_dll->codec_resume(&am_private->vcodec);
1860 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1863 m_dll->codec_resume(&am_private->vcodec);
1864 if (am_private->video_format == VFORMAT_H264)
1865 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
1867 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
1872 int CAMLCodec::GetDataSize()
1877 struct buf_status vbuf ={0};
1878 if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
1879 m_vbufsize = vbuf.size;
1881 return vbuf.data_len;
1884 double CAMLCodec::GetTimeSize()
1889 // if m_cur_pts is zero, hw decoder was not started yet
1890 // so we use the pts of the 1st demux packet that was send
1891 // to hw decoder to calc timesize.
1893 m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
1895 m_timesize = (double)(am_private->am_pkt.lastpts - m_cur_pts) / PTS_FREQ;
1897 // lie to DVDPlayer, it is hardcoded to a max of 8 seconds,
1898 // if you buffer more than 8 seconds, it goes nuts.
1899 double timesize = m_timesize;
1902 else if (timesize > 7.0)
1908 void CAMLCodec::Process()
1910 CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
1912 // bump our priority to be level with SoftAE
1913 SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
1916 int64_t pts_video = 0;
1917 if (am_private->am_pkt.lastpts > 0)
1919 // this is a blocking poll that returns every vsync.
1920 // since we are running at a higher priority, make sure
1921 // we sleep if the call fails or does a timeout.
1922 if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
1924 CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
1928 pts_video = get_pts_video();
1929 if (m_cur_pts != pts_video)
1931 //CLog::Log(LOGDEBUG, "CAMLCodec::Process: pts_video(%lld), pts_video/PTS_FREQ(%f), duration(%f)",
1932 // pts_video, (double)pts_video/PTS_FREQ, 1.0/((double)(pts_video - m_cur_pts)/PTS_FREQ));
1934 // other threads look at these, do them first
1935 m_cur_pts = pts_video;
1937 m_ready_event.Set();
1939 // correct video pts by starting pts.
1940 if (m_start_pts != 0)
1941 pts_video += m_start_pts;
1942 else if (m_start_dts != 0)
1943 pts_video += m_start_dts;
1945 double app_pts = GetPlayerPtsSeconds();
1946 // add in audio delay/display latency contribution
1947 double offset = g_renderManager.GetDisplayLatency() - CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay;
1948 // correct video pts by user set delay and rendering delay
1951 //CLog::Log(LOGDEBUG, "CAMLCodec::Process: app_pts(%f), pts_video/PTS_FREQ(%f)",
1952 // app_pts, (double)pts_video/PTS_FREQ);
1954 double error = app_pts - (double)pts_video/PTS_FREQ;
1955 double abs_error = fabs(error);
1956 if (abs_error > 0.125)
1958 //CLog::Log(LOGDEBUG, "CAMLCodec::Process pts diff = %f", error);
1959 if (abs_error > 0.150)
1961 // big error so try to reset pts_pcrscr
1962 SetVideoPtsSeconds(app_pts);
1966 // small error so try to avoid a frame jump
1967 SetVideoPtsSeconds((double)pts_video/PTS_FREQ + error/4);
1977 SetPriority(THREAD_PRIORITY_NORMAL);
1978 CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
1981 double CAMLCodec::GetPlayerPtsSeconds()
1983 double clock_pts = 0.0;
1984 CDVDClock *playerclock = CDVDClock::GetMasterClock();
1986 clock_pts = playerclock->GetClock() / DVD_TIME_BASE;
1991 void CAMLCodec::SetVideoPtsSeconds(const double pts)
1993 //CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoPtsSeconds: pts(%f)", pts);
1996 int64_t pts_video = (int64_t)(pts * PTS_FREQ);
1997 if (m_start_pts != 0)
1998 pts_video -= m_start_pts;
1999 else if (m_start_dts != 0)
2000 pts_video -= m_start_dts;
2002 set_pts_pcrscr(pts_video);
2006 void CAMLCodec::ShowMainVideo(const bool show)
2008 static int saved_disable_video = -1;
2010 int disable_video = show ? 0:1;
2011 if (saved_disable_video == disable_video)
2014 aml_set_sysfs_int("/sys/class/video/disable_video", disable_video);
2015 saved_disable_video = disable_video;
2018 void CAMLCodec::SetVideoZoom(const float zoom)
2020 // input zoom range is 0.5 to 2.0 with a default of 1.0.
2021 // output zoom range is 2 to 300 with default of 100.
2022 // we limit that to a range of 50 to 200 with default of 100.
2023 aml_set_sysfs_int("/sys/class/video/zoom", (int)(100 * zoom));
2026 void CAMLCodec::SetVideoContrast(const int contrast)
2028 // input contrast range is 0 to 100 with default of 50.
2029 // output contrast range is -255 to 255 with default of 0.
2030 int aml_contrast = (255 * (contrast - 50)) / 50;
2031 aml_set_sysfs_int("/sys/class/video/contrast", aml_contrast);
2033 void CAMLCodec::SetVideoBrightness(const int brightness)
2035 // input brightness range is 0 to 100 with default of 50.
2036 // output brightness range is -127 to 127 with default of 0.
2037 int aml_brightness = (127 * (brightness - 50)) / 50;
2038 aml_set_sysfs_int("/sys/class/video/brightness", aml_brightness);
2040 void CAMLCodec::SetVideoSaturation(const int saturation)
2042 // output saturation range is -127 to 127 with default of 127.
2043 aml_set_sysfs_int("/sys/class/video/saturation", saturation);
2046 void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
2048 renderFeatures.push_back(RENDERFEATURE_ZOOM);
2049 renderFeatures.push_back(RENDERFEATURE_CONTRAST);
2050 renderFeatures.push_back(RENDERFEATURE_BRIGHTNESS);
2051 renderFeatures.push_back(RENDERFEATURE_STRETCH);
2052 renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
2056 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
2058 CAMLCodec *codec = (CAMLCodec*)ctx;
2060 codec->GetRenderFeatures(renderFeatures);
2063 void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
2065 // this routine gets called every video frame
2066 // and is in the context of the renderer thread so
2067 // do not do anything stupid here.
2069 // video zoom adjustment.
2070 float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
2071 if ((int)(zoom * 1000) != (int)(m_zoom * 1000))
2075 // video contrast adjustment.
2076 int contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast;
2077 if (contrast != m_contrast)
2079 SetVideoContrast(contrast);
2080 m_contrast = contrast;
2082 // video brightness adjustment.
2083 int brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness;
2084 if (brightness != m_brightness)
2086 SetVideoBrightness(brightness);
2087 m_brightness = brightness;
2090 // check if destination rect or video view mode has changed
2091 if ((m_dst_rect != DestRect) || (m_view_mode != CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode))
2093 m_dst_rect = DestRect;
2094 m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
2098 // mainvideo 'should' be showing already if we get here, make sure.
2099 ShowMainVideo(true);
2103 CRect gui, display, dst_rect;
2104 gui = g_graphicsContext.GetViewWindow();
2105 // when display is at 1080p, we have freescale enabled
2106 // and that scales all layers into 1080p display including video,
2107 // so we have to setup video axis for 720p instead of 1080p... Boooo.
2108 display = g_graphicsContext.GetViewWindow();
2109 dst_rect = m_dst_rect;
2112 float xscale = display.Width() / gui.Width();
2113 float yscale = display.Height() / gui.Height();
2114 dst_rect.x1 *= xscale;
2115 dst_rect.x2 *= xscale;
2116 dst_rect.y1 *= yscale;
2117 dst_rect.y2 *= yscale;
2120 ShowMainVideo(false);
2122 // goofy 0/1 based difference in aml axis coordinates.
2127 char video_axis[256] = {0};
2128 sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
2129 aml_set_sysfs_str("/sys/class/video/axis", video_axis);
2130 // make sure we are in 'full stretch' so we can stretch
2131 aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
2134 CStdString rectangle;
2135 rectangle.Format("%i,%i,%i,%i",
2136 (int)dst_rect.x1, (int)dst_rect.y1,
2137 (int)dst_rect.Width(), (int)dst_rect.Height());
2138 CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
2141 // we only get called once gui has changed to something
2142 // that would show video playback, so show it.
2143 ShowMainVideo(true);
2146 void CAMLCodec::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
2148 CAMLCodec *codec = (CAMLCodec*)ctx;
2149 codec->SetVideoRect(SrcRect, DestRect);