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/RenderFlags.h"
28 #include "cores/VideoRenderers/RenderManager.h"
29 #include "guilib/GraphicContext.h"
30 #include "settings/MediaSettings.h"
31 #include "settings/Settings.h"
32 #include "utils/AMLUtils.h"
33 #include "utils/log.h"
34 #include "utils/StringUtils.h"
35 #include "utils/TimeUtils.h"
37 #if defined(TARGET_ANDROID)
38 #include "android/activity/AndroidFeatures.h"
39 #include "utils/BitstreamConverter.h"
46 #include <semaphore.h>
50 #include <sys/ioctl.h>
54 #include <amcodec/codec.h>
61 stream_type_t stream_type;
69 unsigned long long ratio64;
73 class DllLibamCodecInterface
76 virtual ~DllLibamCodecInterface() {};
78 virtual int codec_init(codec_para_t *pcodec)=0;
79 virtual int codec_close(codec_para_t *pcodec)=0;
80 virtual int codec_reset(codec_para_t *pcodec)=0;
81 virtual int codec_pause(codec_para_t *pcodec)=0;
82 virtual int codec_resume(codec_para_t *pcodec)=0;
83 virtual int codec_write(codec_para_t *pcodec, void *buffer, int len)=0;
84 virtual int codec_checkin_pts(codec_para_t *pcodec, unsigned long pts)=0;
85 virtual int codec_get_vbuf_state(codec_para_t *pcodec, struct buf_status *buf)=0;
86 virtual int codec_get_vdec_state(codec_para_t *pcodec, struct vdec_status *vdec)=0;
88 virtual int codec_init_cntl(codec_para_t *pcodec)=0;
89 virtual int codec_poll_cntl(codec_para_t *pcodec)=0;
90 virtual int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode)=0;
91 virtual int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh)=0;
92 virtual int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh)=0;
94 // grab these from libamplayer
95 virtual int h263vld(unsigned char *inbuf, unsigned char *outbuf, int inbuf_len, int s263)=0;
96 virtual int decodeble_h263(unsigned char *buf)=0;
98 // grab this from amffmpeg so we do not have to load DllAvUtil
99 virtual AVRational av_d2q(double d, int max)=0;
102 class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
104 // libamcodec is static linked into libamplayer.so
105 DECLARE_DLL_WRAPPER(DllLibAmCodec, "libamplayer.so")
107 DEFINE_METHOD1(int, codec_init, (codec_para_t *p1))
108 DEFINE_METHOD1(int, codec_close, (codec_para_t *p1))
109 DEFINE_METHOD1(int, codec_reset, (codec_para_t *p1))
110 DEFINE_METHOD1(int, codec_pause, (codec_para_t *p1))
111 DEFINE_METHOD1(int, codec_resume, (codec_para_t *p1))
112 DEFINE_METHOD3(int, codec_write, (codec_para_t *p1, void *p2, int p3))
113 DEFINE_METHOD2(int, codec_checkin_pts, (codec_para_t *p1, unsigned long p2))
114 DEFINE_METHOD2(int, codec_get_vbuf_state, (codec_para_t *p1, struct buf_status * p2))
115 DEFINE_METHOD2(int, codec_get_vdec_state, (codec_para_t *p1, struct vdec_status * p2))
117 DEFINE_METHOD1(int, codec_init_cntl, (codec_para_t *p1))
118 DEFINE_METHOD1(int, codec_poll_cntl, (codec_para_t *p1))
119 DEFINE_METHOD2(int, codec_set_cntl_mode, (codec_para_t *p1, unsigned int p2))
120 DEFINE_METHOD2(int, codec_set_cntl_avthresh, (codec_para_t *p1, unsigned int p2))
121 DEFINE_METHOD2(int, codec_set_cntl_syncthresh,(codec_para_t *p1, unsigned int p2))
123 DEFINE_METHOD4(int, h263vld, (unsigned char *p1, unsigned char *p2, int p3, int p4))
124 DEFINE_METHOD1(int, decodeble_h263, (unsigned char *p1))
126 DEFINE_METHOD2(AVRational, av_d2q, (double p1, int p2))
128 BEGIN_METHOD_RESOLVE()
129 RESOLVE_METHOD(codec_init)
130 RESOLVE_METHOD(codec_close)
131 RESOLVE_METHOD(codec_reset)
132 RESOLVE_METHOD(codec_pause)
133 RESOLVE_METHOD(codec_resume)
134 RESOLVE_METHOD(codec_write)
135 RESOLVE_METHOD(codec_checkin_pts)
136 RESOLVE_METHOD(codec_get_vbuf_state)
137 RESOLVE_METHOD(codec_get_vdec_state)
139 RESOLVE_METHOD(codec_init_cntl)
140 RESOLVE_METHOD(codec_poll_cntl)
141 RESOLVE_METHOD(codec_set_cntl_mode)
142 RESOLVE_METHOD(codec_set_cntl_avthresh)
143 RESOLVE_METHOD(codec_set_cntl_syncthresh)
145 RESOLVE_METHOD(h263vld)
146 RESOLVE_METHOD(decodeble_h263)
148 RESOLVE_METHOD(av_d2q)
152 void codec_init_para(aml_generic_param *p_in, codec_para_t *p_out)
154 memset(p_out, 0x00, sizeof(codec_para_t));
156 #ifdef TARGET_ANDROID
157 bits_writer_t bs = {0};
159 // we are always as large as codec_para_t from headers.
160 CBitstreamConverter::init_bits_writer(&bs, (uint8_t*)p_out, sizeof(codec_para_t), 1);
162 // order matters, so pay attention
163 // to codec_para_t in codec_types.h
164 CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE handle
165 CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE cntl_handle
166 CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE sub_handle
168 // added in JellyBean 4.2
169 if (CAndroidFeatures::GetVersion() > 16)
170 CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE audio_utils_handle
172 CBitstreamConverter::write_bits(&bs, 32, p_in->stream_type); // stream_type_t stream_type
174 // watch these, using bit fields (which is stupid)
175 CBitstreamConverter::write_bits(&bs, 1, 1); // unsigned int has_video:1
176 CBitstreamConverter::write_bits(&bs, 1, 0); // unsigned int has_audio:1
177 CBitstreamConverter::write_bits(&bs, 1, 0); // unsigned int has_sub:1
178 unsigned int value = p_in->noblock > 0 ? 1:0;
179 CBitstreamConverter::write_bits(&bs, 1, value); // unsigned int noblock:1
180 CBitstreamConverter::write_bits(&bs, 28, 0); // align back to next word boundary
182 CBitstreamConverter::write_bits(&bs, 32, p_in->video_type); // int video_type
183 CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_type
184 CBitstreamConverter::write_bits(&bs, 32, 0); // int sub_type
186 CBitstreamConverter::write_bits(&bs, 32, p_in->video_pid); // int video_pid
187 CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_pid
188 CBitstreamConverter::write_bits(&bs, 32, 0); // int sub_pid
190 CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_channels
191 CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_samplerate
192 CBitstreamConverter::write_bits(&bs, 32, 0); // int vbuf_size
193 CBitstreamConverter::write_bits(&bs, 32, 0); // int abuf_size
195 // ARM requires 8-byte alignment for 64-bit members (ratio64)
196 // and this will force am_sysinfo to be also have 8-byte alignment.
197 // Since the inclusion of audio_utils_handle for JellyBean 4.2
198 // 'naturally' aligns am_sysinfo to 8-byte, we need to compensate
199 // when we are NOT JellyBean 4.2. If these member values get changed,
200 // then make sure you check that am_sysinfo has 8-byte alignment.
201 if (CAndroidFeatures::GetVersion() < 17)
202 CBitstreamConverter::write_bits(&bs, 32, 0);
204 CBitstreamConverter::write_bits(&bs, 32, p_in->format); // am_sysinfo, unsigned int format
205 CBitstreamConverter::write_bits(&bs, 32, p_in->width); // am_sysinfo, unsigned int width
206 CBitstreamConverter::write_bits(&bs, 32, p_in->height); // am_sysinfo, unsigned int height
207 CBitstreamConverter::write_bits(&bs, 32, p_in->rate); // am_sysinfo, unsigned int rate
208 CBitstreamConverter::write_bits(&bs, 32, p_in->extra); // am_sysinfo, unsigned int extra
209 CBitstreamConverter::write_bits(&bs, 32, p_in->status); // am_sysinfo, unsigned int status
210 CBitstreamConverter::write_bits(&bs, 32, p_in->ratio); // am_sysinfo, unsigned int ratio
211 CBitstreamConverter::write_bits(&bs, 32, (unsigned int)p_in->param); // am_sysinfo, unsigned int param
212 unsigned int lo = 0x00000000ffffffff & p_in->ratio64;
213 unsigned int hi = p_in->ratio64 >> 32;
214 CBitstreamConverter::write_bits(&bs, 32, lo); // am_sysinfo, unsigned long long ratio64
215 CBitstreamConverter::write_bits(&bs, 32, hi); // am_sysinfo, unsigned long long ratio64
217 // we do not care about the rest, flush and go.
218 // FYI there are 4.0 to 4.1 differences here.
219 CBitstreamConverter::flush_bits(&bs);
220 //CLog::MemDump((char*)p_out, 0xFF);
222 // direct struct usage, we do not know which flavor
223 // so just use what we get from headers and pray.
224 p_out->has_video = 1;
225 p_out->noblock = p_in->noblock;
226 p_out->video_pid = p_in->video_pid;
227 p_out->video_type = p_in->video_type;
228 p_out->stream_type = p_in->stream_type;
229 p_out->am_sysinfo.format = p_in->format;
230 p_out->am_sysinfo.width = p_in->width;
231 p_out->am_sysinfo.height = p_in->height;
232 p_out->am_sysinfo.rate = p_in->rate;
233 p_out->am_sysinfo.extra = p_in->extra;
234 p_out->am_sysinfo.status = p_in->status;
235 p_out->am_sysinfo.ratio = p_in->ratio;
236 p_out->am_sysinfo.ratio64 = p_in->ratio64;
237 p_out->am_sysinfo.param = p_in->param;
242 //-----------------------------------------------------------------------------------
243 //-----------------------------------------------------------------------------------
244 // AppContext - Application state
245 #define MODE_3D_DISABLE 0x00000000
246 #define MODE_3D_LR 0x00000101
247 #define MODE_3D_LR_SWITCH 0x00000501
248 #define MODE_3D_BT 0x00000201
249 #define MODE_3D_BT_SWITCH 0x00000601
250 #define MODE_3D_TO_2D_L 0x00000102
251 #define MODE_3D_TO_2D_R 0x00000902
252 #define MODE_3D_TO_2D_T 0x00000202
253 #define MODE_3D_TO_2D_B 0x00000a02
255 #define PTS_FREQ 90000
256 #define UNIT_FREQ 96000
257 #define AV_SYNC_THRESH PTS_FREQ*30
259 #define TRICKMODE_NONE 0x00
260 #define TRICKMODE_I 0x01
261 #define TRICKMODE_FFFB 0x02
263 // same as AV_NOPTS_VALUE
264 #define INT64_0 INT64_C(0x8000000000000000)
266 #define EXTERNAL_PTS (1)
267 #define SYNC_OUTSIDE (2)
270 #define CODEC_TAG_VC_1 (0x312D4356)
271 #define CODEC_TAG_RV30 (0x30335652)
272 #define CODEC_TAG_RV40 (0x30345652)
273 #define CODEC_TAG_MJPEG (0x47504a4d)
274 #define CODEC_TAG_mjpeg (0x47504a4c)
275 #define CODEC_TAG_jpeg (0x6765706a)
276 #define CODEC_TAG_mjpa (0x61706a6d)
278 #define RW_WAIT_TIME (20 * 1000) // 20ms
280 #define P_PRE (0x02000000)
281 #define F_PRE (0x03000000)
282 #define PLAYER_SUCCESS (0)
283 #define PLAYER_FAILED (-(P_PRE|0x01))
284 #define PLAYER_NOMEM (-(P_PRE|0x02))
285 #define PLAYER_EMPTY_P (-(P_PRE|0x03))
287 #define PLAYER_WR_FAILED (-(P_PRE|0x21))
288 #define PLAYER_WR_EMPTYP (-(P_PRE|0x22))
289 #define PLAYER_WR_FINISH (P_PRE|0x1)
291 #define PLAYER_PTS_ERROR (-(P_PRE|0x31))
292 #define PLAYER_UNSUPPORT (-(P_PRE|0x35))
293 #define PLAYER_CHECK_CODEC_ERROR (-(P_PRE|0x39))
295 #define HDR_BUF_SIZE 1024
296 typedef struct hdr_buf {
301 typedef struct am_packet {
318 AM_STREAM_UNKNOWN = 0,
327 typedef struct am_private_t
330 aml_generic_param gcodec;
333 pstream_type stream_type;
336 vformat_t video_format;
338 unsigned int video_codec_id;
339 unsigned int video_codec_tag;
340 vdec_type_t video_codec_type;
341 unsigned int video_width;
342 unsigned int video_height;
343 unsigned int video_ratio;
344 unsigned int video_ratio64;
345 unsigned int video_rate;
346 unsigned int video_rotation_degree;
351 DllLibAmCodec *m_dll;
357 /*************************************************************************/
358 /*************************************************************************/
359 void dumpfile_open(am_private_t *para)
363 static int amcodec_dumpid = 0;
364 char dump_path[128] = {0};
365 sprintf(dump_path, "/temp/dump_amcodec-%d.dat", amcodec_dumpid++);
367 para->dumpfile = open(dump_path, O_CREAT | O_RDWR, 0666);
370 void dumpfile_close(am_private_t *para)
372 if (para->dumpdemux && para->dumpfile != -1)
373 close(para->dumpfile), para->dumpfile = -1;
375 void dumpfile_write(am_private_t *para, void* buf, int bufsiz)
379 CLog::Log(LOGERROR, "dumpfile_write: wtf ? buf is null, bufsiz(%d)", bufsiz);
383 if (para->dumpdemux && para->dumpfile != -1)
384 write(para->dumpfile, buf, bufsiz);
387 /*************************************************************************/
388 /*************************************************************************/
389 static int64_t get_pts_video()
391 int fd = open("/sys/class/tsync/pts_video", O_RDONLY);
395 int size = read(fd, pts_str, sizeof(pts_str));
399 unsigned long pts = strtoul(pts_str, NULL, 16);
404 CLog::Log(LOGERROR, "get_pts_video: open /tsync/event error");
408 static int set_pts_pcrscr(int64_t value)
410 int fd = open("/sys/class/tsync/pts_pcrscr", O_WRONLY);
414 unsigned long pts = (unsigned long)value;
415 sprintf(pts_str, "0x%lx", pts);
416 write(fd, pts_str, strlen(pts_str));
421 CLog::Log(LOGERROR, "set_pts_pcrscr: open pts_pcrscr error");
425 static vformat_t codecid_to_vformat(enum AVCodecID id)
430 case AV_CODEC_ID_MPEG1VIDEO:
431 case AV_CODEC_ID_MPEG2VIDEO:
432 case AV_CODEC_ID_MPEG2VIDEO_XVMC:
433 format = VFORMAT_MPEG12;
435 case AV_CODEC_ID_H263:
436 case AV_CODEC_ID_MPEG4:
437 case AV_CODEC_ID_H263P:
438 case AV_CODEC_ID_H263I:
439 case AV_CODEC_ID_MSMPEG4V2:
440 case AV_CODEC_ID_MSMPEG4V3:
441 case AV_CODEC_ID_FLV1:
442 format = VFORMAT_MPEG4;
444 case AV_CODEC_ID_RV10:
445 case AV_CODEC_ID_RV20:
446 case AV_CODEC_ID_RV30:
447 case AV_CODEC_ID_RV40:
448 format = VFORMAT_REAL;
450 case AV_CODEC_ID_H264:
451 format = VFORMAT_H264;
454 case AV_CODEC_ID_H264MVC:
455 // H264 Multiview Video Coding (3d blurays)
456 format = VFORMAT_H264MVC;
459 case AV_CODEC_ID_MJPEG:
460 format = VFORMAT_MJPEG;
462 case AV_CODEC_ID_VC1:
463 case AV_CODEC_ID_WMV3:
464 format = VFORMAT_VC1;
466 case AV_CODEC_ID_AVS:
467 case AV_CODEC_ID_CAVS:
468 format = VFORMAT_AVS;
472 format = VFORMAT_UNSUPPORT;
476 CLog::Log(LOGDEBUG, "codecid_to_vformat, id(%d) -> vformat(%d)", (int)id, format);
480 static vdec_type_t codec_tag_to_vdec_type(unsigned int codec_tag)
482 vdec_type_t dec_type;
485 case CODEC_TAG_MJPEG:
486 case CODEC_TAG_mjpeg:
490 dec_type = VIDEO_DEC_FORMAT_MJPEG;
496 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
502 dec_type = VIDEO_DEC_FORMAT_MPEG4_3;
507 dec_type = VIDEO_DEC_FORMAT_MPEG4_4;
514 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
518 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
524 case AV_CODEC_ID_MPEG4:
526 dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
528 case AV_CODEC_ID_H263:
534 dec_type = VIDEO_DEC_FORMAT_H263;
540 case AV_CODEC_ID_H264:
542 dec_type = VIDEO_DEC_FORMAT_H264;
545 case AV_CODEC_ID_H264MVC:
546 dec_type = VIDEO_DEC_FORMAT_H264;
549 case AV_CODEC_ID_RV30:
552 dec_type = VIDEO_DEC_FORMAT_REAL_8;
554 case AV_CODEC_ID_RV40:
557 dec_type = VIDEO_DEC_FORMAT_REAL_9;
561 dec_type = VIDEO_DEC_FORMAT_WMV3;
563 case AV_CODEC_ID_VC1:
568 dec_type = VIDEO_DEC_FORMAT_WVC1;
570 case AV_CODEC_ID_VP6F:
572 dec_type = VIDEO_DEC_FORMAT_SW;
574 case AV_CODEC_ID_CAVS:
575 case AV_CODEC_ID_AVS:
577 dec_type = VIDEO_DEC_FORMAT_AVS;
580 dec_type = VIDEO_DEC_FORMAT_UNKNOW;
584 CLog::Log(LOGDEBUG, "codec_tag_to_vdec_type, codec_tag(%d) -> vdec_type(%d)", codec_tag, dec_type);
588 static void am_packet_init(am_packet_t *pkt)
590 memset(&pkt->avpkt, 0, sizeof(AVPacket));
605 void am_packet_release(am_packet_t *pkt)
607 if (pkt->buf != NULL)
608 free(pkt->buf), pkt->buf= NULL;
609 if (pkt->hdr != NULL)
611 if (pkt->hdr->data != NULL)
612 free(pkt->hdr->data), pkt->hdr->data = NULL;
613 free(pkt->hdr), pkt->hdr = NULL;
619 int check_in_pts(am_private_t *para, am_packet_t *pkt)
621 int last_duration = 0;
622 static int last_v_duration = 0;
625 last_duration = last_v_duration;
627 if (para->stream_type == AM_STREAM_ES) {
628 if ((int64_t)INT64_0 != pkt->avpts) {
631 if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
632 CLog::Log(LOGDEBUG, "ERROR check in pts error!");
633 return PLAYER_PTS_ERROR;
636 } else if ((int64_t)INT64_0 != pkt->avdts) {
637 pts = pkt->avdts * last_duration;
639 if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
640 CLog::Log(LOGDEBUG, "ERROR check in dts error!");
641 return PLAYER_PTS_ERROR;
644 last_v_duration = pkt->avduration ? pkt->avduration : 1;
646 if (!para->check_first_pts) {
647 if (para->m_dll->codec_checkin_pts(pkt->codec, 0) != 0) {
648 CLog::Log(LOGDEBUG, "ERROR check in 0 to video pts error!");
649 return PLAYER_PTS_ERROR;
653 if (!para->check_first_pts) {
654 para->check_first_pts = 1;
660 return PLAYER_SUCCESS;
663 static int write_header(am_private_t *para, am_packet_t *pkt)
665 int write_bytes = 0, len = 0;
667 if (pkt->hdr && pkt->hdr->size > 0) {
668 if ((NULL == pkt->codec) || (NULL == pkt->hdr->data)) {
669 CLog::Log(LOGDEBUG, "[write_header]codec null!");
670 return PLAYER_EMPTY_P;
672 //some wvc1 es data not need to add header
673 if (para->video_format == VFORMAT_VC1 && para->video_codec_type == VIDEO_DEC_FORMAT_WVC1) {
674 if ((pkt->data) && (pkt->data_size >= 4)
675 && (pkt->data[0] == 0) && (pkt->data[1] == 0)
676 && (pkt->data[2] == 1) && (pkt->data[3] == 0xd || pkt->data[3] == 0xf)) {
677 return PLAYER_SUCCESS;
681 write_bytes = para->m_dll->codec_write(pkt->codec, pkt->hdr->data + len, pkt->hdr->size - len);
682 if (write_bytes < 0 || write_bytes > (pkt->hdr->size - len)) {
683 if (-errno != AVERROR(EAGAIN)) {
684 CLog::Log(LOGDEBUG, "ERROR:write header failed!");
685 return PLAYER_WR_FAILED;
690 dumpfile_write(para, pkt->hdr->data, write_bytes);
692 if (len == pkt->hdr->size) {
698 return PLAYER_SUCCESS;
701 int check_avbuffer_enough(am_private_t *para, am_packet_t *pkt)
706 int write_av_packet(am_private_t *para, am_packet_t *pkt)
708 //CLog::Log(LOGDEBUG, "write_av_packet, pkt->isvalid(%d), pkt->data(%p), pkt->data_size(%d)",
709 // pkt->isvalid, pkt->data, pkt->data_size);
711 int write_bytes = 0, len = 0, ret;
715 // do we need to check in pts or write the header ?
718 ret = check_in_pts(para, pkt);
719 if (ret != PLAYER_SUCCESS) {
720 CLog::Log(LOGDEBUG, "check in pts failed");
721 return PLAYER_WR_FAILED;
724 if (write_header(para, pkt) == PLAYER_WR_FAILED) {
725 CLog::Log(LOGDEBUG, "[%s]write header failed!", __FUNCTION__);
726 return PLAYER_WR_FAILED;
732 size = pkt->data_size ;
733 if (size == 0 && pkt->isvalid) {
738 while (size > 0 && pkt->isvalid) {
739 write_bytes = para->m_dll->codec_write(pkt->codec, buf, size);
740 if (write_bytes < 0 || write_bytes > size) {
741 CLog::Log(LOGDEBUG, "write codec data failed, write_bytes(%d), errno(%d), size(%d)", write_bytes, errno, size);
742 if (-errno != AVERROR(EAGAIN)) {
743 CLog::Log(LOGDEBUG, "write codec data failed!");
744 return PLAYER_WR_FAILED;
746 // adjust for any data we already wrote into codec.
747 // we sleep a bit then exit as we will get called again
748 // with the same pkt because pkt->isvalid has not been cleared.
750 pkt->data_size -= len;
751 usleep(RW_WAIT_TIME);
752 CLog::Log(LOGDEBUG, "usleep(RW_WAIT_TIME), len(%d)", len);
753 return PLAYER_SUCCESS;
756 dumpfile_write(para, buf, write_bytes);
757 // keep track of what we write into codec from this pkt
758 // in case we get hit with EAGAIN.
760 if (len == pkt->data_size) {
764 } else if (len < pkt->data_size) {
768 // writing more that we should is a failure.
769 return PLAYER_WR_FAILED;
774 return PLAYER_SUCCESS;
777 /*************************************************************************/
778 static int m4s2_dx50_mp4v_add_header(unsigned char *buf, int size, am_packet_t *pkt)
780 if (size > pkt->hdr->size) {
781 free(pkt->hdr->data), pkt->hdr->data = NULL;
784 pkt->hdr->data = (char*)malloc(size);
785 if (!pkt->hdr->data) {
786 CLog::Log(LOGDEBUG, "[m4s2_dx50_add_header] NOMEM!");
787 return PLAYER_FAILED;
791 pkt->hdr->size = size;
792 memcpy(pkt->hdr->data, buf, size);
794 return PLAYER_SUCCESS;
797 static int m4s2_dx50_mp4v_write_header(am_private_t *para, am_packet_t *pkt)
799 CLog::Log(LOGDEBUG, "m4s2_dx50_mp4v_write_header");
800 int ret = m4s2_dx50_mp4v_add_header(para->extradata, para->extrasize, pkt);
801 if (ret == PLAYER_SUCCESS) {
803 pkt->codec = ¶->vcodec;
805 CLog::Log(LOGDEBUG, "[m4s2_dx50_mp4v_add_header]invalid video codec!");
806 return PLAYER_EMPTY_P;
809 ret = write_av_packet(para, pkt);
814 static int mjpeg_data_prefeeding(am_packet_t *pkt)
816 const unsigned char mjpeg_addon_data[] = {
817 0xff, 0xd8, 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
818 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
819 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01,
820 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
821 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10,
822 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
823 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31,
824 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1,
825 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
826 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29,
827 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
828 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
829 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
830 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
831 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
832 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4,
833 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
834 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
835 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02, 0x01,
836 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
837 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
838 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
839 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,
840 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a,
841 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
842 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
843 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82,
844 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
845 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
846 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
847 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
848 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
849 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
852 if (pkt->hdr->data) {
853 memcpy(pkt->hdr->data, &mjpeg_addon_data, sizeof(mjpeg_addon_data));
854 pkt->hdr->size = sizeof(mjpeg_addon_data);
856 CLog::Log(LOGDEBUG, "[mjpeg_data_prefeeding]No enough memory!");
857 return PLAYER_FAILED;
859 return PLAYER_SUCCESS;
862 static int mjpeg_write_header(am_private_t *para, am_packet_t *pkt)
864 mjpeg_data_prefeeding(pkt);
866 pkt->codec = ¶->vcodec;
868 CLog::Log(LOGDEBUG, "[mjpeg_write_header]invalid codec!");
869 return PLAYER_EMPTY_P;
872 write_av_packet(para, pkt);
873 return PLAYER_SUCCESS;
876 static int divx3_data_prefeeding(am_packet_t *pkt, unsigned w, unsigned h)
878 unsigned i = (w << 12) | (h & 0xfff);
879 unsigned char divx311_add[10] = {
880 0x00, 0x00, 0x00, 0x01,
881 0x20, 0x00, 0x00, 0x00,
884 divx311_add[5] = (i >> 16) & 0xff;
885 divx311_add[6] = (i >> 8) & 0xff;
886 divx311_add[7] = i & 0xff;
888 if (pkt->hdr->data) {
889 memcpy(pkt->hdr->data, divx311_add, sizeof(divx311_add));
890 pkt->hdr->size = sizeof(divx311_add);
892 CLog::Log(LOGDEBUG, "[divx3_data_prefeeding]No enough memory!");
893 return PLAYER_FAILED;
895 return PLAYER_SUCCESS;
898 static int divx3_write_header(am_private_t *para, am_packet_t *pkt)
900 CLog::Log(LOGDEBUG, "divx3_write_header");
901 divx3_data_prefeeding(pkt, para->video_width, para->video_height);
903 pkt->codec = ¶->vcodec;
905 CLog::Log(LOGDEBUG, "[divx3_write_header]invalid codec!");
906 return PLAYER_EMPTY_P;
909 write_av_packet(para, pkt);
910 return PLAYER_SUCCESS;
913 static int h264_add_header(unsigned char *buf, int size, am_packet_t *pkt)
916 if ((buf[0]==0 && buf[1]==0 && buf[2]==0 && buf[3]==1) && size < HDR_BUF_SIZE) {
917 CLog::Log(LOGDEBUG, "add four byte NAL 264 header in stream before header len=%d",size);
918 memcpy(pkt->hdr->data, buf, size);
919 pkt->hdr->size = size;
920 return PLAYER_SUCCESS;
923 if ((buf[0]==0 && buf[1]==0 && buf[2]==1) && size < HDR_BUF_SIZE) {
924 CLog::Log(LOGDEBUG, "add three byte NAL 264 header in stream before header len=%d",size);
925 memcpy(pkt->hdr->data, buf, size);
926 pkt->hdr->size = size;
927 return PLAYER_SUCCESS;
930 return PLAYER_FAILED;
932 static int h264_write_header(am_private_t *para, am_packet_t *pkt)
934 // CLog::Log(LOGDEBUG, "h264_write_header");
937 ret = h264_add_header(para->extradata, para->extrasize, pkt);
938 if (ret == PLAYER_SUCCESS) {
941 pkt->codec = ¶->vcodec;
943 //CLog::Log(LOGDEBUG, "[pre_header_feeding]invalid video codec!");
944 return PLAYER_EMPTY_P;
948 ret = write_av_packet(para, pkt);
953 static int wmv3_write_header(am_private_t *para, am_packet_t *pkt)
955 CLog::Log(LOGDEBUG, "wmv3_write_header");
956 unsigned i, check_sum = 0;
957 unsigned data_len = para->extrasize + 4;
959 pkt->hdr->data[0] = 0;
960 pkt->hdr->data[1] = 0;
961 pkt->hdr->data[2] = 1;
962 pkt->hdr->data[3] = 0x10;
964 pkt->hdr->data[4] = 0;
965 pkt->hdr->data[5] = (data_len >> 16) & 0xff;
966 pkt->hdr->data[6] = 0x88;
967 pkt->hdr->data[7] = (data_len >> 8) & 0xff;
968 pkt->hdr->data[8] = data_len & 0xff;
969 pkt->hdr->data[9] = 0x88;
971 pkt->hdr->data[10] = 0xff;
972 pkt->hdr->data[11] = 0xff;
973 pkt->hdr->data[12] = 0x88;
974 pkt->hdr->data[13] = 0xff;
975 pkt->hdr->data[14] = 0xff;
976 pkt->hdr->data[15] = 0x88;
978 for (i = 4 ; i < 16 ; i++) {
979 check_sum += pkt->hdr->data[i];
982 pkt->hdr->data[16] = (check_sum >> 8) & 0xff;
983 pkt->hdr->data[17] = check_sum & 0xff;
984 pkt->hdr->data[18] = 0x88;
985 pkt->hdr->data[19] = (check_sum >> 8) & 0xff;
986 pkt->hdr->data[20] = check_sum & 0xff;
987 pkt->hdr->data[21] = 0x88;
989 pkt->hdr->data[22] = (para->video_width >> 8) & 0xff;
990 pkt->hdr->data[23] = para->video_width & 0xff;
991 pkt->hdr->data[24] = (para->video_height >> 8) & 0xff;
992 pkt->hdr->data[25] = para->video_height & 0xff;
994 memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
995 pkt->hdr->size = para->extrasize + 26;
997 pkt->codec = ¶->vcodec;
999 CLog::Log(LOGDEBUG, "[wmv3_write_header]invalid codec!");
1000 return PLAYER_EMPTY_P;
1003 return write_av_packet(para, pkt);
1006 static int wvc1_write_header(am_private_t *para, am_packet_t *pkt)
1008 CLog::Log(LOGDEBUG, "wvc1_write_header");
1009 memcpy(pkt->hdr->data, para->extradata + 1, para->extrasize - 1);
1010 pkt->hdr->size = para->extrasize - 1;
1012 pkt->codec = ¶->vcodec;
1014 CLog::Log(LOGDEBUG, "[wvc1_write_header]invalid codec!");
1015 return PLAYER_EMPTY_P;
1018 return write_av_packet(para, pkt);
1021 static int mpeg_add_header(am_private_t *para, am_packet_t *pkt)
1023 CLog::Log(LOGDEBUG, "mpeg_add_header");
1024 #define STUFF_BYTES_LENGTH (256)
1026 unsigned char packet_wrapper[] = {
1027 0x00, 0x00, 0x01, 0xe0,
1028 0x00, 0x00, /* pes packet length */
1030 0x20, 0x00, 0x00, 0x00, 0x00, /* PTS */
1031 0x1f, 0xff, 0xff, 0xff, 0xff, /* DTS */
1032 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1035 size = para->extrasize + sizeof(packet_wrapper);
1036 packet_wrapper[4] = size >> 8 ;
1037 packet_wrapper[5] = size & 0xff ;
1038 memcpy(pkt->hdr->data, packet_wrapper, sizeof(packet_wrapper));
1039 size = sizeof(packet_wrapper);
1040 //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]wrapper size=%d\n",__LINE__,size);
1041 memcpy(pkt->hdr->data + size, para->extradata, para->extrasize);
1042 size += para->extrasize;
1043 //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]wrapper+seq size=%d\n",__LINE__,size);
1044 memset(pkt->hdr->data + size, 0xff, STUFF_BYTES_LENGTH);
1045 size += STUFF_BYTES_LENGTH;
1046 pkt->hdr->size = size;
1047 //CLog::Log(LOGDEBUG, "[mpeg_add_header:%d]hdr_size=%d\n",__LINE__,size);
1049 pkt->codec = ¶->vcodec;
1051 CLog::Log(LOGDEBUG, "[mpeg_add_header]invalid codec!");
1052 return PLAYER_EMPTY_P;
1056 return write_av_packet(para, pkt);
1059 int pre_header_feeding(am_private_t *para, am_packet_t *pkt)
1062 if (para->stream_type == AM_STREAM_ES) {
1063 if (pkt->hdr == NULL) {
1064 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1065 pkt->hdr->data = (char *)malloc(HDR_BUF_SIZE);
1066 if (!pkt->hdr->data) {
1067 //CLog::Log(LOGDEBUG, "[pre_header_feeding] NOMEM!");
1068 return PLAYER_NOMEM;
1072 if (VFORMAT_H264 == para->video_format || VFORMAT_H264_4K2K == para->video_format) {
1073 ret = h264_write_header(para, pkt);
1074 if (ret != PLAYER_SUCCESS) {
1077 } else if ((VFORMAT_MPEG4 == para->video_format) && (VIDEO_DEC_FORMAT_MPEG4_3 == para->video_codec_type)) {
1078 ret = divx3_write_header(para, pkt);
1079 if (ret != PLAYER_SUCCESS) {
1082 } else if ((CODEC_TAG_M4S2 == para->video_codec_tag)
1083 || (CODEC_TAG_DX50 == para->video_codec_tag)
1084 || (CODEC_TAG_mp4v == para->video_codec_tag)) {
1085 ret = m4s2_dx50_mp4v_write_header(para, pkt);
1086 if (ret != PLAYER_SUCCESS) {
1090 } else if ((AVI_FILE == para->file_type)
1091 && (VIDEO_DEC_FORMAT_MPEG4_3 != para->vstream_info.video_codec_type)
1092 && (VFORMAT_H264 != para->vstream_info.video_format)
1093 && (VFORMAT_VC1 != para->vstream_info.video_format)) {
1094 ret = avi_write_header(para);
1095 if (ret != PLAYER_SUCCESS) {
1099 } else if (CODEC_TAG_WMV3 == para->video_codec_tag) {
1100 CLog::Log(LOGDEBUG, "CODEC_TAG_WMV3 == para->video_codec_tag");
1101 ret = wmv3_write_header(para, pkt);
1102 if (ret != PLAYER_SUCCESS) {
1105 } else if ((CODEC_TAG_WVC1 == para->video_codec_tag)
1106 || (CODEC_TAG_VC_1 == para->video_codec_tag)
1107 || (CODEC_TAG_WMVA == para->video_codec_tag)) {
1108 CLog::Log(LOGDEBUG, "CODEC_TAG_WVC1 == para->video_codec_tag");
1109 ret = wvc1_write_header(para, pkt);
1110 if (ret != PLAYER_SUCCESS) {
1114 } else if ((MKV_FILE == para->file_type) &&
1115 ((VFORMAT_MPEG4 == para->vstream_info.video_format)
1116 || (VFORMAT_MPEG12 == para->vstream_info.video_format))) {
1117 ret = mkv_write_header(para, pkt);
1118 if (ret != PLAYER_SUCCESS) {
1122 } else if (VFORMAT_MJPEG == para->video_format) {
1123 ret = mjpeg_write_header(para, pkt);
1124 if (ret != PLAYER_SUCCESS) {
1130 if (pkt->hdr->data) {
1131 free(pkt->hdr->data);
1132 pkt->hdr->data = NULL;
1138 else if (para->stream_type == AM_STREAM_PS) {
1139 if (pkt->hdr == NULL) {
1140 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1141 pkt->hdr->data = (char*)malloc(HDR_BUF_SIZE);
1142 if (!pkt->hdr->data) {
1143 CLog::Log(LOGDEBUG, "[pre_header_feeding] NOMEM!");
1144 return PLAYER_NOMEM;
1147 if (( AV_CODEC_ID_MPEG1VIDEO == para->video_codec_id)
1148 || (AV_CODEC_ID_MPEG2VIDEO == para->video_codec_id)
1149 || (AV_CODEC_ID_MPEG2VIDEO_XVMC == para->video_codec_id)) {
1150 ret = mpeg_add_header(para, pkt);
1151 if (ret != PLAYER_SUCCESS) {
1156 if (pkt->hdr->data) {
1157 free(pkt->hdr->data);
1158 pkt->hdr->data = NULL;
1164 return PLAYER_SUCCESS;
1167 int divx3_prefix(am_packet_t *pkt)
1169 #define DIVX311_CHUNK_HEAD_SIZE 13
1170 const unsigned char divx311_chunk_prefix[DIVX311_CHUNK_HEAD_SIZE] = {
1171 0x00, 0x00, 0x00, 0x01, 0xb6, 'D', 'I', 'V', 'X', '3', '.', '1', '1'
1173 if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1174 free(pkt->hdr->data);
1175 pkt->hdr->data = NULL;
1178 if (pkt->hdr == NULL) {
1179 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1181 CLog::Log(LOGDEBUG, "[divx3_prefix] NOMEM!");
1182 return PLAYER_FAILED;
1185 pkt->hdr->data = NULL;
1189 pkt->hdr->data = (char*)malloc(DIVX311_CHUNK_HEAD_SIZE + 4);
1190 if (pkt->hdr->data == NULL) {
1191 CLog::Log(LOGDEBUG, "[divx3_prefix] NOMEM!");
1192 return PLAYER_FAILED;
1195 memcpy(pkt->hdr->data, divx311_chunk_prefix, DIVX311_CHUNK_HEAD_SIZE);
1197 pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 0] = (pkt->data_size >> 24) & 0xff;
1198 pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 1] = (pkt->data_size >> 16) & 0xff;
1199 pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 2] = (pkt->data_size >> 8) & 0xff;
1200 pkt->hdr->data[DIVX311_CHUNK_HEAD_SIZE + 3] = pkt->data_size & 0xff;
1202 pkt->hdr->size = DIVX311_CHUNK_HEAD_SIZE + 4;
1205 return PLAYER_SUCCESS;
1208 int set_header_info(am_private_t *para)
1210 am_packet_t *pkt = ¶->am_pkt;
1215 // pkt->hdr->size = 0;
1217 if (para->video_format == VFORMAT_MPEG4)
1219 if (para->video_codec_type == VIDEO_DEC_FORMAT_MPEG4_3)
1221 return divx3_prefix(pkt);
1223 else if (para->video_codec_type == VIDEO_DEC_FORMAT_H263)
1225 return PLAYER_UNSUPPORT;
1226 unsigned char *vld_buf;
1227 int vld_len, vld_buf_size = para->video_width * para->video_height * 2;
1229 if (!pkt->data_size) {
1230 return PLAYER_SUCCESS;
1233 if ((pkt->data[0] == 0) && (pkt->data[1] == 0) && (pkt->data[2] == 1) && (pkt->data[3] == 0xb6)) {
1234 return PLAYER_SUCCESS;
1237 vld_buf = (unsigned char*)malloc(vld_buf_size);
1239 return PLAYER_NOMEM;
1242 if (para->flv_flag) {
1243 vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 1);
1245 if (0 == para->h263_decodable) {
1246 para->h263_decodable = para->m_dll->decodeble_h263(pkt->data);
1247 if (0 == para->h263_decodable) {
1248 CLog::Log(LOGDEBUG, "[%s]h263 unsupport video and audio, exit", __FUNCTION__);
1249 return PLAYER_UNSUPPORT;
1252 vld_len = para->m_dll->h263vld(pkt->data, vld_buf, pkt->data_size, 0);
1260 pkt->buf_size = vld_buf_size;
1261 pkt->data = pkt->buf;
1262 pkt->data_size = vld_len;
1268 } else if (para->video_format == VFORMAT_VC1) {
1269 if (para->video_codec_type == VIDEO_DEC_FORMAT_WMV3) {
1270 unsigned i, check_sum = 0, data_len = 0;
1272 if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1273 free(pkt->hdr->data);
1274 pkt->hdr->data = NULL;
1277 if (pkt->hdr == NULL) {
1278 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1280 return PLAYER_FAILED;
1283 pkt->hdr->data = NULL;
1287 if (pkt->avpkt.flags) {
1288 pkt->hdr->data = (char*)malloc(para->extrasize + 26 + 22);
1289 if (pkt->hdr->data == NULL) {
1290 return PLAYER_FAILED;
1293 pkt->hdr->data[0] = 0;
1294 pkt->hdr->data[1] = 0;
1295 pkt->hdr->data[2] = 1;
1296 pkt->hdr->data[3] = 0x10;
1298 data_len = para->extrasize + 4;
1299 pkt->hdr->data[4] = 0;
1300 pkt->hdr->data[5] = (data_len >> 16) & 0xff;
1301 pkt->hdr->data[6] = 0x88;
1302 pkt->hdr->data[7] = (data_len >> 8) & 0xff;
1303 pkt->hdr->data[8] = data_len & 0xff;
1304 pkt->hdr->data[9] = 0x88;
1306 pkt->hdr->data[10] = 0xff;
1307 pkt->hdr->data[11] = 0xff;
1308 pkt->hdr->data[12] = 0x88;
1309 pkt->hdr->data[13] = 0xff;
1310 pkt->hdr->data[14] = 0xff;
1311 pkt->hdr->data[15] = 0x88;
1313 for (i = 4 ; i < 16 ; i++) {
1314 check_sum += pkt->hdr->data[i];
1317 pkt->hdr->data[16] = (check_sum >> 8) & 0xff;
1318 pkt->hdr->data[17] = check_sum & 0xff;
1319 pkt->hdr->data[18] = 0x88;
1320 pkt->hdr->data[19] = (check_sum >> 8) & 0xff;
1321 pkt->hdr->data[20] = check_sum & 0xff;
1322 pkt->hdr->data[21] = 0x88;
1324 pkt->hdr->data[22] = (para->video_width >> 8) & 0xff;
1325 pkt->hdr->data[23] = para->video_width & 0xff;
1326 pkt->hdr->data[24] = (para->video_height >> 8) & 0xff;
1327 pkt->hdr->data[25] = para->video_height & 0xff;
1329 memcpy(pkt->hdr->data + 26, para->extradata, para->extrasize);
1332 data_len = para->extrasize + 26;
1334 pkt->hdr->data = (char*)malloc(22);
1335 if (pkt->hdr->data == NULL) {
1336 return PLAYER_FAILED;
1340 pkt->hdr->data[data_len + 0] = 0;
1341 pkt->hdr->data[data_len + 1] = 0;
1342 pkt->hdr->data[data_len + 2] = 1;
1343 pkt->hdr->data[data_len + 3] = 0xd;
1345 pkt->hdr->data[data_len + 4] = 0;
1346 pkt->hdr->data[data_len + 5] = (pkt->data_size >> 16) & 0xff;
1347 pkt->hdr->data[data_len + 6] = 0x88;
1348 pkt->hdr->data[data_len + 7] = (pkt->data_size >> 8) & 0xff;
1349 pkt->hdr->data[data_len + 8] = pkt->data_size & 0xff;
1350 pkt->hdr->data[data_len + 9] = 0x88;
1352 pkt->hdr->data[data_len + 10] = 0xff;
1353 pkt->hdr->data[data_len + 11] = 0xff;
1354 pkt->hdr->data[data_len + 12] = 0x88;
1355 pkt->hdr->data[data_len + 13] = 0xff;
1356 pkt->hdr->data[data_len + 14] = 0xff;
1357 pkt->hdr->data[data_len + 15] = 0x88;
1359 for (i = data_len + 4 ; i < data_len + 16 ; i++) {
1360 check_sum += pkt->hdr->data[i];
1363 pkt->hdr->data[data_len + 16] = (check_sum >> 8) & 0xff;
1364 pkt->hdr->data[data_len + 17] = check_sum & 0xff;
1365 pkt->hdr->data[data_len + 18] = 0x88;
1366 pkt->hdr->data[data_len + 19] = (check_sum >> 8) & 0xff;
1367 pkt->hdr->data[data_len + 20] = check_sum & 0xff;
1368 pkt->hdr->data[data_len + 21] = 0x88;
1370 pkt->hdr->size = data_len + 22;
1372 } else if (para->video_codec_type == VIDEO_DEC_FORMAT_WVC1) {
1373 if ((pkt->hdr != NULL) && (pkt->hdr->data != NULL)) {
1374 free(pkt->hdr->data);
1375 pkt->hdr->data = NULL;
1378 if (pkt->hdr == NULL) {
1379 pkt->hdr = (hdr_buf_t*)malloc(sizeof(hdr_buf_t));
1381 CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1382 return PLAYER_FAILED;
1385 pkt->hdr->data = NULL;
1389 pkt->hdr->data = (char*)malloc(4);
1390 if (pkt->hdr->data == NULL) {
1391 CLog::Log(LOGDEBUG, "[wvc1_prefix] NOMEM!");
1392 return PLAYER_FAILED;
1395 pkt->hdr->data[0] = 0;
1396 pkt->hdr->data[1] = 0;
1397 pkt->hdr->data[2] = 1;
1398 pkt->hdr->data[3] = 0xd;
1404 return PLAYER_SUCCESS;
1407 /*************************************************************************/
1408 CAMLCodec::CAMLCodec() : CThread("CAMLCodec")
1411 am_private = new am_private_t;
1412 memset(am_private, 0, sizeof(am_private_t));
1413 m_dll = new DllLibAmCodec;
1415 am_private->m_dll = m_dll;
1419 CAMLCodec::~CAMLCodec()
1424 delete m_dll, m_dll = NULL;
1427 bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
1429 #ifdef TARGET_ANDROID
1430 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion());
1433 m_speed = DVD_PLAYSPEED_NORMAL;
1438 m_dst_rect.SetRect(0, 0, 0, 0);
1442 m_vbufsize = 500000 * 2;
1447 ShowMainVideo(false);
1449 am_packet_init(&am_private->am_pkt);
1450 // default stream type
1451 am_private->stream_type = AM_STREAM_ES;
1453 am_private->video_width = hints.width;
1454 am_private->video_height = hints.height;
1455 am_private->video_codec_id = hints.codec;
1456 am_private->video_codec_tag = hints.codec_tag;
1457 am_private->video_pid = hints.pid;
1459 // handle video ratio
1460 AVRational video_ratio = m_dll->av_d2q(1, SHRT_MAX);
1461 //if (!hints.forced_aspect)
1462 // video_ratio = m_dll->av_d2q(hints.aspect, SHRT_MAX);
1463 am_private->video_ratio = ((int32_t)video_ratio.num << 16) | video_ratio.den;
1464 am_private->video_ratio64 = ((int64_t)video_ratio.num << 32) | video_ratio.den;
1466 // handle video rate
1467 if (hints.rfpsrate > 0 && hints.rfpsscale != 0)
1469 // check ffmpeg r_frame_rate 1st
1470 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.rfpsscale / hints.rfpsrate;
1472 else if (hints.fpsrate > 0 && hints.fpsscale != 0)
1474 // then ffmpeg avg_frame_rate next
1475 am_private->video_rate = 0.5 + (float)UNIT_FREQ * hints.fpsscale / hints.fpsrate;
1478 // check for 1920x1080, interlaced, 25 fps
1479 // incorrectly reported as 50 fps (yes, video_rate == 1920)
1480 if (hints.width == 1920 && am_private->video_rate == 1920)
1482 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1483 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 25000;
1486 // check for SD h264 content incorrectly reported as 60 fsp
1487 // mp4/avi containers :(
1488 if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720 && am_private->video_rate == 1602)
1490 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1491 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1494 // check for SD h264 content incorrectly reported as some form of 30 fsp
1495 // mp4/avi containers :(
1496 if (hints.codec == AV_CODEC_ID_H264 && hints.width <= 720)
1498 if (am_private->video_rate >= 3200 && am_private->video_rate <= 3210)
1500 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder video_rate exception");
1501 am_private->video_rate = 0.5 + (float)UNIT_FREQ * 1001 / 24000;
1505 // handle orientation
1506 am_private->video_rotation_degree = 0;
1507 if (hints.orientation == 90)
1508 am_private->video_rotation_degree = 1;
1509 else if (hints.orientation == 180)
1510 am_private->video_rotation_degree = 2;
1511 else if (hints.orientation == 270)
1512 am_private->video_rotation_degree = 3;
1514 am_private->video_format = codecid_to_vformat(hints.codec);
1515 if (am_private->video_format == VFORMAT_H264) {
1516 if (hints.width > 1920 || hints.height > 1088) {
1517 am_private->video_format = VFORMAT_H264_4K2K;
1520 switch (am_private->video_format)
1523 am_private->extrasize = hints.extrasize;
1524 am_private->extradata = (uint8_t*)malloc(hints.extrasize);
1525 memcpy(am_private->extradata, hints.extradata, hints.extrasize);
1528 case VFORMAT_MPEG12:
1532 if (am_private->stream_type == AM_STREAM_ES && am_private->video_codec_tag != 0)
1533 am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_tag);
1535 am_private->video_codec_type = codec_tag_to_vdec_type(am_private->video_codec_id);
1537 am_private->flv_flag = 0;
1538 if (am_private->video_codec_id == AV_CODEC_ID_FLV1)
1540 am_private->video_codec_tag = CODEC_TAG_F263;
1541 am_private->flv_flag = 1;
1544 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder "
1545 "hints.width(%d), hints.height(%d), hints.codec(%d), hints.codec_tag(%d), hints.pid(%d)",
1546 hints.width, hints.height, hints.codec, hints.codec_tag, hints.pid);
1547 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.fpsrate(%d), hints.fpsscale(%d), hints.rfpsrate(%d), hints.rfpsscale(%d), video_rate(%d)",
1548 hints.fpsrate, hints.fpsscale, hints.rfpsrate, hints.rfpsscale, am_private->video_rate);
1549 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.aspect(%f), video_ratio.num(%d), video_ratio.den(%d)",
1550 hints.aspect, video_ratio.num, video_ratio.den);
1551 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder hints.orientation(%d), hints.forced_aspect(%d), hints.extrasize(%d)",
1552 hints.orientation, hints.forced_aspect, hints.extrasize);
1554 // default video codec params
1555 am_private->gcodec.noblock = 0;
1556 am_private->gcodec.video_pid = am_private->video_pid;
1557 am_private->gcodec.video_type = am_private->video_format;
1558 am_private->gcodec.stream_type = STREAM_TYPE_ES_VIDEO;
1559 am_private->gcodec.format = am_private->video_codec_type;
1560 am_private->gcodec.width = am_private->video_width;
1561 am_private->gcodec.height = am_private->video_height;
1562 am_private->gcodec.rate = am_private->video_rate;
1563 am_private->gcodec.ratio = am_private->video_ratio;
1564 am_private->gcodec.ratio64 = am_private->video_ratio64;
1565 am_private->gcodec.param = NULL;
1567 switch(am_private->video_format)
1572 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1575 case VFORMAT_H264MVC:
1576 am_private->gcodec.format = VIDEO_DEC_FORMAT_H264;
1577 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1578 // h264 in an avi file
1579 if (m_hints.ptsinvalid)
1580 am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
1582 case VFORMAT_H264_4K2K:
1583 if (aml_get_cputype() >= 8) {
1584 am_private->gcodec.format = VIDEO_DEC_FORMAT_H264_4K2K;
1585 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1586 // h264 in an avi file
1587 if (m_hints.ptsinvalid)
1588 am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
1590 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, 4K supported only on Meson8.");
1595 am_private->stream_type = AM_STREAM_RM;
1596 am_private->vcodec.noblock = 1;
1597 am_private->vcodec.stream_type = STREAM_TYPE_RM;
1598 am_private->vcodec.am_sysinfo.ratio = 0x100;
1599 am_private->vcodec.am_sysinfo.ratio64 = 0;
1601 static unsigned short tbl[9] = {0};
1602 if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type)
1604 am_private->gcodec.extra = am_private->extradata[1] & 7;
1605 tbl[0] = (((am_private->gcodec.width >> 2) - 1) << 8)
1606 | (((am_private->gcodec.height >> 2) - 1) & 0xff);
1608 for (unsigned int i = 1; i <= am_private->gcodec.extra; i++)
1611 tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff);
1614 am_private->gcodec.param = &tbl;
1618 // vc1 in an avi file
1619 if (m_hints.ptsinvalid)
1620 am_private->gcodec.param = (void*)EXTERNAL_PTS;
1623 am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16));
1625 // translate from generic to firemware version dependent
1626 m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec);
1628 int ret = m_dll->codec_init(&am_private->vcodec);
1629 if (ret != CODEC_ERROR_NONE)
1631 CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
1635 am_private->dumpdemux = false;
1636 dumpfile_open(am_private);
1638 // make sure we are not stuck in pause (amcodec bug)
1639 m_dll->codec_resume(&am_private->vcodec);
1640 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1642 m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
1643 m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
1644 // disable tsync, we are playing video disconnected from audio.
1645 aml_set_sysfs_int("/sys/class/tsync/enable", 0);
1647 am_private->am_pkt.codec = &am_private->vcodec;
1648 pre_header_feeding(am_private, &am_private->am_pkt);
1652 g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1653 g_renderManager.RegisterRenderFeaturesCallBack((const void*)this, RenderFeaturesCallBack);
1656 // if display is set to 1080xxx, then disable deinterlacer for HD content
1657 // else bandwidth usage is too heavy and it will slow down video decoder.
1658 char display_mode[256] = {0};
1659 aml_get_sysfs_str("/sys/class/display/mode", display_mode, 255);
1660 if (strstr(display_mode,"1080"))
1661 aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 1);
1663 aml_set_sysfs_int("/sys/module/di/parameters/bypass_all", 0);
1667 // vcodec is open, update speed if it was
1668 // changed before dvdplayer called OpenDecoder.
1674 void CAMLCodec::CloseDecoder()
1676 CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
1679 g_renderManager.RegisterRenderUpdateCallBack((const void*)NULL, NULL);
1680 g_renderManager.RegisterRenderFeaturesCallBack((const void*)NULL, NULL);
1682 // never leave vcodec ff/rw or paused.
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 m_dll->codec_close(&am_private->vcodec);
1689 dumpfile_close(am_private);
1692 am_packet_release(&am_private->am_pkt);
1693 free(am_private->extradata);
1694 am_private->extradata = NULL;
1695 // return tsync to default so external apps work
1696 aml_set_sysfs_int("/sys/class/tsync/enable", 1);
1698 ShowMainVideo(false);
1701 void CAMLCodec::Reset()
1703 CLog::Log(LOGDEBUG, "CAMLCodec::Reset");
1708 // set the system blackout_policy to leave the last frame showing
1709 int blackout_policy = aml_get_sysfs_int("/sys/class/video/blackout_policy");
1710 aml_set_sysfs_int("/sys/class/video/blackout_policy", 0);
1712 // restore the speed (some amcodec versions require this)
1713 if (m_speed != DVD_PLAYSPEED_NORMAL)
1715 m_dll->codec_resume(&am_private->vcodec);
1716 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1718 // reset the decoder
1719 m_dll->codec_reset(&am_private->vcodec);
1720 dumpfile_close(am_private);
1721 dumpfile_open(am_private);
1723 // re-init our am_pkt
1724 am_packet_release(&am_private->am_pkt);
1725 am_packet_init(&am_private->am_pkt);
1726 am_private->am_pkt.codec = &am_private->vcodec;
1727 pre_header_feeding(am_private, &am_private->am_pkt);
1729 // restore the saved system blackout_policy value
1730 aml_set_sysfs_int("/sys/class/video/blackout_policy", blackout_policy);
1732 // reset some interal vars
1740 int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
1745 // grr, m_RenderUpdateCallBackFn in g_renderManager is NULL'ed during
1746 // g_renderManager.Configure call by player, which happens after the codec
1747 // OpenDecoder call. So we need to restore it but it does not seem to stick :)
1748 g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack);
1752 am_private->am_pkt.data = pData;
1753 am_private->am_pkt.data_size = iSize;
1755 am_private->am_pkt.newflag = 1;
1756 am_private->am_pkt.isvalid = 1;
1757 am_private->am_pkt.avduration = 0;
1759 // handle pts, including 31bit wrap, aml can only handle 31
1760 // bit pts as it uses an int in kernel.
1761 if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
1762 am_private->am_pkt.avpts = AV_NOPTS_VALUE;
1765 am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
1766 if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
1767 m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
1769 if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
1770 am_private->am_pkt.avpts -= m_start_pts;
1773 // handle dts, including 31bit wrap, aml can only handle 31
1774 // bit dts as it uses an int in kernel.
1775 if (dts == DVD_NOPTS_VALUE)
1776 am_private->am_pkt.avdts = AV_NOPTS_VALUE;
1779 am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
1780 if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
1781 m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
1783 if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
1784 am_private->am_pkt.avdts -= m_start_dts;
1786 //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
1787 // iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
1789 // some formats need header/data tweaks.
1790 // the actual write occurs once in write_av_packet
1791 // and is controlled by am_pkt.newflag.
1792 set_header_info(am_private);
1794 // loop until we write all into codec, am_pkt.isvalid
1795 // will get set to zero once everything is consumed.
1796 // PLAYER_SUCCESS means all is ok, not all bytes were written.
1797 while (am_private->am_pkt.isvalid)
1799 // abort on any errors.
1800 if (write_av_packet(am_private, &am_private->am_pkt) != PLAYER_SUCCESS)
1803 if (am_private->am_pkt.isvalid)
1804 CLog::Log(LOGDEBUG, "CAMLCodec::Decode: write_av_packet looping");
1807 // if we seek, then GetTimeSize is wrong as
1808 // reports lastpts - cur_pts and hw decoder has
1809 // not started outputing new pts values yet.
1810 // so we grab the 1st pts sent into driver and
1811 // use that to calc GetTimeSize.
1813 m_1st_pts = am_private->am_pkt.lastpts;
1816 // if we have still frames, demux size will be small
1817 // and we need to pre-buffer more.
1818 double target_timesize = 1.0;
1820 target_timesize = 2.0;
1822 // keep hw buffered demux above 1 second
1823 if (GetTimeSize() < target_timesize && m_speed == DVD_PLAYSPEED_NORMAL)
1826 // wait until we get a new frame or 25ms,
1827 if (m_old_pictcnt == m_cur_pictcnt)
1828 m_ready_event.WaitMSec(25);
1830 // we must return VC_BUFFER or VC_PICTURE,
1831 // default to VC_BUFFER.
1832 int rtn = VC_BUFFER;
1833 if (m_old_pictcnt != m_cur_pictcnt)
1837 // we got a new pict, try and keep hw buffered demux above 2 seconds.
1838 // this, combined with the above 1 second check, keeps hw buffered demux between 1 and 2 seconds.
1839 // we also check to make sure we keep from filling hw buffer.
1840 if (GetTimeSize() < 2.0 && GetDataSize() < m_vbufsize/3)
1844 CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
1845 "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
1846 rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
1851 bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
1856 pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
1857 pDvdVideoPicture->format = RENDER_FMT_BYPASS;
1858 pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
1860 pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
1861 if (m_speed == DVD_PLAYSPEED_NORMAL)
1863 pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
1864 // video pts cannot be late or dvdplayer goes nuts,
1865 // so run it one frame ahead
1866 pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
1870 // We are FF/RW; Do not use the Player clock or it just doesn't work
1872 pDvdVideoPicture->pts = (double)m_1st_pts / PTS_FREQ * DVD_TIME_BASE;
1874 pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
1880 void CAMLCodec::SetSpeed(int speed)
1882 CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
1884 // update internal vars regardless
1885 // of if we are open or not.
1893 case DVD_PLAYSPEED_PAUSE:
1894 m_dll->codec_pause(&am_private->vcodec);
1895 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1897 case DVD_PLAYSPEED_NORMAL:
1898 m_dll->codec_resume(&am_private->vcodec);
1899 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
1902 m_dll->codec_resume(&am_private->vcodec);
1903 if ((am_private->video_format == VFORMAT_H264) || (am_private->video_format == VFORMAT_H264_4K2K))
1904 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
1906 m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
1911 int CAMLCodec::GetDataSize()
1916 struct buf_status vbuf ={0};
1917 if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
1918 m_vbufsize = vbuf.size;
1920 return vbuf.data_len;
1923 double CAMLCodec::GetTimeSize()
1928 // if m_cur_pts is zero, hw decoder was not started yet
1929 // so we use the pts of the 1st demux packet that was send
1930 // to hw decoder to calc timesize.
1932 m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
1934 m_timesize = (double)(am_private->am_pkt.lastpts - m_cur_pts) / PTS_FREQ;
1936 // lie to DVDPlayer, it is hardcoded to a max of 8 seconds,
1937 // if you buffer more than 8 seconds, it goes nuts.
1938 double timesize = m_timesize;
1941 else if (timesize > 7.0)
1947 void CAMLCodec::Process()
1949 CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
1951 // bump our priority to be level with SoftAE
1952 SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
1955 int64_t pts_video = 0;
1956 if (am_private->am_pkt.lastpts > 0)
1958 // this is a blocking poll that returns every vsync.
1959 // since we are running at a higher priority, make sure
1960 // we sleep if the call fails or does a timeout.
1961 if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
1963 CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
1967 pts_video = get_pts_video();
1968 if (m_cur_pts != pts_video)
1970 //CLog::Log(LOGDEBUG, "CAMLCodec::Process: pts_video(%lld), pts_video/PTS_FREQ(%f), duration(%f)",
1971 // pts_video, (double)pts_video/PTS_FREQ, 1.0/((double)(pts_video - m_cur_pts)/PTS_FREQ));
1973 // other threads look at these, do them first
1974 m_cur_pts = pts_video;
1976 m_ready_event.Set();
1978 // correct video pts by starting pts.
1979 if (m_start_pts != 0)
1980 pts_video += m_start_pts;
1981 else if (m_start_dts != 0)
1982 pts_video += m_start_dts;
1984 double app_pts = GetPlayerPtsSeconds();
1985 // add in audio delay/display latency contribution
1986 double offset = g_renderManager.GetDisplayLatency() - CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay;
1987 // correct video pts by user set delay and rendering delay
1990 //CLog::Log(LOGDEBUG, "CAMLCodec::Process: app_pts(%f), pts_video/PTS_FREQ(%f)",
1991 // app_pts, (double)pts_video/PTS_FREQ);
1993 double error = app_pts - (double)pts_video/PTS_FREQ;
1994 double abs_error = fabs(error);
1995 if (abs_error > 0.125)
1997 //CLog::Log(LOGDEBUG, "CAMLCodec::Process pts diff = %f", error);
1998 if (abs_error > 0.150)
2000 // big error so try to reset pts_pcrscr
2001 SetVideoPtsSeconds(app_pts);
2005 // small error so try to avoid a frame jump
2006 SetVideoPtsSeconds((double)pts_video/PTS_FREQ + error/4);
2016 SetPriority(THREAD_PRIORITY_NORMAL);
2017 CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
2020 double CAMLCodec::GetPlayerPtsSeconds()
2022 double clock_pts = 0.0;
2023 CDVDClock *playerclock = CDVDClock::GetMasterClock();
2025 clock_pts = playerclock->GetClock() / DVD_TIME_BASE;
2030 void CAMLCodec::SetVideoPtsSeconds(const double pts)
2032 //CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoPtsSeconds: pts(%f)", pts);
2035 int64_t pts_video = (int64_t)(pts * PTS_FREQ);
2036 if (m_start_pts != 0)
2037 pts_video -= m_start_pts;
2038 else if (m_start_dts != 0)
2039 pts_video -= m_start_dts;
2041 set_pts_pcrscr(pts_video);
2045 void CAMLCodec::ShowMainVideo(const bool show)
2047 static int saved_disable_video = -1;
2049 int disable_video = show ? 0:1;
2050 if (saved_disable_video == disable_video)
2053 aml_set_sysfs_int("/sys/class/video/disable_video", disable_video);
2054 saved_disable_video = disable_video;
2057 void CAMLCodec::SetVideoZoom(const float zoom)
2059 // input zoom range is 0.5 to 2.0 with a default of 1.0.
2060 // output zoom range is 2 to 300 with default of 100.
2061 // we limit that to a range of 50 to 200 with default of 100.
2062 aml_set_sysfs_int("/sys/class/video/zoom", (int)(100 * zoom));
2065 void CAMLCodec::SetVideoContrast(const int contrast)
2067 // input contrast range is 0 to 100 with default of 50.
2068 // output contrast range is -255 to 255 with default of 0.
2069 int aml_contrast = (255 * (contrast - 50)) / 50;
2070 aml_set_sysfs_int("/sys/class/video/contrast", aml_contrast);
2072 void CAMLCodec::SetVideoBrightness(const int brightness)
2074 // input brightness range is 0 to 100 with default of 50.
2075 // output brightness range is -127 to 127 with default of 0.
2076 int aml_brightness = (127 * (brightness - 50)) / 50;
2077 aml_set_sysfs_int("/sys/class/video/brightness", aml_brightness);
2079 void CAMLCodec::SetVideoSaturation(const int saturation)
2081 // output saturation range is -127 to 127 with default of 127.
2082 aml_set_sysfs_int("/sys/class/video/saturation", saturation);
2085 void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
2087 renderFeatures.push_back(RENDERFEATURE_ZOOM);
2088 renderFeatures.push_back(RENDERFEATURE_CONTRAST);
2089 renderFeatures.push_back(RENDERFEATURE_BRIGHTNESS);
2090 renderFeatures.push_back(RENDERFEATURE_STRETCH);
2091 renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
2095 void CAMLCodec::SetVideo3dMode(const int mode3d)
2097 CLog::Log(LOGDEBUG, "CAMLCodec::SetVideo3dMode:mode3d(0x%x)", mode3d);
2098 aml_set_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode", mode3d);
2101 std::string CAMLCodec::GetStereoMode()
2103 std::string stereo_mode;
2105 switch(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoMode)
2107 case RENDER_STEREO_MODE_SPLIT_VERTICAL: stereo_mode = "left_right"; break;
2108 case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: stereo_mode = "top_bottom"; break;
2109 default: stereo_mode = m_hints.stereo_mode; break;
2112 if(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoInvert)
2113 stereo_mode = RenderManager::GetStereoModeInvert(stereo_mode);
2117 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
2119 CAMLCodec *codec = (CAMLCodec*)ctx;
2121 codec->GetRenderFeatures(renderFeatures);
2124 void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
2126 // this routine gets called every video frame
2127 // and is in the context of the renderer thread so
2128 // do not do anything stupid here.
2129 bool update = false;
2131 // video zoom adjustment.
2132 float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
2133 if ((int)(zoom * 1000) != (int)(m_zoom * 1000))
2137 // video contrast adjustment.
2138 int contrast = CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast;
2139 if (contrast != m_contrast)
2141 SetVideoContrast(contrast);
2142 m_contrast = contrast;
2144 // video brightness adjustment.
2145 int brightness = CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness;
2146 if (brightness != m_brightness)
2148 SetVideoBrightness(brightness);
2149 m_brightness = brightness;
2153 int view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
2154 if (m_view_mode != view_mode)
2156 m_view_mode = view_mode;
2160 // video stereo mode/view.
2161 RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode();
2162 if (m_stereo_mode != stereo_mode)
2164 m_stereo_mode = stereo_mode;
2167 RENDER_STEREO_VIEW stereo_view = g_graphicsContext.GetStereoView();
2168 if (m_stereo_view != stereo_view)
2170 // left/right/top/bottom eye,
2171 // this might change every other frame.
2172 // we do not care but just track it.
2173 m_stereo_view = stereo_view;
2177 if (m_dst_rect != DestRect)
2179 m_dst_rect = DestRect;
2185 // mainvideo 'should' be showing already if we get here, make sure.
2186 ShowMainVideo(true);
2190 CRect gui, display, dst_rect;
2191 gui = g_graphicsContext.GetViewWindow();
2192 // when display is at 1080p, we have freescale enabled
2193 // and that scales all layers into 1080p display including video,
2194 // so we have to setup video axis for 720p instead of 1080p... Boooo.
2195 display = g_graphicsContext.GetViewWindow();
2196 dst_rect = m_dst_rect;
2199 float xscale = display.Width() / gui.Width();
2200 float yscale = display.Height() / gui.Height();
2201 dst_rect.x1 *= xscale;
2202 dst_rect.x2 *= xscale;
2203 dst_rect.y1 *= yscale;
2204 dst_rect.y2 *= yscale;
2208 std::string rectangle = StringUtils::Format("%i,%i,%i,%i",
2209 (int)dst_rect.x1, (int)dst_rect.y1,
2210 (int)dst_rect.Width(), (int)dst_rect.Height());
2211 CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
2212 CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_mode(%d)", m_stereo_mode);
2213 CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_view(%d)", m_stereo_view);
2216 if (m_stereo_mode == RENDER_STEREO_MODE_MONO)
2218 std::string mode = GetStereoMode();
2219 if (mode == "left_right")
2220 SetVideo3dMode(MODE_3D_TO_2D_L);
2221 else if (mode == "right_left")
2222 SetVideo3dMode(MODE_3D_TO_2D_R);
2223 else if (mode == "top_bottom")
2224 SetVideo3dMode(MODE_3D_TO_2D_T);
2225 else if (mode == "bottom_top")
2226 SetVideo3dMode(MODE_3D_TO_2D_B);
2228 SetVideo3dMode(MODE_3D_DISABLE);
2230 else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
2233 SetVideo3dMode(MODE_3D_DISABLE);
2235 else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
2238 SetVideo3dMode(MODE_3D_DISABLE);
2240 else if (m_stereo_mode == RENDER_STEREO_MODE_INTERLACED)
2242 std::string mode = GetStereoMode();
2243 if (mode == "left_right")
2244 SetVideo3dMode(MODE_3D_LR);
2245 else if (mode == "right_left")
2246 SetVideo3dMode(MODE_3D_LR_SWITCH);
2247 else if (mode == "row_interleaved_lr")
2248 SetVideo3dMode(MODE_3D_LR);
2249 else if (mode == "row_interleaved_rl")
2250 SetVideo3dMode(MODE_3D_LR_SWITCH);
2252 SetVideo3dMode(MODE_3D_DISABLE);
2256 SetVideo3dMode(MODE_3D_DISABLE);
2259 // goofy 0/1 based difference in aml axis coordinates.
2264 char video_axis[256] = {};
2265 sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
2267 aml_set_sysfs_str("/sys/class/video/axis", video_axis);
2268 // make sure we are in 'full stretch' so we can stretch
2269 aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
2271 // we only get called once gui has changed to something
2272 // that would show video playback, so show it.
2273 ShowMainVideo(true);
2276 void CAMLCodec::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect)
2278 CAMLCodec *codec = (CAMLCodec*)ctx;
2279 codec->SetVideoRect(SrcRect, DestRect);