static irqreturn_t vmpeg12_isr(int irq, void *dev_id) { u32 reg, info, seqinfo, offset, pts, pts_valid = 0; vframe_t *vf; ulong flags; WRITE_MPEG_REG(ASSIST_MBOX1_CLR_REG, 1); reg = READ_MPEG_REG(MREG_BUFFEROUT); if (reg) { info = READ_MPEG_REG(MREG_PIC_INFO); offset = READ_MPEG_REG(MREG_FRAME_OFFSET); info = info | PICINFO_TOP_FIRST; if (((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) && (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0)) { pts_valid = 1; } /*if (frame_prog == 0)*/ { frame_prog = info & PICINFO_PROG; } if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_720_576_INTERLACE) && (frame_width == 720) && (frame_height == 576) && (frame_dur == 3840)) { frame_prog = 0; } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_3000_704_480_INTERLACE) && (frame_width == 704) && (frame_height == 480) && (frame_dur == 3200)) { frame_prog = 0; } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_704_576_INTERLACE) && (frame_width == 704) && (frame_height == 576) && (frame_dur == 3840)) { frame_prog = 0; } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_544_576_INTERLACE) && (frame_width == 544) && (frame_height == 576) && (frame_dur == 3840)) { frame_prog = 0; } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_480_576_INTERLACE) && (frame_width == 480) && (frame_height == 576) && (frame_dur == 3840)) { frame_prog = 0; } if (frame_prog & PICINFO_PROG) { u32 index = ((reg & 7) - 1) & 3; seqinfo = READ_MPEG_REG(MREG_SEQ_INFO); vf = vfq_pop(&newframe_q); set_frame_info(vf); vf->index = index; vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; if ((seqinfo & SEQINFO_EXT_AVAILABLE) && (seqinfo & SEQINFO_PROG)) { if (info & PICINFO_RPT_FIRST) { if (info & PICINFO_TOP_FIRST) { vf->duration = vf->duration * 3; // repeat three times } else { vf->duration = vf->duration * 2; // repeat two times } } vf->duration_pulldown = 0; // no pull down } else { vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? vf->duration >> 1 : 0; } vf->duration += vf->duration_pulldown; vf->canvas0Addr = vf->canvas1Addr = index2canvas(index); vf->pts = (pts_valid) ? pts : 0; vfbuf_use[index]++; if (error_skip(info, vf)) { spin_lock_irqsave(&lock, flags); vfq_push(&recycle_q, vf); spin_unlock_irqrestore(&lock, flags); } else { vfq_push(&display_q, vf); } vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); } else {
static irqreturn_t vmjpeg_isr(int irq, void *dev_id) { u32 reg, offset, pts, pts_valid = 0; vframe_t *vf; WRITE_MPEG_REG(ASSIST_MBOX1_CLR_REG, 1); reg = READ_MPEG_REG(MREG_FROM_AMRISC); if (reg & PICINFO_BUF_IDX_MASK) { offset = READ_MPEG_REG(MREG_FRAME_OFFSET); if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0) { pts_valid = 1; } if ((reg & PICINFO_INTERLACE) == 0) { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; vfpool_idx[fill_ptr] = index; vf = &vfpool[fill_ptr]; set_frame_info(vf); vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); vf->pts = (pts_valid) ? pts : 0; vfbuf_use[index]++; INCPTR(fill_ptr); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); } else { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; vfpool_idx[fill_ptr] = index; vf = &vfpool[fill_ptr]; set_frame_info(vf); #if 0 if (reg & PICINFO_AVI1) { /* AVI1 format */ if (reg & PICINFO_INTERLACE_AVI1_BOT) { vf->type = VIDTYPE_INTERLACE_BOTTOM | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_TOP; } } else { if (reg & PICINFO_INTERLACE_FIRST) { vf->type = VIDTYPE_INTERLACE_TOP | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM; } } vf->type |= VIDTYPE_VIU_FIELD; vf->duration >>= 1; vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); if ((vf->type & VIDTYPE_INTERLACE_FIRST) && (pts_valid)) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; INCPTR(fill_ptr); #else /* send whole frame by weaving top & bottom field */ vf->type = VIDTYPE_PROGRESSIVE; vf->canvas0Addr = index2canvas0(index); vf->canvas1Addr = index2canvas1(index); if (pts_valid) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; INCPTR(fill_ptr); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); #endif } WRITE_MPEG_REG(MREG_FROM_AMRISC, 0); }
u32 dsp_codec_get_current_pts(struct audiodsp_priv *priv) { #ifdef CONFIG_AM_PTSSERVER u32 pts; u32 delay_pts; int len; u64 frame_nums; int res; u32 offset, buffered_len, wp; mutex_lock(&priv->stream_buffer_mutex); if (priv->frame_format.channel_num == 0 || priv->frame_format.sample_rate == 0 || priv->frame_format.data_width == 0) { printk("unvalid audio format!\n"); mutex_unlock(&priv->stream_buffer_mutex); return -1; } #if 0 if (priv->stream_fmt == MCODEC_FMT_COOK) { pts = priv->cur_frame_info.offset; mutex_unlock(&priv->stream_buffer_mutex); } else #endif { buffered_len = DSP_RD(DSP_BUFFERED_LEN); wp = DSP_RD(DSP_DECODE_OUT_WD_PTR); offset = DSP_RD(DSP_AFIFO_RD_OFFSET1); // before audio start, the pts always be at the first index if(!timestamp_apts_started()){ offset = 0; } if (priv->stream_fmt == MCODEC_FMT_COOK || priv->stream_fmt == MCODEC_FMT_RAAC) { pts = DSP_RD(DSP_AFIFO_RD_OFFSET1); res = 0; } else { res = pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300); //printk("pts_lookup_offset = %d, buffer_len = %d, res = %d\n", offset, buffered_len, res); if (!priv->first_lookup_over) { priv->first_lookup_over = 1; if (first_lookup_pts_failed(PTS_TYPE_AUDIO)) { priv->out_len_after_last_valid_pts = 0; priv->last_valid_pts = pts; mutex_unlock(&priv->stream_buffer_mutex); return pts; } } } if (res == 0) { //printk("check out pts == %x\n", pts); priv->out_len_after_last_valid_pts = 0; len = buffered_len + dsp_codec_get_bufer_data_len1(priv, wp); frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num)); delay_pts = div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50); //printk("cal delay pts == %x\n", delay_pts); if (pts > delay_pts) { pts -= delay_pts; } else { pts = 0; } priv->last_valid_pts = pts; //printk("len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n", // len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts); } else if (priv->last_valid_pts >= 0) { pts = priv->last_valid_pts; len = priv->out_len_after_last_valid_pts; frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num)); pts += div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50); //printk("last_pts = %d, len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n", // priv->last_valid_pts, len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts); } else { printk("checkout audio pts failed!\n"); pts = -1; } mutex_unlock(&priv->stream_buffer_mutex); } return pts; #endif return -1; }
static irqreturn_t vmjpeg_isr(int irq, void *dev_id) { u32 reg, offset, pts, pts_valid = 0; vframe_t *vf = NULL; WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); reg = READ_VREG(MREG_FROM_AMRISC); if (reg & PICINFO_BUF_IDX_MASK) { offset = READ_VREG(MREG_FRAME_OFFSET); if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0) { pts_valid = 1; } if ((reg & PICINFO_INTERLACE) == 0) { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; if (index >= DECODE_BUFFER_NUM_MAX) { printk("fatal error, invalid buffer index."); return IRQ_HANDLED; } if (kfifo_get(&newframe_q, &vf) == 0) { printk("fatal error, no available buffer slot."); return IRQ_HANDLED; } set_frame_info(vf); vf->index = index; #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; #endif vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); vf->pts = (pts_valid) ? pts : 0; vf->orientation = 0 ; vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); } else { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; if (index >= DECODE_BUFFER_NUM_MAX) { printk("fatal error, invalid buffer index."); return IRQ_HANDLED; } if (kfifo_get(&newframe_q, &vf) == 0) { printk("fatal error, no available buffer slot."); return IRQ_HANDLED; } set_frame_info(vf); vf->index = index; #if 0 if (reg & PICINFO_AVI1) { /* AVI1 format */ if (reg & PICINFO_INTERLACE_AVI1_BOT) { vf->type = VIDTYPE_INTERLACE_BOTTOM | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_TOP; } } else { if (reg & PICINFO_INTERLACE_FIRST) { vf->type = VIDTYPE_INTERLACE_TOP | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM; } } vf->type |= VIDTYPE_VIU_FIELD; #ifdef NV21 vf->type |= VIDTYPE_VIU_NV21; #endif vf->duration >>= 1; vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); vf->orientation = 0 ; if ((vf->type & VIDTYPE_INTERLACE_FIRST) && (pts_valid)) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); #else /* send whole frame by weaving top & bottom field */ #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_NV21; #else vf->type = VIDTYPE_PROGRESSIVE; #endif vf->canvas0Addr = index2canvas0(index); vf->canvas1Addr = index2canvas1(index); vf->orientation = 0 ; if (pts_valid) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); #endif } WRITE_VREG(MREG_FROM_AMRISC, 0); }