试图修复VPlayer的搜索能力,需要一些指导[Android FFmpeg]

时间:2016-05-31 12:52:41

标签: android c ffmpeg android-ndk

我正在尝试修复VPlayer目前已经破解的搜索能力,这是一个针对Android的FFmpeg播放器。作为一名Java开发人员,C代码对我来说看起来像外星语言所以只能使用通用逻辑修复它(这可能会让任何C老手都笑得很开心)。

相关文件为player.c,我会尽力指出相关修改。

所以基本的想法是因为即使使用av_seek_frame,FFmpeg的AVSEEK_FLAG_ANY也非常不准确,所以我试图跟随this suggestion向后搜索最近的关键帧然后解码到帧我想要。另外一个注意事项是,因为我希望以毫秒为基础进行搜索,而所述解决方案显示了逐帧搜索的方式,这可能是问题的根源。

Player我添加以下字段:

struct Player{
....
AVFrame *frame;
int64_t current_time_stamp;
}; 

player_read_from_stream我将seeking part修改为:

void * player_read_from_stream(void *data) {
    ...
    struct DecoderData *decoder_data = data;
    int stream_no = decoder_data->stream_no;
    AVCodecContext * ctx = player->input_codec_ctxs[stream_no];
    ...
    // seeking, start my stuff
    if(av_seek_frame(player->input_format_ctx, seek_input_stream_number, seek_target, AVSEEK_FLAG_BACKWARD) >= 0){
        //seek to key frame success, now need to read every frame from the key frame to our target time stamp


        while(player->current_time_stamp < seek_target){

            int frame_done;

            while (av_read_frame(player->input_format_ctx, &packet) >= 0) {
                if (packet.stream_index == seek_input_stream_number) {

                    avcodec_decode_video2(ctx, player->frame, &frame_done, &packet);
                    LOGI(1,"testing_stuff ctx %d", *ctx);
                    if (frame_done) {

                        player->current_time_stamp = packet.dts;
                        LOGI(1,"testing_stuff current_time_stamp: %"PRId64, player->current_time_stamp);
                        av_free_packet(&packet);
                        return;
                    }
                }
                av_free_packet(&packet);
            }
        }


    }
    //end my stuff

    LOGI(3, "player_read_from_stream seeking success");

    int64_t current_time = av_gettime();
    player->start_time = current_time - player->seek_position;
    player->pause_time = current_time;        
}

player_alloc_frames中,我为我的帧分配内存:

int player_alloc_frames(struct Player *player) {
    int capture_streams_no = player->caputre_streams_no;
    int stream_no;
    for (stream_no = 0; stream_no < capture_streams_no; ++stream_no) {
        player->input_frames[stream_no] = av_frame_alloc();

        //todo: test my stuff
        player->frame = av_frame_alloc();
        //end test

        if (player->input_frames[stream_no] == NULL) {
            return -ERROR_COULD_NOT_ALLOC_FRAME;
        }
    }
    return 0;
}

目前它只是不断崩溃并成为典型的Android NDK的“功能”,它只是提供了一个非常有用的堆栈跟踪:

libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x40 in tid 2717 (FFmpegReadFromS)

如果有人能帮我解决这个问题,我非常感激。谢谢你的时间。

0 个答案:

没有答案