· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
MPlayer Codec


1. ¹®¼­ÀÇ ¸ñÀû ¹× °³°ý


¹®¼­¸¦ ÀÛ¼ºÇÏ´Â ¸ñÀûÀº »ìÆ캻 ³»¿ëÀ» ±î¸ÔÁö ¾Ê°í Á¤¸®Çϱâ À§ÇÔÀÌ Ã¹Â°À̸ç, °°Àº »ðÁúÀ» ÇÏ°íÀÚ ÇϽô ºÐµé¿¡°Ô µµ¿òÀ» µå¸®°íÀÚ ÇÔÀÌ µÎ ¹ø°ÀÌ´Ù. ÀÌ ¹®¼­¿¡¼­´Â H.264 ¼ÒÇÁÆ®¿þ¾î ÄÚµ¦(FFMPEG) ºÐ¼®°ú Çϵå¿þ¾î ÄÚµ¦(Vendor Specific) ¶óÀ̺귯¸®ÀÇ Ãß°¡ ¹æ¹ýÀ» ´Ù·ç°íÀÚ ÇÑ´Ù. ½Ã°£ÀÌ µÉ °æ¿ì MPEG µîÀÇ ´Ù¸¥ ÄÚµ¦À̳ª, MEncoder µîµµ »ìÆ캼 ¼öµµ ÀÖ´Ù.

MPlayer´Â FFMPEGÀÇ library µéÀ» »ç¿ëÇÑ´Ù. MPlayer ¼Ò½ºÄÚµå ³»ÀÇ libavcodec ÀÌ ÄÚµ¦ ºÎºÐÀ» °¡Áö¸ç, libavformat ºÎºÐÀÌ ¹Ìµð¾î ÆÄÀÏÀ» ÆĽÌÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù. ¸¹Àº ¼öÀÇ ¼ÒÇÁÆ®¿þ¾î ÄÚµ¦µéÀ» Áö¿øÇÑ´Ù. Çϵå¿þ¾î¿Í ¿¬°üµÈ ºÎºÐÀ¸·Î XVMC(X Video Motion Compensation) ¿É¼ÇÀÌ ÀÖ´Â µ¥ ÀÌ°ÍÀº Motion CompensationÀ» Áö¿øÇÏ´Â Hardware°¡ ÀÖ´Â °æ¿ì¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

2. Copyright and Acknowledgements


This document is copyright (c) Kwangwoo Lee (kwangwoo.lee at gmail dot com). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License.

3. ÁÖÀÇ»çÇ×


MPlayer License´Â GPL ÀÌ´Ù. ¼öÁ¤ ÈÄ ¹èÆ÷°¡ ÀϾ °æ¿ì¿¡´Â Source Code¸¦ GPLÇÏ¿¡ ´Ù½Ã ¹èÆ÷ÇØ¾ß ÇÑ´Ù. ÀÌ´Â codec library¸¸À» Ãß°¡ÇÑ´Ù°í Çصµ ¸¶Âù°¡ÁöÀÇ È¿°ú¸¦ °¡Áø´Ù. Hardware video codecÀ» »ç¿ëÇϱâ À§ÇÑ libary¸¦ ÀÛ¼ºÇÏ°í MPlayer¿¡¼­ ±×°ÍÀ» »ç¿ëÇÑ´Ù°í Çصµ GPLÀÇ Àû¿ëÀ» ¹Þ´Â´Ù.

4. Reading List


MPlayer codec °ü·Ã ÀÛ¾÷½Ã ²À ºÁ¾ßÇÒ ¹®¼­ libavcodec °ú libavformat °ü·Ã ÀÛ¾÷ ½Ã Âü°íÇØ¾ß ÇÒ ¹®¼­

5. ½ÇÇà ¹æ¹ý


* mplayer -vfm ffmpeg -vo fbdev -nosound

6. Video Decoder


Á» ¸¹ÀÌ »ý·« mplayer.c::main() Àº ´ÙÀ½°ú °°´Ù. ÀÌ ºÎºÐÀÌ ½ÃÀÛÀ̸ç, open_stream(), demux_open(), video_read_properties(), reinit_video_chain(), update_video() µîÀÇ ÇÔ¼ö¸¦ ÁÖÀÇ ±í°Ô »ìÆìºÁ¾ß ÇÑ´Ù. ƯÈ÷ ½ÇÁ¦ decode°¡ ÀϾ°í º¸¿©Áö´Â ºÎºÐÀº update_video() ÇÔ¼ö ³»¿¡¼­ ÀϾ¸ç, ¾ÕÀÇ open_stream(), demux_open() µîÀÇ ÇÔ¼ö´Â ÆÄÀÏÀ» ÆĽÌÇÏ¿© ÄÚµ¦À» ¼±ÅÃÇÏ°í ÀÐ¾î µéÀÌ´Â ÀÏÀ» ÇÑ´Ù.

