⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vid_avi.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:

/*****************************************************************************
 * FUNCTION
 *  med_avi_seek_by_time
 * DESCRIPTION
 *  
 * PARAMETERS
 *  time_in_ms      [IN]        
 * RETURNS
 *  
 *****************************************************************************/
kal_int32 med_avi_seek_by_time(kal_uint64 time_in_ms)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 need_aud_size;
    kal_int32 i;
    kal_int32 data_size;
    kal_int32 prev_data_size;
    kal_int32 data_within;
    med_avi_index_struct *idx_p;
    kal_int32 ret;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    kal_prompt_trace(MOD_MED, "[MED AVI] med_avi_seek_by_time()");
    kal_prompt_trace(MOD_MED, "[MED AVI] seek_time: %d", time_in_ms);

    /* VIDEO!! */

    /* rate/scale = FPS */
    /* rate/(scale*1000) = frame per ms */
    /* scale*1000/rate = ms per frame */
    /* frame_idx = time_in_ms/((scale*1000)/rate) */

    /* 
     * [example]
     * 
     * rate = 5000
     * scale = 1000
     * fps = 5
     * frame per ms = 5/1000
     * ms per frame = 1000/5 = 200ms
     */

    if (time_in_ms > med_avi_p->vid_duration)
    {
        /* seek time exceed total time */
        kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_PARAM_ERROR");
        return MED_RES_PARAM_ERROR;
    }

    med_avi_p->vid_frame_idx
        = time_in_ms / ((med_avi_p->video_stream_header.scale * 1000) / med_avi_p->video_stream_header.rate);

    if (med_avi_p->vid_frame_idx >= med_avi_p->vid_total_frame)
    {
        /* align to last valid index */
        med_avi_p->vid_frame_idx = med_avi_p->vid_total_frame - 1;
    }

    kal_prompt_trace(MOD_MED, "[MED AVI] vid idx: %d", med_avi_p->vid_frame_idx);

    /* AUDIO!! */

    /* avg_byte_per_ms = avg_byte_per_sec/1000 */
    /* need_aud_size = time_in_ms*avg_byte_per_ms = time_in_ms*avg_byte_per_sec/1000 */

    if (med_avi_p->is_valid_aud)
    {
        /* seek from start */
        need_aud_size = time_in_ms * med_avi_p->audio_format_header.avg_byte_per_sec / 1000;

        prev_data_size = 0;
        data_size = 0;

        for (i = 0; i < med_avi_p->aud_total_frame; i++)
        {
            idx_p = (med_avi_index_struct*) & med_avi_p->aud_idx_list_buf_p[i];

            data_size += idx_p->chunk_lenght;

            if (data_size > need_aud_size)
            {
                /* data within this segment */
                data_within = need_aud_size - prev_data_size;

                /* +8 skip xxdb (4 byte), size (4 byte) */
                ret = FSAL_Seek(&med_avi_p->aud_fsal_cntx, idx_p->chunk_offset + 8 + data_within);

                if (ret != FSAL_OK)
                {
                    kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_INVALID_FORMAT");
                    return MED_RES_INVALID_FORMAT;
                }

                med_avi_p->aud_remain_len = idx_p->chunk_lenght - data_within;
                med_avi_p->aud_frame_idx = i;

                kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OK");
                return MED_RES_OK;
            }

            prev_data_size = data_size;

        }

        /* V > A */
        med_avi_p->aud_frame_idx = med_avi_p->aud_total_frame;
        med_avi_p->aud_remain_len = 0;
        return MED_RES_OK;
    }

    kal_prompt_trace(
        MOD_MED,
        "[MED AVI] aud idx: %d, aud remain: %d",
        med_avi_p->aud_frame_idx,
        med_avi_p->aud_remain_len);

    kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OK");
    return MED_RES_OK;

}


/*****************************************************************************
 * FUNCTION
 *  med_avi_open_record_file
 * DESCRIPTION
 *  
 * PARAMETERS
 *  rec_data_p      [?]         
 *  filename_p      [IN]        
 * RETURNS
 *  
 *****************************************************************************/
