/amplayer/player/player_av.c
C | 3147 lines | 2674 code | 252 blank | 221 comment | 1083 complexity | e96f6389f21f9136bd2a5eaffabb6113 MD5 | raw file
Possible License(s): LGPL-3.0, CC-BY-SA-3.0, GPL-2.0, GPL-3.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /************************************************
- * name :av_decoder.c
- * function :decoder relative functions
- * data :2010.2.4
- *************************************************/
- //header file
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <player_error.h>
- #include "player_priv.h"
- #include "player_av.h"
- #include "player_hwdec.h"
- #include "player_set_sys.h"
- #include "h263vld.h"
- #include "thread_mgt.h"
- #include "player_update.h"
- #include <cutils/properties.h>
- #define DUMP_READ_RAW_DATA (1<<0)
- #define DUMP_WRITE_RAW_DATA (1<<1)
- #define DUMP_READ_ES_VIDEO (1<<2)
- #define DUMP_WRITE_ES_VIDEO (1<<3)
- #define DUMP_READ_ES_AUDIO (1<<4)
- #define DUMP_WRITE_ES_AUDIO (1<<5)
- #include <fcntl.h>
- int fdr_raw = -1, fdr_video = -1, fdr_audio = -1;
- int fdw_raw = -1, fdw_video = -1, fdw_audio = -1;
- es_sub_t es_sub_buf[9];
- char sub_buf[9][SUBTITLE_SIZE];
- int sub_stream;
- static const media_type media_array[] = {
- {"mpegts", MPEG_FILE, STREAM_TS},
- {"mpeg", MPEG_FILE, STREAM_PS},
- {"rm", RM_FILE, STREAM_RM},
- {"avi", AVI_FILE, STREAM_ES},
- {"mkv", MKV_FILE, STREAM_ES},
- {"matroska", MKV_FILE, STREAM_ES},
- {"mov", MOV_FILE, STREAM_ES},
- {"mp4", MP4_FILE, STREAM_ES},
- {"flv", FLV_FILE, STREAM_ES},
- {"aac", AAC_FILE, STREAM_AUDIO},
- {"ac3", AC3_FILE, STREAM_AUDIO},
- {"mp3", MP3_FILE, STREAM_AUDIO},
- {"mp2", MP3_FILE, STREAM_AUDIO},
- {"wav", WAV_FILE, STREAM_AUDIO},
- {"dts", DTS_FILE, STREAM_AUDIO},
- {"flac", FLAC_FILE, STREAM_AUDIO},
- {"h264", H264_FILE, STREAM_VIDEO},
- {"cavs", AVS_FILE, STREAM_VIDEO},
- {"mpegvideo", M2V_FILE, STREAM_VIDEO},
- {"p2p", P2P_FILE, STREAM_ES},
- {"asf", ASF_FILE, STREAM_ES},
- {"m4a", MP4_FILE, STREAM_ES},
- {"m4v", MP4_FILE, STREAM_ES},
- {"rtsp", STREAM_FILE, STREAM_ES},
- {"ape", APE_FILE, STREAM_ES},
- {"hls,applehttp", MP4_FILE, STREAM_ES},
- {"DRMdemux", MP4_FILE, STREAM_ES},
- {"cmf", MP4_FILE, STREAM_ES},
- {"amr", AMR_FILE, STREAM_AUDIO},
- };
- aformat_t audio_type_convert(enum CodecID id, pfile_type File_type)
- {
- aformat_t format = -1;
- switch (id) {
- case CODEC_ID_PCM_MULAW:
- //format = AFORMAT_MULAW;
- format = AFORMAT_ADPCM;
- break;
- case CODEC_ID_PCM_ALAW:
- //format = AFORMAT_ALAW;
- format = AFORMAT_ADPCM;
- break;
- case CODEC_ID_MP1:
- case CODEC_ID_MP2:
- case CODEC_ID_MP3:
- format = AFORMAT_MPEG;
- break;
- case CODEC_ID_AAC_LATM:
- format = AFORMAT_AAC_LATM;
- break;
- case CODEC_ID_AAC:
- if (File_type == RM_FILE) {
- format = AFORMAT_RAAC;
- } else {
- format = AFORMAT_AAC;
- }
- break;
- case CODEC_ID_AC3:
- format = AFORMAT_AC3;
- break;
- case CODEC_ID_EAC3:
- format = AFORMAT_EAC3;
- break;
- case CODEC_ID_DTS:
- format = AFORMAT_DTS;
- break;
- case CODEC_ID_PCM_S16BE:
- format = AFORMAT_PCM_S16BE;
- break;
- case CODEC_ID_PCM_S16LE:
- format = AFORMAT_PCM_S16LE;
- break;
- case CODEC_ID_PCM_U8:
- format = AFORMAT_PCM_U8;
- break;
- case CODEC_ID_COOK:
- format = AFORMAT_COOK;
- break;
- case CODEC_ID_ADPCM_IMA_WAV:
- case CODEC_ID_ADPCM_MS:
- format = AFORMAT_ADPCM;
- break;
- case CODEC_ID_AMR_NB:
- case CODEC_ID_AMR_WB:
- format = AFORMAT_AMR;
- break;
- case CODEC_ID_WMAV1:
- case CODEC_ID_WMAV2:
- format = AFORMAT_WMA;
- break;
- case CODEC_ID_FLAC:
- format = AFORMAT_FLAC;
- break;
- case CODEC_ID_WMAPRO:
- format = AFORMAT_WMAPRO;
- break;
- case CODEC_ID_PCM_BLURAY:
- format = AFORMAT_PCM_BLURAY;
- break;
- case CODEC_ID_ALAC:
- format = AFORMAT_ALAC;
- break;
- case CODEC_ID_VORBIS:
- format = AFORMAT_VORBIS;
- break;
- case CODEC_ID_APE:
- format = AFORMAT_APE;
- break;
- case CODEC_ID_PCM_WIFIDISPLAY:
- format = AFORMAT_PCM_WIFIDISPLAY;
- break;
- default:
- format = AFORMAT_UNSUPPORT;
- log_print("audio codec_id=0x%x\n", id);
- }
- log_print("[audio_type_convert]audio codec_id=0x%x format=%d\n", id, format);
- return format;
- }
- vformat_t video_type_convert(enum CodecID id)
- {
- vformat_t format;
- switch (id) {
- case CODEC_ID_MPEG1VIDEO:
- case CODEC_ID_MPEG2VIDEO:
- case CODEC_ID_MPEG2VIDEO_XVMC:
- format = VFORMAT_MPEG12;
- break;
- case CODEC_ID_H263:
- case CODEC_ID_MPEG4:
- case CODEC_ID_H263P:
- case CODEC_ID_H263I:
- case CODEC_ID_XVID:
- case CODEC_ID_MSMPEG4V2:
- case CODEC_ID_MSMPEG4V3:
- case CODEC_ID_FLV1:
- format = VFORMAT_MPEG4;
- break;
- case CODEC_ID_RV10:
- case CODEC_ID_RV20:
- case CODEC_ID_RV30:
- case CODEC_ID_RV40:
- format = VFORMAT_REAL;
- break;
- //case CODEC_ID_AVC1:
- case CODEC_ID_H264:
- format = VFORMAT_H264;
- break;
- case CODEC_ID_H264MVC:
- format = VFORMAT_H264MVC;
- break;
- case CODEC_ID_MJPEG:
- format = VFORMAT_MJPEG;
- break;
- case CODEC_ID_VC1:
- case CODEC_ID_WMV3:
- //case CODEC_ID_WMV1: //not support
- // case CODEC_ID_WMV2: //not support
- format = VFORMAT_VC1;
- break;
- case CODEC_ID_VP6F:
- format = VFORMAT_SW;
- break;
- case CODEC_ID_CAVS:
- case CODEC_ID_AVS:
- format = VFORMAT_AVS;
- break;
- default:
- format = VFORMAT_UNSUPPORT;
- log_print("video_type_convert failed:unsupport video,codec_id=0x%x\n", id);
- }
- log_print("[video_type_convert]video codec_id=0x%x format=%d\n", id, format);
- return format;
- }
- vdec_type_t video_codec_type_convert(unsigned int id)
- {
- vdec_type_t dec_type;
- log_print("[video_codec_type_convert]id=(0x%x) ", id);
- switch (id) {
- case CODEC_TAG_MJPEG:
- case CODEC_TAG_mjpeg:
- case CODEC_TAG_jpeg:
- case CODEC_TAG_mjpa:
- log_print("VIDEO_TYPE_MJPEG\n");
- dec_type = VIDEO_DEC_FORMAT_MJPEG;
- break;
- // xvid
- case CODEC_TAG_XVID:
- case CODEC_TAG_xvid:
- case CODEC_TAG_XVIX:
- log_print("VIDEO_TYPE_XVID\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
- break;
- //divx3.11
- case CODEC_TAG_COL1:
- case CODEC_TAG_DIV3:
- case CODEC_TAG_MP43:
- log_print("VIDEO_TYPE_DIVX311\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_3;
- break;
- // divx4
- case CODEC_TAG_DIV4:
- case CODEC_TAG_DIVX:
- case CODEC_TAG_divx:
- log_print("VIDEO_TYPE_DIVX4\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_4;
- break;
- // divx5
- case CODEC_TAG_DIV5:
- case CODEC_TAG_DX50:
- case CODEC_TAG_M4S2:
- case CODEC_TAG_FMP4:
- case CODEC_TAG_FVFW:
- log_print("VIDEO_TYPE_DIVX 5\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
- break;
- // divx6
- case CODEC_TAG_DIV6:
- log_print("VIDEO_TYPE_DIVX 6\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
- break;
- // mp4
- case CODEC_TAG_MP4V:
- case CODEC_TAG_RMP4:
- case CODEC_TAG_MPG4:
- case CODEC_TAG_mp4v:
- case CODEC_ID_MPEG4:
- log_print("VIDEO_DEC_FORMAT_MPEG4_5\n");
- dec_type = VIDEO_DEC_FORMAT_MPEG4_5;
- break;
- // h263
- case CODEC_ID_H263:
- case CODEC_TAG_H263:
- case CODEC_TAG_h263:
- case CODEC_TAG_s263:
- case CODEC_TAG_F263:
- log_print("VIDEO_DEC_FORMAT_H263\n");
- dec_type = VIDEO_DEC_FORMAT_H263;
- break;
- //avc1
- case CODEC_TAG_AVC1:
- case CODEC_TAG_avc1:
- // h264
- case CODEC_TAG_H264:
- case CODEC_TAG_h264:
- log_print("VIDEO_TYPE_H264\n");
- dec_type = VIDEO_DEC_FORMAT_H264;
- break;
- case CODEC_ID_RV30:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_REAL_8(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_REAL_8;
- break;
- case CODEC_ID_RV40:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_REAL_9(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_REAL_9;
- break;
- case CODEC_ID_H264:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_H264(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_H264;
- break;
- case CODEC_ID_H264MVC:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_H264MVC(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_H264;
- break;
- //case CODEC_TAG_WMV1: //not support
- //case CODEC_TAG_WMV2: //not support
- case CODEC_TAG_WMV3:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_WMV3(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_WMV3;
- break;
- case CODEC_TAG_WVC1:
- case CODEC_ID_VC1:
- case CODEC_TAG_WMVA:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_WVC1(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_WVC1;
- break;
- case CODEC_ID_VP6F:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_SW(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_SW;
- break;
- case CODEC_ID_CAVS:
- case CODEC_ID_AVS:
- log_print("[video_codec_type_convert]VIDEO_DEC_FORMAT_AVS(0x%x)\n", id);
- dec_type = VIDEO_DEC_FORMAT_AVS;
- break;
- default:
- log_print("[video_codec_type_convert]error:VIDEO_TYPE_UNKNOW id = 0x%x\n", id);
- dec_type = VIDEO_DEC_FORMAT_UNKNOW;
- break;
- }
- return dec_type;
- }
- stream_type_t stream_type_convert(pstream_type type, char vflag, char aflag)
- {
- switch (type) {
- case STREAM_TS:
- return STREAM_TYPE_TS;
- case STREAM_PS:
- return STREAM_TYPE_PS;
- case STREAM_RM:
- return STREAM_TYPE_RM;
- case STREAM_ES:
- if (vflag == 1) {
- return STREAM_TYPE_ES_VIDEO;
- }
- if (aflag == 1) {
- return STREAM_TYPE_ES_AUDIO;
- } else {
- return STREAM_TYPE_UNKNOW;
- }
- case STREAM_AUDIO:
- return STREAM_TYPE_ES_AUDIO;
- case STREAM_VIDEO:
- return STREAM_TYPE_ES_VIDEO;
- case STREAM_UNKNOWN:
- default:
- return STREAM_TYPE_UNKNOW;
- }
- }
- int set_file_type(const char *name, pfile_type *ftype, pstream_type *stype)
- {
- int i, j ;
- j = sizeof(media_array) / sizeof(media_type);
- for (i = 0; i < j; i++) {
- //log_print("[set_file_type:0]name = %s mname=%s\n",name ,media_array[i].file_ext);
- if (strcmp(name, media_array[i].file_ext) == 0) {
- break;
- }
- }
- if (i == j) {
- for (i = 0; i < j; i++) {
- //log_print("[set_file_type:1]name = %s mname=%s\n",name ,media_array[i].file_ext);
- if (strstr(name, media_array[i].file_ext) != NULL) {
- break;
- }
- if (i == j) {
- log_print("Unsupport file type %s\n", name);
- return PLAYER_UNSUPPORT;
- }
- }
- }
- *ftype = media_array[i].file_type;
- *stype = media_array[i].stream_type;
- log_info("[set_file_type]file_type=%d stream_type=%d\n", *ftype, *stype);
- return PLAYER_SUCCESS;
- }
- static int compare_pkt(AVPacket *src, AVPacket *dst)
- {
- if (dst->pts != (int64_t)AV_NOPTS_VALUE) {
- if (dst->pts <= src->pts) {
- return 1;
- } else {
- return 0;
- }
- } else if (dst->dts != (int64_t)AV_NOPTS_VALUE) {
- if (dst->dts <= src->dts) {
- return 1;
- } else {
- return 0;
- }
- } else {
- int compare_size = MIN(src->size, dst->size);
- compare_size = compare_size > 1024 ? 1024 : compare_size;
- //log_print("dst size %d, src size %d, dst data 0x%x, src data 0x%x\n",
- // dst->size, src->size, dst->data, src->data);
- if (memcmp(dst->data, src->data, compare_size) == 0) {
- return 1;
- } else {
- //log_print("Packet is different\n");
- return 0;
- }
- }
- }
- static int backup_packet(play_para_t *para, AVPacket *src, AVPacket *dst)
- {
- if (dst->data != NULL) {
- if (dst->pos >= url_ftell(para->pFormatCtx->pb)) {
- log_print("[%s:%d]dst->pos >= url_ftell(pb)\n", __FUNCTION__, __LINE__);
- return 0;
- } else {
- FREE(dst->data);
- }
- }
- dst->data = MALLOC(src->size);
- if (dst->data == NULL) {
- log_error("[%s:%d]No memory!\n", __FUNCTION__, __LINE__);
- return -1;
- }
- dst->pts = src->pts;
- dst->dts = src->dts;
- dst->size = src->size;
- dst->pos = url_ftell(para->pFormatCtx->pb);
- MEMCPY(dst->data, src->data, src->size);
- return 0;
- }
- static int raw_read(play_para_t *para)
- {
- int rev_byte = -1;
- ByteIOContext *pb = para->pFormatCtx->pb;
- am_packet_t *pkt = para->p_pkt;
- unsigned char *pbuf ;
- static int try_count = 0;
- int64_t cur_offset = 0;
- float value;
- int dump_data_mode = 0;
- char dump_path[128];
- #ifdef ANDROID
- if (am_getconfig_float("media.libplayer.dumpmode", &value) == 0) {
- dump_data_mode = (int)value;
- }
- #endif
- if (dump_data_mode == DUMP_READ_RAW_DATA) {
- if (fdr_raw == -1) {
- sprintf(dump_path, "/temp/pid%d_dump_read.dat", para->player_id);
- fdr_raw = open(dump_path, O_CREAT | O_RDWR, 0666);
- if (fdr_raw < 0) {
- log_print("creat %s failed!fd=%d\n", dump_path, fdr_raw);
- }
- }
- }
- if (pkt->data_size > 0) {
- if (!para->enable_rw_on_pause) {
- player_thread_wait(para, RW_WAIT_TIME);
- }
- return PLAYER_SUCCESS;
- }
- if(para->buffering_enable&¶->buffering_threshhold_max){
- int maxlimitsize=0;
- maxlimitsize=((int)((1-para->buffering_threshhold_max)*AB_SIZE-1))&~0x2000;
- if (para->max_raw_size > maxlimitsize) {
- para->max_raw_size =maxlimitsize;
- log_print("Enable autobuf , max_raw_size set to =%d\n",para->max_raw_size);
- }
- }
- if (pkt->buf == NULL || pkt->buf_size != (MAX_RAW_DATA_SIZE+16)) { /*may chaged to short,enarge it*/
- pkt->buf_size = MAX_RAW_DATA_SIZE+16;
- pkt->buf = MALLOC(pkt->buf_size);
- if (pkt->buf == NULL) {
- log_print("not enough memory,please fre memory\n");
- return PLAYER_RD_EMPTYP;
- }
- }
- pkt->data = pkt->buf;
- pbuf = pkt->data;
- cur_offset = url_ftell(pb);
- #ifdef DEBUG_VARIABLE_DUR
- if (para->playctrl_info.info_variable) {
- if ((cur_offset + para->max_raw_size) >= para->pFormatCtx->valid_offset) {
- update_variable_info(para);
- }
- }
- #endif
- if (!para->playctrl_info.read_end_flag && (0 == pkt->data_size)) {
- int tryread_size;
- if (para->playctrl_info.lowbuffermode_flag) {
- tryread_size = 1024; /*keep in low buffer level for less latency ....*/
- } else {
- tryread_size = para->max_raw_size;
- }
- rev_byte = get_buffer(pb, pbuf, tryread_size);
- log_debug1("get_buffer,%d,cur_offset=%lld,para->pFormatCtx->valid_offset==%lld\n", rev_byte , cur_offset, para->pFormatCtx->valid_offset);
- if (AVERROR(ETIMEDOUT) == rev_byte && para->state.current_time >= para->state.full_time) {
- //read timeout ,if playing current time reached end time,we think it is eof
- rev_byte = AVERROR_EOF;
- }
- if ((rev_byte > 0) && (cur_offset <= para->pFormatCtx->valid_offset)) {
- try_count = 0;
- pkt->data_size = rev_byte;
- para->read_size.total_bytes += rev_byte;
- pkt->avpkt_newflag = 1;
- pkt->avpkt_isvalid = 1;
- pkt->pts_checkin_ok = 0;
- if (fdr_raw > 0) {
- int dsize;
- dsize = write(fdr_raw, pkt->data, pkt->data_size);
- if (dsize != pkt->data_size) {
- log_print("dump data write failed!size=%d len=%d\n", dsize, pkt->data_size);
- }
- //log_print("dump data write succeed!size=%d len=%d\n",dsize,pkt->data_size);
- }
- } else if ((rev_byte == AVERROR_EOF) || (cur_offset > para->pFormatCtx->valid_offset)) { //if(rev_byte != AVERROR(EAGAIN))
- static int reach_end = 0;
- if (para->stream_type == STREAM_AUDIO && para->astream_info.audio_format == AFORMAT_MPEG)
- //if(0)
- {
- if (reach_end < 5) {
- reach_end++;
- //if(!get_readend_set_flag())
- //set_readend_flag(1);
- memset(pbuf, 0, tryread_size);
- // strncpy(pbuf,"FREND",5);
- pkt->data_size = tryread_size;
- pkt->avpkt_newflag = 0;
- pkt->avpkt_isvalid = 1;
- pkt->pts_checkin_ok = 0;
- } else {
- reach_end = 0;
- para->playctrl_info.read_end_flag = 1;
- log_print("raw read2: read end!,%d,%lld,%lld add :%d byte zero data\n", rev_byte , cur_offset, para->pFormatCtx->valid_offset, tryread_size * 5);
- }
- } else {
- reach_end = 0;
- /*if the return is EAGAIN,we need to try more times*/
- para->playctrl_info.read_end_flag = 1;
- log_print("raw read: read end!,%d,%lld,%lld\n", rev_byte , cur_offset, para->pFormatCtx->valid_offset);
- if (fdr_raw > 0) {
- close(fdr_raw);
- }
- }
- #if 0 //old
- /*if the return is EAGAIN,we need to try more times*/
- para->playctrl_info.read_end_flag = 1;
- log_print("raw read: read end!,%d,%lld,%lld\n", rev_byte , cur_offset, para->pFormatCtx->valid_offset);
- #if DUMP_READ_AVDATA
- if (fdr > 0) {
- close(fdr);
- }
- #endif
- #endif
- } else {
- if (rev_byte != AVERROR(EAGAIN)) {
- log_print("raw_read buffer error!,%d\n", rev_byte);
- return PLAYER_RD_FAILED;
- } else {
- try_count ++;
- if (try_count >= para->playctrl_info.read_max_retry_cnt) {
- log_print("raw_read buffer try too more counts,exit!\n");
- return PLAYER_RD_TIMEOUT;
- } else {
- return PLAYER_RD_AGAIN;
- }
- }
- }
- }
- if (para->stream_type == STREAM_TS) {
- pkt->codec = para->codec;
- pkt->type = CODEC_COMPLEX;
- } else if (para->stream_type == STREAM_PS) {
- pkt->codec = para->codec;
- pkt->type = CODEC_COMPLEX;
- } else if (para->stream_type == STREAM_RM) {
- pkt->codec = para->codec;
- pkt->type = CODEC_COMPLEX;
- } else if (para->stream_type == STREAM_AUDIO) {
- pkt->codec = para->acodec;
- pkt->type = CODEC_AUDIO;
- } else if (para->stream_type == STREAM_VIDEO) {
- pkt->codec = para->vcodec;
- pkt->type = CODEC_VIDEO;
- }
- return PLAYER_SUCCESS;
- }
- static int non_raw_read(play_para_t *para)
- {
- static int try_count = 0;
- am_packet_t *pkt = para->p_pkt;
- signed short video_idx = para->vstream_info.video_index;
- signed short audio_idx = para->astream_info.audio_index;
- signed short sub_idx = para->sstream_info.sub_index;
- int has_video = para->vstream_info.has_video;
- int has_audio = para->astream_info.has_audio;
- int has_sub = para->sstream_info.has_sub;
- float value;
- int dump_data_mode = 0;
- char dump_path[128];
- #ifdef ANDROID
- if (am_getconfig_float("media.libplayer.dumpmode", &value) == 0) {
- dump_data_mode = (int)value;
- }
- #endif
- if (pkt->data_size > 0) {
- if (!para->enable_rw_on_pause) {
- player_thread_wait(para, RW_WAIT_TIME);
- }
- //log_print("[%s:%d]wait---data_size=%d!\n",__FUNCTION__, __LINE__,pkt->data_size);
- return PLAYER_SUCCESS;
- }
- if (para->vstream_info.has_video && !para->vcodec) {
- log_print("[non_raw_read]video codec invalid!\n");
- return PLAYER_RD_EMPTYP;
- }
- if (para->astream_info.has_audio && !para->acodec) {
- log_print("[non_raw_read]audio codec invalid!\n");
- return PLAYER_RD_EMPTYP;
- }
- if (pkt->avpkt == NULL) {
- log_print("non_raw_read error:avpkt pointer NULL!\n");
- return PLAYER_RD_EMPTYP;
- }
- while (!para->playctrl_info.read_end_flag && (0 == pkt->data_size)) {
- int ret;
- ret = av_read_frame(para->pFormatCtx, pkt->avpkt);
- if (ret < 0) {
- if (AVERROR(EAGAIN) != ret) {
- /*if the return is EAGAIN,we need to try more times*/
- log_error("[%s:%d]av_read_frame return (%d)\n", __FUNCTION__, __LINE__, ret);
- if (AVERROR(ETIMEDOUT) == ret && para->state.current_time >= para->state.full_time) {
- //read timeout ,if playing current time reached end time,we think it is eof
- ret = AVERROR_EOF;
- }
- if (AVERROR_EOF != ret) {
- return PLAYER_RD_FAILED;
- } else {
- /*reach end add 6k audio data*/
- static int reach_end = 0;
- AVStream *st;
- if (reach_end < 3) {
- reach_end++;
- if (audio_idx >= 0) {
- st = para->pFormatCtx->streams[audio_idx];
- if (st->codec->codec_type == CODEC_TYPE_AUDIO && (st->codec->codec_id == CODEC_ID_APE || st->codec->codec_id == CODEC_ID_AAC || st->codec->codec_id == CODEC_ID_AMR_NB || st->codec->codec_id == CODEC_ID_MP3)) {
- //if (st->codec->codec_type==CODEC_TYPE_AUDIO) {
- //set attr
- if (!get_readend_set_flag()) {
- set_readend_flag(1);
- }
- pkt->avpkt->data = av_mallocz(2048);
- //strncpy(pkt->avpkt->data,"FREND",5);
- pkt->avpkt->size = 2048;
- pkt->avpkt->stream_index = st->index;
- ret = 0;
- }
- }
- } else {//audio data add end
- reach_end = 0;
- para->playctrl_info.read_end_flag = 1;
- log_print("non_raw_read: read end!\n");
- if (fdr_video >= 0) {
- close(fdr_video);
- }
- if (fdr_audio >= 0) {
- close(fdr_audio);
- }
- }
- }
- } else {
- try_count ++;
- if (try_count >= para->playctrl_info.read_max_retry_cnt) {
- log_print("try %d counts, can't get packet,exit!\n", para->playctrl_info.read_max_retry_cnt);
- return PLAYER_RD_TIMEOUT;
- } else {
- log_print("[non_raw_read]EAGAIN, try count=%d\n", try_count);
- return PLAYER_RD_AGAIN;
- }
- }
- } else { //read success
- try_count = 0;
- if (dump_data_mode == DUMP_READ_ES_VIDEO) {
- if (fdr_video == -1) {
- sprintf(dump_path, "/temp/pid%d_dump_vread.dat", para->player_id);
- fdr_video = open(dump_path, O_CREAT | O_RDWR, 0666);
- if (fdr_video < 0) {
- log_print("creat %s failed!fd=%d\n", dump_path, fdr_video);
- }
- }
- } else if (dump_data_mode == DUMP_READ_ES_AUDIO) {
- if (fdr_audio == -1) {
- sprintf(dump_path, "/temp/pid%d_dump_aread.dat", para->player_id);
- fdr_audio = open(dump_path, O_CREAT | O_RDWR, 0666);
- if (fdr_audio < 0) {
- log_error("creat %s failed!fd=%d\n", dump_path, fdr_audio);
- }
- }
- }
- }
- //log_print("av_read_frame return (%d) pkt->avpkt=%p pkt->avpkt->data=%p\r",ret,pkt->avpkt,pkt->avpkt->data);
- if (pkt->avpkt->size >= MAX_PACKET_SIZE) {
- log_print("non_raw_read error:packet size exceed malloc memory! size %d\n", pkt->avpkt->size);
- av_free_packet(pkt->avpkt);
- return PLAYER_RD_FAILED;
- }
- if (para->stream_type == STREAM_ES && !para->playctrl_info.read_end_flag) {
- if (has_video && video_idx == pkt->avpkt->stream_index) {
- if (para->playctrl_info.audio_switch_vmatch) {
- if (compare_pkt(pkt->avpkt, &pkt->bak_avpkt) == 0) {
- av_free_packet(pkt->avpkt);
- continue;
- } else {
- //FREE(pkt->bak_avpkt.data);
- pkt->bak_avpkt.pos = 0;
- para->playctrl_info.audio_switch_vmatch = 0;
- }
- } else if (para->vstream_info.discard_pkt == 1) {
- av_free_packet(pkt->avpkt);
- para->vstream_info.discard_pkt = 2;
- continue;
- } else if (para->vstream_info.discard_pkt == 2) {
- para->vstream_info.discard_pkt = 1;
- }
- pkt->codec = para->vcodec;
- pkt->type = CODEC_VIDEO;
- if (ret != AVERROR_EOF) {
- para->read_size.vpkt_num ++;
- }
- } else if (has_audio && audio_idx == pkt->avpkt->stream_index) {
- pkt->codec = para->acodec;
- pkt->type = CODEC_AUDIO;
- para->read_size.apkt_num ++;
- //} else if (has_sub && ((1<<(pkt->avpkt->stream_index))&sub_stream)/*&& sub_idx == pkt->avpkt->stream_index*/) {
- } else if (has_sub && ((1<<(para->pFormatCtx->streams[pkt->avpkt->stream_index]->id))&sub_stream)/*&& sub_idx == pkt->avpkt->stream_index*/) {
- #if 0
- /* here we get the subtitle data, something should to be done */
- if (para->playctrl_info.audio_switch_smatch) {
- if (compare_pkt(pkt->avpkt, &pkt->bak_spkt) == 0) {
- pkt->codec = NULL;
- pkt->type = CODEC_UNKNOW;
- av_free_packet(pkt->avpkt);
- continue;
- } else {
- //FREE(pkt->bak_avpkt.data);
- pkt->bak_avpkt.pos = 0;
- para->playctrl_info.audio_switch_smatch = 0;
- }
- }
- #endif
- para->read_size.spkt_num ++;
- pkt->type = CODEC_SUBTITLE;
- pkt->codec = para->scodec;
- } else {
- pkt->codec = NULL;
- pkt->type = CODEC_UNKNOW;
- av_free_packet(pkt->avpkt);
- continue;
- }
- if (para->first_index == -1) {
- para->first_index = pkt->avpkt->stream_index;
- }
- }
- if (ret == 0) {
- //discard the first package when resume from pause state for ape
- if (para->astream_info.audio_format == AFORMAT_APE && pkt->type == CODEC_AUDIO) {
- if (para->state.current_time > 0 && pkt->avpkt->pts == 0) {
- av_free_packet(pkt->avpkt);
- continue;
- }
- }
- pkt->data = pkt->avpkt->data;
- pkt->data_size = pkt->avpkt->size;
- int dsize;
- if (fdr_video >= 0 && pkt->type == CODEC_VIDEO) {
- dsize = write(fdr_video, pkt->data, pkt->data_size);
- } else if (fdr_audio >= 0 && pkt->type == CODEC_AUDIO) {
- dsize = write(fdr_audio, pkt->data, pkt->data_size);
- }
- if ((fdr_audio >= 0 || fdr_video >= 0) && (dsize != pkt->data_size)) {
- log_print("dump read es data failed!type=%d size=%d len=%d\n",
- pkt->type, dsize, pkt->data_size);
- }
- //log_print("[%s:%d]dump data read size=%d, want len=%d\n", __FUNCTION__, __LINE__, dsize, pkt->data_size);
- pkt->avpkt_newflag = 1;
- pkt->avpkt_isvalid = 1;
- pkt->pts_checkin_ok = 0;
- //log_print("[%s:%d]read finish-data_size=%d!\r",__FUNCTION__, __LINE__,pkt->data_size);
- }
- break;
- }
- return PLAYER_SUCCESS;
- }
- int read_av_packet(play_para_t *para)
- {
- am_packet_t *pkt = para->p_pkt;
- char raw_mode = para->playctrl_info.raw_mode;
- int ret = PLAYER_SUCCESS;
- if (para == NULL || pkt == NULL) {
- return PLAYER_RD_EMPTYP;
- }
- if (raw_mode == 1) {
- player_mate_wake(para, 100 * 1000);
- ret = raw_read(para);
- if(ret <0 && para->playctrl_info.ignore_ffmpeg_errors){
- para->playctrl_info.ignore_ffmpeg_errors=0;
- if(para->pFormatCtx&& para->pFormatCtx->pb)
- para->pFormatCtx->pb->error=0;
- ret=0;
- }
- player_mate_sleep(para);
- if (ret != PLAYER_SUCCESS && ret != PLAYER_RD_AGAIN) {
- log_print("raw read failed!\n");
- return ret;
- }
- } else if (raw_mode == 0) {
- player_mate_wake(para, 100 * 1000);
- ret = non_raw_read(para);
- if(ret <0 && para->playctrl_info.ignore_ffmpeg_errors){
- para->playctrl_info.ignore_ffmpeg_errors=0;
- if(para->pFormatCtx&& para->pFormatCtx->pb)
- para->pFormatCtx->pb->error=0;
- ret=0;
- }
- player_mate_sleep(para);
- if (ret != PLAYER_SUCCESS && ret != PLAYER_RD_AGAIN) {
- log_print("non raw read failed!\n");
- return ret;
- }
- }
- return ret;
- }
- static int write_header(play_para_t *para)
- {
- int write_bytes = 0, len = 0;
- am_packet_t *pkt = para->p_pkt;
- if (para->pFormatCtx->skip_extradata) {
- //log_print("skip header!\n");
- return PLAYER_EMPTY_P;
- }
- if (pkt->hdr && pkt->hdr->size > 0) {
- if ((NULL == pkt->codec) || (NULL == pkt->hdr->data)) {
- log_error("[write_header]codec null!\n");
- return PLAYER_EMPTY_P;
- }
- //some wvc1 es data not need to add header
- if (pkt->type == CODEC_VIDEO && para->vstream_info.video_format == VFORMAT_VC1 && para->vstream_info.video_codec_type == VIDEO_DEC_FORMAT_WVC1) {
- if ((pkt->data) && (pkt->data_size >= 4) && (pkt->data[0] == 0) && (pkt->data[1] == 0) && (pkt->data[2] == 1) && (pkt->data[3] == 0xd || pkt->data[3] == 0xf)) {
- return PLAYER_SUCCESS;
- }
- }
- while (1) {
- write_bytes = codec_write(pkt->codec, pkt->hdr->data + len, pkt->hdr->size - len);
- if (write_bytes < 0 || write_bytes > (pkt->hdr->size - len)) {
- if (-errno != AVERROR(EAGAIN)) {
- log_print("ERROR:write header failed!\n");
- return PLAYER_WR_FAILED;
- } else {
- log_print("[write_header]need write again\n");
- //continue;
- return PLAYER_WR_AGAIN;
- }
- } else {
- int size;
- if (fdw_video >= 0 && pkt->type == CODEC_VIDEO) {
- size = write(fdw_video, pkt->hdr->data + len, write_bytes);
- } else if (fdw_audio >= 0 && pkt->type == CODEC_AUDIO) {
- size = write(fdw_audio, pkt->hdr->data + len, write_bytes);
- } else if (fdw_raw >= 0 && pkt->type == CODEC_COMPLEX) {
- size = write(fdw_raw, pkt->hdr->data + len, write_bytes);
- }
- if ((fdw_video >= 0 || fdw_audio >= 0 || fdw_raw >= 0) &&
- (size != write_bytes)) {
- log_print("dump data write failed!size=%d bytes=%d\n", size, write_bytes);
- }
- // log_print("[%s:%d]dump data write size=%d, want len=%d\n", __FUNCTION__, __LINE__, size, len);
- }
- len += write_bytes;
- if (len == pkt->hdr->size) {
- break;
- }
- }
- }
- return PLAYER_SUCCESS;
- }
- static int check_write_finish(play_para_t *para)
- {
- am_packet_t *pkt = para->p_pkt;
- if (para->playctrl_info.read_end_flag) {
- if (para->playctrl_info.raw_mode
- && (para->write_size.total_bytes == para->read_size.total_bytes)) {
- return PLAYER_WR_FINISH;
- }
- if (!para->playctrl_info.raw_mode
- && (para->write_size.vpkt_num == para->read_size.vpkt_num)
- && (para->write_size.apkt_num == para->read_size.apkt_num)) {
- return PLAYER_WR_FINISH;
- }
- }
- return PLAYER_WR_FAILED;
- }
- static int64_t rm_offset_search_pts(AVStream *pStream, float timepoint)
- {
- int64_t wanted_pts = (int64_t)(timepoint * 1000);
- int index_entry, index_entry_f, index_entry_b;
- int64_t pts_f, pts_b;
- index_entry_f = av_index_search_timestamp(pStream, wanted_pts, 0);
- index_entry_b = av_index_search_timestamp(pStream, wanted_pts, AVSEEK_FLAG_BACKWARD);
- if (index_entry_f < 0) {
- if (index_entry_b < 0) {
- log_error("[%s]not found valid backward index entry\n", __FUNCTION__);
- return 0;
- } else {
- log_print("[%s:%d]time_point=%d pos=0x%llx\n", __FUNCTION__, __LINE__, timepoint, pStream->index_entries[index_entry_b].pos);
- return pStream->index_entries[index_entry_b].pos;
- }
- }
- #if 0
- if (index_entry_b < 0) {
- if (index_entry_f < 0) {
- return 0;
- } else {
- return pStream->index_entries[index_entry_f].pos;
- }
- }
- pts_f = pStream->index_entries[index_entry_f].timestamp;
- pts_b = pStream->index_entries[index_entry_b].timestamp;
- if ((wanted_pts - pts_b) < (pts_f - wanted_pts)) {
- index_entry = index_entry_b;
- } else {
- index_entry = index_entry_f;
- }
- #endif
- index_entry = index_entry_f;
- return pStream->index_entries[index_entry].pos;
- }
- static int64_t rm_offset_search(play_para_t *am_p, int64_t offset, float time_point)
- {
- int read_length = 0;
- unsigned char *data;
- unsigned short video_id = am_p->vstream_info.video_pid;
- unsigned short audio_id = am_p->astream_info.audio_pid;
- unsigned skip_byte = 0;
- unsigned char *pkt;
- const unsigned int read_size = 16 * 1024;
- int64_t cur_offset = 0;
- unsigned short sync_flag = 0;
- unsigned int i = 0;
- AVStream *pStream;
- int retry_get_data = 0;
- AVFormatContext *s = am_p->pFormatCtx;
- /* first check the video stream index table */
- for (i = 0; i < s->nb_streams; i++) {
- pStream = s->streams[i];
- if (pStream->index == am_p->vstream_info.video_index) {
- break;
- }
- }
- if (i < s->nb_streams) {
- if (s->index_builded && (pStream->nb_index_entries > 1)) {
- cur_offset = rm_offset_search_pts(pStream, time_point);
- log_info("rm time search by index:pos=%f offset=%lld\n", time_point, cur_offset);
- return cur_offset;
- }
- }
- /* no index, then search byte by byte */
- data = MALLOC(read_size + 12);
- if (!data) {
- log_error("[%s]malloc failed \n", __FUNCTION__);
- return am_p->data_offset;
- }
- cur_offset = offset;
- while (1) {
- url_fseek(s->pb, offset, SEEK_SET);
- retry_get_data = 0;
- do {
- read_length = get_buffer(s->pb, data + 12, read_size);
- if (read_length <= 0) {
- if (read_length == AVERROR(EAGAIN)) {
- retry_get_data ++;
- continue;
- } else {
- FREE(data);
- log_error("[%s]get data failed. ret=%d\n", __FUNCTION__, read_length);
- return am_p->data_offset;
- }
- } else {
- break;
- }
- } while (retry_get_data < am_p->playctrl_info.read_max_retry_cnt);
- pkt = data + 12;
- for (;;) {
- for (i = 0; i < read_size; i++) {
- if (skip_byte > 0) {
- skip_byte--;
- if (skip_byte == 0) {
- //media_packet_header
- unsigned short version = (pkt[0] << 8) | pkt[1];
- unsigned short size = (pkt[2] << 8) | pkt[3];
- unsigned short streamid = (pkt[4] << 8) | pkt[5];
- unsigned char flag = pkt[11];
- unsigned int timestamp;
- if (((version == 0) || (version == 1))
- && (size >= 12)
- && ((streamid == video_id) || (streamid == audio_id))) {
- if ((flag & 2) && (streamid == video_id)) {
- timestamp = (pkt[6] << 24) | (pkt[7] << 16) | (pkt[8] << 8) | pkt[9];
- cur_offset += pkt - (data + 12);
- FREE(data);
- log_print("[%s:%d]find key_frame offset=0x%llx\n", __FUNCTION__, __LINE__, cur_offset);
- return cur_offset;
- } else {
- skip_byte = size;
- }
- sync_flag = 0;
- }
- }
- } else {
- unsigned short version = (pkt[0] << 8) | pkt[1];
- unsigned short size = (pkt[2] << 8) | pkt[3];
- unsigned short streamid = (pkt[4] << 8) | pkt[5];
- if (((version == 0) || (version == 1))
- && (size >= 12)
- && ((streamid == video_id) || (streamid == audio_id))) {
- skip_byte = size;
- sync_flag = 0;
- }
- }
- pkt++;
- }
- sync_flag++;
- MEMCPY(data, data + read_size, 12);
- cur_offset += read_size;
- //log_print("[%s:%d]cur_offset=%x file_size=%x\n",__FUNCTION__, __LINE__,cur_offset,s->file_size);
- if (cur_offset < s->file_size) {
- url_fseek(s->pb, cur_offset, SEEK_SET);
- }
- retry_get_data = 0;
- do {
- read_length = get_buffer(s->pb, data + 12, read_size);
- if ((read_length <= 0) || (sync_flag == 1024)) {
- if (read_length == AVERROR(EAGAIN)) {
- continue;
- } else {
- FREE(data);
- log_error("[%s]get data failed. ret=%d\n", __FUNCTION__, read_length);
- return am_p->data_offset;
- }
- } else {
- break;
- }
- } while (retry_get_data < am_p->playctrl_info.read_max_retry_cnt);
- pkt = data;
- }
- }
- FREE(data);
- log_error("[%s]not found key frame. ret=0\n", __FUNCTION__);
- return am_p->data_offset;
- }
- #ifdef DEBUG_VARIABLE_DUR
- int update_variable_info(play_para_t *para)
- {
- int64_t t_fsize = 0;
- int t_fulltime = 0;
- int byte_rate = para->media_info.stream_info.bitrate >> 3;
- int64_t file_size = para->file_size;
- int full_time = para->state.full_time;
- int aac_nb_frames = 0;
- if (para && para->pFormatCtx && para->pFormatCtx->pb) {
- t_fsize = url_fsize2(para->pFormatCtx->pb);
- log_print("[%s:%dtfsize=%lld fsize=%lld\n", __FUNCTION__, __LINE__, t_fsize, file_size);
- if (t_fsize > file_size && t_fsize > 0) {
- para->pFormatCtx->file_size = t_fsize;
- para->pFormatCtx->valid_offset = t_fsize;
- para->file_size = t_fsize;
- if (byte_rate) {
- if ((unsigned int)(file_size / byte_rate) == full_time) {
- t_fulltime = t_fsize / byte_rate;
- }
- } else {
- t_fulltime = (unsigned int)(full_time * ((double)t_fsize / (double)file_size));
- }
- log_print("[%s:%d]fulltime=%d tfulltime=%d\n", __FUNCTION__, __LINE__, full_time, t_fulltime);
- if (t_fulltime > para->state.full_time) {
- para->state.full_time = t_fulltime;
- para->pFormatCtx->duration = t_fulltime * AV_TIME_BASE;
- }
- } else {
- para->pFormatCtx->valid_offset = INT64_MAX; /*Is a no ended streaming*/
- }
- }
- //log_print("[%s:%d]stream_type=%d fulltime=%d aformat=%d\n", __FUNCTION__, __LINE__, para->stream_type, para->state.full_time,para->astream_info.audio_format = AFORMAT_AAC);
- return PLAYER_SUCCESS;
- }
- #endif
- int time_search(play_para_t *am_p)
- {
- AVFormatContext *s = am_p->pFormatCtx;
- float time_point = am_p->playctrl_info.time_point;
- int64_t timestamp = 0;
- int64_t offset = 0;
- unsigned int temp = 0;
- int stream_index = -1;
- int64_t ret = PLAYER_SUCCESS;
- #ifdef ANDROID
- int seek_flags = am_getconfig_bool("media.libplayer.seek.fwdsearch") ? 0 : AVSEEK_FLAG_BACKWARD;
- #else
- int seek_flags = AVSEEK_FLAG_BACKWARD;
- #endif
- int sample_size;
-
- //-----------------------------------
- // forcing updating the value of <first_time> when seeking to the start of file,
- // other wise: <bug 69038 > will happend,
- // in this case, after push the <last_song_buton>, the libplayer will seek to start of file instead of
- // switching to last song, then <first_time> was not the value of first packge and become unvalid,
- // need to update it;
-
- if(time_point==0)
- am_p->state.first_time=-1;
- //----------------------------------
-
-
- url_start_user_seek(s->pb);
- /* If swith audio, then use audio stream index */
- if (am_p->playctrl_info.seek_base_audio) {
- seek_flags |= AVSEEK_FLAG_ANY;
- stream_index = am_p->astream_info.audio_index;
- am_p->playctrl_info.seek_base_audio = 0;
- log_info("[time_search]switch audio, audio_idx=%d time=%f\n", stream_index, time_point);
- }
- if (s->duration > 0) {
- temp = (unsigned int)(s->duration / AV_TIME_BASE);
- log_info("[time_search:%d]time_point =%f temp=%d duration= %lld\n", __LINE__, time_point, temp, s->duration);
- }
- /* if seeking requested, we execute it */
- if (url_support_time_seek(s->pb) && time_point >= 0) {
- log_info("[time_search:%d] direct seek to time_point =%f\n", __LINE__, time_point);
- ret = url_fseektotime(s->pb, time_point, seek_flags);
- if (ret >= 0) {
- av_read_frame_flush(s);
- am_p->discontinue_point = (int)ret;
- am_p->playctrl_info.time_point = (int)ret;
- log_info("[time_search:%d] direct seek discontinue_point =%d\n", __LINE__, am_p->discontinue_point);
- ret = PLAYER_SUCCESS;
- goto searchexit;
- }
- /*failed*/
- log_error("[time_search:%d] seek failed , ret=%d\n", __LINE__, ret);
- ret = PLAYER_SEEK_FAILED;
- goto searchexit;
- } else if (time_point <= temp || temp <= 0) {
- if (am_p->file_type == AVI_FILE ||
- am_p->file_type == MP4_FILE ||
- am_p->file_type == MKV_FILE ||
- am_p->file_type == FLV_FILE ||
- am_p->file_type == MOV_FILE ||
- am_p->file_type == P2P_FILE ||
- am_p->file_type == ASF_FILE ||
- am_p->file_type == STREAM_FILE) {
- if (am_p->file_type == AVI_FILE && !s->seekable) {
- time_point = am_p->state.current_time;
- }
- timestamp = (int64_t)(time_point * AV_TIME_BASE);
- /* add the stream start time */
- if (s->start_time != (int64_t)AV_NOPTS_VALUE) {
- timestamp += s->start_time;
- }
- if (timestamp == s->start_time) {
- if (am_p->file_type == AVI_FILE) {
- //stream_index = am_p->first_index;
- seek_flags |= AVSEEK_FLAG_ANY;
- }
- }
- if (am_p->vstream_info.video_format == VFORMAT_MJPEG ||
- am_p->file_type == MKV_FILE) {
- seek_flags |= AVSEEK_FLAG_ANY;
- }
- log_info("[time_search:%d] stream_index %d, time_point=%f timestamp=%lld start_time=%lld\n",
- __LINE__, stream_index, time_point, timestamp, s->start_time);
- if ((am_p->vstream_info.video_index == -1 || !am_p->vstream_info.has_video)
- && am_p->stream_type != STREAM_ES) {
- offset = ((int64_t)(time_point * (s->bit_rate >> 3)));
- ret = url_fseek(s->pb, offset, SEEK_SET);
- if (ret < 0) {
- log_info("%s: could not seek to position 0x%llx ret=0x%llx\n", s->filename, offset, ret);
- ret = PLAYER_SEEK_FAILED;
- goto searchexit;
- }
- } else {
- log_info("[%s:%d] stream_index=%d, timestamp=%llx, seek_flags=%d,\n",__FUNCTION__, __LINE__,stream_index, timestamp, seek_flags);
- ret = (int64_t)av_seek_frame(s, stream_index, timestamp, seek_flags);
- if (ret < 0) {
- log_info("[%s] could not seek to position %0.3f s ret=%lld\n", __FUNCTION__, (double)timestamp / AV_TIME_BASE, ret);
- ret = PLAYER_SEEK_FAILED;
- goto searchexit;
- }
- offset = url_ftell(s->pb);
- if ((am_p->playctrl_info.last_seek_time_point != (int)time_point)
- && (am_p->playctrl_info.last_seek_offset == offset)) {
- am_p->playctrl_info.seek_offset_same = 1;
- } else {
- am_p->playctrl_info.seek_offset_same = 0;
- am_p->playctrl_info.last_seek_offset = offset;
- }
- am_p->playctrl_info.last_seek_time_point = time_point;
- }
- } else {
- if (((am_p->file_type == MPEG_FILE&&time_point > 0) || (am_p->file_type == APE_FILE&& time_point >= 0))
- && !am_p->playctrl_info.seek_frame_fail
- && (s->pb && !s->pb->is_slowmedia)) {
- timestamp = (int64_t)(time_point * AV_TIME_BASE);
- if (s->start_time != (int64_t)AV_NOPTS_VALUE) {
- timestamp += s->start_time;
- }
- log_info("av_seek_frame:time_point = %f timestamp=%x, starttime=%xn", time_point, timestamp, s->start_time);
- ret = (int64_t)av_seek_frame(s, stream_index, timestamp, seek_flags);
- if (ret >= 0) {
- ret = PLAYER_SUCCESS;
- goto searchexit;
- } else {
- am_p->playctrl_info.seek_frame_fail = 1;
- }
- }
-
- if (am_p->file_type == MPEG_FILE && time_point > 0 && am_p->pFormatCtx->is_vbr == 1) {
- double factor_tm = (double)time_point * AV_TIME_BASE / (double)am_p->pFormatCtx->duration;
- if (factor_tm > 1.0 || factor_tm < 0.0) {
- offset = ((int64_t)(time_point * (s->bit_rate >> 3)));
- }
- else {
- offset = (int64_t)(s->valid_offset * factor_tm);
- }
- }
- else {
- offset = ((int64_t)(time_point * (s->bit_rate >> 3)));
- }
- log_info("time_point = %f bit_rate=%x offset=0x%llx\n", time_point, s->bit_rate, offset);
- if (am_p->file_type == RM_FILE) {
- if (offset > 0) {
- offset = rm_offset_search(am_p, am_p->data_offset + offset, time_point);
- } else {
- offset = am_p->data_offset;
- }
- }
- /**
- * all of PCM format need align to sample size
- * **/
- if (am_p->file_type == WAV_FILE) { //&&am_p->astream_info.audio_format == AFORMAT_ADPCM) {
- AVCodecContext *codec = s->streams[am_p->astream_info.audio_index]->codec;
- if (codec->sample_fmt == 0) { //AV_SAMPLE_FMT_U8
- sample_size = 1;
- } else if (codec->sample_fmt == 2) { //AV_SAMPLE_FMT_S32
- sample_size = 4;
- } else {
- sample_size = 2;
- }
- offset = /*am_p->data_offset + */((int64_t)(time_point * (s->bit_rate >> 3)));
- offset -= offset % codec->block_align;
- offset -= (offset % (codec->channels * sample_size));
- offset += am_p->data_offset;
- }
- log_info("time_point = %f offset=%llx \n", time_point, offset);
- if (offset > s->valid_offset) {
- if (time_point > am_p->state.full_time) {
- offset = url_ftell(s->pb);
- log_info("seek offset exceed, use current 0x%llx\n", offset);
- } else {
- timestamp = (int64_t)(time_point * AV_TIME_BASE);
- offset = s->file_size * (timestamp - s->start_time)/(s->duration - s->start_time);
- log_info("## file_size=%llx, time_point=%f, timestamp=%lld,s->duration=%lld,offset=%llx,--------\n",
- s->file_size, time_point, timestamp, s->duration, offset);
- if (offset > s->valid_offset){
- offset = url_ftell(s->pb);
- }
- }
- }
- ret = url_fseek(s->pb, offset, SEEK_SET);
- if (ret < 0) {
- log_info("%s: could not seek to position 0x%llx ret=0x%llx\n", s->filename, offset, ret);
- …
Large files files are truncated, but you can click here to view the full file