aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-blackbird.c
diff options
context:
space:
mode:
authorCatalin Climov <catalin@climov.com>2005-11-09 00:36:17 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:07 -0500
commit31629424132c87f7c8bd79d7ed4d014354a06427 (patch)
treed06538533ad02a6e498a0c9e3ed6fde9eaf65bb5 /drivers/media/video/cx88/cx88-blackbird.c
parent7df64e8c9cee596c2609c99b0ca1ebb6ae2d5b1d (diff)
[PATCH] v4l: 631: implemented the v4l2 mpeg api for blackbird cards
- Implemented the v4l2 mpeg api for blackbird cards. Signed-off-by: Catalin Climov <catalin@climov.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/cx88/cx88-blackbird.c')
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c638
1 files changed, 573 insertions, 65 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..eca36b8539fa 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 8; 41static unsigned int mpegbufs = 32;
42module_param(mpegbufs,int,0644); 42module_param(mpegbufs,int,0644);
43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); 43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
44 44
@@ -683,84 +683,553 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
683================================================================================================================= 683=================================================================================================================
684*DB: "DirectBurn" 684*DB: "DirectBurn"
685*/ 685*/
686static void blackbird_codec_settings(struct cx8802_dev *dev) 686
687static struct blackbird_dnr default_dnr_params = {
688 .mode = BLACKBIRD_DNR_BITS_MANUAL,
689 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
690 .spatial = 0,
691 .temporal = 0
692};
693static struct v4l2_mpeg_compression default_mpeg_params = {
694 .st_type = V4L2_MPEG_PS_2,
695 .st_bitrate = {
696 .mode = V4L2_BITRATE_CBR,
697 .min = 0,
698 .target = 0,
699 .max = 0
700 },
701 .ts_pid_pmt = 16,
702 .ts_pid_audio = 260,
703 .ts_pid_video = 256,
704 .ts_pid_pcr = 259,
705 .ps_size = 0,
706 .au_type = V4L2_MPEG_AU_2_II,
707 .au_bitrate = {
708 .mode = V4L2_BITRATE_CBR,
709 .min = 224,
710 .target = 224,
711 .max = 224
712 },
713 .au_sample_rate = 44100,
714 .au_pesid = 0,
715 .vi_type = V4L2_MPEG_VI_2,
716 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
717 .vi_bitrate = {
718 .mode = V4L2_BITRATE_CBR,
719 .min = 4000,
720 .target = 4500,
721 .max = 6000
722 },
723 .vi_frame_rate = 25,
724 .vi_frames_per_gop = 15,
725 .vi_bframes_count = 2,
726 .vi_pesid = 0,
727 .closed_gops = 0,
728 .pulldown = 0
729};
730
731static enum blackbird_stream_type mpeg_stream_types[] = {
732 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
733 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
734 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
735 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
736};
737static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
738 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
739 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
740 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
741 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
742};
743static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
744 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
745 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
746 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
747};
748/* find the best layer I/II bitrate to fit a given numeric value */
749struct bitrate_bits {
750 u32 bits; /* layer bits for the best fit */
751 u32 rate; /* actual numeric value for the layer best fit */
752};
753struct bitrate_approximation {
754 u32 target; /* numeric value of the rate we want */
755 struct bitrate_bits layer[2];
756};
757static struct bitrate_approximation mpeg_audio_bitrates[] = {
758 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
759 { 0, { { 0, 0, }, { 0, 0, }, }, },
760 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
761 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
762 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
763 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
764 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
765 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
766 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
767 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
768 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
769 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
770 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
771 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
772 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
773 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
774 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
775 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
776 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778};
779static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
780
781static void blackbird_set_default_params(struct cx8802_dev *dev)
687{ 782{
688 int bitrate_mode = 1; 783 struct v4l2_mpeg_compression *params = &dev->params;
689 int bitrate = 7500000;
690 int bitrate_peak = 7500000;
691 bitrate_mode = BLACKBIRD_VIDEO_CBR;
692 bitrate = 4000*1024;
693 bitrate_peak = 4000*1024;
694 784
695 /* assign stream type */ 785 /* assign stream type */
696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 786 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
697 787 params->st_type = V4L2_MPEG_PS_2;
698 /* assign output port */ 788 if( params->st_type == V4L2_MPEG_SS_1 )
699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 789 params->vi_type = V4L2_MPEG_VI_1;
790 else
791 params->vi_type = V4L2_MPEG_VI_2;
792 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
700 793
701 /* assign framerate */ 794 /* assign framerate */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); 795 if( params->vi_frame_rate <= 25 )
703 796 {
704 /* assign frame size */ 797 params->vi_frame_rate = 25;
705 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, 798 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
706 dev->height, dev->width); 799 }
800 else
801 {
802 params->vi_frame_rate = 30;
803 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
804 }
707 805
708 /* assign aspect ratio */ 806 /* assign aspect ratio */
709 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); 807 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
710 808 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
711 /* assign bitrates */ 809 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
712 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
713 bitrate_mode, /* mode */
714 bitrate, /* bps */
715 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
716 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
717 810
718 /* assign gop properties */ 811 /* assign gop properties */
719 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); 812 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
813
814 /* assign gop closure */
815 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
720 816
721 /* assign 3 2 pulldown */ 817 /* assign 3 2 pulldown */
722 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); 818 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
819
820 /* make sure the params are within bounds */
821 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
822 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
823 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
824 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
825 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
826 params->au_bitrate.mode = V4L2_BITRATE_NONE;
723 827
724 /* assign audio properties */ 828 /* assign audio properties */
725 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 829 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
726 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 830 u32 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
727 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
728 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
729 BLACKBIRD_AUDIO_BITS_44100HZ |
730 BLACKBIRD_AUDIO_BITS_LAYER_2 |
731 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
732 BLACKBIRD_AUDIO_BITS_STEREO |
733 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ 831 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
734 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | 832 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
735 BLACKBIRD_AUDIO_BITS_CRC_OFF | 833 BLACKBIRD_AUDIO_BITS_CRC_OFF |
736 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | 834 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
737 BLACKBIRD_AUDIO_BITS_COPY 835 BLACKBIRD_AUDIO_BITS_COPY |
738 ); 836 0;
837 if( params->au_sample_rate <= 32000 )
838 {
839 params->au_sample_rate = 32000;
840 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
841 }
842 else if( params->au_sample_rate <= 44100 )
843 {
844 params->au_sample_rate = 44100;
845 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
846 }
847 else
848 {
849 params->au_sample_rate = 48000;
850 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
851 }
852 if( params->au_type == V4L2_MPEG_AU_2_I )
853 {
854 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
855 }
856 else
857 {
858 /* TODO: try to handle the other formats more gracefully */
859 params->au_type = V4L2_MPEG_AU_2_II;
860 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
861 }
862 if( params->au_bitrate.mode )
863 {
864 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
865 params->au_bitrate.max = params->vi_bitrate.target;
866 else
867 params->au_bitrate.target = params->vi_bitrate.max;
868
869 int layer = params->au_type;
870 if( params->au_bitrate.target == 0 )
871 {
872 /* TODO: use the minimum possible bitrate instead of 0 ? */
873 au_params |= 0;
874 }
875 else if( params->au_bitrate.target >=
876 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
877 {
878 /* clamp the bitrate to the max supported by the standard */
879 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
880 params->au_bitrate.max = params->au_bitrate.target;
881 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
882 }
883 else
884 {
885 /* round up to the nearest supported bitrate */
886 int i;
887 for(i = 1; i < BITRATES_SIZE; i++)
888 {
889 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
890 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
891 {
892 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
893 params->au_bitrate.max = params->au_bitrate.target;
894 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
895 break;
896 }
897 }
898 }
899 }
900 else
901 {
902 /* TODO: ??? */
903 params->au_bitrate.target = params->au_bitrate.max = 0;
904 au_params |= 0;
905 }
906 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
907
908 /* assign bitrates */
909 if( params->vi_bitrate.mode )
910 {
911 /* bitrate is set, let's figure out the cbr/vbr mess */
912 if( params->vi_bitrate.max < params->vi_bitrate.target )
913 {
914 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
915 params->vi_bitrate.max = params->vi_bitrate.target;
916 else
917 params->vi_bitrate.target = params->vi_bitrate.max;
918 }
919 }
920 else
921 {
922 if( params->st_bitrate.max < params->st_bitrate.target )
923 {
924 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
925 params->st_bitrate.target = params->st_bitrate.max;
926 else
927 params->st_bitrate.max = params->st_bitrate.target;
928 }
929 /* calculate vi_bitrate = st_bitrate - au_bitrate */
930 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
931 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
932 }
933 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
934 mpeg_video_bitrates[params->vi_bitrate.mode],
935 params->vi_bitrate.target * 1000, /* kbps -> bps */
936 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
937 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
938
939 /* TODO: implement the stream ID stuff:
940 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
941 ps_size, au_pesid, vi_pesid
942 */
943}
944#define CHECK_PARAM( name ) ( dev->params.name != params->name )
945#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
946#define UPDATE_PARAM( name ) dev->params.name = params->name
947void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
948{
949 /* assign stream type */
950 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
951 params->st_type = V4L2_MPEG_PS_2;
952 if( params->st_type == V4L2_MPEG_SS_1 )
953 params->vi_type = V4L2_MPEG_VI_1;
954 else
955 params->vi_type = V4L2_MPEG_VI_2;
956 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
957 {
958 UPDATE_PARAM( st_type );
959 UPDATE_PARAM( vi_type );
960 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
961 }
962
963 /* assign framerate */
964 if( params->vi_frame_rate <= 25 )
965 params->vi_frame_rate = 25;
966 else
967 params->vi_frame_rate = 30;
968 IF_PARAM( vi_frame_rate )
969 {
970 UPDATE_PARAM( vi_frame_rate );
971 if( params->vi_frame_rate == 25 )
972 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
973 else
974 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
975 }
976
977 /* assign aspect ratio */
978 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
979 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
980 IF_PARAM( vi_aspect_ratio )
981 {
982 UPDATE_PARAM( vi_aspect_ratio );
983 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
984 }
985
986 /* assign gop properties */
987 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
988 {
989 UPDATE_PARAM( vi_frames_per_gop );
990 UPDATE_PARAM( vi_bframes_count );
991 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
992 }
739 993
740 /* assign gop closure */ 994 /* assign gop closure */
741 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); 995 IF_PARAM( closed_gops )
996 {
997 UPDATE_PARAM( closed_gops );
998 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
999 }
1000
1001 /* assign 3 2 pulldown */
1002 IF_PARAM( pulldown )
1003 {
1004 UPDATE_PARAM( pulldown );
1005 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1006 }
1007
1008 /* make sure the params are within bounds */
1009 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1010 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1011 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1012 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1013 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1014 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1015
1016 /* assign audio properties */
1017 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1018 u32 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1019 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1020 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1021 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1022 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1023 BLACKBIRD_AUDIO_BITS_COPY |
1024 0;
1025 if( params->au_sample_rate < 32000 )
1026 {
1027 params->au_sample_rate = 32000;
1028 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1029 }
1030 else if( params->au_sample_rate < 44100 )
1031 {
1032 params->au_sample_rate = 44100;
1033 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1034 }
1035 else
1036 {
1037 params->au_sample_rate = 48000;
1038 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1039 }
1040 if( params->au_type == V4L2_MPEG_AU_2_I )
1041 {
1042 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1043 }
1044 else
1045 {
1046 /* TODO: try to handle the other formats more gracefully */
1047 params->au_type = V4L2_MPEG_AU_2_II;
1048 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1049 }
1050 if( params->au_bitrate.mode )
1051 {
1052 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1053 params->au_bitrate.max = params->vi_bitrate.target;
1054 else
1055 params->au_bitrate.target = params->vi_bitrate.max;
742 1056
1057 int layer = params->au_type;
1058 if( params->au_bitrate.target == 0 )
1059 {
1060 /* TODO: use the minimum possible bitrate instead of 0 ? */
1061 au_params |= 0;
1062 }
1063 else if( params->au_bitrate.target >=
1064 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1065 {
1066 /* clamp the bitrate to the max supported by the standard */
1067 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1068 params->au_bitrate.max = params->au_bitrate.target;
1069 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1070 }
1071 else
1072 {
1073 /* round up to the nearest supported bitrate */
1074 int i;
1075 for(i = 1; i < BITRATES_SIZE; i++)
1076 {
1077 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1078 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1079 {
1080 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1081 params->au_bitrate.max = params->au_bitrate.target;
1082 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1083 break;
1084 }
1085 }
1086 }
1087 }
1088 else
1089 {
1090 /* TODO: ??? */
1091 params->au_bitrate.target = params->au_bitrate.max = 0;
1092 au_params |= 0;
1093 }
1094 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1095 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1096 || CHECK_PARAM( au_bitrate.target )
1097 )
1098 {
1099 UPDATE_PARAM( au_type );
1100 UPDATE_PARAM( au_sample_rate );
1101 UPDATE_PARAM( au_bitrate );
1102 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1103 }
743 1104
1105 /* assign bitrates */
1106 if( params->vi_bitrate.mode )
1107 {
1108 /* bitrate is set, let's figure out the cbr/vbr mess */
1109 if( params->vi_bitrate.max < params->vi_bitrate.target )
1110 {
1111 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1112 params->vi_bitrate.max = params->vi_bitrate.target;
1113 else
1114 params->vi_bitrate.target = params->vi_bitrate.max;
1115 }
1116 }
1117 else
1118 {
1119 if( params->st_bitrate.max < params->st_bitrate.target )
1120 {
1121 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1122 params->st_bitrate.target = params->st_bitrate.max;
1123 else
1124 params->st_bitrate.max = params->st_bitrate.target;
1125 }
1126 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1127 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1128 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1129 }
1130 UPDATE_PARAM( st_bitrate );
1131 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1132 || CHECK_PARAM( vi_bitrate.target )
1133 )
1134 {
1135 UPDATE_PARAM( vi_bitrate );
1136 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1137 mpeg_video_bitrates[params->vi_bitrate.mode],
1138 params->vi_bitrate.target * 1000, /* kbps -> bps */
1139 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1140 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1141 }
1142
1143 /* TODO: implement the stream ID stuff:
1144 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1145 ps_size, au_pesid, vi_pesid
1146 */
1147 UPDATE_PARAM( ts_pid_pmt );
1148 UPDATE_PARAM( ts_pid_audio );
1149 UPDATE_PARAM( ts_pid_video );
1150 UPDATE_PARAM( ts_pid_pcr );
1151 UPDATE_PARAM( ps_size );
1152 UPDATE_PARAM( au_pesid );
1153 UPDATE_PARAM( vi_pesid );
1154}
1155
1156static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1157{
744 /* assign dnr filter mode */ 1158 /* assign dnr filter mode */
1159 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1160 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1161 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1162 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
745 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, 1163 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
746 BLACKBIRD_DNR_BITS_MANUAL, 1164 dev->dnr_params.mode,
747 BLACKBIRD_MEDIAN_FILTER_DISABLED 1165 dev->dnr_params.type
748 ); 1166 );
1167
1168 /* assign dnr filter props*/
1169 if( dev->dnr_params.spatial > 15 )
1170 dev->dnr_params.spatial = 15;
1171 if( dev->dnr_params.temporal > 31 )
1172 dev->dnr_params.temporal = 31;
1173 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1174 dev->dnr_params.spatial,
1175 dev->dnr_params.temporal
1176 );
1177}
1178#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1179#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1180void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1181{
1182 /* assign dnr filter mode */
1183 /* clamp values */
1184 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1185 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1186 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1187 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1188 /* check if the params actually changed */
1189 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1190 {
1191 UPDATE_DNR_PARAM( mode );
1192 UPDATE_DNR_PARAM( type );
1193 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1194 }
749 1195
750 /* assign dnr filter props*/ 1196 /* assign dnr filter props*/
751 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); 1197 if( dnr_params->spatial > 15 )
1198 dnr_params->spatial = 15;
1199 if( dnr_params->temporal > 31 )
1200 dnr_params->temporal = 31;
1201 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1202 {
1203 UPDATE_DNR_PARAM( spatial );
1204 UPDATE_DNR_PARAM( temporal );
1205 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1206 }
1207}
1208
1209static void blackbird_codec_settings(struct cx8802_dev *dev)
1210{
1211
1212 /* assign output port */
1213 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1214
1215 /* assign frame size */
1216 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1217 dev->height, dev->width);
752 1218
753 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 1219 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
754 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); 1220 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
755 1221
756 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ 1222 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
757 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, 1223 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
758 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, 1224 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
759 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ 1225 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
760 ); 1226 );
761 1227
762 /* assign frame drop rate */ 1228 /* assign frame drop rate */
763 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ 1229 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1230
1231 blackbird_set_default_params(dev);
1232 blackbird_set_default_dnr_params(dev);
764} 1233}
765 1234
766static int blackbird_initialize_codec(struct cx8802_dev *dev) 1235static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1320,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
851 struct cx8802_fh *fh = q->priv_data; 1320 struct cx8802_fh *fh = q->priv_data;
852 1321
853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ 1322 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
854 fh->dev->ts_packet_count = 32; /* was: 100 */ 1323 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
855 1324
856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 1325 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
857 if (0 == *count) 1326 *count = fh->dev->ts_packet_count;
858 *count = mpegbufs;
859 if (*count < 2)
860 *count = 2;
861 if (*count > 32)
862 *count = 32;
863 return 0; 1327 return 0;
864} 1328}
865 1329
@@ -868,7 +1332,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
868 enum v4l2_field field) 1332 enum v4l2_field field)
869{ 1333{
870 struct cx8802_fh *fh = q->priv_data; 1334 struct cx8802_fh *fh = q->priv_data;
871 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); 1335 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
872} 1336}
873 1337
874static void 1338static void
@@ -920,8 +1384,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
920 V4L2_CAP_VIDEO_CAPTURE | 1384 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE | 1385 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING | 1386 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0; 1387 0;
926 if (UNSET != core->tuner_type) 1388 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER; 1389 cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1403,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
941 1403
942 memset(f,0,sizeof(*f)); 1404 memset(f,0,sizeof(*f));
943 f->index = index; 1405 f->index = index;
944 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 1406 strlcpy(f->description, "MPEG", sizeof(f->description));
945 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1407 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
946 f->pixelformat = V4L2_PIX_FMT_MPEG; 1408 f->pixelformat = V4L2_PIX_FMT_MPEG;
947 return 0; 1409 return 0;
948 } 1410 }
949 case VIDIOC_G_FMT: 1411 case VIDIOC_G_FMT:
950 case VIDIOC_S_FMT:
951 case VIDIOC_TRY_FMT:
952 { 1412 {
953 /* FIXME -- quick'n'dirty for exactly one size ... */
954 struct v4l2_format *f = arg; 1413 struct v4l2_format *f = arg;
955 1414
956 memset(f,0,sizeof(*f)); 1415 memset(f,0,sizeof(*f));
957 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1416 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1417 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1418 f->fmt.pix.bytesperline = 0;
1419 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
1420 f->fmt.pix.colorspace = 0;
958 f->fmt.pix.width = dev->width; 1421 f->fmt.pix.width = dev->width;
959 f->fmt.pix.height = dev->height; 1422 f->fmt.pix.height = dev->height;
1423 f->fmt.pix.field = fh->mpegq.field;
1424 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1425 dev->width, dev->height, fh->mpegq.field );
1426 return 0;
1427 }
1428 case VIDIOC_TRY_FMT:
1429 {
1430 struct v4l2_format *f = arg;
1431
1432 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1433 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0; 1434 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; 1435 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
964 f->fmt.pix.colorspace = 0; 1436 f->fmt.pix.colorspace = 0;
1437 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1438 dev->width, dev->height, fh->mpegq.field );
1439 return 0;
1440 }
1441 case VIDIOC_S_FMT:
1442 {
1443 struct v4l2_format *f = arg;
1444
1445 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1446 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1447 f->fmt.pix.bytesperline = 0;
1448 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
1449 f->fmt.pix.colorspace = 0;
1450 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1451 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
965 return 0; 1452 return 0;
966 } 1453 }
967 1454
@@ -985,6 +1472,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
985 case VIDIOC_STREAMOFF: 1472 case VIDIOC_STREAMOFF:
986 return videobuf_streamoff(&fh->mpegq); 1473 return videobuf_streamoff(&fh->mpegq);
987 1474
1475 /* --- mpeg compression -------------------------------------- */
1476 case VIDIOC_G_MPEGCOMP:
1477 {
1478 struct v4l2_mpeg_compression *f = arg;
1479
1480 memcpy(f,&dev->params,sizeof(*f));
1481 return 0;
1482 }
1483 case VIDIOC_S_MPEGCOMP:
1484 {
1485 struct v4l2_mpeg_compression *f = arg;
1486
1487 blackbird_set_params(dev, f);
1488 return 0;
1489 }
1490
988 default: 1491 default:
989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); 1492 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
990 } 1493 }
@@ -1034,16 +1537,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
1034 file->private_data = fh; 1537 file->private_data = fh;
1035 fh->dev = dev; 1538 fh->dev = dev;
1036 1539
1037 /* FIXME: locking against other video device */
1038 cx88_set_scale(dev->core, dev->width, dev->height,
1039 V4L2_FIELD_INTERLACED);
1040
1041 videobuf_queue_init(&fh->mpegq, &blackbird_qops, 1540 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
1042 dev->pci, &dev->slock, 1541 dev->pci, &dev->slock,
1043 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1542 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1044 V4L2_FIELD_TOP, 1543 V4L2_FIELD_INTERLACED,
1045 sizeof(struct cx88_buffer), 1544 sizeof(struct cx88_buffer),
1046 fh); 1545 fh);
1546
1547 /* FIXME: locking against other video device */
1548 cx88_set_scale(dev->core, dev->width, dev->height,
1549 fh->mpegq.field);
1550
1047 return 0; 1551 return 0;
1048} 1552}
1049 1553
@@ -1173,6 +1677,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1173 dev->core = core; 1677 dev->core = core;
1174 dev->width = 720; 1678 dev->width = 720;
1175 dev->height = 576; 1679 dev->height = 576;
1680 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1681 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1176 1682
1177 err = cx8802_init_common(dev); 1683 err = cx8802_init_common(dev);
1178 if (0 != err) 1684 if (0 != err)
@@ -1257,6 +1763,8 @@ module_exit(blackbird_fini);
1257 1763
1258EXPORT_SYMBOL(cx88_ioctl_hook); 1764EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator); 1765EXPORT_SYMBOL(cx88_ioctl_translator);
1766EXPORT_SYMBOL(blackbird_set_params);
1767EXPORT_SYMBOL(blackbird_set_dnr_params);
1260 1768
1261/* ----------------------------------------------------------- */ 1769/* ----------------------------------------------------------- */
1262/* 1770/*