mplayer.c
main()
{
mpctx->stream = open_stream(filename, 0, &mpctx->file_format);
    initialized_flags |= INITIALIZED_STREAM;

    // get sh_video_t and sh_audio_t instance and initialize them.
    // get width and height information for video
    mpctx->demuxer = demux_open(mpctx->stream, mpctx->file_format,
                        audio_id, video_id, dvdsub_id, filename);

    if (mpctx->demuxer && mpctx->demuxer->type == DEMUXER_TYPE_PLAYLIST) {
    
        initialized_flags |= INITIALIZED_DEMUXER;
    }

    mpctx->d_audio = mpctx->demuxer->audio;
    mpctx->d_video = mpctx->demuxer->video;
    mpctx->d_sub = mpctx->demuxer->sub;

    select_audio(mpctx->demuxer, audio_id, audio_lang);

    mpctx->sh_audio = mpctx->d_audio->sh;
    mpctx->sh_video = mpctx->d_vidio->sh;

    if (mpctx->sh_vidio) {
        if (! video_read_properties(mpctx->sh_video) ) {
        ¡¦
        } elsle {
            mp_msg(MSGT_CPLAYER, MSGL_V,
            ¡±[V] filefmt:%d fourcc:0x%X size:%dx%d fps:%5.2f ftime:=%6.4f\n¡±,
            mpctx->demuxer->file_format, mpctx->sh_video->format,
            mpctx->sh_video->disp_w,
            mpctx->sh_video->disp_h, mpctx->sh_vidio->fps,
            mpctx->sh_video->frametime);
        }
    }
    demux_info_print(mpctx->demuxer);

    // init vo, vf
    // call init_best_video_codec(),init_video(),init() in vd_ffmpeg.c
    reinit_video_chain();

main:
    // setup audio
    if (mpctx->sh_audio)
        reinit_audio_chain();
    
    // play audio
    if (mpctx->sh_audio)
        fill_audio_out_buffers();

    if (!mpctx->sh_video) {
        ¡¦
    } else {
        //play video
        if (!mpctx->num_buffered_frames) {

            double frame_time = update_video(&blit_frame);

            mp_dbg(MSGT_AVSYNC,MSGL_DBG2,
                ¡±*** ftime=%5.3f ***\n¡±, frame_time);

            if (mpctx->sh_video->vf_initialized < 0) {
                mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_NotInitializedVOPorVO);
                mpctx->eof = 1; goto goto_next_file;
            }
            if (frame_time < 0)
                mpctx->eof = 1;
            else {
                mpctx->num_buffered_frames += blit_frame;
                // for nosound
                time_frame += frmae_time / playback_speed;
            }
        }
    }

    ¡¦
}

6.1. MP4 - H.264 Container Format Example


MP4 ÆÄÀÏ Çü½ÄÀº H.264 video streamÀ» ´ã°í ÀÖÀ» ¼ö ÀÖ´Ù. sh->format ºÎºÐ¿¡ avc1 À̶ó´Â Á¤º¸¸¦ °¡Áö°í ÀÖ´Ù. ÀÌ Æ÷¸ä¿¡¼­ ÁÖÀÇÇØ¾ß ÇÒ Á¡Àº SPS(Sequence Parameter Set)°ú PPS(Picture Parameter Set)ÀÌ avcC ¶ó´Â Meta Tag ºÎºÐ¿¡ ÀÖ´Ù´Â °ÍÀÌ´Ù. ÀÌ °æ¿ì MPlayer ÄÚµå »ó¿¡¼­´Â extradata·Î ó¸®ÇÑ´Ù´Â °ÍÀÌ´Ù.

ÄÚµ¦ÀÇ decode() ÇÔ¼ö´Â sh_video_t ŸÀÔÀ» °¡Áö´Â sh¸¦ ÀÎÀÚ·Î ¹Þ°Ô µÇ´Â µ¥ MP4 ÆÄÀÏÀÇ °æ¿ì¿¡´Â ´ÙÀ½°ú °°ÀÌ avcC Meta TagÀÇ µ¥ÀÌÅ͸¦ ã¾Æ¼­ ¾µ ¼ö ÀÖ´Ù. ÀÌ µ¥ÀÌÅÍ´Â MPlayer°¡ ÆÄÀÏÀ» ÆĽÌÇÒ ¶§ ä¿ö ³Ö¾î Áø Á¤º¸ÀÌ´Ù.

avcc_size = sh->bih->biSize - sizeof(BITMAPINFOHEADER);
avcc = (unsigned char *) (sh->bih + 1);

