· 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¸¦ »ç¿ëÇÑ´Ù´Â ÀǹÌÀÌ´Ù.




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.0074 sec