/* * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved. * * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit). * * Use of this source code is governed by MIT-like license that can be found in the * LICENSE file in the root of the source tree. All contributing project authors * may be found in the AUTHORS file in the root of the source tree. */ #include #include #include #include "mk_mediakit.h" typedef struct { mk_player player; mk_decoder video_decoder; mk_swscale swscale; } Context; void API_CALL on_track_frame_out(void *user_data, mk_frame frame) { Context *ctx = (Context *) user_data; mk_decoder_decode(ctx->video_decoder, frame, 1, 1); } void API_CALL on_frame_decode(void *user_data, mk_frame_pix frame) { Context *ctx = (Context *) user_data; int w = mk_get_av_frame_width(mk_frame_pix_get_av_frame(frame)); int h = mk_get_av_frame_height(mk_frame_pix_get_av_frame(frame)); #if 1 int align = 32; size_t pixel_size = 3; size_t raw_linesize = w * pixel_size; // 对齐后的宽度 [AUTO-TRANSLATED:f9bfe888] // Aligned width size_t aligned_linesize = (raw_linesize + align - 1) & ~(align - 1); size_t total_size = aligned_linesize * h; uint8_t* brg24 = malloc(total_size); mk_swscale_input_frame(ctx->swscale, frame, brg24); free(brg24); #else // todo 此处转换为opencv对象 [AUTO-TRANSLATED:37358ee1] // todo Convert to opencv object here cv::Mat *mat = new cv::Mat(); mat->create(h, w, CV_8UC3); mk_swscale_input_frame(ctx->swscale, frame, (uint8_t *) mat->data); #endif log_trace("decode frame output, pts:%d, w:%d, h:%d", mk_get_av_frame_dts(mk_frame_pix_get_av_frame(frame)), w, h); } void API_CALL on_mk_play_event_func(void *user_data, int err_code, const char *err_msg, mk_track tracks[], int track_count) { Context *ctx = (Context *) user_data; if (err_code == 0) { //success log_debug("play success!"); int i; for (i = 0; i < track_count; ++i) { if (mk_track_is_video(tracks[i])) { log_info("got video track: %s", mk_track_codec_name(tracks[i])); ctx->video_decoder = mk_decoder_create(tracks[i], 0); mk_decoder_set_cb(ctx->video_decoder, on_frame_decode, user_data); // 监听track数据回调 [AUTO-TRANSLATED:8295ebf6] // Listen to track data callback mk_track_add_delegate(tracks[i], on_track_frame_out, user_data); } } } else { log_warn("play failed: %d %s", err_code, err_msg); } } void API_CALL on_mk_shutdown_func(void *user_data, int err_code, const char *err_msg, mk_track tracks[], int track_count) { log_warn("play interrupted: %d %s", err_code, err_msg); } int main(int argc, char *argv[]) { mk_config config = { .ini = NULL, .ini_is_path = 0, .log_level = 0, .log_mask = LOG_CONSOLE, .ssl = NULL, .ssl_is_path = 1, .ssl_pwd = NULL, .thread_num = 0 }; mk_env_init(&config); if (argc != 2) { printf("Usage: ./player url\n"); return -1; } Context ctx; memset(&ctx, 0, sizeof(Context)); ctx.player = mk_player_create(); ctx.swscale = mk_swscale_create(3, 0, 0); mk_player_set_on_result(ctx.player, on_mk_play_event_func, &ctx); mk_player_set_on_shutdown(ctx.player, on_mk_shutdown_func, &ctx); mk_player_play(ctx.player, argv[1]); log_info("enter any key to exit"); getchar(); if (ctx.player) { mk_player_release(ctx.player); } if (ctx.video_decoder) { mk_decoder_release(ctx.video_decoder, 1); } if (ctx.swscale) { mk_swscale_release(ctx.swscale); } return 0; }