ÀÌ ÆÄÀÏ Çü½Ä¿¡´Â NAL Indicator(0x000001)°¡ ¾ø´Ù. °¢ FrameÀÇ Á¦ÀÏ ¾Õ¿¡ ¿À´Â 4 Bytes Á¤º¸´Â NALÀÇ Å©±âÀÌ´Ù. ÀÌ ÆÄÀÏ Çü½Ä¿¡ ´ëÇÑ ÂüÁ¶´Â AppleÀÇ Quicktime File Format °ü·Ã ¹®¼­¸¦ ÂüÁ¶ÇÏ±æ ¹Ù¶õ´Ù.

6.2. H.264 Decoder (-vfm ffmpeg)


update_vedio() ¿¡¼­ generate_video_frame()À» È£ÃâÇÑ´Ù. generate_video_frame() ³»¿¡¼­ decode_video()¸¦ ÅëÇØ frameÀ» decode ÇÏ°í, filter_video()¸¦ ÅëÇØ video filterµéÀ» Àû¿ëÇÑ ÈÄ ¸¶Áö¸· filter¿¡ ÇØ´çÇÏ´Â vo filter¸¦ ÅëÇØ Ãâ·ÂÇÑ´Ù. vo filter´Â video outÀ» ¶æÇÑ´Ù.

mplayer.c
generate_video_frame()
{
    // get demux_packet_t  buffer ptr in &start
    in_size = ds_get_packet_pts(d_video, &start, &pts);

    decode_video();
    filter_video();
}

decode_video() ÇÔ¼ö ³»ÀÇ mpi°¡ decode µÈ ¿µ»óÀ» °¡Áö°í ÀÖ´Ù.

dec_video.c
decode_video()
{
    // start has demux_packet_t dp.
    // It seems to be started with start sync (0x00000x).
    // Why not 0x000001?
    mpi = mpvdec->decode(sh_video, start, in_size, drop_frame);
}

mpvdec->decode() ÇÔ¼ö´Â ÃʱâÈ­ ½Ã ÆÄÀÏÀ» ÀÐ¾î ¼±ÅÃµÈ ÄÚµ¦ÀÇ decode ÇÔ¼ö¸¦ È£ÃâÇϰԵȴÙ. ¸ðµç ÄÚµ¦µéÀº decode() ÇÔ¼ö¸¦ °¡Áö¸ç ÇÔ¼ö Æ÷ÀÎÅÍ·Î µî·ÏµÇ¾î ÀÖ´Ù.

libavcodec/h264.c
AVCodec h264_decoder = {
    ¡°h264¡±,
    CODEC_TYPE_VIDEO,
    CODEC_ID_H264,
    sizeof(H264Context),
    decode_init,
    NULL,
    decode_end,
    decode_frame,
    CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
    .flush = flush_dpb,
};

vd_ffmpeg.c
decode()
{
    mpcodecs_get_image();
    avcodec_decode_video();
}

libavcodec/utils.c
avcodec_decode_video()
{
    avctx->codec->decode();
}

H.264 Çü½ÄÀÇ ÆÄÀÏÀº NALÀ̶õ ´ÜÀ§·Î decode µÈ´Ù.

libavcodec/h264.c
decode_frame()
{
    decode_nal_units();
    execute_ref_pic_marking();

    if (!FIELD_PICTURE)
        ff_er_frame_end();

    MPV_frame_end(); // HAVE_XVMC

    return get_consumed_bytes();
}

libavcodec/h264.c
decode_nal_units()
{
    decode_nal();
    decode_rsbp_trailing();
    decode_slice_header();
    // loop
    execute_decode_slices();
}

6.3. Video Filter


display¸¦ À§ÇÑ vo filter¿¡¼­ Áö¿øÇÏ´Â colorspace¿Í decode µÇ¾î ³ª¿Â frameÀÇ colorspace°¡ ¸ÂÁö ¾Ê´Â °æ¿ì ȤÀº display Å©±â°¡ ¸ÂÁö ¾Ê´Â °æ¿ì swscale filter°¡ ÀÚµ¿À¸·Î µ¿ÀÛÇÑ´Ù. ÀÌ filter´Â ÇÊ¿äÇÑ °æ¿ì software ÀûÀ¸·Î colorspace conversion°ú scalingÀ» ÇÑ´Ù.

mplayer ½ÇÇà½Ã -vo fbdev ¿É¼ÇÀ» »ç¿ëÇÑ´Ù¸é, vo filter·Î frame buffer¸¦ »ç¿ëÇÑ´Ù´Â ÀǹÌÀÌ´Ù.


ID
Password
Join
You plan things that you do not even attempt because of your extreme caution.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-04-16 13:48:09
Processing time 0.0066 sec