kal_int32 med_avi_open_record_file(med_avi_rec_struct *rec_data_p, const kal_wchar *filename_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_char *data_filename_p;
    kal_char *idx_filename_p;
    kal_int32 v_idx_count;
    kal_int32 a_idx_count;    
    kal_int64 max_limit;
    kal_int32 max_count;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    kal_prompt_trace(MOD_MED, "[MED AVI] med_avi_open_record_file()");

    /* check if rec_data is valid */
    ASSERT(rec_data_p->vid_scale != 0);

    med_avi_p->data_h = 0;
    med_avi_p->idx_h = 0;
    med_avi_p->total_av_data_written = 0;
    med_avi_p->av_data_offset = 0;
    med_avi_p->vid_frame_count = 0;
    med_avi_p->aud_len = 0;

    memcpy(&med_avi_p->rec_data, rec_data_p, sizeof(med_avi_rec_struct));

    /* allocate file name buf */
    data_filename_p = (kal_char*) med_alloc_ext_mem(MAX_FILE_NAME_LEN * ENCODE_BYTE);
    ASSERT(data_filename_p != 0);

    idx_filename_p = (kal_char*) med_alloc_ext_mem(MAX_FILE_NAME_LEN * ENCODE_BYTE);
    ASSERT(idx_filename_p != 0);

    /* rate/scale = fps */
    v_idx_count = med_avi_p->rec_data.vid_rate/med_avi_p->rec_data.vid_scale;
    a_idx_count = 3; /* we assume 3 audio frame per sec */

    max_count = (v_idx_count > a_idx_count) ? v_idx_count : a_idx_count;

    /* we need record limit size, this will be restricted by playback's idx buffer size */
    max_limit = 
        ((kal_uint64)MED_AVI_FSAL_IDX_BUF_SIZE) * ((kal_uint64)1000) / 
        ((kal_uint64)(sizeof(med_avi_index_struct) * (max_count)));

    /* we hard code record time to 60 min */
    med_avi_p->time_limit = MED_AVI_RECORD_TIME_LIMIT*60*1000; /* in ms */
    ASSERT(max_limit > med_avi_p->time_limit);

    med_avi_p->ms_per_frame 
        = ((kal_uint64)med_avi_p->rec_data.vid_scale) * \
          ((kal_uint64)1000) / \
          ((kal_uint64)med_avi_p->rec_data.vid_rate);
    
    /*
     * [AVI File Format] for MJPEG
     * 
     * = Data File ========================
     * RIFF.4.AVI .
     *     LIST.4.hdlr.avih.4.(file header)
     *     LIST.4.strl.strh.4.(video header)
     *                .strf.4.(video format)
     *     LIST.4.strl.strh.4.(audio header)
     *                .strf.4.(audio format)
     *     JUNK.4.(junk)
     *     LIST.4.movi.xxdb.4.(video data)
     *                 xxdc.4.(video data) 
     *                 xxwb.4.(audio data)  
     * = Idx File =========================     
     *            idx1.4.(list data)
     * ====================================
     */

    /* data file - avi header and data chunk file  */
    kal_mem_cpy(data_filename_p, filename_p, MAX_FILE_NAME_LEN * ENCODE_BYTE);
    med_remove_file_name((kal_wchar*) data_filename_p);
    kal_wstrcat((kal_wchar*) data_filename_p, MED_AVI_VISUAL_FILE);

    med_avi_p->data_h = FS_Open((kal_wchar*) data_filename_p, /* VID_TEMP_FILE_ATTRIBUTES */ FS_READ_WRITE | FS_CREATE_ALWAYS);

    if (med_avi_p->data_h <= 0)
    {
        med_free_ext_mem((void **)&data_filename_p);
        med_free_ext_mem((void **)&idx_filename_p);

        kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OPEN_FILE_FAIL");
        return MED_RES_OPEN_FILE_FAIL;
    }

    /* seek to movi chunk */
    med_avi_p->av_data_offset = 4 + 4 + 4;  /* (RIFF.4.AVI .) */
    med_avi_p->av_data_offset += 4 + 4 + 4 + 4 + 4 + sizeof(med_avi_file_header_struct);        /*    LIST.4.hdlr.avih.4.(file header)    */
    med_avi_p->av_data_offset += 4 + 4 + 4 + 4 + 4 + sizeof(med_avi_stream_header_struct);      /*    LIST.4.strl.strh.4.(video header)   */
    med_avi_p->av_data_offset += 4 + 4 + sizeof(med_avi_video_format_header_struct);    /*               .strf.4.(video format)   */
    med_avi_p->av_data_offset += 4 + 4 + 4 + 4 + 4 + sizeof(med_avi_stream_header_struct);      /*    LIST.4.strl.strh.4.(audio header)   */
    med_avi_p->av_data_offset += 4 + 4 + sizeof(med_avi_audio_format_header_struct);    /*               .strf.4.(audio format)   */
    med_avi_p->av_data_offset += 4 + 4 + 4; /*    LIST.4.movi.                      */

    /* extend file - and seek to movi start */
    FS_Extend(med_avi_p->data_h, med_avi_p->av_data_offset);
    FS_Seek(med_avi_p->data_h, med_avi_p->av_data_offset, FS_FILE_BEGIN);

    /* idx file */
    kal_mem_cpy(idx_filename_p, filename_p, MAX_FILE_NAME_LEN * ENCODE_BYTE);
    med_remove_file_name((kal_wchar*) idx_filename_p);
    kal_wstrcat((kal_wchar*) idx_filename_p, MED_AVI_IDX_FILE);

    /* Todo */
    FS_Delete((kal_wchar*) idx_filename_p);

    med_avi_p->idx_h = FS_Open((kal_wchar*) idx_filename_p, /* VID_TEMP_FILE_ATTRIBUTES */ FS_READ_WRITE | FS_CREATE_ALWAYS);

    if (med_avi_p->idx_h <= 0)
    {
        FS_Close(med_avi_p->data_h);
        med_free_ext_mem((void **)&data_filename_p);
        med_free_ext_mem((void **)&idx_filename_p);

        kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OPEN_FILE_FAIL");
        return MED_RES_OPEN_FILE_FAIL;
    }

    med_free_ext_mem((void **)&data_filename_p);
    med_free_ext_mem((void **)&idx_filename_p);

    /* extend to idx.4 */
    FS_Extend(med_avi_p->idx_h, 8);
    FS_Seek(med_avi_p->idx_h, 8, FS_FILE_BEGIN);

    /* open file ok, allocate buffer for caching */
    med_avi_p->data_buf_p[0] = (kal_char*) med_alloc_ext_mem(MED_AVI_WRITE_DATA_BUF_SIZE);
    ASSERT(med_avi_p->data_buf_p[0] != 0);

    med_avi_p->data_buf_p[1] = (kal_char*) med_alloc_ext_mem(MED_AVI_WRITE_DATA_BUF_SIZE);
    ASSERT(med_avi_p->data_buf_p[1] != 0);

    med_avi_p->idx_buf_p[0] = (kal_char*) med_alloc_ext_mem(MED_AVI_WRITE_IDX_BUF_SIZE);
    ASSERT(med_avi_p->idx_buf_p[0] != 0);

    med_avi_p->idx_buf_p[1] = (kal_char*) med_alloc_ext_mem(MED_AVI_WRITE_IDX_BUF_SIZE);
    ASSERT(med_avi_p->idx_buf_p[1] != 0);

    med_avi_p->act_data_buf_id = 0;
    med_avi_p->act_idx_buf_id = 0;

    med_avi_p->data_written[0] = 0;
    med_avi_p->data_written[1] = 0;
    med_avi_p->idx_written[0] = 0;
    med_avi_p->idx_written[1] = 0;

    kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OK");
    return MED_RES_OK;

}


