Skip to content

Commit

Permalink
* optimize decode
Browse files Browse the repository at this point in the history
  • Loading branch information
lxowalle committed Sep 5, 2024
1 parent 3116465 commit 2447fbf
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 25 deletions.
40 changes: 24 additions & 16 deletions components/vision/include/maix_video.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ namespace maix::video
enum VideoType
{
VIDEO_NONE = 0, // format invalid
VIDEO_ENC_H265_CBR,
VIDEO_ENC_MP4_CBR,
VIDEO_DEC_H265_CBR,
VIDEO_DEC_MP4_CBR,
VIDEO_H264_CBR,
VIDEO_H265_CBR,
VIDEO_H264_CBR_MP4,
VIDEO_H265_CBR_MP4,
VIDEO_ENC_H265_CBR, // Deprecated
VIDEO_ENC_MP4_CBR, // Deprecated
VIDEO_DEC_H265_CBR, // Deprecated
VIDEO_DEC_MP4_CBR, // Deprecated
VIDEO_H264_CBR, // Deprecated
VIDEO_H265_CBR, // Deprecated
VIDEO_H264_CBR_MP4, // Deprecated
VIDEO_H265_CBR_MP4, // Deprecated

VIDEO_H264,
VIDEO_H264_MP4,
Expand All @@ -47,13 +47,13 @@ namespace maix::video
*/
enum MediaType
{
MEDIA_TYPE_UNKNOWN = -1,
MEDIA_TYPE_VIDEO,
MEDIA_TYPE_AUDIO,
MEDIA_TYPE_DATA,
MEDIA_TYPE_SUBTITLE,
MEDIA_TYPE_ATTACHMENT,
MEDIA_TYPE_NB
MEDIA_TYPE_UNKNOWN = -1, // Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA.
MEDIA_TYPE_VIDEO, // Represents a video stream, such as video content encoded in H.264, MPEG-4, etc.
MEDIA_TYPE_AUDIO, // Represents an audio stream, such as audio content encoded in AAC, MP3, etc.
MEDIA_TYPE_DATA, // Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes.
MEDIA_TYPE_SUBTITLE, // Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc.
MEDIA_TYPE_ATTACHMENT, // Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media.
MEDIA_TYPE_NB // Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items.
};

typedef struct {
Expand Down Expand Up @@ -159,6 +159,14 @@ namespace maix::video
int duration() {
return _duration;
}

/**
* @brief Duration of the current frame. unit: us
* @maixpy maix.video.Context.duration_us
*/
uint64_t duration_us() {
return _duration * 1000000 / (_timebase[1] / _timebase[0]);
}
private:
video::MediaType _media_type;
image::Image *_image;
Expand Down Expand Up @@ -656,7 +664,7 @@ namespace maix::video
public:
/**
* @brief Construct a new decoder object
* @param path Path to the file to be decoded
* @param path Path to the file to be decoded. Supports files with .264 and .mp4 extensions. Note that only mp4 files containing h.264 streams are supported.
* @param format Decoded output format, currently only support YUV420SP
* @maixpy maix.video.Decoder.__init__
* @maixcdk maix.video.Decoder.Decoder
Expand Down
6 changes: 3 additions & 3 deletions components/vision/port/maixcam/maix_video_mmf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,8 +1655,8 @@ namespace maix::video
// Get video width/height
_width = codec_params->width;
_height = codec_params->height;
_timebase.push_back(pFormatContext->streams[video_stream_index]->time_base.den);
_timebase.push_back(pFormatContext->streams[video_stream_index]->time_base.num);
_timebase.push_back(pFormatContext->streams[video_stream_index]->time_base.den);
AVStream *video_stream = pFormatContext->streams[video_stream_index];
AVRational frame_rate = av_guess_frame_rate(pFormatContext, video_stream, NULL);
_fps = av_q2d(frame_rate);
Expand Down Expand Up @@ -1863,8 +1863,8 @@ namespace maix::video
err::check_bool_raise(!mmf_vdec_push_v2(param->vdec_ch, &stStream));
}

std::vector<int> timebase = {(int)pFormatContext->streams[video_stream_index]->time_base.den,
(int)pFormatContext->streams[video_stream_index]->time_base.num};
std::vector<int> timebase = {(int)pFormatContext->streams[video_stream_index]->time_base.num,
(int)pFormatContext->streams[video_stream_index]->time_base.den};
context = new video::Context(media_type, timebase);
context->set_image(img, pPacket->duration, frame.stVFrame.u64PTS, last_pts);
av_packet_unref(pPacket);
Expand Down
11 changes: 5 additions & 6 deletions examples/decoder_demo/main/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ int _main(int argc, char* argv[])
helper();
return -1;
}

std::string filepath = argv[2];
double seek_s = 0.0;
if (argc > 3) seek_s = atof(argv[3]);
video::Decoder decoder = video::Decoder(filepath);
display::Display disp = display::Display();
uint64_t loop_ms = time::ticks_ms(), last_ms = loop_ms;
uint64_t loop_ms = time::ticks_ms(), last_us = time::ticks_us();
log::info("resolution:%dx%d bitrate:%d duration:%.2f s fps:%d seek_s:%f", decoder.width(), decoder.height(), decoder.bitrate(), decoder.duration(), decoder.fps(), seek_s);

std::vector<int> timebase = decoder.timebase();
err::check_bool_raise(decoder.seek(seek_s) >= 0, "decoder.seek failed");
log::info("decoder.seek:%f", decoder.seek());
while (!app::need_exit()) {
Expand All @@ -53,11 +53,10 @@ int _main(int argc, char* argv[])
image::Image *img = ctx->image();
disp.show(*img);

double wait_ms = (double)ctx->duration() * 1000 / (timebase[0] / timebase[1]);
while ((double)(time::ticks_ms() - last_ms) < wait_ms) {
time::sleep_us(1);
while (time::ticks_us() - last_us < ctx->duration_us()) {
time::sleep_ms(1);
}
last_ms = time::ticks_ms();
last_us = time::ticks_us();

delete img;
delete ctx;
Expand Down

0 comments on commit 2447fbf

Please sign in to comment.