void ES_PlayInjectionMediaDatas ( MEDIA_CODEC_TYPE_E data_type, void *es_buffer, unsigned int buffer_len, unsigned int PTS ) { int ret; if( (DAL_ES_VCODEC_TYPE_H264 == data_type) && ( vpcodec != NULL) ) { int len = buffer_len; int wcnt = buffer_len; if( PTS != 0xffffffff ) ret = codec_checkin_pts( vpcodec, PTS); while( 1 ) { wcnt = codec_write( vpcodec, es_buffer, buffer_len); if( wcnt > 0 ) { len = len - wcnt; if( len <= 0 ) { break; } memmove( es_buffer, (unsigned char*)es_buffer+wcnt, len ); } else { break; } } } else if( (DAL_ES_ACODEC_TYPE_AAC == data_type) && ( apcodec != NULL) ) { int len = buffer_len; int wcnt = buffer_len; ret = codec_checkin_pts( apcodec, PTS); while( 1 ) { wcnt = codec_write( apcodec, es_buffer, buffer_len); if( wcnt > 0 ) { len = len - wcnt; if( len <= 0 ) { break; } memmove( es_buffer, (unsigned char*)es_buffer+wcnt, len ); } else { break; } } } }
int check_in_pts(AppContext *para, am_packet_t *pkt) { int last_duration = 0; static int last_v_duration = 0, last_a_duration = 0; int64_t pts; float time_base_ratio = 0; long long start_time = 0; if (pkt->type == CODEC_VIDEO) { time_base_ratio = para->vstream_info.video_pts; start_time = para->vstream_info.start_time; last_duration = last_v_duration; } if (para->stream_type == STREAM_ES && (pkt->type == CODEC_VIDEO || pkt->type == CODEC_AUDIO)) { if ((int64_t)INT64_0 != pkt->avpkt->pts) { pts = pkt->avpkt->pts * time_base_ratio; if (pts < start_time) { pts = pts * last_duration; } if (codec_checkin_pts(pkt->codec, pts) != 0) { log_error("ERROR check in pts error!\n"); return PLAYER_PTS_ERROR; } //log_print("[check_in_pts:%d]type=%d pkt->pts=%llx pts=%llx start_time=%llx \n",__LINE__,pkt->type,pkt->avpkt->pts,pts, start_time); } else if ((int64_t)INT64_0 != pkt->avpkt->dts) { pts = pkt->avpkt->dts * time_base_ratio * last_duration; //log_print("[check_in_pts:%d]type=%d pkt->dts=%llx pts=%llx time_base_ratio=%.2f last_duration=%d\n",__LINE__,pkt->type,pkt->avpkt->dts,pts,time_base_ratio,last_duration); if (codec_checkin_pts(pkt->codec, pts) != 0) { log_error("ERROR check in dts error!\n"); return PLAYER_PTS_ERROR; } if (pkt->type == CODEC_AUDIO) { last_a_duration = pkt->avpkt->duration ? pkt->avpkt->duration : 1; } else if (pkt->type == CODEC_VIDEO) { last_v_duration = pkt->avpkt->duration ? pkt->avpkt->duration : 1; } } else { if (!para->vstream_info.check_first_pts && pkt->type == CODEC_VIDEO) { if (codec_checkin_pts(pkt->codec, 0) != 0) { log_print("ERROR check in 0 to audio pts error!\n"); return PLAYER_PTS_ERROR; } } } if (pkt->type == CODEC_VIDEO && !para->vstream_info.check_first_pts) { para->vstream_info.check_first_pts = 1; } } return PLAYER_SUCCESS; }
static GstFlowReturn gst_aml_vdec_decode (GstAmlVdec *amlvdec, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; guint8 *data; guint size; gint written; GstClockTime timestamp, pts; struct buf_status vbuf; GstMapInfo map; if (!amlvdec->info) { return GST_FLOW_OK; } if (amlvdec->pcodec && amlvdec->codec_init_ok) { while (codec_get_vbuf_state(amlvdec->pcodec, &vbuf) == 0) { if (vbuf.data_len * 10 < vbuf.size * 7) { break; } if (amlvdec->is_paused) { break; } usleep(20000); } timestamp = GST_BUFFER_TIMESTAMP (buf); pts = timestamp * 9LL / 100000LL + 1L; if (timestamp != GST_CLOCK_TIME_NONE) { GST_INFO_OBJECT(amlvdec, " video pts = %x", (unsigned long) pts); if (codec_checkin_pts(amlvdec->pcodec, (unsigned long) pts) != 0) GST_ERROR_OBJECT(amlvdec, "pts checkin flied maybe lose sync"); } if (!amlvdec->is_headerfeed) { if (amlvdec->info->writeheader) { amlvdec->info->writeheader(amlvdec->info, amlvdec->pcodec); } amlvdec->is_headerfeed = TRUE; } if (amlvdec->info->add_startcode) { amlvdec->info->add_startcode(amlvdec->info, amlvdec->pcodec, buf); } gst_buffer_map(buf, &map, GST_MAP_READ); data = map.data; size = map.size; while (size > 0) { written = codec_write(amlvdec->pcodec, data, size); if (written >= 0) { size -= written; data += written; } else if (errno == EAGAIN || errno == EINTR) { GST_WARNING_OBJECT(amlvdec, "codec_write busy"); if (amlvdec->is_paused) { break; } usleep(20000); } else { GST_ERROR_OBJECT(amlvdec, "codec_write failed"); ret = GST_FLOW_ERROR; break; } } gst_buffer_unmap(buf, &map); } return ret; }