/*****************************************************************************
 * FUNCTION
 *  med_avi_close_record_file
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  
 *****************************************************************************/
kal_int32 med_avi_close_record_file(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    kal_prompt_trace(MOD_MED, "[MED AVI] med_avi_close_record_file()");

    /* dump remain data in buffer to file */
    med_avi_toggle_data_buffer();
    med_avi_toggle_idx_buffer();
    med_avi_dump_data_buffer_to_file();
    med_avi_dump_idx_buffer_to_file();

    /* make sure resource is not freed yet */
    ASSERT(med_avi_p->data_buf_p[0] != 0);
    ASSERT(med_avi_p->data_buf_p[1] != 0);
    ASSERT(med_avi_p->idx_buf_p[0] != 0);
    ASSERT(med_avi_p->idx_buf_p[1] != 0);

    med_free_ext_mem((void **)&med_avi_p->data_buf_p[0]);
    med_free_ext_mem((void **)&med_avi_p->data_buf_p[1]);
    med_free_ext_mem((void **)&med_avi_p->idx_buf_p[0]);
    med_free_ext_mem((void **)&med_avi_p->idx_buf_p[1]);

    med_avi_p->data_buf_p[0] = NULL;
    med_avi_p->data_buf_p[1] = NULL;
    med_avi_p->idx_buf_p[0] = NULL;
    med_avi_p->idx_buf_p[1] = NULL;

    if (med_avi_p->data_h != 0)
    {
        FS_Close(med_avi_p->data_h);
    }

    if (med_avi_p->idx_h != 0)
    {
        FS_Close(med_avi_p->idx_h);
    }

    kal_prompt_trace(MOD_MED, "[MED AVI] ret: MED_RES_OK");
    return MED_RES_OK;
}


/*****************************************************************************
 * FUNCTION
 *  med_avi_toggle_data_buffer
 * DESCRIPTION
 *  
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void med_avi_toggle_data_buffer(void)
{
    /*----------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -