STM32
直播中

abdkjshd

8年用户 1168经验值
擅长:可编程逻辑
私信 关注
[问答]

播放avi如何实现快进退啊 ?

请教下,播放avi如何实现快进退啊 ???

自己捣鼓了了一下,没有成功,代码如下:

void AVI_timeSet(FIL *_pFile, VideoPlayCtrlRTOS   *_VideoPlayCtrl)
{
        uint32_t fpos = _pFile->fptr;
  uint32_t uiPos = 0;
        uint32_t BytesRD = 0;
        uint32_t offset = 0;
        uint8_t  *tempbuf = 0;
        uint8_t  *pbuf = 0;

        uiPos = (_pFile->obj.objsize / _VideoPlayCtrl->Totsec) * g_tWav.uiCurTime;  //每次前进 g_tWav.uiCurTime 秒钟的数据量
        tempbuf   = mymalloc(SRAMEX,   AVI_MAX_SIZE);            // 申请视频buf 120KByte or 1MB
        
        while(1)
        {
                if(fpos < _pFile->obj.objsize)
                {
                        fpos += uiPos;
                        if(fpos > (_pFile->obj.objsize - AVI_MAX_SIZE))
                        {
                                fpos = _pFile->obj.objsize - AVI_MAX_SIZE;
                        }        
                }
                else
                {
                        if(fpos > uiPos)
                                fpos -= uiPos;
                        else
                                fpos=0;         
                }
                f_lseek (_pFile, fpos);      //偏移到数据开始的地方

                if(fpos == 0)
                        AVI_GetFrame( AVI_Handel, _pFile);   //从 0 开始寻找, 这个测试 ok
                else
                {

                        pbuf = tempbuf;
                        f_read(_pFile, pbuf, AVI_MAX_SIZE, (UINT*) BytesRD );
                        pbuf = tempbuf;
                        offset = __AVI_SearchID(pbuf,  AVI_MAX_SIZE, AVI_Handel.aviInfo.VideoFLAG);   //寻找视频帧
                        
                        // Read first Frame info
                        __AVI_GetStreamInfo(  AVI_Handel, pbuf + offset );  //获取流信息
                        
                        if(AVI_Handel.aviInfo.StreamID == AVI_VIDS_FLAG)//显示帧
                        {
                                // go to the first frame offset in the avi file
                                f_lseek(_pFile,  fpos + offset  );//偏移到流数据开始处
                                
                                  // Get the current frame size
                                AVI_Handel.FrameSize = AVI_Handel.aviInfo.StreamSize;
                                
                                break;
                        }
                        else if(AVI_Handel.aviInfo.StreamID == AVI_AUDS_FLAG)
                        {
                                // go to the first frame offset in the avi file
                                f_lseek(_pFile,  fpos + offset  );//偏移到流数据开始处
                                
                                  // Get the current frame size
                                AVI_Handel.FrameSize = AVI_Handel.aviInfo.StreamSize;
                                
                                break;
                        }
                }
        }
        myfree(SRAMEX, tempbuf);                //释放内存
}


经过上面查找后,进入正常播放状态,貌似只能够 播放一帧,后续识别到的

AVI_Handel.aviInfo.StreamID  这个数据流的值为 0  ?

回帖(1)

廖阿朋

2024-4-26 17:07:43
要在AVI文件播放过程中实现快进和快退功能,您需要修改AVI文件的索引以跳转到所需的播放位置。以下是实现快进和快退功能的步骤:

1. 首先,您需要解析AVI文件的索引(idx1)以获取每个关键帧的位置。这可以通过读取AVI文件头和索引块来完成。

2. 根据用户选择的快进或快退时间,计算需要跳转到的关键帧。这可以通过将用户选择的时间与AVI文件的帧率相除来实现。

3. 使用计算出的关键帧索引,更新文件指针(fptr)以跳转到所需的播放位置。

以下是修改后的代码示例:

```c
void AVI_TimeSet(FIL *_pFile, VideoPlayCtrlRTOS *_VideoPlayCtrl) {
    uint32_t fpos = _pFile->fptr;
    uint32_t uiPos = 0;
    uint32_t BytesRD = 0;
    uint32_t offset = 0;
    uint8_t *tempbuf = 0;

    // 1. 解析AVI文件的索引(idx1)以获取每个关键帧的位置
    // ...

    // 2. 根据用户选择的快进或快退时间,计算需要跳转到的关键帧
    uint32_t targetFrame = (userSelectedTime / (1000.0 / AVI_FrameRate)) + currentFrame;

    // 3. 使用计算出的关键帧索引,更新文件指针(fptr)以跳转到所需的播放位置
    for (uint32_t i = 0; i < totalKeyFrames; i++) {
        if (keyFrameIndices[i] >= targetFrame) {
            offset = keyFrameOffsets[i];
            break;
        }
    }

    f_lseek(_pFile, offset);
    _pFile->fptr = offset;

    // 继续播放AVI文件
    // ...
}
```

请注意,这段代码只是一个示例,您需要根据您的具体实现和AVI文件格式进行调整。在实现快进和快退功能时,确保正确处理文件指针和索引,以避免播放过程中的错误。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分